[英]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 在我的代码中,我想要做的是
.row
as the range to start searching for "subject". .row
作为范围开始搜索“主题”。 "===="
. "===="
。 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: 你离这里不远,但有几点需要考虑:
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.