'I got an error on calculations with textbox vb.net

I try to do some calculation with textbox but i get error on the results the right result is 3700 = 4000 -300 but i get 3667 instead of 3700 i use this code

Private Sub Txtpaid_TextChanged(sender As Object, e As EventArgs) Handles Txtpaid.TextChanged
        Dim totalcredit As Decimal
        totalcredit = Val(Txtforhim.Text) - Val(Txtpaid.Text)
        Txtforhim.Text = totalcredit.ToString
    End Sub


Solution 1:[1]

Neither answer provided so far addresses the actual issue so I'll go for it here. You are handling the TextChanged event of a TextBox, which is raised EVERY time the Text property value changes. If the user types "300" into that TextBox, the Text property will change from String.Empty to "3", to "30" and finally to "300". That means that the TextCahnged event will be raised three times, so your calculation will be performed three times. You start with "4000" in the second TextBox and then subtract 3 from 4000 and display the result, which is "3997". You then subtract 30 from that and display that result, which is "3967". Finally, you subtract 300 from that and display that final result, which is "3667", so your calculation is displaying the exact result you should expect it to.

This is why everyone is telling you to debug your code. If you had done that in the first place, as you should, then you would have seen the event handler code executed three times and you wouldn't have had to ask this question at all. You may have had to ask another question but that's still better. ALWAYS debug your code as a first step if it doesn't produce the results you expect.

The question now is what you do about it. One solution is to stop using controls as data storage and start using variables for that, as you should have in the first place. Your initial value, i.e. 4000 should be stored in a numeric variable and that shouldn't change. You would then always be subtracting the user's input from that same 4000. That means that performing the calculation three times, while not ideal, wouldn't matter, because each result would simply overwrite the previous one. You should convert the user input to a number, subtract that from one numeric variable, store the result in another numeric variable and then display that final value in a control. The value in that output control is never used as input for any other calculation. If need the value, you use the number stored in the variable, not the contents of the control.

Solution 2:[2]

Add a breakpoint to the function, so you can see exactly what the code is doing during that method. Alternatively, you can add a MsgBox() like this:

Private Sub Txtpaid_TextChanged(sender As Object, e As EventArgs) Handles Txtpaid.TextChanged
    MsgBox($"Forhim Text: {Txtforhim.Text}{vbCrLf}Forhim Value: {Val(Txtforhim.Text)}{vbCrLf}Paid Text: {Txtpaid.Text}{vbCrLf}Paid Value: {Val(Txtpaid.Text)}")

    Txtforhim.Text = (Val(Txtforhim.Text) - Val(Txtpaid.Text)).ToString()
End Sub

I also strongly recommend using Decimal.Parse() or Decimal.TryParse() instead of Val(), which can be kind of naiive.

Solution 3:[3]

Maybe you wanted to do it of this way. Try it!, the code works as you had thought at the beginning. And good luck friend!, :-)

Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim totalcredit As Integer
    Try
        totalcredit = CInt(Txtforhim.Text) - CInt(Txtpaid.Text)
        Txtforhim.Text = totalcredit.ToString
    Catch ex As Exception
        MsgBox("There was an error changing value from string to integer ", MsgBoxStyle.Exclamation, "Error")
    End Try
End Sub
End Class

Solution 4:[4]

The code is converting the text in the TextBox controls and then finding the difference.

There are some very bad design flaws here. For one, you should be using a NumericUpDown control (aka NUD) as opposed to a TextBox. NUDs provide users a way to only enter numeric values. NUDs also have a Value property (documentation) which returns a Decimal.

You are also using the legacy Visual Basic holdover, Val. Val works by trying to convert a String but stops reading the String at the first character that it can't recognize as part of a number. So if you use a comma for a decimal point and use Val("1,23") then the result of this operation is 1 because the first character that it didn't recognize as part of a number was the comma. If you wanted to continue using TextBox controls, then you should use Decimal.TryParse (documentation).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John
Solution 2 Joel Coehoorn
Solution 3
Solution 4 David