使用R1C1表示法的Excel单元格的正则expression式

我需要一些代码来testing一个单元格是否包含一个引用另一个单元格的公式。

我find了答案在Excel公式中查找所有使用的引用,但解决scheme也错误地匹配表引用的公式,如下所示:

=SearchValInCol2(Tabella1[articolo];[@articolo];Tabella1[b]) 

然后,我使用Like运算符编写了下面的VBA代码,但肯定有一个正则expression式的解决scheme会更稳定(我认为下面的代码在许多情况下不起作用)。

 Private Function TestIfCellContainsAFormula(cellToTest As Variant) As Boolean Dim result As Object Dim r As Range Dim testExpression As String Dim objRegEx As Object Set r = cellToTest ' INPUT THE CELL HERE , eg RANGE("A1") Set objRegEx = CreateObject("VBScript.RegExp") objRegEx.IgnoreCase = True objRegEx.Global = True objRegEx.Pattern = """.*?""" ' remove expressions testExpression = CStr(r.FormulaR1C1) ' search for pattern "=R[-3]C+4" If testExpression Like "*R[[]*[]]*C*" Then TestIfCellContainsAFormula2 = True Exit Function End If ' search for pattern "=RC[2]" If testExpression Like "*R*C[[]*[]]*" Then 'If InStr(1, testExpression, "C[", vbTextCompare) <> 0 Then TestIfCellContainsAFormula2 = True Exit Function End If TestIfCellContainsAFormula2 = False End Function 

选项1

要匹配R1C1风格的引用,你可以使用这个正则expression式 :

 R(\[-?\d+\])C(\[-?\d+\])|R(\[-?\d+\])C|RC(\[-?\d+\]) 

请参阅铁路图以获得视觉解释:

在这里输入图像描述

核心是'偏移',它是-?\d+ ,它是可选的-后面跟着一个数字或更多。 这个序列进入括号( [] )给出\[-?\d+\] 。 然后,正则expression式允许组合:

  • R[offset]C[offset]
  • R[offset]C或( |
  • RC[offset]或( |

选项2

上面的正则expression式不匹配RCRC 。 它将与等同的R[0]C[0]R[0]CRC[0]R[0]C[0]相匹配。 要消除这些匹配,你可以使用这个正则expression式 :

 R(\[-?[1-9][0-9]*\])C(\[-?[1-9][0-9]*\])|R(\[-?[1-9][0-9]*\])C|RC(\[-?[1-9][0-9]*\]) 

这是: 在这里输入图像说明

但似乎在我的Excel(v2013)中将R[0]C[0]R[0]C[0]变成RCRC ,所以您可以避免额外的复杂性,如果这不是关心。

选项3

如果你想允许RCRC你可以使用一个更简单的正则expression式:

 R(\[-?\d+\])?C(\[-?\d+\])? 

VBAtesting代码

这使用选项1。

 Option Explicit Sub Test() Dim varTests As Variant Dim varTest As Variant Dim varMatches As Variant Dim varMatch As Variant varTests = Array("RC", _ "R[1]C", _ "RC[1]", _ "R[1]C[1]", _ "R[-1]C", _ "RC[-1]", _ "R[-1]C[-1]", _ "=SUM(A1:B2)", _ "RC[1]+R[-1]C+R[2]C[-99]", _ "R[-1]CR[1]C[-44]-RC[999]+R[0]C[0]", _ "SearchValInCol2(Tabella1[articolo];[@articolo];Tabella1[b])") For Each varTest In varTests varMatches = FormulaContainsR1C1Reference(CStr(varTest)) Debug.Print "Input: " & CStr(varTest) Debug.Print VBA.String(Len(CStr(varTest)) + 7, "-") If IsEmpty(varMatches) Then Debug.Print "No matches" Else Debug.Print UBound(varMatches) & " matches" For Each varMatch In varMatches Debug.Print varMatch Next varMatch End If Debug.Print vbCrLf Next varTest End Sub Function FormulaContainsR1C1Reference(ByVal strFormula As String) As Variant Dim objRegex As Object Dim strPattern As String Dim objMatches As Object Dim varMatches As Variant Dim lngCounter As Long Set objRegex = CreateObject("VBScript.RegExp") With objRegex ' setup regex .Global = True .IgnoreCase = False .Pattern = "R(\[-?\d+\])C(\[-?\d+\])|R(\[-?\d+\])C|RC(\[-?\d+\])" ' get matches Set objMatches = .Execute(strFormula) ' iterate matches If objMatches.Count > 0 Then ReDim varMatches(1 To objMatches.Count) For lngCounter = 1 To objMatches.Count varMatches(lngCounter) = objMatches.Item(lngCounter - 1) Next lngCounter Else varMatches = Empty End If End With FormulaContainsR1C1Reference = varMatches End Function 

A1风格参考

我在这里发布了一个用于A1风格引用的正则expression式:

^(?:[AZ]|[AZ][AZ]|[AX][AF][AD])(?:[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|10[0-3][0-9][0-9][0-9][0-9]|104[0-7][0-9][0-9][0-9]|1048[0-4][0-9][0-9]|10485[0-6][0-9]|104857[0-6])$