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
CodePudding user response:
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
CodePudding user response:
Insert this instead in your code to get the correct fields ! !
If ofd.ShowDialog() <> DialogResult.Cancel Then
Using myreader As New Microsoft.VisualBasic.FileIO.TextFieldParser(ofd.FileName)
myreader.TextFieldType = FileIO.FieldType.Delimited
myreader.SetDelimiters("~")
Dim x As Short
Dim currentrow As String()
While Not myreader.EndOfData
Try
currentrow = myreader.ReadFields()
Dim Count As Short = 0
For x = 0 To currentrow.Count - 1
Count = Count 1
MsgBox(currentrow(x) & " - " & Count)
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
You can also do this:-
You can also use the logic I have shown above but first get all lines into a array - then manipulate each line :-
Dim Lines = File.ReadAllLines(ofd.FileName)
Dim Lp As Single
Dim X As Short
For Lp = 0 To Lines.Length - 1
Dim items() As String = Split(Lines(Lp), "~")
Dim Count As Short = 0
For x = 0 To items.Count - 1
Count = Count 1
MsgBox(items(X) & " - " & Count)
Next
Next
CodePudding user response:
The following code works for me.
Private curIndex As Integer = -1
Private maxIndex As Integer = 0
Private dic As Dictionary(Of Integer, String()) = New Dictionary(Of Integer, String())
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim lines = File.ReadAllLines(filePath).Where(Function(x) Not String.IsNullOrWhiteSpace(x))
maxIndex = lines.Count - 1
For i As Integer = 0 To maxIndex
dic.Add(i, lines(i).Split("~"c).Where(Function(x) Not String.IsNullOrWhiteSpace(x)).ToArray())
Next
Label1.Text = "0"
curIndex = 0
TextBox1.Text = dic(0)(curIndex)
TextBox2.Text = dic(0)(curIndex 1)
TextBox3.Text = dic(0)(curIndex 2)
TextBox4.Text = dic(0)(curIndex 3)
TextBox5.Text = dic(0)(curIndex 4)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If Not curIndex - 1 < 0 Then
curIndex -= 1
Label1.Text = curIndex.ToString
TextBox1.Text = dic(curIndex)(0)
TextBox2.Text = dic(curIndex)(1)
TextBox3.Text = dic(curIndex)(2)
TextBox4.Text = dic(curIndex)(3)
TextBox5.Text = dic(curIndex)(4)
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
If Not curIndex 1 > maxIndex Then
curIndex = 1
Label1.Text = curIndex.ToString
TextBox1.Text = dic(curIndex)(0)
TextBox2.Text = dic(curIndex)(1)
TextBox3.Text = dic(curIndex)(2)
TextBox4.Text = dic(curIndex)(3)
TextBox5.Text = dic(curIndex)(4)
End If
End Sub
You can use Dictionary to save line number and values.