微软Excel VBA:查找具有特定公式类型的单元格

dgiusagp  于 2023-03-13  发布在  其他
关注(0)|答案(4)|浏览(235)

我希望自动查找包含仅作为简单引用的公式的单元格。例如:
=D20='Sheet1'!D20
这样做的目的是,我想自动对这些单元格进行颜色编码。
VBA中有搜索公式类型的方法吗?

1qczuiv0

1qczuiv01#

经过一段时间的思考,我认为这并不是那么简单。直接单元格引用可以包括如下简单的引用:

=A1

但是,在某些情况下,您可以引用另一个工作表、另一个打开的工作簿甚至另一个关闭的工作簿中的另一个单元格。虽然这使得使用RIGHTLEFT函数甚至FORMULATEXT等变得困难,但您可以做的一件事是检查模式。
任何直接单元格引用都不能包含任何其他计算,这意味着它必须排除任何不需要的运算符(/,*,-,+)。就我而言,这意味着如果我们检查一个只有一个Precedent的单元格,公式不能以数字开头,也不能以上述任何运算符之后的数字结尾。
这里我们最好的办法是把这些条件放在正则表达式中。我绝不是RegExMaven,但我认为下面的方法可以做到这一点:

"^=.*[A-Z]+\$*\d+$"
  • 线的起点为=
  • 后跟任何单词/非单词字符,0-n次
  • 行尾必须是数字,1-n次,前面是大写字母字符或美元符号组合(用于绝对单元格引用)

只要我们包含一个.Precedent的检查和一个公式的第二个字符是否不是数字的检查,上面的代码示例就可以工作。

Sub FindFormualaType()

Dim rng1 As Range, rng2 As Range, cl As Range
Dim regex As New RegExp
Dim matches As Object
Dim tststr As String

With regex
    .Global = True
    .Pattern = "^=.*[A-Z]+\$*\d+$"
End With

With Sheet1 'Change to your sheet's codename
    Set rng1 = Intersect(.Cells, .Cells.SpecialCells(-4123))
    For Each cl In rng1
        On Error Resume Next
        If cl.Precedents.Count = 1 Then
            If Left(cl.Formula, 2) Like "=#" = False Then
                Set matches = regex.Execute(cl.Formula)
                If matches.Count = 1 Then
                    If Not rng2 Is Nothing Then
                        Set rng2 = Union(rng2, cl)
                    Else
                        Set rng2 = cl
                    End If
                End If
            End If
        End If
        On Error GoTo 0
    Next cl
End With

rng2.Interior.Color = vbGreen

End Sub

要解释上面代码中的一些步骤:

  • 要使用RegExp,您必须设置对它的引用:

  • 然后代码使用.SpecialCellsxlCellTypeFormulas-4123),并通过.Intersect创建一个.Range对象,因此我们不必循环所有单元格来检查.HasFormula(希望节省一些时间)。
  • 接下来是循环遍历新创建的.Range对象中的所有单元格,并检查是否为Precendents.Count = 1。我们需要将其封装到On Error Resume Next中,因为如果没有找到引用,则会出错,例如:一个类似="Hello"的分子式。
  • 当计数等于1时,我们使用Like操作符检查是否可以安全地执行正则表达式并测试所用模式的匹配。
  • 因为我更愿意一次性完成填充操作,所以建议创建另一个.Range对象(rng 2),并使用Union设置该对象。
  • 最后,我们可以使用类似rng2.Interior.Color = vbGreen的方法来为所有直接引用了一个单元格的单元格着色。

希望这能有所帮助。我绝不是一个RegExMaven,它可能会做得更简单。
一些关于我为什么使用Like运算符的背景信息。因为我想确保没有对单元格引用进行计算,所以公式中的第一个字符不能是数字。在RegEx中,你得到了一个叫做“lookahead”的东西。尽管,不幸的是,我无法让表达式在VBA中工作(不支持?),因此使用Like操作符来确保第二个字符不是数字。

vd2z7a6w

vd2z7a6w2#

Conditional Formatting中使用FORMULATEXT()函数可自动突出显示包含公式的单元格。请参阅以下Conditional Formatting公式

=OR(FORMULATEXT(A1)="=Sheet1!D20",FORMULATEXT(A1)="=D20")

lfapxunr

lfapxunr3#

创建一个循环来遍历所有包含公式的单元格(.HasFormula),将单元格的公式文本作为字符串获取,获取除第一个字符(RIGHT(text,(LEN(text)- 1))之外的所有公式文本,然后测试该字符串是否为有效的Range。如果不是,则单元格中还有更多内容,而不是“只是一个简单的引用”。祝您好运,能找到代码:)

tzdcorbm

tzdcorbm4#

enter image description here这是一个老问题,但我认为可能有一个更简单的解决方案,几乎解决了这里没有提到的原始问题。在工作中,我偶尔会遇到这样的问题:表中的一个或多个单元格被硬输入,而其余单元格链接到另一个数据集。如果硬编码的相应数据发生了变化,我使用的表中的总计将是错误的。我没有进行编程,而是简单地使用“cntrlf”来搜索公式中应该存在的一个组成部分,并用相同的文本替换该组成部分。但使用格式突出显示文本(确保您在“公式”而非文本中搜索)结果可轻松显示哪些单元格包含公式,哪些单元格不包含公式。如果您的数据格式设置为表格,或仅具有数据筛选器,您可以按该颜色进行排序,以便快速将需要重新处理的单元格分组。对我来说,这节省了大量时间。我经常处理20 K行的工作表,因此能够查找、排序和修复硬条目的问题是一种救命稻草。虽然没有完全回答问题,但已经很接近了!

相关问题