我有一个粗略格式化的数据集可供使用,我正在使用多个Find
方法来获取我需要的数据点。我的示例数据库有三个数据周期(全部在一张纸上),有多个官员名称。名称可能在特定时期内也可能不在。我使用变量officerSearch
来存储地址,该地址充当以下Find
方法的定位点。除非官员姓名不在特定时期,否则我的Find
方法会偏离正常。我的代码评论中有更多细节。
For Each k In dateArray.keys 'loops through my periods. Each key is a unique date
For i = 0 To officerListBox.ListCount - 1
If officerListBox.Selected(i) = True Then 'Performs _
Find methods for each officer selected in list box
officerSearch = Cells.Find(what:=CDate(k), LookIn:=xlFormulas, _
searchorder:=xlByRows, searchdirection:=xlNext).Address 'Finds first instance of the first period (k)
officerSearch = Cells.Find(what:=officerListBox.List(i), _
after:=Range(officerSearch), LookIn:=xlValues, lookat:=xlWhole, _
searchorder:=xlByRows, searchdirection:=xlNext).Address _
'Finds officer name starting after the date cell was found. _
But if the raw data set doesn't have the officer name in that period, _
my Find method will find an officer name further on down the sheet _
(or loop around at the beginning of the sheet) where the name is found in a different period.
officerSearch = Cells.Find(what:="Gross Loans", after:=Range(officerSearch), _
LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, _
searchdirection:=xlNext).Address 'Finds the cell labeled Gross Loans starting after an officer name is found
officerSearch = Cells.Find(what:="Total 30 - 59 days past due", _
after:=Range(officerSearch), LookIn:=xlValues, lookat:=xlWhole, _
searchorder:=xlByRows, searchdirection:=xlNext).Address 'Finds the cell _
labeled Total 30-59 days past due starting after _
an officer name is found.
End If
Next i 'Starts the find loop over for the next selected officer name
Next k 'Starts the find loop over for the next period in the dataset
所以我的第一,第三和第四个Find方法保证存在于我期望的位置,但第二个Find方法可能不在我的循环搜索的时间段内,因此抛弃其他所有内容。我很难理解如何解释这一点。
答案 0 :(得分:2)
将.Find
的结果作为Range
对象返回,并检查Nothing
- ness,而不是将方法/属性(例如,.Address
)链接到对象可能不存在(即找不到值)。
为不同的事情使用不同的变量名称可能也是一个好主意,当然你可以重新转换为officerSearch
,这可能会让人感到困惑和限制,此外,变量很便宜。 / p>
理想情况下,您希望定义一个您关注的表或一系列单元格,而不是以Cells.Find
开头,然后将其用作.Find
的基础,而不是调用该方法针对整个工作表。这是您需要定义的dataRange
对象。
Dim dataRange As Range '## range containing ALL data
Set data Range = Range(...) '## MODIFY AS NEEDED
Dim searchRange as Range, offName as Range, grossLoans as Range, pastDue as Range
'## Finds first instance of the first period (k) in the worksheet.Cells
Set searchRange = dataRange.Find(what:=CDate(k), LookIn:=xlFormulas, searchorder:=xlByRows, searchdirection:=xlNext)
'## Define the range of cells containing this (k) period:
' Assumes the (k) date is only present in one column
Set searchRange = searchRange.Resize(Application.WorksheetFunction.CountA(dataRange, CDate(k))
'## Finds officer name ONLY WITHIN THE searchRange, defined above
Set offName = searchRange.Find(what:=officerListBox.List(i), after:=Range(officerSearch.Cells(1).Address), LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext)
'## Get out of here if the value isn't found
If offName Is Nothing Then
' you probably want a GoTo or Exit For statement here...
MsgBox "Not found!"
Else
'## Otherwise, find Gross Loans beneath Officer Name:
Set grossLoans = searchRange.Find(what:="Gross Loans", after:=Range(offName.Address), LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext)
Set pastDue = searchRange.Find(what:="Total 30 - 59 days past due", after:=Range(grossLoans.Address), LookIn:=xlValues, lookat:=xlWhole, searchorder:=xlByRows, searchdirection:=xlNext)
End If
searchRange
值将dataRange
定义为CDate(k)
中的初始找到范围。 Resize
这基于该日期的实例数
价值存在于dataRange
中。
searchRange
作为所有后续调用的.Find
方法的父级,这样我们就可以将其限制为特定日期(k)。MsgBox
。 grossLoans
,pastDue
)。< / LI>
醇>
注意:代码未经过测试,可能包含错别字,错位的括号等。特别是searchRange.CurrentRegion
可能不可靠,如果您可以定义范围更好包含循环外相关数据的单元格。