Excel VBA:嵌套循环中的FindNext

Excel VBA:嵌套循环中的FindNext,vba,excel,Vba,Excel,我正在尝试在另一个循环中使用.Find函数创建一个循环,该循环已经在使用.Find。我想搜索保存在数组中的字符串 例如,这些是保存在Sheet1中数组strItem中的字符串值 "unit1", "unit2", "unit3" 我想从第2页中逐一搜索它们。表2如下所示: unit1 unit2 unit3 unit1.pdf text1 subject1 subject2 subject3 text2 ========= unit2.pdf text1 subject1 subject2 s

我正在尝试在另一个循环中使用
.Find
函数创建一个循环,该循环已经在使用
.Find
。我想搜索保存在数组中的字符串

例如,这些是保存在Sheet1中数组
strItem
中的字符串值

"unit1", "unit2", "unit3"
我想从第2页中逐一搜索它们。表2如下所示:

unit1
unit2
unit3
unit1.pdf
text1
subject1
subject2
subject3
text2
=========
unit2.pdf
text1
subject1
subject2
subject3
text2
=========
unit3.pdf
text1
subject1
subject2
subject3
text2
=========
在搜索了
“unit1.pdf”
之后,我在它下面的所有单元格中搜索“subject”,并获得subject1、2和3的单元格值。对“主题”单元格的搜索应在包含“=”的下一个单元格停止

接下来,我搜索
“unit2”
,如果找到,则像以前一样搜索它下面的“subject”单元格。同样,在包含“==”的单元格处停止。等等

在我的代码中,我试图做的是

  • 搜索字符串“unit”
  • 使用其
    .row
    作为开始搜索“主题”的范围
  • 返回所有主题,直到单元格包含
    “==”
    这是我的代码的一部分,我无法真正使其工作
代码:

Wb2.Sheets(“Sheet2”)。激活
带Wb2.图纸(“图纸2”).范围(“A1:A1048575”)
对于ArrexcelValue中的每个strItem
myStr=strItem&“.pdf”
设置p=.Find(What:=myStr,LookIn:=xlValues_
LookAt:=xlPart,SearchOrder:=xlByRows,MatchCase:=False)
如果不是p,那么p什么都不是
firstAddress=p.地址
做
myStr2=p.row
strStart=“A”和myStr2
strEnd=“A1048575”
带Wb2.板材(“板材2”).范围(strStart,strEnd)
设置p1=.Find(What:=“Subject”,LookIn:=xlValues_
LookAt:=xlPart,SearchOrder:=xlByRows,MatchCase:=False)
如果不是p1,那么p1什么都不是
firstAddress=p1.地址
做
myStr2=myStr2+1
如果p1.Offset(myStr2,0).Value=“=”则
退出Do
其他的
MsgBox p1.值和符号
如果结束
设置p1=.FindNext(p1)
循环而非p1为Nothing,p1.Address为firstAddress
其他的
MsgBox“未找到”
如果结束
以
设置p=.FindNext(p)
循环而不是p为Nothing,p.Address为firstAddress
其他的
MsgBox“未找到”
如果结束
下一个
以

虽然离你不远,但有几件事需要考虑:

  • 似乎您知道数据的顺序,您可以使用此选项来简化操作,而不是在整个列中使用
    Find
  • 除非深入子元素,否则不能将嵌套的
    语句一起使用。很好,你正在尝试完全限定事物,但要小心。比如说,

    ' This is okay
    With ThisWorkbook.Sheets("Sheet2")
        With .Range("A1")
            MsbBox .Value
        End With
        With .Range("A2")
            MsgBox .Value
        End With
    End With 
    
    ' This is not okay, and present in your code
    With ThisWorkbook.Sheets("Sheet2").Range("A1")
        MsgBox .Value
        With ThisWorkbook.Sheets("Sheet2").Range("A2")
            Msgbox .Value
        End With
    End With
    
我已经采纳了您代码中的想法,并将其重新编写为更清晰一点,希望实现您想要的。有关详细信息,请参见评论:

Dim Wb2 As Workbook
Dim lastRow As Long
Set Wb2 = ThisWorkbook
' Get last used row in sheet, so search isn't on entire column
lastRow = Wb2.Sheets("Sheet2").UsedRange.Rows.Count
' Set up array of "unit" values
Dim arrExcelValues() As String
arrExcelValues = Split("unit1,unit2,unit3", ",")

' Declare variables
Dim pdfCell As Range
Dim eqCell As Range
Dim eqRow As Long
eqRow = 1
Dim subjCell As Range
Dim strItem As Variant

' Loop over unit array
With Wb2.Sheets("Sheet2")
For Each strItem In arrExcelValues
    ' Find the next "unitX.pdf" cell after the last equals row (equals row starts at 1)
    Set pdfCell = .Range("A" & eqRow, "A" & lastRow).Find(what:=strItem & ".pdf", lookat:=xlPart)
    If Not pdfCell Is Nothing Then
        ' pdf row found, find next equals row, store row value or use last row
        Set eqCell = .Range("A" & pdfCell.Row, "A" & lastRow).Find(what:="====", lookat:=xlPart)
        If eqCell Is Nothing Then
            eqRow = lastRow
        Else
            eqRow = eqCell.Row
        End If
        ' Loop through cells between pdf row and equals row
        For Each subjCell In .Range("A" & pdfCell.Row, "A" & eqRow)
            ' If cell contents contain the word "subject" then do something (display message)
            If InStr(UCase(subjCell.Value), "SUBJECT") > 0 Then
                MsgBox "Subject: " & subjCell.Value & ", Unit: " & strItem
            End If
        Next subjCell
    Else
        MsgBox "Item not found: " & strItem & ".pdf"
    End If
Next strItem
End With   

你离这里不远,但有几件事需要考虑:

  • 似乎您知道数据的顺序,您可以使用此选项来简化操作,而不是在整个列中使用
    Find
  • 除非深入子元素,否则不能将嵌套的
    语句一起使用。很好,你正在尝试完全限定事物,但要小心。比如说,

    ' This is okay
    With ThisWorkbook.Sheets("Sheet2")
        With .Range("A1")
            MsbBox .Value
        End With
        With .Range("A2")
            MsgBox .Value
        End With
    End With 
    
    ' This is not okay, and present in your code
    With ThisWorkbook.Sheets("Sheet2").Range("A1")
        MsgBox .Value
        With ThisWorkbook.Sheets("Sheet2").Range("A2")
            Msgbox .Value
        End With
    End With
    
我已经采纳了您代码中的想法,并将其重新编写为更清晰一点,希望实现您想要的。有关详细信息,请参见评论:

Dim Wb2 As Workbook
Dim lastRow As Long
Set Wb2 = ThisWorkbook
' Get last used row in sheet, so search isn't on entire column
lastRow = Wb2.Sheets("Sheet2").UsedRange.Rows.Count
' Set up array of "unit" values
Dim arrExcelValues() As String
arrExcelValues = Split("unit1,unit2,unit3", ",")

' Declare variables
Dim pdfCell As Range
Dim eqCell As Range
Dim eqRow As Long
eqRow = 1
Dim subjCell As Range
Dim strItem As Variant

' Loop over unit array
With Wb2.Sheets("Sheet2")
For Each strItem In arrExcelValues
    ' Find the next "unitX.pdf" cell after the last equals row (equals row starts at 1)
    Set pdfCell = .Range("A" & eqRow, "A" & lastRow).Find(what:=strItem & ".pdf", lookat:=xlPart)
    If Not pdfCell Is Nothing Then
        ' pdf row found, find next equals row, store row value or use last row
        Set eqCell = .Range("A" & pdfCell.Row, "A" & lastRow).Find(what:="====", lookat:=xlPart)
        If eqCell Is Nothing Then
            eqRow = lastRow
        Else
            eqRow = eqCell.Row
        End If
        ' Loop through cells between pdf row and equals row
        For Each subjCell In .Range("A" & pdfCell.Row, "A" & eqRow)
            ' If cell contents contain the word "subject" then do something (display message)
            If InStr(UCase(subjCell.Value), "SUBJECT") > 0 Then
                MsgBox "Subject: " & subjCell.Value & ", Unit: " & strItem
            End If
        Next subjCell
    Else
        MsgBox "Item not found: " & strItem & ".pdf"
    End If
Next strItem
End With   

感谢您提供的信息丰富的回复。我真的学到了很多。我已经阅读并研究了您的代码,并将其合并到我的sub中。我只是调整了很少的内容,它工作得非常完美!我真的很感激不用担心,很高兴我能帮上忙:)谢谢你的回复。我真的学到了很多。我已经阅读并研究了您的代码,并将其合并到我的sub中。我只是调整了很少的内容,它工作得非常完美!我真的很感激不用担心,很高兴我能帮忙:)