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
    可能无法工作:)很好地将此代码调整到您的解决方案中!!