清除范围内的常量,但不清除引用和公式

我正在尝试清除一个单元格范围内的所有数字常量,而不清除任何公式或单元格引用。 从没有任何公式或单元格引用的单元格中清除常量很简单,但是当这些常量出现时,我遇到了麻烦。 以下是我到目前为止的代码。

Range("B2:B11").Select Selection.SpecialCells(xlCellTypeConstants, 1).Select Selection.ClearContents 

在此范围内,单元格B5和B7具有单元格引用的公式如下:

B5:=(G83 * H1)+1181.05

B7:= E33 + 1292.76

单元格引用也有时会引用同一工作簿中其他工作表上的单元格。 我需要清除这些公式中的常量,同时保持引用不变。

这将基于2个模式从当前工作簿中的所有公式中移除常量:

  • "=Formula-[Space]- PlusSign -[Space]-Constant" "=Formula-[Space]- PlusSign -[Space]-Constant" (空格可选)

    • =(G83*H1)+1181.05 or =(G83*H1) +1181.05 or =(G83*H1)+ 1181.05变为=(G83*H1)
    • =E33+1292.76 or =E33 +1292.76 or =E33+ 1292.76 or =E33 + 1292.76变成=E33
  • "=Formula-[Space]- MinusSign -[Space]-Constant" "=Formula-[Space]- MinusSign -[Space]-Constant" (空格可选)


 Public Sub clearConstantsFromWorkBookFormulas() Const PATTERNS As String = "~+*|~+ *|~ +*| ~+ *|~-*|~- *|~ -*|~ - *" Dim pat As Variant For Each pat In Split(PATTERNS, "|") Cells.Replace What:=pat, _ Replacement:=vbNullString, _ LookAt:=xlPart, _ SearchOrder:=xlByRows, _ MatchCase:=False Next End Sub 

这是使用regEx模式匹配和数组的更通用选项:

 Public Sub testClear() Dim ws As Worksheet For Each ws In Application.ActiveWorkbook.Worksheets removeConstantsFromFormulas ws.Range("B2:B11"), getRegEx Next End Sub Public Sub removeConstantsFromFormulas(ByRef rng As Range, ByRef regEx As Object) Dim v As Variant, r As Long, c As Long, lr As Long, lc As Long lr = rng.Rows.Count lc = rng.Columns.Count If lr > 0 And lc > 0 Then v = rng.Formula For r = 1 To lr For c = 1 To lc If Left(v(r, c), 1) = "=" Then If regEx.Test(v(r, c)) Then v(r, c) = regEx.Replace(v(r, c), vbNullString) End If Next Next rng.Formula = v End If End Sub Private Function getRegEx() As Object Set getRegEx = CreateObject("VBScript.RegExp") getRegEx.Pattern = "[^a-zA-Z][0-9]+(\.?[0-9]+)" getRegEx.Global = True getRegEx.IgnoreCase = True End Function 

RegEx模式:一个或多个数字,数字组前面没有字母,有或没有小数部分

这个尝试应该使用Regexp来处理大多数例子。

上面的讨论指出可能有一些边缘案例。 对于下面的代码

=(G83 * H1)1181.05
= 10 + A1
= A1 + 10
= A1 +(10)
= A1 + 10.0

=(G83 * H1)
= + A1
= A1
= A1
= A1

我注意到它也会拿出^ 2 =A1^2

这显然也不会迎合命名公式(命名范围)。

更新:现在处理级联括号,即

= A1 +(27+(11-2))

= A1

 Sub Format() Dim objRegexB As Object Dim lngCnt As Long Dim X X = [b2:b11].Formula Set RegExB = CreateObject("vbscript.regexp") With RegExB .Pattern = "[=\+\/\*^\-](\([0-9]\d*(\.\d+)?\)|[0-9]\d*(\.\d+)?|\.\d+)" .Global = True For lngCnt = 1 To UBound(X) Do While .Test(X(lngCnt, 1)) X(lngCnt, 1) = .Replace(X(lngCnt, 1), vbNullString) Loop Next End With [b2:b11].Formula = X End Sub