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

Clear Constants in a range without clearing references and formulas

我试图在不清除任何公式或单元格引用的情况下清除一系列单元格中的所有数字常量。从没有任何公式或单元格引用的单元格中清除常量很简单,但是当存在这些常量时我很难做到。以下是我目前的代码。

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"(space可选)

    • =(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"(space可选)


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

正则表达式模式:一个或多个数字,数字组前面没有字母,有或没有小数部分

此尝试应使用 Regexp 处理大多数示例。

正如上面的讨论所指出的,可能存在一些边缘情况。对于下面的代码

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

变成

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

我注意到它还会去掉 =A1^2

中的 ^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