3

これが VBForums への私の最初の投稿であると言って始めましょう。私はしばらく潜んでいました。私はVBにかなり慣れていないので、論文を完成させるためにVBを学んでいます。では、私の無知をお許しください。

私がやろうとしているのは、別のプログラムによって生成されたログ ファイルからデータを読み取ることです。他のアルゴリズムで使用するために、そのファイルから特定の行を VB に取り込む必要があります。このログ ファイルは常に更新されるため、可能であればライブで読み取る必要があります。

問題がある場合は、別のソフトウェアと通信している USB デバイスからログ ファイルが生成されています。

サンプル ログは次のとおりです。

`
08:57:00.932    COM12
08:57:00.935    COM11
08:57:00.935    COM10
08:57:00.936    COM9
08:57:00.936    COM8
08:57:00.937    COM7
08:57:00.938    COM6
08:57:00.939    COM5
08:57:00.939    COM4
08:57:00.998    --> 0108000304FF0000
08:57:01.007    <-- 0108000304FF0000

TRF7970A EVM 


08:57:01.014    **** COM Port found! ****
08:57:05.009    --> 010A0003041001210000
08:57:05.009    COM4
08:57:05.173    <-- 010A0003041001210000

Register write request.


08:57:05.173    --> 010C00030410002101020000
08:57:05.280    <-- 010C00030410002101020000

Register write request.


08:57:05.280    --> 010B000304140601000000
08:57:05.715    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:05.716    --> 010A0003041001210000
08:57:05.822    <-- 010A0003041001210000

Register write request.


08:57:05.822    --> 010C00030410002101020000
08:57:05.929    <-- 010C00030410002101020000

Register write request.


08:57:05.929    --> 010B000304140601000000
08:57:06.364    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:06.365    --> 010A0003041001210000
08:57:06.470    <-- 010A0003041001210000

Register write request.


08:57:06.470    --> 010C00030410002101020000
08:57:06.576    <-- 010C00030410002101020000

Register write request.


08:57:06.576    --> 010B000304140601000000
08:57:07.011    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:07.012    --> 010A0003041001210000
08:57:07.117    <-- 010A0003041001210000

Register write request.


08:57:07.117    --> 010C00030410002101020000
08:57:07.223    <-- 010C00030410002101020000

Register write request.


08:57:07.223    --> 010B000304140601000000
08:57:07.658    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:07.659    --> 010A0003041001210000
08:57:07.764    <-- 010A0003041001210000

Register write request.


08:57:07.764    --> 010C00030410002101020000
08:57:07.870    <-- 010C00030410002101020000

Register write request.


08:57:07.870    --> 010B000304140601000000
08:57:08.305    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:08.306    --> 010A0003041001210000
08:57:08.411    <-- 010A0003041001210000

Register write request.


08:57:08.411    --> 010C00030410002101020000
08:57:08.517    <-- 010C00030410002101020000

Register write request.


08:57:08.517    --> 010B000304140601000000
08:57:08.952    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:08.952    --> 010A0003041001210000
08:57:09.058    <-- 010A0003041001210000

Register write request.


08:57:09.058    --> 010C00030410002101020000
08:57:09.164    <-- 010C00030410002101020000

Register write request.


08:57:09.164    --> 010B000304140601000000
08:57:09.585    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]

[AD87851A000007E0,7F]

[,40][,40]D
08:57:09.586    --> 010A0003041001210000
08:57:09.692    <-- 010A0003041001210000

Register write request.


08:57:09.692    --> 010C00030410002101020000
08:57:09.798    <-- 010C00030410002101020000

Register write request.


08:57:09.798    --> 010B000304140601000000
08:57:10.233    <-- 010B000304140601000000

ISO 15693 Inventory request.

[,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40][,40]D
08:57:10.234    --> 010A0003041001210000
08:57:10.340    <-- 010A0003041001210000

Register write request.


08:57:10.340    --> 010C00030410002101020000
08:57:10.446    <-- 010C00030410002101020000

Register write request.

`

次の行を取得できるようにする必要があります: [AD87851A000007E0,7F]

「AD87851A000007E0」だけにして、VBでその文字列を使用できるようにします。これは変更される 16 進コードです。

ログ ファイルから読み取ることはできましたが、有効な出力を生成できませんでした。

これが私が使用しようとしているコードです:

Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False
        Do While line IsNot Nothing
            If line.StartsWith("[") Then
                take = False
            End If
            If String.Equals("[" + keyword + ",", line) Then
                take = True
            End If
            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                result.Add(line)
            End If
            line = reader.ReadLine()
    Label1.Text = line
        Loop
    End Using
    Return result
End Function

正直なところ、コードが機能していないのか、それとも関数から文字列を取得することに関して何か間違ったことをしているだけなのか、私にはわかりません。関数はそのまま Label1.Text に出力しますか?

また、次のように関数を呼び出してみました。

Dim items = ReadData("AD87851A000007E0")

Label1.Text = Convert.ToString(items)

これにより、Label1.Text は "System.Collections.Generic.List`1[System.String]" になります。


編集1

Imports System.IO

パブリック クラス Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("AD87851A000007E0")

    Label1.Text = String.Join(Environment.NewLine, items)


End Sub

Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False
        Do While line IsNot Nothing

            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith("[" + keyword + ",") Then
                take = True
            End If

            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                result.Add(line)
            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

クラス終了

編集2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

現在までの新しいコード:

Imports System.IO

パブリック クラス Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("AD87851A000007E0")  ' Calling the specific hex code from the function. Advancement needed to get ALL hex codes.

    '   Dim items1 As String = Convert.ToString(items)
    '   Dim items2 As String = ""


    '   Dim k As Long
    '   k = InStrRev(items, ",")
    '   If k > 0 Then items2 = Left$(items, k)

    Label1.Text = String.Join(Environment.NewLine, items)  'Printing function result to Label1


End Sub


'Function to search log file for a specific hex code. Removes not needed portions of the string. Advancements needed: 
'Find ALL hex codes
'Ignore repeats until a reset is set true
'Store each hex code found in it's own variable for use in algorithms


Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim take = False

        Do While line IsNot Nothing
            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith("[" + keyword + ",") Then
                take = True
            End If


            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                line = line.Remove(0, 1) 'removing the extra parts of the line
                line = line.Remove(16, 4)
                result.Add(line) 'adding the valid result

            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

クラス終了


編集3

Imports System.IO

パブリック クラス Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim items = ReadData("[")  ' Calling the specific hex code from the function. Advancement needed to get ALL hex codes.

    Label1.Text = String.Join(Environment.NewLine, items)  'Printing function result to Label1


End Sub


'Function to search log file for a specific hex code. Removes not needed portions of the string. Advancements needed: 
'Find ALL hex codes
'Ignore repeats until a reset is set true
'Store each hex code found in it's own variable for use in algorithms


Function ReadData(ByRef keyword As String) As IEnumerable(Of String)
    Dim result = New List(Of String)
    Using reader = New StreamReader("C:\rfid-reader.log")
        Dim line As String = reader.ReadLine()
        Dim line1 As String = "COOKIES"
        Dim line2 As String = "COOKIES1"
        Dim line3 As String = "COOKIES2"
        Dim line4 As String = "COOKIES3"
        Dim line5 As String = "COOKIES4"
        Dim line6 As String = "COOKIES5"
        Dim line7 As String = "COOKIES6"
        Dim line8 As String = "COOKIES7"
        Dim line1found = False
        Dim line2found = False
        Dim line3found = False
        Dim line4found = False
        Dim line5found = False
        Dim line6found = False
        Dim line7found = False
        Dim line8found = False
        Dim take = False

        Do While line IsNot Nothing

            take = False ' resetting take = false to avoide printing all lines

            If line.StartsWith(keyword) And Not line.StartsWith("[,4") And Not line.StartsWith("[z,") Then
                take = True
            End If

            If line.Contains(line1) Or line.Contains(line2) Or line.Contains(line3) Or line.Contains(line4) Or line.Contains(line5) Or line.Contains(line6) Or line.Contains(line7) Or line.Contains(line8) Then  'attempting to ignore duplicates
                take = False
            End If

            If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
                line = line.Remove(0, 1) 'removing the extra parts of the line
                line = line.Remove(16, 4)
                result.Add(line) 'adding the valid result

                If line1 <> line And Not line1found Then  'assining results to variables for duplicate elimiation
                    line1 = line
                    line1found = True

                ElseIf line2 <> line And line1 <> line And Not line2found Then
                    line2 = line
                    line2found = True

                ElseIf line <> line3 And line <> line2 And line1 <> line And Not line3found Then
                    line3 = line
                    line3found = True

                ElseIf line <> line4 And line <> line3 And line <> line2 And line <> line1 And Not line4found Then
                    line4 = line
                    line4found = True

                ElseIf line <> line5 And line <> line4 And line <> line3 And line <> line2 And line <> line1 And Not line5found Then
                    line5 = line
                    line5found = True

                ElseIf line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line6found Then
                    line6 = line
                    line6found = True

                ElseIf line7 <> line And line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line7found Then
                    line7 = line
                    line7found = True

                ElseIf line8 <> line And line7 <> line And line6 <> line And line5 <> line And line4 <> line And line3 <> line And line2 <> line And line1 <> line And Not line8found Then
                    line8 = line
                    line8found = True

                End If
            End If
            line = reader.ReadLine()
        Loop
    End Using
    Return result
End Function

クラス終了

4

2 に答える 2

1

私はパーティーに遅れていますが、これはEdit 3を変更して、いくつかのことを合理化し、ラインを検証する方法を拡張できるフレームワークを作成します。

Function readData() As List(Of String)
    readData = New List(Of String)
    Using reader As New StreamReader("C:\rfid-reader.log")
        While Not reader.EndOfStream
            For Each line In reader.ReadToEnd.Split(ControlChars.CrLf)
                If validLine(line) AndAlso Not readData.Contains(line.Split(",")(0).Substring(1)) Then readData.Add(line.Split(",")(0).Substring(1))
            Next
        End While
    End Using
End Function

Private Function validLine(line As String) As Boolean
    validLine = True
    'insert criteria to validate the line's format (you could also look at regex)
    If Not line.Trim.Length > 0 Then
        validLine = False
        Exit Function
    End If
    If Not line.Trim.StartsWith("[") AndAlso line.Trim.EndsWith("]") Then
        validLine = False
        Exit Function
    End If
    If Not line.Split(",").Length = 2 Then
        validLine = False
        Exit Function
    End If
    If Not line.Split(",")(0).Substring(1).Length > 1 Then
        validLine = False
        Exit Function
    End If
    If Not isHex(line.Split(",")(0).Substring(1)) Then
        validLine = False
        Exit Function
    End If
    '...
End Function

Private Function isHex(str As String) As Boolean
    isHex = True
    For i = 0 To str.Length - 1
        If Not {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "B", "C", "D", "E", "F"}.Contains(str.Substring(i, 1)) Then
            isHex = False
            Exit Function
        End If
    Next
End Function
于 2013-02-27T15:31:39.713 に答える
1

コードにはいくつかの問題があります。最初の問題は、次String.Equalsの代わりに使用していることですline.StartsWith

If String.Equals("[" + keyword + ",", line) Then
    take = True
End If

take = True上記のコードでは、行全体が文字列 "[AD87851A000007E0," と正確に一致する場合にのみ設定されることがわかります。しかし、探している行はその文字列と同じではありません。単にその文字列で始まっているだけです。したがって、そのコードを次のように変更する必要があります。

If line.StartsWith("[" + keyword + ",") Then
    take = True
End If

次に、Label1.Text = line行が一致するかどうかに関係なく、各行を読み取った後、ループ内に を設定します。あなたがしていることはうまくいきますが、おそらくあなたが意図した方法ではありません. 現在の方法では、読み取られる新しい行ごとにラベルのテキスト コンテンツ全体が上書きされます。私が言ったように、一致する行だけでなく、すべての行でそうします。ループで忙しいので、完了するまで画面は実際には更新されません。そのため、最終的には、ファイルの最後の行を表示するだけです。

一致するすべての行を表示する場合は、If take...ブロック内に移動する必要があり、次のように行を連結する必要があります。

If take And Not String.IsNullOrEmpty(line) And Not line.StartsWith("'") Then
    result.Add(line)
    Label1.Text = Label1.Text & Environment.NewLine & line
End If

ただし、それはまだ良い方法ではありません。UI コードをビジネス ロジックと混在させることは決して良い考えではないため、呼び出し後にラベルを設定するという本能ReadDataは正しい考えです。Convert.ToStringただし、 を使用してリストの内容を表示することはできません。お気づきのとおり、データ型の名前が表示されるだけです。これを行うには、次のように、リスト内の文字列を 1 つの文字列に結合する必要があります。

Label1.Text = String.Join(Environment.NewLine, items)

区切り文字として使用Environment.NewLineしましたが、区切り文字としては何でも使用できます。たとえば、すべてを 1 行で表示したい場合は", "、区切り記号として使用できます。

于 2013-02-26T13:31:34.417 に答える