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 ответа:
У вас возникли эти проблемы, потому что вы не сбрасываете переменную "дом Боба" на следующей строке, если эта строка не равна "электричеству". Поэтому, как только дом Боба будет найден, это всегда будет правдой, и не имеет значения, где "электричество" входит.
Вы можете достичь того, что вы ищете, одним из двух способов. Используя булевы, как у вас, и код в "Способе 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
Правка: Проверено.