Search code examples
.netvb.netvisual-studioflat-file

Populating multiple text fields in vb.net from a text file


I am attempting to populate 5 boxes on a form from a text file using VB.net. The text file is a report sent to me that contains an unknown number of lines as the events of each day are different. In the text file, each line contains 5 items separated by a "~".

ie: AccountNumber~Name~Phone~email~data

The form I have setup is just a simple form with 5 text boxes and 2 buttons. (In addition to the file menu to open the txt file).

The 2 buttons are for a "Previous record" and "Next Record" feature. They would do the obvious.

Here is the code I have so far. It's all in the File > Open menu item (which may in itself be wrong) so I'm including that whole setup.

I have it to where it will pop a message box for each item in each line one at a time. Also, it keeps track by counting from 0 to 4 so I know when it's back at the first item. In testing, that works.

I need to figure out how to get all 5 items from the first line to show in the text boxes and then, make the "Next" and "Previous" buttons go to the next or previous line and populate the text boxes from those. Each process I've tried has failed miserably.

Any assistance would be much appreciated.

Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
    Dim ofd As OpenFileDialog = New OpenFileDialog
    ofd.DefaultExt = "txt"
    ofd.FileName = "defaultname"
    ofd.InitialDirectory = "C:\users\%username%\desktop\"
    ofd.Filter = "Text files|*.txt"
    ofd.Title = "Select file"

    If ofd.ShowDialog() <> DialogResult.Cancel Then
        Using myreader As New Microsoft.VisualBasic.FileIO.TextFieldParser(ofd.FileName)
            myreader.TextFieldType = FileIO.FieldType.Delimited
            myreader.SetDelimiters("~")

            Dim currentrow As String()
            While Not myreader.EndOfData
                Try
                    currentrow = myreader.ReadFields()
                    Dim currentfield As String
                    For Each currentfield In currentrow
                        Dim count As Integer

                        If count = 4 Then
                            count = 0

                        Else
                            ' populate form

                            MsgBox(currentfield & " - " & count)
                            count = count + 1


                        End If

                    Next
                Catch ex As Microsoft.VisualBasic.
                    fileio.MalformedLineException
                    MsgBox("line " & ex.Message &
            "is not valid and will be skipped.")
                End Try
            End While

        End Using

    End If

End Sub

Solution

  • You need to store all the string arrays for each line in a structure OUTSIDE of the import method so that you can move forward and/or backwards through them.

    Here I've stored them in a List(Of String()):

    Public Class Form1
    
        Private _dataIndex As Integer = -1
        Public Property DataIndex As Integer
            Get
                Return _dataIndex
            End Get
            Set(value As Integer)
                If value >= 0 AndAlso value < data.Count Then
                    _dataIndex = value
                    UpdateCurrentRecord()
                End If
            End Set
        End Property
    
        Private TextBoxes() As TextBox
        Private data As New List(Of String())
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            ' ...change the names of the textboxes below...
            TextBoxes = {TextBox1, TextBox2, TextBox3, TextBox4, TextBox5}
        End Sub
    
        Private Sub OpenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click
            Dim ofd As OpenFileDialog = New OpenFileDialog
            ofd.DefaultExt = "txt"
            ofd.FileName = "defaultname"
            ofd.InitialDirectory = "C:\users\%username%\desktop\"
            ofd.Filter = "Text files|*.txt"
            ofd.Title = "Select file"
    
            If ofd.ShowDialog() = DialogResult.OK Then
                _dataIndex = -1
                data.Clear()
                UpdateCurrentRecord()
    
                Using myreader As New Microsoft.VisualBasic.FileIO.TextFieldParser(ofd.FileName)
                    myreader.TextFieldType = FileIO.FieldType.Delimited
                    myreader.SetDelimiters("~")
    
                    Dim currentrow As String()
                    While Not myreader.EndOfData
                        Try
                            currentrow = myreader.ReadFields()
                            If currentrow.Length = 5 Then
                                data.Add(currentrow)
                            End If
                        Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
                            MessageBox.Show("Line " & ex.Message & " is not valid and will be skipped.")
                        End Try
                    End While
    
                    If data.Count > 0 Then
                        DataIndex = 0
                    End If
                End Using
            End If
        End Sub
    
        Private Sub UpdateCurrentRecord()
            If _dataIndex >= 0 AndAlso _dataIndex < data.Count Then
                Dim row() As String = data(_dataIndex)
                If row.Length = 5 Then
                    For i As Integer = 0 To 4
                        TextBoxes(i).Text = row(i)
                    Next
                End If
            Else
                For Each tb As TextBox In TextBoxes
                    tb.Clear()
                Next
            End If
        End Sub
    
        Private Sub btnPrev_Click(sender As Object, e As EventArgs) Handles btnPrev.Click
            DataIndex = (DataIndex - 1)
        End Sub
    
        Private Sub btnNext_Click(sender As Object, e As EventArgs) Handles btnNext.Click
            DataIndex = (DataIndex + 1)
        End Sub
    
    End Class