Excel 2010+ VBA – 如何search范围的公式而不是值

我需要使用Excel VBAsearch一系列单元格,返回第一个匹配的行号。 只要我正在search值,Match函数就很容易。 但是我需要search公式,而不是价值。

例如,当我search“= 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"))
此外,函数本身可以很容易地改进,也可以输出数组,或者在一次运行中检查不同的string,或者做任何你想做的事情(如果没有必要的话,你也可以跳过2个可选的部分来保持它的快速和容易理解): )

如果你想要find的第一个单元格的地址 – 这将作为一个工作表函数( =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 

另一方面,如果您希望所有find的单元格都可以使用,但是请注意,它不能用作工作表函数。

 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 

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