valid keyascii after numeric char

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

LVL 1
crystal_TechAsked:
Who is Participating?
 
aikimarkConnect With a Mentor Commented:
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
 
mlmccCommented:
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
 
GrahamSkanRetiredCommented:
How about?

        Case 120, 88   ' This is a x and X
            If Not IsNumeric(Text18.Text) Then
                code = 0
            End If
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
aikimarkCommented:
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
 
GrahamSkanRetiredCommented:
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
 
crystal_TechAuthor Commented:
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
 
aikimarkCommented:
might these numbers be negative, or are they always positive?
0
 
crystal_TechAuthor Commented:
always positive
0
 
aikimarkCommented:
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
 
aikimarkCommented:
your floating point numbers will need to start with a digit, not a decimal point.
0
 
aikimarkCommented:
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
 
mlmccCommented:
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
 
mlmccCommented:
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
 
crystal_TechAuthor Commented:

@ 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
 
mlmccCommented:
I added this to the form load

   HasX = False
   HasNum = False
   HasDecimal = False

It works on my machine

mlmcc


0
 
aikimarkCommented:
>>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
 
crystal_TechAuthor Commented:
@ 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
 
aikimarkCommented:
is all the text in the textbox selected?
0
 
aikimarkCommented:
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
 
mlmccCommented:
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
 
crystal_TechAuthor Commented:

@aikimark
compile error
Variable not defined

Highlighted on
SelStart
& Mid$(Text18.Text, SelStart + 1)
0
 
crystal_TechAuthor Commented:
@ 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
 
aikimarkCommented:
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.