Excel VBA如何在工作表结束后阻止FIND方法循环?
我有一个大致格式化的数据集要处理,我正在使用多个Excel VBA如何在工作表结束后阻止FIND方法循环?,excel,vba,Excel,Vba,我有一个大致格式化的数据集要处理,我正在使用多个Find方法来获取我需要的数据点。我的示例数据库有三段数据(都在一张纸上),有多个官员姓名。一个名字可能在某个特定时期,也可能不在某个特定时期。我正在使用变量officerSearch存储地址,该地址作为以下Find方法的定位点。除非某个军官的名字不在某个特定的时期,否则这是有效的,然后我的Find方法就偏离了轨道。更多详细信息请参见我的代码注释 For Each k In dateArray.keys 'loops through my per
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
因此,我的第一、第三和第四个查找方法保证出现在我期望的位置,但第二个查找方法可能不在我的循环搜索的时间段内,因此会抛开所有其他方法。如何解释这一点,我被难住了。返回
的结果。作为范围
对象查找,并检查无
-ness,而不是将方法/属性(例如,.Address
)链接到可能不存在的对象(即,找不到值)
为不同的事情使用不同的变量名可能也是一个好主意,当然您可以重新转换到officerSearch
,这样做可能会造成混淆和限制,而且,变量很便宜
理想情况下,与其从单元格开始。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
工作原理:
首先,我们使用您的CDate(k)
值将searchRange
定义为dataRange
中的初始查找范围李>
然后,我们根据该日期的实例数量调整大小
值存在于数据范围中。
- 我们将使用此调整大小的
searchRange
作为所有后续调用的.Find
方法的父级,这样我们将它限制在特定的日期周期(k)内
然后我们找到军官的名字。
- 如果找不到官员姓名,您可能想做其他事情,现在有一个占位符
MsgBox
李>
如果找到了官员姓名,那么我们将查找贷款总额和逾期范围,并将其分配给相应的范围变量(grosslons
,passdue
)
注意:代码未经测试,可能包含打字错误、括号错位等。尤其是搜索范围。CurrentRegion
可能不可靠,如果您可以在循环外定义包含相关数据的单元格范围,则更好。可能不在我的循环搜索范围的期间。代码中的Find
方法是工作表。单元格
,即整个工作表。您需要一种更好的方法来定义第二、第三、第四次Find
调用的搜索范围,因为在当前编写的情况下,第二次.Find
将从周期的第一个实例(如您所观察)搜索到它下面的整个工作表。数据是否按日期排序?谢谢。这似乎奏效了。我重新编写了代码,只对您的解决方案做了一个更改。我能够做一些格式化魔术,使每个语句周期都是一个单独的currentregion
,因此我不需要使用Resize
或CountA
,而是Set SearchRange=SearchRange.currentregion
@GoldStandard,如果没有连续的数据,即每个“Set”,它可能会起作用一个或多个空行分隔一个或多个数据。如果它是一个连续的数据表,没有空行,那么CurrentRegion
可能无法工作:)很好地将此代码调整到您的解决方案中!!