【问题标题】:Locating Cell Values in Excel VBA在 Excel VBA 中定位单元格值
【发布时间】:2011-11-29 06:46:31
【问题描述】:

使用:Excel 2007/Win 7

首先,我创建了一个子程序来查找名为“WIP”的工作表的动态范围:

Sub GetWIPRange()
Dim WIPrng1 As Range
Dim WIPrng2 As Range
Sheets("WIP").Activate
Set WIPrng1 = Cells.find("*", [a1], , , xlByRows, xlPrevious)
Set WIPrng2 = Cells.find("*", [a1], , , xlByColumns, xlPrevious)
If Not WIPrng1 Is Nothing Then
    Set WIPrng3 = Range([a1], Cells(WIPrng1.Row, WIPrng2.Column))
Application.Goto WIPrng3
Else
    MsgBox "sheet is blank", vbCritical
End If
End Sub

现在我想在上面定义的范围内找到给定的合同编号:

Sub find()
Dim find As Long
find = Application.WorksheetFunction.Match("545499", Range(WIPrng3.Parent.Name & "!" & WIPrng3.Address), 0)
MsgBox "Found at row : " & find
End Sub

但是我从上面的代码中得到的错误是:

运行时错误“91”: 对象变量 未设置块变量。

  1. 如何修复此代码,使其返回我正在寻找的值的行号?
  2. 是否有使用 VBA 查找单元格值的更有效方法?例如,如果我有很多工作表,我想搜索所有工作表并返回一个值的特定行号和工作表位置。

非常感谢!

【问题讨论】:

    标签: vba excel excel-2007


    【解决方案1】:

    WIPrng3 在哪里定义?它被定义为公共吗?问题是,当您运行“查找”时,WIPrng3 已经超出范围,因此什么也没有。您可以在“查找”代码中检查 Nothing 并在需要时运行 Get 过程。像这样

    Sub find()
        Dim find As Long
    
        If WIPrng3 Is Nothing Then GetWIPRange
    
        find = Application.WorksheetFunction.Match("545499", Range(WIPrng3.Parent.Name & "!" & WIPrng3.Columns(1).Address), 0)
        MsgBox "Found at row : " & find
    End Sub
    

    需要注意两点:如果 WIPrng3 返回多列范围,MATCH 将失败并返回 1004 错误。 MATCH 仅适用于单个列或行。在上面的示例中,我将 WIPrng3 限制在 MATCH 函数的第一列以避免这种情况。你的代码中没有这个。

    另一件事是您正在寻找文本字符串“545499”,而不是数字 545499。如果您的范围包含数字而不是字符串,您将收到错误消息。您可以使用 On Error 语句捕获该错误并进行适当处理。

    最后,我没有看到定义 WIPrng3 的优势(但我看不到你在做什么)。您可以轻松使用

    Sub Find2()
    
        Dim lRow As Long
    
        On Error Resume Next
            lRow = Application.WorksheetFunction.Match("545499", Sheets("WIP").UsedRange.Columns(1), 0)
    
        If lRow > 0 Then
            'add where the used range starts in case it's not row 1
            MsgBox "Found at row : " & lRow + Sheets("WIP").UsedRange.Cells(1).Row - 1
        Else
            MsgBox "Not found"
        End If
    
    End Sub
    

    您最终可能会查看更大的范围,但这不会明显影响性能。

    我在此示例中添加了 On Error,以便您了解它是如何工作的。在测试之前不要将 On Error 放在那里,因为它会掩盖所有其他错误。

    Charles Williams 在http://fastexcel.wordpress.com/2011/10/26/match-vs-find-vs-variant-array-vba-performance-shootout/http://fastexcel.wordpress.com/2011/10/26/match-vs-find-vs-variant-array-vba-performance-shootout/

    上做了一些很好的分析

    【讨论】:

    • 我在模块的声明部分定义了 WIPrng3。不应该一直坚持吗?条件语句确实运行 GetWIPRange 子例程,但现在我得到一个不同的错误:运行时错误 1004 无法获取 WorksheetFunction 类的匹配属性。
    • 它将一直存在,直到您编辑代码,然后您的所有持久变量都会被重置。我想如果你一个接一个地运行它,它会起作用的。我在文本中列出了一些可能的错误,所以请检查一下。
    • Columns("I:I").Select Selection.find(What:=x(0), After:=ActiveCell, LookIn:=xlValues, _ LookAt:=xlPart, SearchOrder:=xlByColumns , SearchDirection:=xlNext, _ MatchCase:=False, SearchFormat:=False).Activate BKRow = ActiveCell.Row
    • 不会像上面的代码那样完成同样的任务吗?用“CTRL+F”搜索值基本上是一样的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多