Reputation: 181
I want this program to open a text file and find those specific character and add the words after that into the list (each character has specific subitem in the list). It work well if there is no duplication. But if I have list like:
/* First row of the list */
#Alireza
%Human
&1
@$1200
$*1
*$1000
/* ' Second row */
#Behzad
%Human
&1
@$1340
$*1
*$1000
/* ' And third row */
#Samaneh
%Human
&1
@$1570
$*1
*$1230
then it only add the first row. I also make a while loop but it will only add first row to other rows. Is there anyone can help please!(by the way my list include 6 columns )
this is the code:
Public code As String
Public cat As String
Public stock As Integer
Public price As Double
Public sold As Double
Public cost As Double
Public i As Integer
Public Sub _Load(ByVal FileName As String)
Dim strLines() As String
Dim strLine As String
Dim strData As String
Dim objFileInfo As New FileInfo(FileName)
strData = My.Computer.FileSystem.ReadAllText(FileName)
strLines = strData.Split(New String() {ControlChars.CrLf}, StringSplitOptions.RemoveEmptyEntries)
For Each strLine In strLines
If strLine.StartsWith("#") Then
code = strLine.Substring(1)
End If
strLine = Nothing
Next
For Each strLine In strLines
If strLine.StartsWith("%") Then
cat = strLine.Substring(1)
Exit For
End If
strLine = Nothing
Next
For Each strLine In strLines
If strLine.StartsWith("&") Then
stock = strLine.Substring(1)
Exit For
End If
strLine = Nothing
Next
For Each strLine In strLines
If strLine.StartsWith("@$") Then
price = strLine.Substring(2)
Exit For
End If
strLine = Nothing
Next
For Each strLine In strLines
If strLine.StartsWith("$*") Then
sold = strLine.Substring(2)
Exit For
End If
strLine = Nothing
Next
For Each strLine In strLines
If strLine.StartsWith("*$") Then
cost = strLine.Substring(2)
Exit For
End If
strLine = Nothing
Next
End Sub
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolImport.Click
Dim ans As String
OpenFileDialog1.Title = "What are you looking for?"
OpenFileDialog1.InitialDirectory = Application.StartupPath
OpenFileDialog1.Filter = "text Files (*.txt)|*.txt|Data Files (*.dat)|*.dat|All files (*.*)|*.*"
OpenFileDialog1.FileName = "myList"
Try
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim sr As StreamReader = New StreamReader(OpenFileDialog1.FileName)
Do While sr.Peek > -1
_Load(OpenFileDialog1.FileName)
Dim list As New ListViewItem(code)
list.SubItems.Add(cat)
list.SubItems.Add(stock)
list.SubItems.Add(price)
list.SubItems.Add(sold)
list.SubItems.Add(cost)
listClothes.Items.Add(list)
i += 1
MessageBox.Show("Your list has been uploaded successfully", "ccc!", MessageBoxButtons.OK, MessageBoxIcon.Information)
Loop
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Upvotes: 2
Views: 1700
Reputation: 28520
By "duplicate strings", I think you mean how to read the file when there is more than one item (group of 6 columns) in the file.
The reason your current program is getting only the first item is because you're exiting the For
loop after you find the first occurrence of a given sub item, regardless of how many there may be in the file.
One way to resolve this is to change your sub _Load
to a function and have it return a List(Of ListViewItem)
object, which you could then iterate through and add to the master list (ListClothes
). I would also get rid of the StreamReader
, as you don't need it for what you are doing. You're passing the FileName
property (which contains the path and extensions) from the OpenFileDialog
, so you can simply use that in the _Load
function.
It would look something like this:
Public Function _Load(ByVal FileName As String) As List(Of ListViewItem)
Dim Lines() As String
Dim List(Of ListViewItem) StockList = New List(Of ListViewItem)
Dim ListViewItem As StockItem
Lines = File.ReadAllText(FileName).Split(New String() _
{ ControlChars.CrLf}, StringSplitOptions.RemoveEmptyEntries)
For j = 0 To Lines.Length - 1 Step 6
StockItem = New ListViewItem(Lines(j))
StockItem.SubItems.Add(Lines(j + 1))
StockItem.SubItems.Add(Lines(J + 2))
StockItem.SubItems.Add(Lines(j + 3))
StockItem.SubItems.Add(Lines(J + 4))
StockItem.SubItems.Add(Lines(j + 5))
StockList.Add(StockItem)
Next
Return StockList
End Function
The above code takes the passed in FileName
, does a split on the string returned from ReadAllText
and removes empty entries.
Next it loops through code, 6 lines at a time. In the loop a new ListViewItem is created, and the sub items are populated, and then this ListViewItem is added to the List(Of ListViewItem)
.
The populated StockList
is then returned.
In your button1_Click
event, you could use it like this:
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles toolImport.Click
Dim ans As String
Dim stockItems As List(Of ListViewItem)
OpenFileDialog1.Title = "What are you looking for?"
OpenFileDialog1.InitialDirectory = Application.StartupPath
OpenFileDialog1.Filter = "text Files (*.txt)|*.txt|Data Files (*.dat)|*.dat|All files (*.*)|*.*"
OpenFileDialog1.FileName = "myList"
Try
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
stockItems = _Load(OpenFileDialog1.FileName)
For Each (stockItem As ListViewItem in stockItems)
listClothes.Add(stockItem)
Next
MessageBox.Show("Your list has been uploaded successfully", "ccc!", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
In this code, you pass the selected FileName
to the _Load
method and assign its return value to the local stockItems
variable.
Then you loop through the stockItems
list, and add each ListViewItem
in it to your clothesList
.
NOTE that this code is brittle - if the columns are not in the correct order in the input file, or if a column(s) is/are missing, your data will be skewed, and the program could potentially crash if you try to read a line in the array (from the file) that doesn't exist. Of course, you can wrap that code in a Try Catch block as well.
This is merely one way to do it - I have no doubt there are others. But this should at least get you going in the right direction.
EDIT The easiest way to remove the leading characters is to add them to the split, like this:
Lines = File.ReadAllText(FileName).Split(New String() _
{ ControlChars.CrLf, "#", "%", "&", "@$", "$*", "*$"}, _
StringSplitOptions.RemoveEmptyEntries)
This will return an array of all the lines, minus empty lines and the leading characters.
Of course, with the code above, you actually don't need those leading characters anymore, as long as the input file always has the columns in the same order.
Upvotes: 2