Object enter event "string to decimal not valid" - vb.net

I have VB program which concatenates decimals of 2 categories, income and expenses.
For some reason incomeTextBox.Enter and expensesTextBox.Enter has weird behavior, saying:
Please enter numeric value for expenses
when I use either tab key or mouse to select other InputBox even after inputting an integer (which IsNumeric=True).
I also get error:
An unhandled exception of type 'System.InvalidCastException' occurred in Microsoft.VisualBasic.dll
Additional information: Conversion from string "" to type 'Decimal' is not valid.
Also, this is VB, not VB.Net, but there is no VB tag??
Option Explicit On
Public Class MainForm
Public decexpenses, decincome As Decimal
Public dectotalexpenses As Decimal = 0
Public dectotalincome As Decimal = 0
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MsgBox("Use Enter key to enter values.")
End Sub
Private Sub expensesTextBox_Enter(sender As Object, e As EventArgs) Handles expensesTextBox.Enter
Dim expenses = expensesTextBox.Text
If IsNumeric(expenses) = False Then
MsgBox("Please enter numeric value for expenses.")
End If
expensesTextBox.Text = ""
decexpenses = CDec(expenses)
dectotalexpenses = decexpenses + dectotalexpenses
End Sub
Private Sub incomeTextBox_Enter(sender As Object, e As EventArgs) Handles incomeTextBox.Enter
Dim income = incomeTextBox.Text
If IsNumeric(income) = False Then
MsgBox("Please enter numeric value for income.")
ElseIf IsNumeric(income) = True Then
decincome = CDec(income)
dectotalincome = decincome + dectotalexpenses
End If
End Sub
End Class

I would instead of using Enter for the raise event I would use Text_Changed and use the KeyDown for Enter. Once the Text is Entered then they click enter on the textbox the routine will run Example the below:
Private Sub expensesTextBox_TextChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles expensesTextBox.KeyDown
Dim dectotalexpenses As Decimal = 0
Dim dectotalincome As Decimal = 0
If e.KeyCode = Keys.Enter Then
Dim value As String = TextBox1.Text
Dim decincome As Decimal
If Not Decimal.TryParse(value, decincome) Then
MsgBox("Please enter numeric value for expenses.")
Return
End If
End If
End Sub

The Enter event is raised if the TextBox gets focus the first time, probably the text is empty at this point which raises your exception.
In your code you are also netiher using If...Else nor returning if the value is not numeric, so CDec(expenses) gets executed anyway which causes the exception. Also, instead of IsNumeric use Decimal.TryParse:
Private Sub expensesTextBox_Enter(sender As Object, e As EventArgs) Handles expensesTextBox.Enter
Dim value As String = expensesTextBox.Text
Dim decincome As Decimal
If Not Decimal.TryParse(value, decincome) Then
MsgBox("Please enter numeric value for expenses.")
Return
End If
dectotalexpenses = decincome + dectotalexpenses
End Sub
You should also use a different event like TextBox.TextChanged.

Related

VB Entering a Non_Numeric value crashes the program

Please consider adding a description to this question to attract more helpful responses.
Public Class Form1
Private Sub BtnCalculateRevenue_Click(sender As Object, e As EventArgs) Handles BtnCalculateRevenue.Click
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
Try
LblStatus.Text = String.Empty
LblClassAResult.Text = (intvalue * 15).ToString("c")
LblClassBResult.Text = (intvalue2 * 12).ToString("c")
LblClassCResult.Text = (intvalue3 * 9).ToString("c")
total = CDbl((intvalue * 15) + (intvalue2 * 12) + (intvalue3 * 9))
LblTotal.Text = total.ToString("c")
Catch
LblStatus.Text = "Please Enter a Number"
End Try
End Sub
Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles BtnExit.Click
Me.Close()
End Sub
Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
TxtInputClassA.Clear()
TxtInputClassB.Clear()
TxtinputClassC.Clear()
LblClassAResult.Text = String.Empty
LblClassBResult.Text = String.Empty
LblClassCResult.Text = String.Empty
LblTotal.Text = String.Empty
End Sub
End Class
VB Entering a Non_Numeric value crashes the program
Validation is built right into Windows Forms so you should make use of it. If you want to force the user to enter numbers in each of three TextBoxes then you can do this:
Private Sub TextBoxes_Validating(sender As Object, e As ComponentModel.CancelEventArgs) Handles TextBox3.Validating, TextBox2.Validating, TextBox1.Validating
Dim tb = DirectCast(sender, TextBox)
If Not Integer.TryParse(tb.Text, Nothing) Then
'Select all the invalid text and highlight it.
tb.SelectAll()
tb.HideSelection = False
MessageBox.Show("Please enter a whole number",
"Invalid Input",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
'Remove highlight when TextBox is not focused.
tb.HideSelection = True
'Don't let the control lose focus while data is invalid.
e.Cancel = True
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If ValidateChildren() Then
'All data is valid so proceed.
Dim n1 = CInt(TextBox1.Text)
Dim n2 = CInt(TextBox2.Text)
Dim n3 = CInt(TextBox3.Text)
'...
End If
End Sub
The ValidateChildren method will raise the Validating event for every control on the form and return False if any fail validation, i.e. e.Cancel is set to True in any event handlers, so that ensures that even controls that never received focus will be validated before the data is used.
Its bombing out on your cast "CInt(*value*)" so you can fix the code a couple ways. You can move your try above the casts like...
Try
Dim intvalue As Integer = CInt(TxtInputClassA.Text)
Dim intvalue2 As Integer = CInt(TxtInputClassB.Text)
Dim intvalue3 As Integer = CInt(TxtinputClassC.Text)
Dim total As Double
LblStatus.Text = String.Empty
You can do a data validation on your inputs and exit if they aren't all numeric (put this above your Dim intvalue code)
For Each value As String In {TxtInputClassA.Text, TxtInputClassA.Text, TxtInputClassA.Text}
If Not IsNumeric(TxtInputClassA.Text) Then
LblStatus.Text = "Please Enter a Number"
Exit Sub
End If
Next
Instead of casting as an int, use the tryparse method on Int32...
Dim intvalue As Integer
If Not Int32.TryParse(TxtInputClassA.Text, intvalue) Then
Exit Sub
End If
Or you could intercept the keypresses on each text box so that only numbers can be entered
Private Sub TxtInputClassA_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
You can make that routine universal and append the event handler for all three text boxes like...
Private Sub EnforceOnlyNumericKeyPresses(sender As Object, e As KeyPressEventArgs) Handles TxtInputClassA.KeyPress, TxtInputClassB.KeyPress, TxtInputClassC.KeyPress
If Not Char.IsDigit(e.KeyChar) Then
e.Handled = True
End If
End Sub
Choose your favorite or do all of them, lots of choices.
Replace your textboxes with NumericUpDown controls and retrieve their .Value for your calculation. NUDs don't allow non numeric input and can have a fixed number of decimal places which may also be useful in a financial context

How can I get ten numbers and displays the biggest and lowest one?

sorry I'm a newbie and I'm trying to write a program to get ten integers from user with a an Inputbox or Textbox and displays the biggest and lowest one in a label with visual basic. I'll be appreciated if you help me out with this.
Thank you. this is my solution. I don't know how to compare these ten numbers with each other.
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers
Max = 0
i = 1
While (i <= 10)
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers
i = i + 1
End While
lblresult.Text = Container
End Sub
conceptually speaking you should use a List(Of Integer) or List(Of Double), perform the loop 10 times adding the value into the list.
Suppose this is our list
Dim container As New List(Of Integer)
To get input
Dim userInput = ""
Dim input As Integer
userInput = InputBox("please enter a number", "Enter a number")
If Integer.TryParse(userInput, input) Then
container.Add(input)
End If
After the loop
Console.WriteLine($"Min: {container.Min()} Max: {container.Max()}")
Does this make sense to you ?
Edit, based on asking for Windows Forms example.
You could do the following instead of a InputBox, requires a label, a button and a TextBox.
Public Class MainForm
Private container As New List(Of Integer)
Private Sub CurrentInputTextBox_KeyPress(sender As Object, e As KeyPressEventArgs) _
Handles CurrentInputTextBox.KeyPress
If Asc(e.KeyChar) <> 8 Then
If Asc(e.KeyChar) < 48 Or Asc(e.KeyChar) > 57 Then
e.Handled = True
End If
End If
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
CurrentLabel.Text = "Enter number 1"
End Sub
Private Sub ContinueButton_Click(sender As Object, e As EventArgs) _
Handles ContinueButton.Click
If Not String.IsNullOrWhiteSpace(CurrentInputTextBox.Text) Then
container.Add(CInt(CurrentInputTextBox.Text))
CurrentLabel.Text = $"Enter number {container.Count + 1}"
If container.Count = 10 Then
ContinueButton.Enabled = False
CurrentLabel.Text =
$"Count: {container.Count} " &
$"Max: {container.Max()} " &
$"Min: {container.Min()}"
Else
ActiveControl = CurrentInputTextBox
CurrentInputTextBox.Text = ""
End If
End If
End Sub
End Class
I really didn't want to do your homework for you but I was afraid you might be hopelesly confused.
First let's go over your code. See comments
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
Dim i, Container, Max, Numbers 'Don't declare variables without an As clause
Max = 0 'Max is an object
i = 1 'i is and object
While i <= 10 'the parenthesis are unnecessary. You can't use <= 2 with an object
Numbers = InputBox("please enter a number", "Enter a number")
Max = Numbers
Container = Container & " " & Numbers 'Container is an object; you can't use & with an object
i = i + 1 'Again with the object i can't use +
End While
lblresult.Text = Container
End Sub
Now my approach.
I created a List(Of T) at the Form level so it can be seen from different procedures. The T stands for type. I could be a built in type or type you create by creating a Class.
The first click event fills the list with the inputted numbers. I used .TryParse to test if the input is a correct value. The first parameter is a string; the input from the user. The second parameter is a variable to hold the converted string. .TryParse is very clever. It returns True or False base on whether the input string can be converted to the correct type and it fills the second parameter with the converted value.
The second click event loops through the list building a string to display in Label1. Then we use methods available to List(Of T) to get the numbers you desire.
Private NumbersList As New List(Of Integer)
Private Sub FillNumberList_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
While i < 10
Dim input = InputBox("Please enter a whole number")
Dim inputInt As Integer
If Integer.TryParse(input, inputInt) Then
NumbersList.Add(inputInt)
i += 1 'We only increment i if the parse is succesful
End If
End While
MessageBox.Show("Finished Input")
End Sub
Private Sub DisplayResults_Click(sender As Object, e As EventArgs) Handles Button2.Click
Label1.Text = "You input these numbers "
For Each num In NumbersList
Label1.Text &= $"{num}, "
Next
Label2.Text = $"The largest number is {NumbersList.Max}"
Label3.Text = $"The smallest number is {NumbersList.Min}"
End Sub

How do I multiply a user's text by an array item selected from a menu?

I'm trying to write a gross pay calculator, and can't quite get the coding right to multiply the user entered number by the selected pay rate.
Everything I try based off tweaking other project's code to fit my current project just returns errors.
Private strCode(,) As String = {{“P23”, “10.5”},
{“P56”, “12.5”},
{“F45”, “14.25”},
{“F68”, “15.75”},
{“F96”, “17.65”}}
Private Sub txtHours_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtHours.KeyPress
' Accept only numbers, the period, and the Backspace key.
If (e.KeyChar < "0" OrElse e.KeyChar > "9") AndAlso e.KeyChar <> "." AndAlso e.KeyChar <> ControlChars.Back Then
e.Handled = True
End If
End Sub
Private Sub BtnCal_click(sender As Object, e As EventArgs) Handles btnCalc.Click
Const V As strCodes(,)(,)
Dim txtHours As Decimal = txtHours.text
lblGross.Text = {{txtHours.Text} * {lstCodes.SelectedIndex}}
End Sub
Whether I declare the txtHours as double, decimal, it always returns the error that it can't be converted. The bottom portion of the code is non-working, but is essentially what I need to happen with this code.
I would expect to see something more like:
Private Sub BtnCal_click(sender As Object, e As EventArgs) Handles btnCalc.Click
If lstCodes.SelectedIndex <> -1 Then
Dim quantity, rate As Double
If Double.TryParse(txtHours.Text, quantity) AndAlso Double.TryParse(lstCodes.SelectedItem, rate) Then
Dim price As Double = quantity * rate
lblGross.Text = price
Else
MessageBox.Show("Invalid Quantity and/or Rate!")
End If
Else
MessageBox.Show("No Rate Selected!")
End If
End Sub
I created a structure to hold your data. A list of the type of structure then can keep the data and a List(Of T) can be bound to a list box. The display and value members are set to the properties of the structure. When an item is selected in the list box we can get the .SelectedValue and use it in the calculation.
Public Structure PayRate
Public Property RateClass As String
Public Property PayRate As Decimal
Public Sub New(rClass As String, pRate As Decimal)
RateClass = rClass
PayRate = pRate
End Sub
End Structure
Private PayRates As New List(Of PayRate)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
PayRates.Add(New PayRate(“P56”, 12.5D))
PayRates.Add(New PayRate(“F45”, 14.25D))
PayRates.Add(New PayRate(“F68”, 15.75D))
PayRates.Add(New PayRate(“F96”, 17.65D))
ListBox1.DataSource = PayRates
ListBox1.DisplayMember = "RateClass"
ListBox1.ValueMember = "PayRate"
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Hours As Decimal
If Decimal.TryParse(TextBox1.Text, Hours) Then
Label1.Text = (Hours * CDec(ListBox1.SelectedValue)).ToString("000.00")
Else
MessageBox.Show("Please enter a valid number in Hours box.")
End If
End Sub

Convert each String in ListBox1 to Integer and add to ListBox2: Incorrectly formatted input string

I have one TextBox, two ListBoxes and two Buttons. The first Button separates each String in the TextBox and adds them one by one to ListBox1. The second Button converts each String in to an Integer. But I get an exception thrown by the debugger:
Incorrectly formatted input string.
System.FormatException was unhandled
HResult=-2146233033
Message=Cadeia de caracteres de entrada com formato incorrecto.
Source=mscorlib
StackTrace:
em System.Number.StringToNumber(String str, NumberStyles options,
NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
em System.Number.ParseDecimal(String value, NumberStyles options,
NumberFormatInfo numfmt)
em System.Convert.ToDecimal(String value)
em g_.Form2.Button2_Click(Object sender, EventArgs e) em
C:\Users\Utilizador\Documents\Visual Studio
2012\Projects\g+\g+\Form2.vb:line 17
I have inserted code to clean the empty spaces but it continues to throw the same error.
After to reflecting to the problem i have decide to change the way to do it
This is my code:
Public Class Form2
Dim frequency
Dim interval
Dim textconverted
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myArray() As Char
myArray = Me.TextBox1.Text.ToCharArray
For Each chr As Char In Me.TextBox1.Text
ListBox1.Items.Add(chr)
Next
For i As Integer = ListBox1.Items.Count - 1 To 0 Step -1
If ListBox1.GetItemText(ListBox1.Items(i)) = String.Empty Then
ListBox1.Items.RemoveAt(i)
End If
Next i
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For i As Integer = 0 To ListBox1.Items.Count - 1
If (ListBox1.Items(i).ToString.Contains("a")) Then
ListBox2.Items.Add("1") 'Indexing is zero-based
Exit For
End If
Next
End Sub
End Class
Well i find a different way to do it and its do what i need.
This is the working solution
Public Class Form2
Dim frequency
Dim interval
Dim textconverted
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myArray() As Char
myArray = Me.TextBox1.Text.ToCharArray
For Each chr As Char In Me.TextBox1.Text
ListBox1.Items.Add(chr)
Next
For i As Integer = ListBox1.Items.Count - 1 To 0 Step -1
If ListBox1.GetItemText(ListBox1.Items(i)) = String.Empty Then
ListBox1.Items.RemoveAt(i)
End If
Next i
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim myVariable As String = "foo"
For x As Integer = 0 To ListBox1.Items.Count - 1
If ListBox1.Items(x) = "a" Then
ListBox2.Items.Add("1")
End If
If ListBox1.Items(x) = "b" Then
ListBox2.Items.Add("2")
End If
If ListBox1.Items(x) = "c" Then
ListBox2.Items.Add("3")
End If
Next
End Sub
End Class
But now i have other problem with it it only check one string
How can i verify multiple strings there?
I added .ToString to your button 2 code and it worked fine. Turn on Option Strict; you will avoid some runtime errors. I have posted code that will handle a-z instead of a bunch of if statements. Add .ToLower to your TextBox1.Text.ToLower myArray is never used neither is myVariable.
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For x As Integer = 0 To ListBox3.Items.Count - 1
Dim s As String = (Asc(ListBox3.Items(x).ToString) - 96).ToString
ListBox2.Items.Add(s)
Next
End Sub

Conversion from string "" to type 'Double' is not valid using TryParse Method

I have a simple addition program in VB.Net and I am attempting to test if the textbox is only taking in a number and not any letters. I need to use the TryParse method, and I cannot figure out wny I am still receiving this error. Pls Help
Public Class perrySolutionForm
Dim numberOne As Double
Dim numberTwo As Double
Public Function sum(ByRef numberOne As Double, ByRef numberTwo As Double)
sum = Val(numberOne) + Val(numberTwo)
End Function
Public Function difference(ByRef numberOne As Double, numberTwo As Double)
difference = Val(numberOne) - Val(numberTwo)
End Function
Private Sub sumButton_Click(sender As Object, e As EventArgs) Handles sumButton.Click
If numberOneInput.Text = "" Then
MessageBox.Show("Both fields must be filled out.")
If Double.TryParse(numberOneInput.Text, numberOne) Then
MessageBox.Show("Success")
'numberOne has a Double value
Else
MessageBox.Show("Failure")
'numberOne = Nothing
End If
Else
outputLabel.Text = sum(numberOne, numberTwo)
End If
End Sub
Private Sub numberOneInput_TextChanged(sender As Object, e As EventArgs) Handles numberOneInput.TextChanged
numberOne = numberOneInput.Text
End Sub
Private Sub numberTwoInput_TextChanged(sender As Object, e As EventArgs) Handles numberTwoInput.TextChanged
numberTwo = numberTwoInput.Text
End Sub
This is how you use the TryParse:
If Double.TryParse(numberOneInput.Text, numberOne) Then
'code for a success
'numberOne has a Double value
Else
'code for a failure
'numberOne = Nothing
End If
End the code block if text is empty:
If String.IsNullOrWhiteSpace(numberOneInput.Text) Then
MessageBox.Show("Value is incorrect format")
Exit Sub
End If