清除范围内的常量而不清除引用和公式
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
我试图在不清除任何公式或单元格引用的情况下清除一系列单元格中的所有数字常量。从没有任何公式或单元格引用的单元格中清除常量很简单,但是当存在这些常量时我很难做到。以下是我目前的代码。
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
它显然也不适合命名公式(命名范围)。
更新:现在处理级联括号,即
=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