在VBA中,我想搜索一个Excel公式(字符串)以查找单元格引用。
具体来说,我想在字符串中找到相对单元格引用(任何相对单元格引用,而不是特定的引用)或混合单元格引用的位置。
我该怎么做?(这是主要问题)
我的想法:
我可以看到如何找到混合单元格引用-我很确定$符号只能出现在混合单元格引用,绝对引用,内部工作表名称或内部字符串中(有人可以确认吗?) ,因此使用正确的正则表达式或算法,您可以找到所有这些情况,然后只需检查它是否是绝对单元格引用,然后忽略它即可。
但是如何找到所有相关的单元格引用呢?我唯一的想法与上述类似。除单元格引用外,Excel公式中(表名之外或字符串内)是否曾经有字母后面有数字?任何公式名称或其他名称?我能想到的唯一另一个是在定义的数据名称中,但是我不确定是否可以在公式(尤其是条件格式公式)中使用它们。谁能想到其他时间吗?
有人有什么想法吗?
答案 0 :(得分:1)
我不确定您的用例是什么,但是您可以在此函数中尝试一些方法:
该项目使用 Early Binding -您必须将引用设置为:
Microsoft VBScript Regular Expressions 5.5
Function findCellReferences(vTestVal As Variant) As Variant
'Check if vTestVal is a range, if so, convert to string
If TypeName(vTestVal) = "Range" Then
vTestVal = vTestVal.Formula
ElseIf TypeName(vTestVal) <> "String" Then
findCellReferences = "Type-Err!"
Exit Function
End If
Dim oMatches As MatchCollection
With New RegExp
.Pattern = "(?:^|[,!(=\s])((?:\$?[A-Z]{1,3}\$?\d+(?::\$?[A-Z]{1,3}\$?\d+)?|" & _
"\$?[a-z]{1,3}:\$?[a-z]{1,3}|\$?\d+:\$?\d+))(?:$|[\s,)])"
.IgnoreCase = True
.Global = True
If .test(vTestVal) Then
Dim i As Long, retArr()
Set oMatches = .Execute(vTestVal)
With oMatches
ReDim retArr(.Count - 1)
For i = 0 To .Count - 1
retArr(i) = .Item(i).SubMatches(0)
Next
End With
findCellReferences = Join(retArr, ",")
Else
findCellReferences = False
End If
End With
End Function
此函数可以接受两种不同的数据类型:
这使您可以将其用作工作表函数来测试公式的文本值,也可以将其直接用于测试输入字符串。
这是检查单元格的返回信息:
这是上面的公式:
这也可以在VBA中使用:
Sub Test()
Rem: Passing a string argument
Debug.Print findCellReferences("A1:B1, $C1")
' Prints: A1:B1,$C1
End Sub
(?:^|[,!(=\s])((?:\$?[A-Z]{1,3}\$?\d+(?::\$?[A-Z]{1,3}\$?\d+)?|\$?[a-z]{1,3}:\$?
[a-z]{1,3}|\$?\d+:\$?\d+))(?:$|[\s,)])
(?:^|[,(=\s])
要求在匹配之前之前发生以下情况之一
^
字符串的开头;或,
逗号(在公式中有用)!
感叹号(用于Sheet!
引用)(
开括号(在公式中有用)=
文字等号(在公式中有用)\s
空格字符(...)
捕获组将返回您的值(三个选项之一)
\$?[A-Z]{1,3}\$?\d+(?::\$?[A-Z]{1,3}\$?\d+)?
而不是整个行/列
\$
获取绝对引用(列),后跟?
使其成为可选[A-Z]
个字母的字符类,+
一次或多次\$
获取绝对引用(行),后跟?
使其成为可选\d
任意一位,+
一次或多次(?:...)
非捕获组以匹配范围范围(例如A1:B1
)
?
,使整个非捕获组都是可选的\$?[a-z]{1,3}:\$?[a-z]{1,3}
整个列,例如A:C
\$?\d+:\$?\d+
整个行,例如1:3
(?:$|[\s,)])
要求您的比赛之后发生以下情况之一
$
字符串结尾;或\s
空格字符,
逗号)
右括号积分:
tripleee的建议:
-使用字符类[xyz]
代替OR
语句(?:x|y|z)
-更好的击穿压痕
-语法用法
Makyen的建议:
-支持整行1:4
和整列A:C
-通过检查Excel的最大列限制[a-z]{1,3}
(而不是[a-z]+
)