【问题标题】:Range.Find method returning unexpected valueRange.Find 方法返回意外值
【发布时间】:2015-09-19 02:40:09
【问题描述】:

这很奇怪。根据 MSDN(以及 StackOverflow 上的几个问题),当在指定范围内找不到指定值时,VBA 中的 Range.Find 方法应该返回Nothing。但是,当我运行以下代码时,如果未找到该值,则 Range.Find 方法不会返回 Nothing。它不会返回任何东西

请假设所有变量都已正确定义。 VBA 位于 Access 2013 模块中,并引用了 Microsoft Office 15.0 对象库。

Dim rng As Excel.Range
Dim rngFound As Excel.Range
' ...
For i = 0 To UBound(strHeader)
    Set rngFound = rng.Find( _
        What:=strHeader(i), _
        After:=rng(rng.Cells.Count), _
        LookAt:=xlWhole, _
        MatchCase:=True _
    )
    If rngFound Is Nothing Then
        bolValid = False
        Exit For
    ElseIf i = UBound(strHeader) Then
        bolValid = True
    End If
Next i

如果在rng 范围内找不到strHeader(i) 中的字符串,则应将变量rngFound 设置为Nothing。但是,事实并非如此。

假设早期迭代中rngFound.Address 的值是“$J$1”。现在假设在rng 中找不到当前迭代的值。 Range.Find 应该返回Nothing,但是在立即窗口中查询时,rngFound.Address 仍然是“$J$1”。

知道是什么导致了这种奇怪的行为吗?

编辑:完整的功能代码,根据要求。

Private Function CheckIntegrity(FileName As String) As Boolean
    Dim wb As Excel.Workbook
    Dim ws As Excel.Worksheet
    Dim rng As Excel.Range
    Dim rngFound As Excel.Range
    Dim strHeader() As String
    Dim i As Integer
    Dim bolValid As Boolean

    On Error GoTo PROC_ERR

    ReDim strHeader(9)
    strHeader(0) = "String1"
    strHeader(1) = "String2"
    strHeader(2) = "String3"
    strHeader(3) = "String4"
    strHeader(4) = "String5"
    strHeader(5) = "String6"
    strHeader(6) = "String7"
    strHeader(7) = "String8"
    strHeader(8) = "String9"
    strHeader(9) = "String10"

    Set wb = OpenWorkbook(FileName, True)
    If Not wb Is Nothing Then Set ws = wb.Worksheets(1)
    If Not ws Is Nothing Then Set rng = ws.Range("A1:Z1")

    If Not rng Is Nothing Then
        For i = 0 To Ubound(strHeader)
            Set rngFound = rng.Find( _
                What:=strHeader(i), _
                After:=rng(rng.Cells.Count), _
                LookAt:=xlWhole, _
                MatchCase:=True _
            )
            If rngFound Is Nothing Then
                bolValid = False
                Exit For
            ElseIf i = Ubound(strHeader) Then
                bolValid = True
            End If
        Next i
    End If

    wb.Close SaveChanges:=False

    CheckIntegrity = bolValid
    PROC_EXIT:
    Set wb = Nothing
    Set ws = Nothing
    Set rng = Nothing
    Set rngFound = Nothing
    Erase strHeader
    i = 0
    bolValid = False
    Exit Function

    PROC_ERR:
    MsgBox "Error encountered. " & Err.Number & " " & Err.Description
    Resume PROC_EXIT
End Function

如果未找到 strHeader 的元素,则不会将 rngFound 的值设置为 Nothing

【问题讨论】:

  • 你怎么知道rngFound不是Nothing,这是什么意思它什么都不返回。 -> 每个变量都有一个值。以After:=rng(rng.Cells.Count)为起点的目的是什么?
  • 在没有匹配时为我返回Nothing。当您从即时窗口查询时,您停在哪一行?
  • @TimWilliams 当我查询即时窗口时它停在If rngFound Is Nothing Then 线上。
  • @user3964075 我知道 Range.Find 没有返回 Nothing,因为在 Range.Find 方法搜索了某些内容之后,rngFound 的值不是 If rngFound Is Nothing Then 线上的 Nothing我知道不在那里。 After:=... 参数的目的是搜索rng 范围的第一个单元格。
  • 我从未见过这种行为,也无法复制您所看到的。愿意分享您的整个代码吗?

标签: excel vba ms-access


【解决方案1】:

解决了。在开始出现其他一些错误之后,我在 Windows 控制面板中对我的 Microsoft Office 安装进行了“修复”,这个问题的问题显然已经解决了。与上面相同的代码现在可以正常工作了。

感谢大家的帮助,但我认为这只是一个糟糕的 Office 安装问题。

【讨论】:

    【解决方案2】:
     Option Compare Database
     Sub test()
     Dim bolValid As Boolean
     Dim rng As Excel.Range
     Dim rngFound As Excel.Range
     Dim strHeader() As Variant
     ' ...
     Dim wb As Excel.Workbook, ws As Excel.Worksheet
    
    Set wb = Excel.Workbooks.Open("M:\My Documents\Heat Trace\Macro    Workbooks\StackOverflow\test1.xlsx")
     wb.Application.Visible = True
     Set ws = wb.Sheets("Sheet1")
     Set rng = Range("A1:A1")
    
     strHeader() = Array("this", "again")
     For i = 0 To UBound(strHeader)
         Set rngFound = rng.Find( _
             What:=strHeader(i), _
             After:=rng(rng.Rows.Count, rng.Columns.Count), _
             LookAt:=xlWhole, _
             MatchCase:=True _
         )
         If rngFound Is Nothing Then
             bolValid = False
             Exit For
         ElseIf i = UBound(strHeader) Then
             bolValid = True
         End If
     Next i
    
     Set rng = Nothing
     Set ws = Nothing
     wb.Close
     Set wb = Nothing
    
    
     End Sub
    

    以上对我有用。我必须添加 Microsoft Excel 引用才能使用 Excel.Range 等。试试看。

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      相关资源
      最近更新 更多