VBA: если A найдено в строке 1, А B найдено в строке 2.. затем


В настоящее время мой VBA настроен для чтения текстового файла (с помощью FileSystemObject) и поиска определенных строк. Все это прекрасно работает. Но я пытаюсь добиться того, чтобы VBA прочитала текст, и когда она найдет определенную строку (а) и в следующей строке под ней другую строку (б), она что-то сделает. Но только если б сразу после О.

Пример:

Find in the following text "Bob's House" and in the next line after that "Electricity.
Text 1: - Return False
blablabla *Bob's House* blablabla
blablabla blablabla blablabla
blabla *Electiricity* blablabla

Text 1: - Return True
blablabla *Bob's House* blablabla
blabla *Electiricity* blablabla

Вот что у меня есть до сих пор:

Set fsFile = fs.OpenTextFile(FilePath, 1, False)
sLine = fsFile.ReadLine

If VBA.InStr(1, sLine, "Bobs House") > 0 Then
   checkpointHeading = True
End If
If VBA.InStr(1, sLine, "Electricity") > 0 Then
   checkpointSubheading = True
End If
If checkpointHeading = True And checkpointSubheading = True Then
   MsgBox "Found it!"
End If

Это возвращает "нашел его" независимо от того, сколько строк есть между Bobs House и Electricity. Что вполне логично. Но как я могу заставить второе ограничение действовать только после того, как первое будет найдено на предыдущей линии?

Есть ли что-то вроде sLine +1 / .Readline + 1 (а затем применить второе утверждение if внутри первого?). Заранее спасибо, R

3 2

3 ответа:

У вас возникли эти проблемы, потому что вы не сбрасываете переменную "дом Боба" на следующей строке, если эта строка не равна "электричеству". Поэтому, как только дом Боба будет найден, это всегда будет правдой, и не имеет значения, где "электричество" входит.

Вы можете достичь того, что вы ищете, одним из двух способов. Используя булевы, как у вас, и код в "Способе 1" (который я немного раздул, поэтому его легко следовать), или, возможно, лучший способ, где вы просто устанавливаете текущую строку строковая переменная в новую строковую переменную, которая содержит предыдущую строку в конце цикла, а затем проверьте обе эти переменные в следующей строке, как в "способе 2".

(Обратите внимание, что в вашем примере есть несколько опечаток, которые я сохранил, поэтому код работает с примером).

    Sub Way1()
    Dim fs As New FileSystemObject, fsfile As Object
    Dim sLine As String
    Dim checkpointHeading As Boolean, checkpointSubheading As Boolean

    'Open file
    Set fsfile = fs.OpenTextFile("G:Test.txt", 1, False)

    'Loop through
    Do While fsfile.AtEndOfStream <> True

        sLine = fsfile.ReadLine

        If VBA.InStr(1, sLine, "Bob's House") > 0 Then
           checkpointHeading = True
        Else
           'If the line doesn't have Bob's House then check if the line before did
           If checkpointHeading Then
               'If it did then check for Electricity
               If VBA.InStr(1, sLine, "Electiricity") > 0 Then
                   'If it's found then happy days
                   checkpointSubheading = True
               Else
                   'If it's not found then reset everything
                   checkpointHeading = False: checkpointSubheading = False
               End If
           End If
        End If

        'Check if we've found it
        If checkpointHeading = True And checkpointSubheading = True Then
           MsgBox "Found it!"

           'You may want to reset here to be safe
           checkpointHeading = False:    checkpointSubheading = False
        End If

    Loop

    fsfile.Close
    Set fsfile = Nothing
    Set fs = Nothing
End Sub

Более простой и лаконичный способ 2:

Sub Way2()
    Dim fs As New FileSystemObject, fsfile As Object
    Dim sLine As String, sPrevLine As String

    'Open file
    Set fsfile = fs.OpenTextFile("G:Test.txt", 1, False)

    'Loop through
    Do While fsfile.AtEndOfStream <> True

        sLine = fsfile.ReadLine

        If VBA.Len(sPrevLine) > 0 Then
            If VBA.InStr(1, sPrevLine, "Bob's House") > 0 And VBA.InStr(1, sLine, "Electiricity") Then
                MsgBox "Found it!"
            End If
        End If

        'Set the current line to the previous line *at the end of the loop*
        sPrevLine = sLine
    Loop

    fsfile.Close
    Set fsfile = Nothing
    Set fs = Nothing
End Sub

Я не проверял его, но это должно продемонстрировать логику:

 Const filepath = "..."

 Sub test()

    Dim fs
    Dim fsFile
    Dim found As Boolean
    Dim flag As Boolean
    Dim sLine As String

    Set fs = CreateObject("Scripting.FileSystemObject")
    Set fsFile = fs.OpenTextFile(filepath, 1, False)

    found = False
    flag = False
    Do While Not fsFile.AtEndOfStream And Not found
        sLine = fsFile.readLine
        If flag And InStr(sLine, "Electricity") Then found = True
        flag = (InStr(sLine, "Bobs House") > 0)
    Loop

    If found Then
        MsgBox sLine
    Else
        MsgBox "not found"
    End If

 End Sub

Правка: Проверено.

Что-то вроде этого:

    sLine = fsFile.ReadLine

    If isHeading Then
        If InStr(1, sLine, "Electricity") > 0 Then
            MsgBox "Found It!"
        End If
        isHeading = False
    End If

    If InStr(1, sLine, "Bobs House") > 0 Then
        isHeading = True
    End If