Hi all,

I have a form in visual basic with about 62 textboxes.
On this form is two columns of textboxes. Textbox 61 -62 is a total textbox for each column.
When the user types in digits to 60 textboxes the program must add it up automatically to textbox61/62.

My current coding that I have is:

Private sub Textboxes61.textchanged(byval sender as system.object, byval e as system.eventargs) handles textbox61.textchanged, textbox1.textchanged, (ALL THE WAY TO TEXTBOX30)
Dim textboxes() as textbox = {textbox1.text, textbox2.text, etc...}
Dim d as decimal
Textbox61.text  = textboxes.sum(function(tb) if(decimal.tryparse(tb.text, d, 0)).tostring
End sub

This is a long way to do it automatically...

Isn't there a shorter way that I can do this?
For example:

Private sub Textbox61.textchanged(byval sender as system.object, byval e as system.eventargs) handles textbox61.textchanged
    Textbox61=textbox1+textbox2+ .... 
    End sub

Thanks all.

Hi, instead of all the textboxes you could make use of a datagridview. Would be a lot easier for what you want to do.

I cant Actually use datagridview, because my program is designed specifically according to Accounting Formats... I'd rather use textboxes... But I need help with the coding to add them up.

Something like this, don't have more time at the moment.

Dim i As Integer
For i = 1 To 30
    Dim tb = Controls("TextBox" & i)
    Textbox61.Text = TextBox61 + tb.Text
Next

@Gé48:
Do i just type that in under the Private sub... All the textboxes' names are Textbox1, Textbox2, etc... Do i have to change any names?

Hi, back again, I have tried this (with fewer textboxes) in a mouse click event was easier for testing. By clicking on textbox 61 or 62 you should get the same result. Should work in your textchanged event as well.

Private Sub TextBox61_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TextBox61.MouseClick, TextBox62.MouseClick
        Dim count1 As Integer = 0
        Dim i1 As Integer
        For i1 = 1 To 30
            Dim tb = Controls("TextBox" & i1)
            If tb.Text <> "" Then
                count1 = count1 + tb.Text
            End If
        Next
        TextBox61.Text = count1
        Dim count2 As Integer = 0
        Dim i2 As Integer
        For i2 = 31 To 60
            Dim tb = Controls("TextBox" & i2)
            If tb.Text <> "" Then
                count2 = count2 + tb.Text
            End If
        Next
        TextBox62.Text = count2
    End Sub

It only works for the TextChanged event if it Handels every textbox.
See coding:

Private Sub TextBoxes185_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox185.TextChanged, TextBox61.TextChanged, TextBox62.TextChanged, TextBox63.TextChanged, TextBox64.TextChanged, TextBox65.TextChanged, TextBox66.TextChanged, TextBox67.TextChanged, TextBox68.TextChanged, TextBox69.TextChanged, TextBox70.TextChanged, TextBox71.TextChanged, TextBox72.TextChanged, TextBox73.TextChanged, TextBox74.TextChanged, TextBox75.TextChanged, TextBox76.TextChanged, TextBox77.TextChanged, TextBox78.TextChanged, TextBox79.TextChanged, TextBox80.TextChanged
        Dim count1 As Integer = 0
        Dim i1 As Integer
        For i1 = 61 To 80
            Dim tb = Controls("TextBox" & i1)
            If tb.Text <> "" Then
                count1 = count1 + tb.Text
            End If
        Next
        TextBox185.Text = count1
    End Sub

I can't do it with the MouseClick event, because the user won't have time to go click on the textbox to see an answer... My Program's mission is to make everything for the user faster and easier...

Hi, maybe it's an idea to put the code in a timer event, then you won't need the handels for all the textboxes. The timer will take over.

Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
        Dim count1 As Integer = 0
        Dim i1 As Integer
        For i1 = 1 To 30
            Dim tb = Controls("TextBox" & i1)
            If tb.Text <> "" Then

            End If
            count1 = count1 + tb.Text
        Next
        TextBox61.Text = count1
        Dim count2 As Integer = 0
        Dim i2 As Integer
        For i2 = 31 To 60
            Dim tb = Controls("TextBox" & i2)
            If tb.Text <> "" Then
                count2 = count2 + tb.Text
            End If
        Next
        TextBox62.Text = count2
    End Sub

If you can distinguish between whether a textbox is in column 1 or column 2 then you can save yourself a lot of coding. Let's assume that you have the textboxes arranged and named as follows:

TextBox1      TextBox2
TextBox3      TextBox4
.
.
.
TextBox29     TextBox30
txtSumCol1    txtSumCol2

Note that all odd numbered textboxes are in column1 and all even ones in column 2. Note also that the only controls starting with "TextBox" are the controls that you want to add up.

Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        'add handler for text changed for all user entry fields

        For Each tbx As TextBox In Me.Controls.OfType(Of TextBox)()
            If tbx.Name.StartsWith("TextBox") Then
                AddHandler tbx.TextChanged, AddressOf TextBox_TextChanged
            End If
        Next

    End Sub

    Private Sub TextBox_TextChanged(sender As System.Object, e As System.EventArgs)

        Dim col As Integer = ColNum(sender)
        Dim sum As Integer = 0

        'recalculates the sum of all textboxes that are in the column
        'containing the textbox that was changed.

        For Each tbx As TextBox In Me.Controls.OfType(Of TextBox)()
            If tbx.Name.StartsWith("TextBox") Then
                If ColNum(tbx) = col Then
                    If IsNumeric(tbx.Text) Then sum += CInt(tbx.Text)
                End If
            End If
        Next

        Me.Controls("txtSumCol" & col).Text = sum

    End Sub

    Private Function ColNum(ctrl As Control) As Integer

        'Returns the value 1 or 2 to identify which column the textbox
        'is in. Odd numbered boxes are in column 1 and even numbered
        'boxes are in column 2.

        Return IIf(CInt(ctrl.Name.Substring(7)) Mod 2 = 0, 2, 1)

    End Function

End Class

This code works with integer values. Modify it as you need. Also, you could restrict the textboxes so that only numbers may be entered. You may also want to make the total boxes read-only.

If you put each column of boxes in its own groupbox you can simplify things quite a bit. you can simplify things even further by using a label with AutoSize off and background color and border the same as the textbox.

To add the event handler to all the relevant textboxes:

    For Each gb As GroupBox In Me.Controls.OfType(Of GroupBox)()
        For Each tb As TextBox In gb.Controls.OfType(Of TextBox)()
            AddHandler tb.TextChanged, AddressOf TextBox_TextChanged
        Next
    Next

The event handler:

Private Sub TextBox_TextChanged(sender As Object, e As EventArgs)
    Dim CurrentTB As TextBox = DirectCast(sender, TextBox)
    Dim ParentGB As GroupBox = DirectCast(CurrentTB.Parent, GroupBox)
    Dim TLabel As Label = ParentGB.Controls.OfType(Of Label).ToArray(0)

    If Double.TryParse(CurrentTB.Text, vbNull) Then
        TLabel.Text = (From tb As TextBox In ParentGB.Controls.OfType(Of TextBox)()
                       Where Double.TryParse(tb.Text, vbNull)
                       Select Double.Parse(tb.Text)).ToArray.Sum.ToString
    Else
        MessageBox.Show("Numbers only please.")
        CurrentTB.Focus()
        CurrentTB.SelectAll()
    End If
End Sub

This has simple validating built in as well.

With this every time the user types either the total is updated or a messagebox pops up and the text is selected.

Edited 3 Years Ago by tinstaafl

You can use the Tag property of the textboxes to specify that they are to be part of the sum and then loop through the controls. I used a button, but the same thing will work by handeling the textchange. Also, I did one column, but if I used 2 different words for the tag properties, I could add to 2 different sum textboxes.

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, TextBox1.TextChanged ' etc.

        Dim ctrAdd As Control ' Each Textbox to be summed has the Tag property set to "add"
        Dim addSum As Integer
        addSum = 0
        For Each ctrAdd In Me.Controls
            If ctrAdd.Tag = "add" Then
                If IsNumeric(ctrAdd.Text) Then
                    addSum = addSum + CInt(ctrAdd.Text)
                End If
            End If
        Next
        txtSumBox.Text = addSum
    End Sub

Thanks for all the replies. I have managed to manipulate the coding of @Gé48. Thanks very much.

A timer event is not the preferred option because it executes at every timer click whether it needs to or not and it does not check for non-numeric entries so it will error out if invalid entries are found.

This question has already been answered. Start a new discussion instead.