简体   繁体   English

Excel VBA:嵌套循环中的FindNext

[英]Excel VBA: FindNext in nested loops

I am trying to create a loop using the .Find function within another loop which is already using .Find . 我试图在另一个已经使用.Find的循环中使用.Find函数创建一个循环。 I want to search for strings that I have saved in an array. 我想搜索已保存在数组中的字符串。

For example, these are the string values saved in the array strItem in Sheet1. 例如,这些是保存在Sheet1中的数组strItem中的字符串值。

"unit1", "unit2", "unit3"

I would like to search them one by one from Sheet2. 我想从Sheet2逐一搜索它们。 Sheet2 looks like this: Sheet2看起来像这样:

unit1
unit2
unit3
unit1.pdf
text1
subject1
subject2
subject3
text2
=========
unit2.pdf
text1
subject1
subject2
subject3
text2
=========
unit3.pdf
text1
subject1
subject2
subject3
text2
=========

After searching for "unit1.pdf" , I search all cells below it for "subject", and get cell values of subject1, 2, and 3. The search for "subject" cells should stop at the next cell which contains "====". 搜索"unit1.pdf" ,我搜索其下面的所有单元格中的“subject”,并获取subject1,2和3的单元格值。搜索“subject”单元格应该停在包含“==”的下一个单元格==”。

Next I search for "unit2" , and if found search for "subject" cells under it as before. 接下来,我搜索"unit2" ,如果发现像以前一样在其下搜索“subject”单元格。 Again, stop at the cell containing "====". 再次,停在包含“====”的单元格。 And so on. 等等。

In my code, what I am trying to do was 在我的代码中,我想要做的是

  • Search for the string "unit". 搜索字符串“unit”。
  • Use its .row as the range to start searching for "subject". 使用.row作为范围开始搜索“主题”。
  • Return all subjects until the cell contains "====" . 返回所有主题,直到单元格包含"====" This is a part of my code that I can't really make to work . 这是我的代码的一部分,我无法真正使用

Code: 码:

Wb2.Sheets("Sheet2").Activate
With Wb2.Sheets("Sheet2").Range("A1:A1048575")
    For Each strItem In arrExcelValues
        myStr = strItem & ".pdf"
        Set p = .Find(What:=myStr, LookIn:=xlValues, _
                      LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False)
        If Not p Is Nothing Then
            firstAddress = p.Address
            Do
                myStr2 = p.row
                strStart = "A" & myStr2
                strEnd = "A1048575"

                With Wb2.Sheets("Sheet2").Range(strStart, strEnd)
                    Set p1 = .Find(What:="Subject", LookIn:=xlValues, _
                                   LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False)
                    If Not p1 Is Nothing Then
                        firstAddress = p1.Address
                        Do
                            myStr2 = myStr2 + 1
                            If p1.Offset(myStr2, 0).Value = "====" Then
                                Exit Do
                            Else
                                MsgBox p1.Value & strItem
                            End If
                            Set p1 = .FindNext(p1)
                        Loop While Not p1 Is Nothing And p1.Address <> firstAddress
                    Else
                        MsgBox "Not found"
                    End If
                End With
                    Set p = .FindNext(p)
            Loop While Not p Is Nothing And p.Address <> firstAddress
        Else
            MsgBox "Not found"
        End If
    Next
End With

You're not far off, but there are a couple of things to think about: 你离这里不远,但有几点需要考虑:

  • It seems you know the order of your data, you can use this to make life easier than using Find on the entire column. 您似乎知道数据的顺序,您可以使用它来比在整个列上使用Find更容易。
  • You cannot use nested With statements unless you are going further into the child elements. 除非进一步使用子元素,否则不能使用嵌套的With语句。 It is good you are trying to fully qualify things, but be careful. 你想要完全符合条件,这很好,但要小心。 For instance, 例如,

     ' 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 

I have taken the ideas in your code, and re-written it to be a bit clearer, and hopefully achieve what you want. 我已经在您的代码中采用了这些想法,并重新编写它以使其更清晰,并希望实现您想要的。 See the comments for details: 有关详细信息,请参阅注释

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   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM