Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Simple VB Question

Options
  • 03-04-2003 5:25pm
    #1
    Registered Users Posts: 23,641 ✭✭✭✭


    I want to give an error msgbox telling the user to enter a Numerical Value when they try to enter a non-numerical value.

    I am looking fot the IsNaN value in VB.


Comments

  • Closed Accounts Posts: 19,777 ✭✭✭✭The Corinthian


    If IsNumeric(foobar) Then
      'It's a Number
    Else
      'It's not a number
    End If
    


  • Registered Users Posts: 15,443 ✭✭✭✭bonkey


    Alternately, use "on error" to handle what happens when you put the value into a numberic variable and it fails.

    This is often an easier solution if you need the user to enter an integer value. IsNumeric will accept non-integer, scientific-notation and other number forms, if memory serves.

    jc


  • Registered Users Posts: 7,468 ✭✭✭Evil Phil


    Well you can do either. He is testing for numeric values so IsNumeric is fine. If he's testing for something specific he could do something like
    IsNumeric(CInt(foo)) Or IsNumeric(CLng(foo))
    

    Personally, and this is just my preference, I go with IsNumeric and use error trapping for something unexepected. However there have been times that I've used on error and deliberately caused errors to be raised. Waffle waffle etc ...


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Another solution is to ignore keystrokes that add any characters other than numbers (and possibly minus and/or decimal seperator depending on whether those would be valid or not).

    Then add a final check along the lines of bonkey's suggestion.


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Demo of very efficient way of banning non-numeric keystrokes:

    Create a form, stick a textbox on it. Leave the name "Text1".
    Option Explicit
    Private Const GWL_STYLE As Long = &HFFFFFFF0
    Private Const ES_NUMBER As Long = &H2000&
    
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As OLE_HANDLE, ByVal nIndex As Long) As Long
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As OLE_HANDLE, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    
    Private Sub Form_Load()
        Dim hWndText As OLE_HANDLE
        hWndText = Text1.hWnd
        SetWindowLong Text1.hWnd, GWL_STYLE, GetWindowLong(Text1.hWnd, GWL_STYLE) Or ES_NUMBER
    End Sub
    

    If you are only supporting NT/2000/XP then you can use GetWindowLongW instead of GetWindowLongA, and so on.

    This code alters the way the actual text-edit window works, so the non-numeric keystrokes get blocked way before the event-handlers kick in, and without any further processing by your code.

    It's still possible to paste in non-numeric stuff though, so you still need to check for that.


  • Advertisement
  • Closed Accounts Posts: 7,230 ✭✭✭scojones


    I need to get me a book on the windows api.


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Originally posted by sjones
    I need to get me a book on the windows api.
    Hardcore Visual Basic used to be part of MSDN. Don't know if it still is now, but it has enough to get you started and then to the point where you'd mostly be looking at the API documentation rather than how-tos.


  • Closed Accounts Posts: 19,777 ✭✭✭✭The Corinthian


    This is a simpler way of banning non-numeric keystrokes, imho:
    Private Sub Text1_KeyPress(KeyAscii As Integer)
        If Not IsNumeric(Chr(KeyAscii)) Then KeyAscii = 0
    End Sub
    
    Again, as Talliesin pointed out, it's still possible to paste in non-numeric stuff though, so you still need to check for that.


  • Closed Accounts Posts: 7,230 ✭✭✭scojones


    Thanks Talliesin :)


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Originally posted by The Corinthian
    This is a simpler way of banning non-numeric keystrokes, imho:
    Private Sub Text1_KeyPress(KeyAscii As Integer)
        If Not IsNumeric(Chr(KeyAscii)) Then KeyAscii = 0
    End Sub
    
    Again, as Talliesin pointed out, it's still possible to paste in non-numeric stuff though, so you still need to check for that.

    Slight error, that also bans backspace. This fixes that:
    Private Sub Text1_KeyPress(KeyAscii As Integer)
        If Not IsNumeric(Chr(KeyAscii)) And KeyAscii <> vbKeyBack Then KeyAscii = 0
    End Sub
    

    There are of course numerous ways of skinning a cat. My preferred variation on the above uses a Select Case, and an explicit check of the key (as opposed to calling IsNumeric). 99% of the time it makes little difference.

    My main reason for preferring the API version isn't the speed increase (which just makes the program get back to doing nothing faster), but because it's a "fire and forget" technique, and because the user32.dll code that makes ES_NUMBER do its stuff has been around since at least Windows 3.1 (possibly since 1.0) and I can be pretty sure it's bug-free.


  • Advertisement
  • Closed Accounts Posts: 19,777 ✭✭✭✭The Corinthian


    Originally posted by Talliesin
    Slight error, that also bans backspace.
    Pedant :p

    (Of course backspace is not strictly speaking a numeric character...)


  • Registered Users Posts: 1,393 ✭✭✭Inspector Gadget


    Silly question, perhaps, but will that also ban decimal points, plus/minus signs and/or exponents ("E")? It's too late in the evening for me to bother checking myself...

    Also, don't the arrow keys generate ASCII codes? (vbKeyLeft, vbKeyDown, etc.)?

    Gadget


  • Closed Accounts Posts: 9,314 ✭✭✭Talliesin


    Originally posted by Inspector Gadget
    Silly question, perhaps, but will that also ban decimal points, plus/minus signs and/or exponents ("E")? It's too late in the evening for me to bother checking myself...
    Yes both methods above will ban these. Which of course may be a good or bad thing. Corinthian's method is easily adapted to allow them, mine is not.
    Also, don't the arrow keys generate ASCII codes? (vbKeyLeft, vbKeyDown, etc.)?

    Not in this case. Both of these methods deal with the keypresses at a point in the default processing were the conversion of keypresses into either characters, caret movements, loss of focus, etc. has already been performed and that processing has decided to enter characters into the text. Hence vbKeyLeft etc. doesn't trigger the filter at all.

    A version of Corinthian's that used the keydown or keyup event could block the arrow keys if you wanted to. An API version that would do that would require you to subclass the window, which I'm not going to get into right now.


  • Registered Users Posts: 23,641 ✭✭✭✭Elmo


    Thanks all


Advertisement