?
Solved

valid keyascii after numeric char

Posted on 2011-10-18
23
Medium Priority
?
729 Views
Last Modified: 2012-05-12
value from text18.text is
18.5x2.75
3.50X3.50
1.75X10.25

how can i fix only one x ( it doesn't matter lower x or upper X ) but only one after number (like i mentioned above)

please check attached code


Private Sub Text18_KeyPress(KeyAscii As Integer)
'    MsgBox KeyAscii
'    KeyAscii = Asc(UCase$(Chr$(KeyAscii)))
    Call Check_Numeric_Multiply(KeyAscii)
    If KeyAscii = 13 Then KeyAscii = 0
    
End Sub


Public Sub Check_Numeric_Multiply(ByRef code As Integer)
    Select Case code
        Case 13
        Case 120, 88   ' This is a x and X
        Case 48 To 57  ' This is a digit.
        Case Else      ' Reject any other key.
        
             code = 0  ' Reject any other key.
    End Select
End Sub

Open in new window

0
Comment
Question by:crystal_Tech
  • 10
  • 6
  • 5
  • +1
23 Comments
 
LVL 101

Expert Comment

by:mlmcc
ID: 36986040
I assume this code is part of a form.

Add a form variable
Dim HasX as Boolean

Private Sub Text18_KeyPress(KeyAscii As Integer)
'    MsgBox KeyAscii
'    KeyAscii = Asc(UCase$(Chr$(KeyAscii)))
    If (KeyAscii = 88 OR KeyAscii = 120)  AND HasX then
        KeyAscii = 0
    Else
        HasX = True
    EndIf
       
    Call Check_Numeric_Multiply(KeyAscii)
    If KeyAscii = 13 Then KeyAscii = 0
   
End Sub

mlmcc
0
 
LVL 76

Expert Comment

by:GrahamSkan
ID: 36986044
How about?

        Case 120, 88   ' This is a x and X
            If Not IsNumeric(Text18.Text) Then
                code = 0
            End If
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36986380
Use the Split() function with text comparison parameter (non-case-sensitive comparison)

This will result in an array (actually a vector).

example:
Text18.Text = "18.5x2.75"

Private Sub Text18_LostFocus()
  Dim strParsed() As String
  strParsed = Split(Text18.Text, "x", vbTextCompare)
  Debug.Print "First Number: " & strParsed(0)
  Debug.Print "Second Number: " & strParsed(1)
End Sub

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 76

Expert Comment

by:GrahamSkan
ID: 36986476
Note that you do not allow the decimal point (ASCII 46) to be typed in.

A full, final validation could be
Function Validate(strText As String) As Boolean
    Dim strNumbers() As String
    
    strNumbers = Split(Replace(strText, "x", "X"), "X")
    If UBound(strNumbers) = 1 Then
       If IsNumeric(strNumbers(0)) Then
           If IsNumeric(strNumbers(1)) Then
               Validate = True
           End If
       End If
    End If
End Function

Open in new window

0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36986868
i want only one x or X between  number
if user press x or X before first number, then keyascci = 0 but after first number only one x or X allow if another x or X pressed then keyascii = 0
after second number any key not allowed  keyascci = 0
so how can i do this

0
 
LVL 46

Expert Comment

by:aikimark
ID: 36986955
might these numbers be negative, or are they always positive?
0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36986997
always positive
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36987295
Since all new (KeyAscii) characters will be placed at a specific location in a textbox (upon exit from the KeyPress event), we have to use the SetStart property to mimic a post-exit textbox string for our validation.

This should be close to what you need.
Private Sub Text18_KeyPress(KeyAscii As Integer)
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If SelStart = 0 Then
        strPostKeyValue = Chr(KeyAscii) & Text18.Text
    Else
        strPostKeyValue = Left$(Text18.Text, Text18.SelStart) & Chr(KeyAscii) & Mid$(Text18.Text, SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyAscii = 0
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyAscii = 0
        End If
    End If

End Sub

Open in new window

0
 
LVL 46

Expert Comment

by:aikimark
ID: 36987307
your floating point numbers will need to start with a digit, not a decimal point.
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36987362
You might also package the code for use with other textbox controls.

Example:
Private Sub Text18_KeyPress(KeyAscii As Integer)
    If KeyIsValid(Text18, KeyAscii) Then
    Else
        KeyAscii =  0
    End If

End Sub

Public Function KeyIsValid(parmTxtBox As TextBox, parmKeyAscii As Integer) As Boolean
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If SelStart = 0 Then
        strPostKeyValue = Chr(parmKeyAscii) & parmTxtBox.Text
    Else
        strPostKeyValue = Left$(parmTxtBox.Text, parmTxtBox.SelStart) & Chr(parmKeyAscii) & Mid$(parmTxtBox.Text, SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    KeyIsValid =  True
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyIsValid = False
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyIsValid = False
        End If
    End If
End Sub

Open in new window

0
 
LVL 101

Expert Comment

by:mlmcc
ID: 36987441
Try this code

mlmcc
If (KeyAscii = 88 Or KeyAscii = 120) And HasX Then
        KeyAscii = 0
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) And HasNum Then
        HasX = True
        HasNum = False
        HasDecimal = False
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) Then
        KeyAscii = 0
    ElseIf KeyAscii >= 48 And KeyAscii <= 57 Then
        HasNum = True
    ElseIf KeyAscii = Asc(".") And HasDecimal Then
        KeyAscii = 0
    ElseIf KeyAscii = Asc(".") Then
        HasDecimal = True
    Else
        KeyAscii = 0
    End If

Open in new window

0
 
LVL 101

Expert Comment

by:mlmcc
ID: 36987500
This one ensures format has a digit before and after the decimal

mlmcc
If (KeyAscii = 88 Or KeyAscii = 120) And HasX Then
        KeyAscii = 0
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) And HasNum Then
        HasX = True
        HasNum = False
        HasDecimal = False
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) Then
        KeyAscii = 0
    ElseIf KeyAscii >= 48 And KeyAscii <= 57 Then
        HasNum = True
    ElseIf KeyAscii = Asc(".") And HasDecimal Then
        KeyAscii = 0
    ElseIf KeyAscii = Asc(".") And HasNum Then
        HasDecimal = True
        HasNum = False
    Else
        KeyAscii = 0
    End If

Open in new window

0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36988066

@ aikimark: tried your code , but i can not pressed x or X after first number.

@ mlmcc: tried your code , but also i can not pressed x or X after first number.
0
 
LVL 101

Expert Comment

by:mlmcc
ID: 36988179
I added this to the form load

   HasX = False
   HasNum = False
   HasDecimal = False

It works on my machine

mlmcc


0
 
LVL 46

Expert Comment

by:aikimark
ID: 36988307
>>i can not pressed x or X after first number.

This works for me.  What does your textbox look like before you press the X key?

Where is the cursor?
0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36988453
@ mlmcc  
 
Private Sub Text18_KeyPress(KeyAscii As Integer)
    
Dim HasX, HasNum, HasDecimal As Boolean
HasX = False
   HasNum = False
   HasDecimal = False

If (KeyAscii = 88 Or KeyAscii = 120) And HasX Then
        KeyAscii = 0
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) And HasNum Then
        HasX = True
        HasNum = False
        HasDecimal = False
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) Then
        KeyAscii = 0
    ElseIf KeyAscii >= 48 And KeyAscii <= 57 Then
        HasNum = True
    ElseIf KeyAscii = Asc(".") And HasDecimal Then
        KeyAscii = 0
    ElseIf KeyAscii = Asc(".") And HasNum Then
        HasDecimal = True
        HasNum = False
    Else
        KeyAscii = 0
    End If
End Sub

Open in new window


@ aikimark:
after 153 i pressed X but it wont, on debug i found that here
strPostKeyValue is "X153"
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36988554
is all the text in the textbox selected?
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36988772
I see the problem.  I was working entirely in code (formless) and had created a SelStart variable.  I failed to change it when I posted it.  It should be the SelStart property of the textbox.

Private Sub Text18_KeyPress(KeyAscii As Integer)
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If Text18.SelStart = 0 Then
        strPostKeyValue = Chr(KeyAscii) & Text18.Text
    Else
        strPostKeyValue = Left$(Text18.Text, Text18.SelStart) & Chr(KeyAscii) & Mid$(Text18.Text, SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyAscii = 0
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyAscii = 0
        End If
    End If

End Sub

Open in new window


Likewise, the packaged code must be changed as well.
Private Sub Text18_KeyPress(KeyAscii As Integer)
    If KeyIsValid(Text18, KeyAscii) Then
    Else
        KeyAscii =  0
    End If

End Sub

Public Function KeyIsValid(parmTxtBox As TextBox, parmKeyAscii As Integer) As Boolean
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If parmTxtBox.SelStart = 0 Then
        strPostKeyValue = Chr(parmKeyAscii) & parmTxtBox.Text
    Else
        strPostKeyValue = Left$(parmTxtBox.Text, parmTxtBox.SelStart) & Chr(parmKeyAscii) & Mid$(parmTxtBox.Text, SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    KeyIsValid =  True
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyIsValid = False
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyIsValid = False
        End If
    End If
End Sub

Open in new window


========================
The fact that the code didn't give you a compile error indicates that you lack an
Option Explicit
statement in your General Declarations section.
0
 
LVL 101

Expert Comment

by:mlmcc
ID: 36988807
In my code
Form Code
Dim HasX, HasNum, HasDecimal As Boolean

Sub Form1_Load()
   HasX = False
   HasNum = False
   HasDecimal = False
End Sub

Private Sub Text18_KeyPress(KeyAscii As Integer)
    If (KeyAscii = 88 Or KeyAscii = 120) And HasX Then
        KeyAscii = 0
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) And HasNum Then
        HasX = True
        HasNum = False
        HasDecimal = False
    ElseIf (KeyAscii = 88 Or KeyAscii = 120) Then
        KeyAscii = 0
    ElseIf KeyAscii >= 48 And KeyAscii <= 57 Then
        HasNum = True
    ElseIf KeyAscii = Asc(".") And HasDecimal Then
        KeyAscii = 0
    ElseIf KeyAscii = Asc(".") And HasNum Then
        HasDecimal = True
        HasNum = False
    Else
        KeyAscii = 0
    End If
End Sub
0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36988879

@aikimark
compile error
Variable not defined

Highlighted on
SelStart
& Mid$(Text18.Text, SelStart + 1)
0
 
LVL 46

Accepted Solution

by:
aikimark earned 500 total points
ID: 36988933
Thanks for the feedback.  Here are the corrected code snippets.

Private Sub Text18_KeyPress(KeyAscii As Integer)
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If Text18.SelStart = 0 Then
        strPostKeyValue = Chr(KeyAscii) & Text18.Text
    Else
        strPostKeyValue = Left$(Text18.Text, Text18.SelStart) & Chr(KeyAscii) & Mid$(Text18.Text, Text18.SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyAscii = 0
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyAscii = 0
        End If
    End If

End Sub

Open in new window


Private Sub Text18_KeyPress(KeyAscii As Integer)
    If KeyIsValid(Text18, KeyAscii) Then
    Else
        KeyAscii =  0
    End If

End Sub

Public Function KeyIsValid(parmTxtBox As TextBox, parmKeyAscii As Integer) As Boolean
    Dim strParsed() As String
    Dim strPostKeyValue As String
    If parmTxtBox.SelStart = 0 Then
        strPostKeyValue = Chr(parmKeyAscii) & parmTxtBox.Text
    Else
        strPostKeyValue = Left$(parmTxtBox.Text, parmTxtBox.SelStart) & Chr(parmKeyAscii) & Mid$(parmTxtBox.Text, parmTxtBox.SelStart + 1)
    End If
    strParsed = Split(strPostKeyValue, "x", , vbTextCompare)
    KeyIsValid =  True
    If (UBound(strParsed) >= 0) And (UBound(strParsed) < 2) Then
        If IsNumeric(strParsed(LBound(strParsed))) And (IsNumeric(strParsed(UBound(strParsed))) Or Len(strParsed(UBound(strParsed))) = 0) Then
        Else
            KeyIsValid = False
        End If
    Else
        If IsNumeric(Chr(KeyAscii)) Then
        Else
            KeyIsValid = False
        End If
    End If
End Sub

Open in new window

0
 
LVL 1

Author Comment

by:crystal_Tech
ID: 36989187
@ aikimark : Thanks aikimark, your code is working

@ mlmcc : your code is also working mlmcc, but when user make mistake than need to be reload form,
like by mistake if user removed x or decimal point then need to be reload form.
0
 
LVL 46

Expert Comment

by:aikimark
ID: 36989232
my code should facilitate the insertion of digits as well as the insertion of an x between two numbers as long as the number on the right of the X is an integer
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses
Course of the Month16 days, 12 hours left to enroll

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question