2

このプログラムでテキスト ファイルを開き、それらの特定の文字を見つけて、その後の単語をリストに追加します (各文字には、リストに特定のサブアイテムがあります)。重複がなければうまくいきます。しかし、次のようなリストがある場合:

    /* 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

次に、最初の行のみを追加します。while ループも作成しますが、最初の行を他の行に追加するだけです。誰か助けてください! (ちなみに、私のリストには6つの列が含まれています)

これはコードです:

   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
4

1 に答える 1

2

「重複文字列」とは、ファイルに複数の項目 (6 列のグループ) がある場合にファイルを読み取る方法を意味していると思います。

現在のプログラムが最初の項目のみを取得する理由はFor、ファイル内にいくつあるかに関係なく、特定のサブ項目の最初の出現を見つけた後にループを終了しているためです。

これを解決する 1 つの方法は、サブルーチン_Loadを関数に変更し、オブジェクトを返すようにするList(Of ListViewItem)ことです。オブジェクトを反復処理してマスター リストに追加できます ( ListClothes)。StreamReaderあなたがやっていることには必要ないので、私も取り除きます。FileNameからプロパティ (パスと拡張子を含む)を渡しているOpenFileDialogので、それを関数で簡単に使用でき_Loadます。

次のようになります。

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

上記のコードは、渡された を受け取り、FileNameから返された文字列を分割し、ReadAllText空のエントリを削除します。

次に、一度に 6 行ずつコードをループします。ループでは、新しい ListViewItem が作成され、サブ項目が設定されてから、この ListViewItem が に追加されList(Of ListViewItem)ます。

移入StockListされたものが返されます。

button1_Clickイベントでは、次のように使用できます。

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   

このコードでは、selectedFileName_Loadメソッドに渡し、その戻り値をローカルstockItems変数に割り当てます。

次に、stockItemsリストをループして、その中のそれぞれを に追加ListViewItemしますclothesList

このコードは脆弱であることに注意してください。入力ファイルで列が正しい順序になっていない場合、または列が欠落している場合、データが歪んでしまい、読み取ろうとするとプログラムがクラッシュする可能性があります。存在しない (ファイルからの) 配列内の行。もちろん、そのコードを Try Catch ブロックでラップすることもできます。

これはその方法の 1 つにすぎません。他にも方法があることは間違いありません。しかし、これで少なくとも正しい方向に進むはずです。

編集 先頭の文字を削除する最も簡単な方法は、次のように分割に追加することです。

Lines = File.ReadAllText(FileName).Split(New String() _
             { ControlChars.CrLf, "#", "%", "&", "@$", "$*", "*$"}, _
              StringSplitOptions.RemoveEmptyEntries)

これは、空の行と先頭の文字を除いたすべての行の配列を返します。

もちろん、上記のコードでは、入力ファイルの列が常に同じ順序である限り、これらの先頭文字は実際には必要ありません。

于 2013-08-05T06:53:00.500 に答える