Automatic decimal places in textbox - vb.net

It looks very strange, but I can't find an online solution for my problem! At least in VB.NET.
Here's the deal:
I have a TextBox in a form (limited to numbers by a KeyPress event) and want to keep two decimal places as long as the user inputs his data.
For example, if the TextBox is blank, then, when the user presses, let's say, "2", the TextBox shows "0,02". Then, if the user presses "7", the TextBox shows "0,27". Then again, by pressing "6", it shows "2,76" and so on...
I managed to do this for one decimal place with the code:
Select Case Me.TextBox.Text
Case ""
Case ","
Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Strings.Left(Replace(Me.TextBox.Text, ",", ""), Strings.Len(Replace(Me.TextBox.Text, ",", "")) - 1) & "," & Strings.Right(Replace(Me.TextBox.Text, ",", ""), 1)
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
Please note that: 1. This code's running on a TextChanged event; 2. I'm from Portugal and here we use a comma (",") instead of a dot (".") for the decimal separator.
Could you help me to adjust my piece of code to work properly with two decimal places?
Any help will be very appreciated. And, as always, thank you all in advance.

Here's a custom class I've made which does what you require:
Public Class FactorDecimal
Private _value As String = "0"
Public DecimalPlaces As Integer
Public Sub AppendNumber(ByVal Character As Char)
If Char.IsNumber(Character) = False Then Throw New ArgumentException("Input must be a valid numerical character!", "Character")
_value = (_value & Character).TrimStart("0"c)
End Sub
Public Sub RemoveRange(ByVal Index As Integer, ByVal Length As Integer)
If _value.Length >= Me.DecimalPlaces + 1 AndAlso _
Index + Length > _value.Length - Me.DecimalPlaces Then Length -= 1 'Exclude decimal point.
If Index + Length >= _value.Length Then Length = _value.Length - Index 'Out of range checking.
_value = _value.Remove(Index, Length)
If _value.Length = 0 Then _value = "0"
End Sub
Public Overrides Function ToString() As String
Dim Result As Decimal
If Decimal.TryParse(_value, Result) = True Then
'Divide Result by (10 ^ DecimalPlaces) in order to get the amount of decimal places we want.
'For example: 2 decimal places => Result / (10 ^ 2) = Result / 100 = x,xx.
Return (Result / (10 ^ Me.DecimalPlaces)).ToString("0." & New String("0"c, Me.DecimalPlaces))
End If
Return "<parse error>"
End Function
Public Sub New(ByVal DecimalPlaces As Integer)
If DecimalPlaces <= 0 Then DecimalPlaces = 1
Me.DecimalPlaces = DecimalPlaces
End Sub
End Class
It works by letting you append numbers to form a long string of numerical characters (for example 3174 + 8 = 31748), then when you call ToString() it does the following:
It parses the long number string into a decimal (ex. "31748" => 31748.0)
It divides the decimal by 10 raised to the power of the amount of decimals you want (for example: 2 decimals => 31748.0 / 102 = 317.48).
Finally it calls ToString() on the decimal with the format 0.x - where x is a repeating amount of zeros depending on how many decimals you want (ex. 2 decimals => 0.00).
NOTE: This solution adapts to the current system's culture settings and will therefore automatically use the decimal point defined in that culture. For example in an American (en-US) system it will use the dot: 317.48, whereas in a Swedish (sv-SE) or Portuguese (pt-PT) system it will use the comma: 317,48.
You can use it like this:
Dim FactorDecimal1 As New FactorDecimal(2)
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
If Char.IsNumber(e.KeyChar) = False Then
e.Handled = True 'Input was not a number.
Return
End If
FactorDecimal1.AppendNumber(e.KeyChar)
TextBox1.Text = FactorDecimal1.ToString()
End Sub
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
Dim TargetTextBox As TextBox = DirectCast(sender, TextBox)
e.SuppressKeyPress = True
Select Case e.KeyData 'In order to not block some standard keyboard shortcuts (ignoring paste since the pasted text won't get verified).
Case Keys.Control Or Keys.C
TargetTextBox.Copy()
Case Keys.Control Or Keys.X
TargetTextBox.Cut()
Case Keys.Control Or Keys.A
TargetTextBox.SelectAll()
Case Keys.Back, Keys.Delete 'Backspace or DEL.
FactorDecimal1.RemoveRange(TextBox1.SelectionStart, If(TextBox1.SelectionLength = 0, 1, TextBox1.SelectionLength))
TextBox1.Text = FactorDecimal1.ToString()
Case Else
e.SuppressKeyPress = False 'Allow all other key presses to be passed on to the KeyPress event.
End Select
End Sub
Online test: http://ideone.com/fMcKJr
Hope this helps!

Thank you #Visual Vincent. Your method works fine. However I managed to find a simpler way of doing what I asked by the following code:
Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox.KeyPress
If Not Char.IsDigit(e.KeyChar) And Not Char.IsControl(e.KeyChar) Then
e.Handled = True
End If
End Sub
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox.TextChanged
Select Case Val(Replace(Me.TextBox.Text, ",", "."))
Case 0 : Me.TextBox.Text = ""
Case Else
Me.TextBox.Text = Format(Val(Replace(Me.TextBox.Text, ",", "")) / 100, "0.00")
Me.TextBox.SelectionStart = Len(Me.TextBox.Text)
End Select
End Sub
This piece of code look suspicious simple to me. For now it works fine and does the trick exactly how I wanted. Maybe there's something missing to me, or maybe I wasn't clear enough on the description of my goal.
If you find any flaw on my method, please feel free to point it! I'll appreciate it very much.

Related

visual basic: Enter some numbers until a negative value is entered to stop the program

private Sub Command1_Click()
a = InputBox("What is the Number ?", "Input Example"," ")
If a = "-1" Then
End If
End Sub
the whole question is: Enter some numbers until a negative value is entered to stop the program(stop running the what is your number thing). then find the average of the entered numbers.
What I want to do, for now, I want to know how can I make my "a" variable accept any negative value like in the code above it stops when I enter -1 but I want to stop when I enter -3, -10, or any negative value.
There are some helpful answers down below
If you are expecting the usual input to be text then you can use the Double.TryParse method to check if a number was entered. If it was, then you can check if that number is negative, and exit the application if so:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim userMsg As String
userMsg = Microsoft.VisualBasic.InputBox("What is your message?", "Message Entry Form", "Enter your message here", 500, 700)
If userMsg <> "" Then
Dim x As Double
If Double.TryParse(userMsg, x) AndAlso x < 0 Then
Application.Exit()
End If
MessageBox.Show(userMsg)
Else
MessageBox.Show("No Message")
End If
End Sub
The AndAlso operator only looks at the second argument if the first evaluated to True.
If you would like to repeat some portion of code till specific condition is met, you need to use:
While...End While Statement (Visual Basic)
or
Do...Loop Statement (Visual Basic)
It's also possible to write conditional loop using For... Next statement
Dim myNumber As Integer = 0
Dim mySum As Integer = 0
Dim myCounter As Integer = 0
Do
Dim answer As Object = InputBox("Enter integer value", "Getting average of integer values...", "")
'check if user clicked "Cancel" button
If answer <> "" Then
'is it a number?
If Int32.TryParse(answer, myNumber)
If myNumber >=0 Then
mySum += myNumber
myCounter += 1
Else
Exit Do
End If
End If
End If
Loop
Dim average As Double = mySum/myCounter
'you can display average now
Tip: Do not use InputBox, because this "control" is VisualBasic specific. Use custom Form instead. There's tons of examples on Google!

VB.net convert , to decimal (order of placement)

Hi I have a textbox which dose some math calculations perfect if you work with decimals not so if you work with commas.. the first option i explored was to just accept numbers and decimals in a masked textbox... but why? some of us have learned to use commas since we first started school... so my idea is to have a textbox which searches for commas and turns them into decimals for the user.
I have the following code but as example if I type in 2,5 my conversion becomes 25. so yes i have converted the comma to decimal but have lost its placing. The question thus being how can I do my conversion properly with the right decimal placement?
If TextBox13.Text.Contains(",") Then
TextBox13.Text = Replace(TextBox13.Text, ",", ".")
dim test as double textbox1.text
msgbox(test)
End If
Why not make comma an illegal entry. Don't you block entering letters anyway.
Private Sub textBox1_KeyPress(sender As Object, e As KeyPressEventArgs)
e.Handled = SingleDecimal(sender, e.KeyChar)
End Sub
Public Function SingleDecimal(sender As System.Object, eChar As Char) As Boolean
Dim chkstr As String = "0123456789."
If chkstr.IndexOf(eChar) > -1 OrElse eChar = Constants.vbBack Then
If eChar = "." Then
If DirectCast(sender, TextBox).Text.IndexOf(eChar) > -1 Then
Return True
Else
Return False
End If
End If
Return False
Else
Return True
End If
End Function
Other solution maybe is replacing comma with dot in string and then passing it back to textbox.
If TextBox13.Text.Contains(",") Then
dim tempStr as string = TextBox13.Text
TextBox13.Text = Replace(tempStr, ",", ".")
dim test as double textbox1.text
msgbox(test)
End If
And anyway shouldn't this be written this way:
TextBox13.Text = tempStr.Replace(",", ".")
Have you tried to cast the string to decimal or double?
Dim test as Decimal = CDec(textbox1.Text)
Or Dim test as Double= CDbl(textbox1.Text)

Detect the sign in number input

how can i detect if the input number in textbox contains "-"
so i can change the output into positive number and
if not contain "-" the output number is become negative
i'm using Vb.net 2010 tnx in advance for who wants to help
Dim output As String
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If getbyte(TextBox1.Text, 0) = Chr(45) Then ' check whether the first character is - or not
output = New String((From c As Char In TextBox1.Text Select c Where Char.IsDigit(c)).ToArray())
else
output="-" & textbox1.text
End If
msgbox (CInt(output))' will give the number
End Sub
Getbyte function to take each character from a string based on the position
Private Function getbyte(ByVal s As String, ByVal place As Integer) As String
If place < Len(s) Then
place = place + 1
getbyte = Mid(s, place, 1)
Else
getbyte = ""
End If
End Function
if you want to convert the -eve number to positive for calculation you can use
You have couple of options, two of them are:
1) Use StartsWith functions:
If Textbox1.Text.Trim().StartsWith("-"))Then
' It is a negative number
End If
2) If you just need to toggle the number sign, then:
Dim number as Integer = Integer.Parse(Textbox1.Text) ' Preferrably use Integer.TryParse()
number *= -1 ' Toggle the number sign
Using option2, i get:
Dim txta1 As New TextBox
txta1.Text = "-2"
Dim number As Double = Double.Parse(txta1.Text) ' Preferrably use Integer.TryParse()
number *= -1 ' Toggle the number sign
Dim s As String = number & " | "
Output: 2 |

Getting even/odd numbers specifically with a random number generator in visual basic [duplicate]

This question already has answers here:
Generating Even Random Numbers
(2 answers)
Closed 8 years ago.
trying to make a random number generator using visual basic for a school project. The user would enter in 2 different values in textbox1 and textbox 2, press a button and a random number would be generated between these 2 digits (this random number would be displayed in textbox3). This was too basic for the project, so i decided to add in 2 checkboxs which, when checked would make the generated number either even or odd.
Really need some help with an algorithm that limits the random number to be even or odd. Any help is greatly appreciated! :) (checkbox1 is for making it even, checkbox2 for odd)
Dim answer As Integer
Dim result As Integer
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox3.Clear()
TextBox3.Text = answer
If CheckBox1.Checked = False And CheckBox2.Checked = False Then
answer = CInt(Int((TextBox2.Text * Rnd() + TextBox1.Text)))
End If
^ the above code also seems to generate random numbers in a specific order, always starting from 0, any help with this would be greatly appreciated :)
If CheckBox1.Checked = True Then
Do Until result = 0
result = CDec(TextBox1.Text / 2) - CInt(TextBox1.Text / 2)
Loop
If result = 0 Then
answer = CInt(Int((TextBox2.Text * Rnd() + TextBox1.Text)))
End If
End If
End Sub
This is what I'd do to solve this problem:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 'Handles Button1.Click
'Parse the two numbers
Dim minValue = Integer.Parse(TextBox1.Text)
Dim maxValue = Integer.Parse(TextBox2.Text)
'Create a list of all possible valid numbers
Dim values = Enumerable.Range(minValue, maxValue - minValue).ToArray()
'Keep only the even numbers if selected
If CheckBox1.Checked Then
values = values.Where(Function (v) v Mod 2 = 0).ToArray()
End If
'Keep only the odd numbers if selected
If CheckBox2.Checked Then
values = values.Where(Function (v) v Mod 2 = 1).ToArray()
End If
'Check there are numbers
If values.Length = 0 Then
TextBox3.Text = "There no available numbers to choose."
Else
'`rnd` here is `System.Random` as I didn't know what `Rnd()` was.
TextBox3.Text = values(rnd.Next(0, values.Length)).ToString()
End If
End Sub
You could use a function to generate either an even or odd number depending on which checkbox is checked, the functions would use mod to determine whether the generated number id even/odd. If it is not what you require, then it would try again until the generated number matches. For example:
Private Sub btnGenerate_Click(sender As System.Object, e As System.EventArgs) Handles btnGenerate.Click
If chkOdd.Checked Then
GenerateOdd()
ElseIf chkEven.Checked Then
GenerateEven()
End If
End Sub
Private Function GenerateOdd()
Dim r = CInt(Math.Ceiling(Rnd() * 100))
If ((r Mod 2) = 0) Then
'r is even, generate another number and try again
GenerateOdd()
Else
'r is odd we have a match
yourTextBox.Text = r
Return r
End If
Return Nothing
End Function
Private Function GenerateEven()
Dim r = CInt(Math.Ceiling(Rnd() * 100))
If ((r Mod 2) = 0) Then
'r is even, we have a match
yourTextBox.Text = r
Return r
Else
'r is odd, generate another number and try again
GenerateEven()
End If
Return Nothing
End Function
I haven't tried this but you get the point!
*Edit - the (Rnd() * 100)) is a random number between 1 and 100

Keeping Leading Zeros in a Textbox

I need to keep leading zerod in a textbox that will be used to input data into a database. It is for SKU Numbers. I need to be able to type in leading zeros (ex. 001234567890) and then input them into the database.
However I can't figure out how to keep the leading zeros in a double. I do not need it in a string format but in a double. Is there a way to do this while keeping it a number and not a string?
EX.
txtProductBarcode.Text = Format(txtProductBarcode.Text, "############")
'This does not work
Using 0 in place of # will cause leading zeros to be output.
For example:
Dim s as string = string.Format("{0:000###}", 12345d)
Console.WriteLine(s)
will output
012345
See Pad a Number with Leading Zeros on MSDN.
BTW, not sure why you are worried about keeping the leading zeros whilst "as a double". The double is just a double, and formatting for display shouldn't matter. 0123 is the same as 123, otherwise you should be using a string datatype and not a double.
Try this is one.
You can convert the integer num to double.
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
Dim num As Integer
Dim temp As String = ""
Try
If Regex.IsMatch(TextBox1.Text, "^[0-9 ]+$") Then
num = Integer.Parse(TextBox1.Text)
If num <> 0 then
TextBox1.Text = num.ToString("D6")
temp = num
else
TextBox1.ReadOnly = False
End If
If num.Length = 6 Then
TextBox1.ReadOnly = True
TextBox1.BackColor = Color.White
ElseIf num = 0 Then
TextBox1.ReadOnly = False
End If
TextBox1.SelectionStart = TextBox1.Text.Length
End If
Catch ex As Exception
Msgbox(ex.Message)
End Try
End Sub