将数字格式更改为特定小数位的宏
Macro to change the number format to a certain number of decimal places
我想使用宏更改单元格中显示的小数位数。我希望宏能够处理各种自定义格式,我有以下示例需要正确更改:
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.0000" Test 0.00";[Red]$ -#,##0.0000" Test 0.00"
$ #,##0" Test 0.00";[Red]$ -#,##0" Test 0.00"
$ #,##0.0000000" Test 0.00";[Red]$ -#,##0.0000000" Test 0.00"
$ #,##0%" Test 0.00";[Red]8" Test 0.00"
$ #,##0%" Test 0.00";[Red]8" Test 0.00"
"Test 0.0000"$ #,##0.0000000" Test 0.00";[Red]"Test 0.0000"$ -#,##0.0000000" Test 0.00"
"Test 0.0000"$ #,##0%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
"Test 0.0000"$ #,##0%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
注意,我在引号内使用了 0.00
。我不希望脚本改变这一点,我希望他们保持这种状态。
我已经开始使用 RegEx,但我不确定这是否是正确的方法:
Sub ChangeDecimalPoints(sRange As Range, DP As Integer)
Dim sCell As Range, sFmt As String
Dim regEx As New VBScript_RegExp_55.RegExp, arrMatch As Variant, i As Long
For Each sCell In sRange
sFmt = sCell.NumberFormat
With regEx
.Global = True
.ignorecase = True
.Pattern = "[^""]+|(0\.[0]+)"
If .test(sFmt) Then
Set arrMatch = .Execute(sFmt)
i = 0
Do Until i = arrMatch.Count
Debug.Print sFmt, arrMatch(i)
i = i + 1
Loop
End If
End With
Next sCell
End Sub
编辑:
为了显示我希望它如何更改的示例,如果我 运行 以下(假设上面的列表显示 Selection
的 .NumberFormat
):
ChangeDecimalPoints Selection, 2
我希望上面的输出如下:
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00%" Test 0.00";[Red]8" Test 0.00"
$ #,##0.00%" Test 0.00";[Red]8" Test 0.00"
"Test 0.0000"$ #,##0.00" Test 0.00";[Red]"Test 0.0000"$ -#,##0.00" Test 0.00"
"Test 0.0000"$ #,##0.00%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
"Test 0.0000"$ #,##0.00%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
在思考了整个下午之后,我找到了适用于我在上面发布的所有示例格式的答案:
Sub ChangeDecimalPoints(sRange As Range, DP As Integer)
Dim sCell As Range, sFmt As String, sNewFmt As String
Dim regEx As New VBScript_RegExp_55.RegExp, arrMatch As Variant, i As Long, arrReplace As Variant
sNewFmt = "0" & IIf(DP > 0, ".", "")
For i = 1 To DP
sNewFmt = sNewFmt & "0"
Next i
For Each sCell In sRange
sFmt = sCell.NumberFormat
With regEx
.Global = True
.ignorecase = True
.Pattern = "[\""].*?[\""]|(0\.?0*)"
If .test(sFmt) Then
Set arrMatch = .Execute(sFmt)
For i = arrMatch.Count - 1 To 0 Step -1
If Not IsEmpty(arrMatch(i).submatches(0)) Then
sFmt = WorksheetFunction.Replace(sFmt, arrMatch(i).FirstIndex + 1, arrMatch(i).Length, sNewFmt)
End If
Next i
End If
End With
sCell.NumberFormat = sFmt
Next sCell
End Sub
我不确定是否有办法在没有 .submatches
的情况下使它工作,我假设可能有一种方法使用 `regEx.Replace(input, "$match") 但我太懒了,这个也行。
我会去
(?<=#,##)([^%"]+)
它将匹配 #、## 和第一个引号或之后找到的 % 之间的任何内容,并将其放在一个组中。
然后你用0.00替换你得到的。
我想使用宏更改单元格中显示的小数位数。我希望宏能够处理各种自定义格式,我有以下示例需要正确更改:
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.0000" Test 0.00";[Red]$ -#,##0.0000" Test 0.00"
$ #,##0" Test 0.00";[Red]$ -#,##0" Test 0.00"
$ #,##0.0000000" Test 0.00";[Red]$ -#,##0.0000000" Test 0.00"
$ #,##0%" Test 0.00";[Red]8" Test 0.00"
$ #,##0%" Test 0.00";[Red]8" Test 0.00"
"Test 0.0000"$ #,##0.0000000" Test 0.00";[Red]"Test 0.0000"$ -#,##0.0000000" Test 0.00"
"Test 0.0000"$ #,##0%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
"Test 0.0000"$ #,##0%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
注意,我在引号内使用了 0.00
。我不希望脚本改变这一点,我希望他们保持这种状态。
我已经开始使用 RegEx,但我不确定这是否是正确的方法:
Sub ChangeDecimalPoints(sRange As Range, DP As Integer)
Dim sCell As Range, sFmt As String
Dim regEx As New VBScript_RegExp_55.RegExp, arrMatch As Variant, i As Long
For Each sCell In sRange
sFmt = sCell.NumberFormat
With regEx
.Global = True
.ignorecase = True
.Pattern = "[^""]+|(0\.[0]+)"
If .test(sFmt) Then
Set arrMatch = .Execute(sFmt)
i = 0
Do Until i = arrMatch.Count
Debug.Print sFmt, arrMatch(i)
i = i + 1
Loop
End If
End With
Next sCell
End Sub
编辑:
为了显示我希望它如何更改的示例,如果我 运行 以下(假设上面的列表显示 Selection
的 .NumberFormat
):
ChangeDecimalPoints Selection, 2
我希望上面的输出如下:
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00" Test 0.00";[Red]$ -#,##0.00" Test 0.00"
$ #,##0.00%" Test 0.00";[Red]8" Test 0.00"
$ #,##0.00%" Test 0.00";[Red]8" Test 0.00"
"Test 0.0000"$ #,##0.00" Test 0.00";[Red]"Test 0.0000"$ -#,##0.00" Test 0.00"
"Test 0.0000"$ #,##0.00%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
"Test 0.0000"$ #,##0.00%" Test 0.00";[Red]"Test 0.0000"8" Test 0.00"
在思考了整个下午之后,我找到了适用于我在上面发布的所有示例格式的答案:
Sub ChangeDecimalPoints(sRange As Range, DP As Integer)
Dim sCell As Range, sFmt As String, sNewFmt As String
Dim regEx As New VBScript_RegExp_55.RegExp, arrMatch As Variant, i As Long, arrReplace As Variant
sNewFmt = "0" & IIf(DP > 0, ".", "")
For i = 1 To DP
sNewFmt = sNewFmt & "0"
Next i
For Each sCell In sRange
sFmt = sCell.NumberFormat
With regEx
.Global = True
.ignorecase = True
.Pattern = "[\""].*?[\""]|(0\.?0*)"
If .test(sFmt) Then
Set arrMatch = .Execute(sFmt)
For i = arrMatch.Count - 1 To 0 Step -1
If Not IsEmpty(arrMatch(i).submatches(0)) Then
sFmt = WorksheetFunction.Replace(sFmt, arrMatch(i).FirstIndex + 1, arrMatch(i).Length, sNewFmt)
End If
Next i
End If
End With
sCell.NumberFormat = sFmt
Next sCell
End Sub
我不确定是否有办法在没有 .submatches
的情况下使它工作,我假设可能有一种方法使用 `regEx.Replace(input, "$match") 但我太懒了,这个也行。
我会去
(?<=#,##)([^%"]+)
它将匹配 #、## 和第一个引号或之后找到的 % 之间的任何内容,并将其放在一个组中。
然后你用0.00替换你得到的。