繁体   English   中英

Excel 2010+ VBA - 如何搜索范围的公式而不是值

[英]Excel 2010+ VBA - How can I Search a Range's Formulas Rather Than Values

我需要使用Excel VBA搜索一系列单元格,返回第一个匹配的行号。 只要我在搜索值,使用Match功能就可以轻松完成。 但我需要搜索公式,而不是值。

当我搜索“= A4 + 2”时,我需要VBA返回“4”... 在此输入图像描述

你可以直接用match来做

Application.Match("=A4+2", Range("B1:B5").Formula)

会给你4

编辑

您可能会遇到来自Match的255个字符限制的错误。 您还可以使用工作表中的输出。 只需将此代码放入模块中:

Public Function MATCHFUNC(str As String, rng As Range, Optional fOnly As Boolean, Optional fAdr As Boolean) As Variant
  Dim i As Long, runner As Variant
  If UBound(rng.Value, 1) > 1 And UBound(rng.Value, 2) > 1 And Not fAdr Then MATCHFUNC = 0: Exit Function
  For Each runner In rng
    i = i + 1
    If Not fOnly Or (runner.Text <> runner.Formula) Then
      If InStr(1, runner.Formula, str, 1) Then
        If fAdr Then MATCHFUNC = runner.Address Else MATCHFUNC = i
        Exit Function
      End If
    End If
  Next
  MATCHFUNC = 0
End Function

您现在可以像普通的工作表一样使用它。 以你的照片为例:
MATCHFUNC([string to search for],[range to look in],[1 to look only in cells containing formulas],[1 to get the address in $A$1 format])

=MATCHFUNC("+2",B3:B5)     = 1      - it was found in the first cell
=MATCHFUNC("2",B1:B5)      = 2      - "2" is also in B2
=MATCHFUNC("2",B1:B5,1)    = 3      - B2 will be skipped - formulas only
=MATCHFUNC("+2",B3:B5,,1)  = "$B$3" - address of the first cell with match
=MATCHFUNC("9",B1:B5)      = 0      - not found in range
=MATCHFUNC("2",A1:B5)      = 0      - range needs to be only 1 row or 1 column without fAdr
=MATCHFUNC("2",A1:B5,,1)   = "$B$2" - check goes A1->B1...->A2->B2...

对于特殊情况,您可能希望使用fAdr = 1

=ROW(INDIRECT(MATCHFUNC("2",B4:B5,,1)))  = 4 - absolute row of the first cell with match

假设您不想因任何原因检查B1:B3,但您需要绝对行。

你还可以在VBA中使用它,如: iVal = MATCHFUNC("=B", Range("B4:B5"))
此外,函数本身也可以轻松改进,也可以输出数组或在一次运行中检查不同的字符串,或者做任何你想做的事情(如果没有必要,你也可以跳过2个optinal部分以保持快速和易于理解): )

如果你想要第一个找到的单元格的地址 - 这将作为工作表函数( =FindFirst("=A",B2:B6) )并从另一个VBA过程调用:

Public Function FindFirst(FindValue As String, InRange As Range) As Variant

    Dim rFound As Range

    With InRange

        Set rFound = .Find( _
            What:=FindValue, _
            After:=InRange.Cells(InRange.Cells.Count), _
            LookIn:=xlFormulas, _
            LookAt:=xlPart)

        If Not rFound Is Nothing Then
            FindFirst = rFound.Address
        Else
            FindFirst = CVErr(xlErrValue)
        End If

    End With

End Function

另一方面,如果你想要所有找到的单元格,你可以使用它 - 但请注意它不能用作工作表函数。

Public Sub Test()

    MsgBox FindInFormula("=A", ThisWorkbook.Worksheets("Sheet1").Range("B2:B6")).Address

End Sub

Public Function FindInFormula(FindValue As String, InRange As Range) As Range

    Dim rFound As Range
    Dim sFirstAdd As String
    Dim rReturnRange As Range

    With InRange

        Set rFound = .Find( _
            What:=FindValue, _
            After:=InRange.Cells(InRange.Cells.Count), _
            LookIn:=xlFormulas, _
            LookAt:=xlPart)

        If Not rFound Is Nothing Then
            sFirstAdd = rFound.Address
            Do
                If rReturnRange Is Nothing Then
                    Set rReturnRange = rFound
                Else
                    Set rReturnRange = Union(rReturnRange, rFound)
                End If
                Set rFound = .FindNext(rFound)
            Loop While Not rFound Is Nothing And rFound.Address <> sFirstAdd
        End If

    End With

    Set FindInFormula = rReturnRange

End Function

您需要更新程序以返回地址或对单元格的引用 - 根据您的需要进行调整。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM