txtCustCode_Change()

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mclueless
    New Member
    • Jan 2008
    • 56

    txtCustCode_Change()

    [CODE=vb]Private Sub txtCustCode_Cha nge()

    Dim str As String
    Dim i As Integer
    For i = 1 To Len(txtCustCode )
    str = Mid(txtCustCode , i, 1)
    If Not IsNumeric(str) Then
    msgbox "Only Numeric values allowed"
    txtCustCode.Tex t = ""
    End If
    Next

    End Sub[/CODE]

    This is my code.....so when user enters some values that are not numeric an error message is shown and the entire textbox is cleared while I want only the non-numeric text to be cleared. Is there any way to achieve this in VB6?
    Last edited by Killer42; Feb 25 '08, 12:49 AM. Reason: Added CODE=vb tag
  • jagged
    New Member
    • Feb 2008
    • 23

    #2
    Code:
    Private Sub Text1_Change()
        Dim strChar
        Dim strNumbersOnly
        
        For x = 1 To Len(Text1)
            strChar = Mid(Text1, x, 1)
            If Asc(strChar) >= 48 And Asc(strChar) < 58 Then
                strNumbersOnly = strNumbersOnly & strChar
            End If
        Next
        
        Text1.Text = strNumbersOnly
        Text1.SelStart = Len(strNumbersOnly) ' Move caret to end
        
        
    End Sub
    FYI, 48 to 57 are ASCII codes for 0 - 9.

    Comment

    • Killer42
      Recognized Expert Expert
      • Oct 2006
      • 8429

      #3
      Thanks for the input, jagged.

      One thing I'd recommend is simply comparing strchar with "0" and "9", rather than invoking the Asc function each time. Fewer function calls means less CPU used, though of course the difference in this case will be microscopic. However, in this case dropping the function calls actually improves the readability.

      And I have one comment, mclueless. Stick with explicitly declaring the variable types you plan to use, as you have done here.

      The lazy way, as jagged has done, is to allow VB to choose the data type. In VB6, that generally means Variant type, which is the slowest and most space-wasting type available. It's also the most flexible, which is obviously not a coincidence. But it's generally better to use the correct type for the data you expect to store.

      Oh, and one other thing. I believe this code will make editing the textbox very difficult, since the text cursor will keep jumping to the end, no matter what. I believe you'd see an improved user experience by making any one (or more) of these changes...
      • Check the key pressed in KeyDown (or perhaps KeyPress) event and cancel it if unwanted, instead of changing the textbox contents after the fact.
      • Do the check-and-correct in LostFocus event rather than the Change event.
      • Make a note of the cursor position (.SelStart) before changing the contents, and restore it afterward so the cursor doesn't jump around.
      Last edited by Killer42; Feb 25 '08, 01:01 AM.

      Comment

      • jagged
        New Member
        • Feb 2008
        • 23

        #4
        Hey Killer,

        Are you revising all my recent posts? :)

        What do you mean by comparing strcat to "0" or "9"? Like one big IF strChar = "0" or strchar = "1" or .... or a Select Case strchar : Case "0","1","2" .... ?

        From experience, string manipulation in VB is not the fastest thing. Maybe it doesn't apply to comparison (I doubt it) but like you said, best case, calling asc() is a microscopic lag.

        With keydown / keypress / keyup, you can't cancel the events as far as I know. It's been a while since I did UI in vb6 but I didn't find it when I looked earlier but yeah, that would be preferable if it exists.

        As for LostFocus (or the newer Validate event), the problem is you enter "asdf2134asdfas df" and magically your asdfasdfasdf text disappears when you click away. That's funky behaviour. At that point, the most the app should do is notify the user of the error, not delete stuff.

        I hadn't considered the caret jumping back and forth if the user were to edit in mid string, which is definitely a problem. Storing the current position and returning to that position + 1 would be the better.

        And thanks for pointing out my laziness in not declaring explicit types.

        Comment

        • Killer42
          Recognized Expert Expert
          • Oct 2006
          • 8429

          #5
          Originally posted by jagged
          Are you revising all my recent posts? :)
          Well, I wouldn't quite say all... ;)

          Originally posted by jagged
          What do you mean by comparing strcat to "0" or "9"? Like one big IF strChar = "0" or strchar = "1" or .... or a Select Case strchar : Case "0","1","2" .... ?
          The Select Case might be an option, but what I had in mind was, instead of
          If Asc(strChar) >= 48 And Asc(strChar) < 58 Then
          using
          If strChar >= "0" And strChar <= "9" Then

          People often forget that you can make the same sort of comparisons between strings that you can between numbers - you're not limited to "=".

          Oh, and don't forget the To clause in the Select Case structure. It's ideal for this sort of situation. For example...[CODE=vb]Select Case strChar
          Case "0" To "9"
          ' Ok
          Case Else
          ' Not OK.
          End Select[/CODE]

          Originally posted by jagged
          ...
          With keydown / keypress / keyup, you can't cancel the events as far as I know. It's been a while since I did UI in vb6 but I didn't find it when I looked earlier but yeah, that would be preferable if it exists.
          You can cancel the KeyPress event by setting KeyAscii to zero. (Had to go test this, as I can never remember whether it's KeyDown or KeyPress you can cancel.)

          Originally posted by jagged
          As for LostFocus (or the newer Validate event), the problem is you enter "asdf2134asdfas df" and magically your asdfasdfasdf text disappears when you click away. That's funky behaviour. At that point, the most the app should do is notify the user of the error, not delete stuff.
          Well, that's a largely subjective argument, and would depend on the circumstances. It's a bit like AutoCorrect as you type in Word, for instance. Some love it, some hate it. I do think that there should be some visual hint to alert the user that the value was changed, at the very least. Depending on how it's used, yes it may be a pain. But it is an option to be considered.

          Originally posted by jagged
          I hadn't considered the caret jumping back and forth if the user were to edit in mid string, which is definitely a problem. Storing the current position and returning to that position + 1 would be the better.
          Not so sure about the +1. Since you're removing the character they (presumably) just entered, doesn't that mean you'd skip over the next one? I guess I should try this, when I can find a few minutes.

          Originally posted by jagged
          And thanks for pointing out my laziness in not declaring explicit types.
          Hey, no problem. If there's one thing that I love, it's poking holes in someone else's code. :D



          mclueless, there's one other thing you need to consider in such a situation. That is, exactly what constitutes a "numeric" value. For instance, do you allow decimal points? Thousands separators? What about if there's already a decimal point, do you allow another? VB won't like trying to interpret "123.456.78 9" as a number. As for thousands separators, you will proably need to strip them out before moving to a numeric variable.

          One of my favourite techniques is to format a number as simple digits in the GotFocus event, and format it for display (with digits grouped in thousands, etc.) in the LostFocus event.
          Last edited by Killer42; Feb 25 '08, 02:39 AM.

          Comment

          • Killer42
            Recognized Expert Expert
            • Oct 2006
            • 8429

            #6
            Oh, one last thing I forgot to mention.

            You may be able to avoid this whole mess by using a Masked Edit control rather than a textbox. The Masked Edit control allows you more control over what is input without having to code it all.

            Comment

            Working...