Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1015
  • Last Modified:

Thousands separators and fixed number of decimals in numeric TextBox

Hi,

I’d like to use a textbox (Text1) to accept only numbers with a fixed number of decimals (e.g. 1, 2 or 3) and yet format it with  thousands  separators.

Does anyone know how to do that?

Any help shall be greatly appreciated.

This code (from expert-exchange.com) is supposed to allow handling two decimals but actually it doesn’t limit at all the number of decimals:

Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim KeyAscii As Integer
KeyAscii = Asc(e.KeyChar)

If KeyAscii >= Asc("0") And KeyAscii <= Asc("9") Then
        If InStr(Text1.Text, ".") = 0 Then
            ' it is valid, do nothing
        Else
            'only 2 digits
            If Len(Mid(Text1, InStr(1, Text1, "."))) > 2 Then
                KeyAscii = 0
            Else
                'do nothing
            End If
        End If
        ' it is valid, do nothing
    ElseIf KeyAscii = Asc(".") Then
        If InStr(Text1.Text, ".") = 0 Then
            ' it is valid, do nothing
        Else
            KeyAscii = 0
        End If
    Else
        If KeyAscii = 8 Then
            'do nothing
        Else
            KeyAscii = 0
        End If
    End If

End Sub


To allow for thousands separators the following code works but it doesn’t allow any decimals :

Private Sub Text1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtMin.TextChanged
        If Me.Text1.Text <> "" Then
 Me.Text1.Text = ormat(Double.Parse(Me.Text1.Text), "##,##")
        End If
End Sub

0
Ghanisen
Asked:
Ghanisen
1 Solution
 
iboutchkineCommented:
It allows numeric "," and "."
 Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        If Char.IsDigit(e.KeyChar) Or e.KeyChar = "."c Or e.KeyChar = ","c Then
            MsgBox("Digit entered")
        Else
            e.Handled = True
        End If
    End Sub


add whatever you need there
0
 
GhanisenAuthor Commented:
Hi Iboutchkine,

Sorry but your code does nothing more than mine above. It even has the inconvenience to allow entering several "." and "," !!!

You can limit that with:

If e.KeyChar = "." And TextBox1.Text.IndexOf(".") <> -1 Then
        e.Handled = True
End If

But still there is no automatic formatting of the number entered.


Uptill now the best solution I arrived at is the following:

To validate data input, ensuring only digits and 1 decimal separator are entered:

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        Dim KeyAscii As Integer
        KeyAscii = Asc(e.KeyChar)

        If Char.IsDigit(e.KeyChar) Or e.KeyChar = "."c Then
            'do nothing
        ElseIf e.KeyChar = "," And TextBox1.Text.IndexOf(",") <> -1 Then
            e.Handled = True
        End If
End Sub


To format automatically the number entered with thousands separators and keep 3 decimals I arrived to the following code that works :

Private Sub TextBox1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave
        If Me.TextBox1.Text <> "" Then
            Me.TextBox1.Text = Format(Double.Parse(Me.TextBox1.Text), "#,#0.000")
        End If
    End Sub

The number of zeros after the comma determines the number of decimals that are allowed.

Unfortunately the latter code works well only in the Leave event and not in the TextChanged event.

Do you have a better idea? Thanks Iboutchkine.

0
 
GhanisenAuthor Commented:
Hi,

Sorry I meant
"The number of zeros after the dot determines the number of decimals that are allowed"
not

"The number of zeros after the comma determines the number of decimals that are allowed".

Thanks
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
GhanisenAuthor Commented:
Hi,

Sorry again, the second sub above contains uneeded stuff. The correct one, with an error message, is :

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
        If Char.IsDigit(e.KeyChar) Or e.KeyChar = ","c Then
            'do nothing
        ElseIf e.KeyChar = "," And TextBox1.Text.IndexOf(",") <> -1 Then
            e.Handled = True
            MsgBox("You cannot enter a number with more than three decimals !")
        End If
End Sub

Thanks
0
 
GhanisenAuthor Commented:
Hi,

I'm terribly sorry. forget about my latest post, the second Sub was allright:

 Private Sub TextBox1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave
        If Me.TextBox1.Text <> "" Then
            Me.TextBox1.Text = Format(Double.Parse(Me.TextBox1.Text), "#,#0.000")
        End If
 End Sub

Thanks.
0
 
GhanisenAuthor Commented:
Hi Iboutchkine,

This the latest code I arrived at:


To validate data input, ensuring only digits and 1 decimal separator are entered:

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress
                If Char.IsDigit(e.KeyChar) = False And e.KeyChar <> "."c Then
            MsgBox("You must enter an integer or a decimal number !")
            e.Handled = True
        ElseIf e.KeyChar = "." And txtMin.Text.IndexOf(".") <> -1 Then
            e.Handled = True
            MsgBox("You cannot enter more than one dot for decimals !")
        End If
End Sub


To format automatically the number entered with thousands separators and keep 3 decimals I arrived to the following code that works :

Private Sub TextBox1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Leave
        If Me.TextBox1.Text <> "" Then
            Me.TextBox1.Text = Format(Double.Parse(Me.TextBox1.Text), "#,#0.000")
            Me.TextBox1.SelectionStart = Me.TextBox1.Text.Length
        End If
 End Sub

Still the latter code works well only in the Leave event and not in the TextChanged event.

Thanks
0
 
arif_eqbalCommented:
Use regular Expressions that will simplify things for you
0
 
GhanisenAuthor Commented:
Hi arif eqbal,

Can you elaborate on how to use regular expressions in my case?

Thanks
0
 
EagleEye1975Commented:
There are a few functions you should know about.

1) IsNumeric($var)
  Evaluates a variable and returns TRUE if the value is numeric.

Use that to replace this line:

If KeyAscii >= Asc("0") And KeyAscii <= Asc("9") Then

2) Format($str, "###,##0.00")
   Will format your text in to the number format specified.  The # signs indicate non-required numerical positions, the 0s indicate required numerical positions.

So:  Format(38.91838, "###,000.00") outputs 038.92

If you don't want the leading zero, use ###,##0.00 instead... see how that works?
0
 
EagleEye1975Commented:
A little critique of your code too...

Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim KeyAscii As Integer

You have a KeyAscii variable already declared in your sub header... There should be no need to DIM it again.

KeyAscii = Asc(e.KeyChar)

You can combine this with the declaration of the variable above.

So:

Private Sub Text1_KeyPress()
Dim KeyAscii as Integer = Asc(e.KeyChar)

Next, we replace ALL of the rest of the sub with:

If IsNumeric(KeyAscii) = True then
  OutputVar = Format(KeyAscii, "###,###,##0.00") ' Maybe a little overboard on the # signs, but oh well...
End If

And there you have it. :)
End Sub
0
 
GhanisenAuthor Commented:
Hi EagleEye,

I do know about IsNumeric and about the syntax of optional and required digits in a custom format string.

Also if you read again my posts you would notice that the unecessary declarations were already removed. They were a "leftover" of another code I used before.

Although your explanations are correct, they add nothing new to my code.

I don't use IsNumeric here because the keypress event allows better control of user input.

Arif Eqbal suggested the use of RegEx to validate input but I'm not very familiar with regular expression though I know the basics (^ =start, d=digit, w= alphanumeric character, $=end, etc.).

He did not elaborate on the expression to use. I'll give it a try this afternoon.

Thanks EagleEye. You'll get part of the points for your kind effort but I still hope someone to come up with a better solution than mine because in my case the formatting takes place only after leaving the textbox.

Thanks.
0

Featured Post

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now