I have a section of code that builds a table as the user enters information. I'm having trouble figuring out how to navigate through this table. There is a NEXT button and a BACK button. When they hit NEXT, either the next row loads, or the textboxes are emptied out. When they hit BACK, if there is text in the textboxes, save it, then load the row above current one. The code I have now will work until you go back too many times. You can go back, then forward, but it has trouble seeing the end of the table. And for some reason, I get phantom rows in between, but not every time. The rest of the code, where this table gets saved to the server, all works. Just navigating the table is giving me trouble. Here is what I have so far:

Private Sub nextNewTr()
        Try
            'check that the itemNo and item boxes have text
            'if not, exit
            If txtItemNo.Text = "" Or txtItem.Text = "" Then
                MsgBox("PLEASE ENTER INFORMATION FIRST")
                Exit Sub
            End If

            'check to see if there are rows beyond the current one.
            'if the "BACK" button was pressed, this should be true
            If Me.tblTraining.Rows.Count > Me.rwNo Then

                Me.tblTraining.Rows(rwNo).Item("itemNo") = Me.txtItemNo.Text
                Me.tblTraining.Rows(rwNo).Item("task") = Me.txtItem.Text
                Me.tblTraining.Rows(rwNo).Item("ques1") = Me.txtQues1.Text
                Me.tblTraining.Rows(rwNo).Item("ques2") = Me.txtQues2.Text
                Me.tblTraining.Rows(rwNo).Item("ques3") = Me.txtQues3.Text

                Me.rwNo = Me.rwNo + 1
                Me.txtItemNo.Text = Me.tblTraining.Rows(rwNo).Item("itemNo").ToString
                Me.txtItem.Text = Me.tblTraining.Rows(rwNo).Item("task").ToString
                Me.txtQues1.Text = Me.tblTraining.Rows(rwNo).Item("ques1").ToString
                Me.txtQues2.Text = Me.tblTraining.Rows(rwNo).Item("ques2").ToString
                Me.txtQues3.Text = Me.tblTraining.Rows(rwNo).Item("ques3").ToString

            Else
                'we can only end up here if there are no rows beyond the current one.

                'create a new row
                rwTr = tblTraining.NewRow

                'accept the text from the window when NEXT is pressed.
                Try
                    rwTr.Item("itemNo") = Me.txtItemNo.Text
                    rwTr.Item("task") = Me.txtItem.Text
                    rwTr.Item("ques1") = Me.txtQues1.Text
                    rwTr.Item("ques2") = Me.txtQues2.Text
                    rwTr.Item("ques3") = Me.txtQues3.Text
                    rwTr.Item("docID") = Me.hdrID
                    rwTr.Item("itemID") = Me.starthere

                    'add the row to the table
                    Me.tblTraining.Rows.Add(rwTr)

                    'set the screen controls empty, and increment the row
                    Me.btnBack.Enabled = True
                    Me.lblPrev.Visible = True
                    Me.lblPrevA.Visible = True
                    Me.lblPrev.Text = Me.txtItemNo.Text
                    Me.txtItemNo.Text = ""
                    Me.txtItem.Text = ""
                    Me.txtQues1.Text = ""
                    Me.txtQues2.Text = ""
                    Me.txtQues3.Text = ""
                    Me.rwNo = Me.rwNo + 1
                    Me.starthere = Me.starthere + 1

                Catch r As Exception
                    MsgBox(r.ToString)
                End Try
            End If
            
            If Me.rwNo > 0 Then
                Me.btnBack.Enabled = True
            End If

        Catch w As Exception
            MsgBox(w.ToString)
        End Try

    End Sub

Private Sub backNewTr()

        If Me.tblTraining.Rows.Count > Me.rwNo Then
            rwTr = tblTraining.NewRow
            Me.tblTraining.Rows(rwNo).Item("itemNo") = Me.txtItemNo.Text
            Me.tblTraining.Rows(rwNo).Item("task") = Me.txtItem.Text
            Me.tblTraining.Rows(rwNo).Item("ques1") = Me.txtQues1.Text
            Me.tblTraining.Rows(rwNo).Item("ques2") = Me.txtQues2.Text
            Me.tblTraining.Rows(rwNo).Item("ques3") = Me.txtQues3.Text
            'add the row to the table
            'Me.tblTraining.Rows.Add(rwTr)
        End If

        Me.lblPrev.Text = Me.txtItemNo.Text
        Me.rwNo = Me.rwNo - 1
        Me.txtItemNo.Text = Me.tblTraining.Rows(rwNo).Item("itemNo").ToString
        Me.txtItem.Text = Me.tblTraining.Rows(rwNo).Item("task").ToString
        Me.txtQues1.Text = Me.tblTraining.Rows(rwNo).Item("ques1").ToString
        Me.txtQues2.Text = Me.tblTraining.Rows(rwNo).Item("ques2").ToString
        Me.txtQues3.Text = Me.tblTraining.Rows(rwNo).Item("ques3").ToString

        If rwNo = 0 Then
            Me.btnBack.Enabled = False
        End If
        
    End Sub

Please, if anyone has any ideas, let me know. I have a deadline approaching, and this needs to work. Thanks!!

Recommended Answers

All 3 Replies

You really need to learn about databinding. It will make this way simpler.
I'll put together a sample using the code you have here and repost in just a bit.

A SIMPLE example, using the same textbox names and field names you used in your snippet.

You have to make sure that you have valid datatable. It doesn't have to have records, but it does have to have fields.

Also, in production code, you would have checks in the next, previous, first and last button clicks to make sure there were actually rows, that the _CM object was instantiated, etc...

Public Class Form1

    Dim dtData As New DataTable 'Make sure dtData gets filled with data somewhere
    Private WithEvents _CM As CurrencyManager

    Private Sub nextNewTr()
        _CM = CType(Me.BindingContext(dtData.DefaultView), CurrencyManager)
        BindControls()
    End Sub

    Private Sub btnMoveFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMoveFirst.Click
        _CM.Position = 0
    End Sub

    Private Sub btnMoveLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMoveLast.Click
        _CM.Position = _CM.Count - 1
    End Sub

    Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click
        If _CM.Position < _CM.Count - 1 Then
            _CM.Position += 1
        End If
    End Sub

    Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
        If _CM.Position > 0 Then
            _CM.Position -= 1
        End If
    End Sub

    Private Sub ClearBindings()
        Me.txtItem.DataBindings.Clear()
        Me.txtItemNo.DataBindings.Clear()
        Me.txtQues1.DataBindings.Clear()
        Me.txtQues2.DataBindings.Clear()
        Me.txtQues3.DataBindings.Clear()
    End Sub

    Private Sub BindControls()
        Try
            ClearBindings()

            Dim bndItemNo As New Binding("Text", dtData.DefaultView, "itemNo")
            Dim bndTask As New Binding("Text", dtData.DefaultView, "task")
            Dim bndQueue1 As New Binding("Text", dtData.DefaultView, "ques1")
            Dim bndQueue2 As New Binding("Text", dtData.DefaultView, "ques2")
            Dim bndQueue3 As New Binding("Text", dtData.DefaultView, "ques3")


            bndItemNo.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged
            bndTask.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged
            bndQueue1.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged
            bndQueue2.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged
            bndQueue3.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged

            txtItem.DataBindings.Add(bndTask)
            txtItemNo.DataBindings.Add(bndItemNo)
            txtQues1.DataBindings.Add(bndQueue1)
            txtQues2.DataBindings.Add(bndQueue2)
            txtQues3.DataBindings.Add(bndQueue3)

        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub


End Class

I didn't actually run this code, there may be a bug, but the concept is good.

Let me know if there are issues or you have more questions.

I'm sorry it took me so long to get to this. It has been a very busy few weeks for me!

I do not anything about databinding. I am able to understand most of your code. A few questions though:
- The function btnMoveFirst() can be placed in my initialization code?
- The function btnMoveLast() can be placed just before the saving of the information to the database?
- By "binding" this data to textboxes, are these textboxes going to change every time the table is changed? This program uses this same form for many different things, and this is just one of those uses. This form is not the main form of the program though, and so I might be able to find ways of only running this code when in this one mode.

I'm sorry if these questions sound elementary, but I'm new to VB. From what I can gather, databinding sounds easier - its just a matter of learning about it.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.