2016-11-23 104 views
0

我正在使用宏更改单元格中显示的小数位数。我想宏观与定制各种格式的工作,我有我要适当地改变下面的例子:宏将数字格式更改为一定的小数位数

$ #,##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引号内。我不希望剧本改变这一点,我希望他们保持这种状态。

我一直在使用正则表达式开始有点,但我不知道这是正确的做法:

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" 
+0

你的正则表达式会选择引号之间的东西 - 但你说这就是你不想改变的位。如果你能显示你想要做什么,这将是有帮助的。 –

+0

数字格式的语法:https://support.office.com/zh-cn/article/Create-or-delete-a-custom-number-format-78f2a361-936b-4c03-8772-09fab54be7f4相当一般,所以你需要覆盖很多不同的情况(即一个,两个,三个或四个参数),检查转义字符等,这显然不适用,如果你控制输入。 –

+0

如何检索现有的数字格式,然后使用替换(numberFormat,“.0”,“.00”)如果您想增加小数的数量,并替换(numberFormat,“.0”,“。”)如果你想减少,写回编辑的数字格式? – johankr

回答

0

花整个下午都在思考这个之后,我发现,所有的示例格式我已经张贴上述问题的解答:

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

我会去

(?<=#,##)([^%"]+) 

这将匹配任何betwee#,##和第一次报价或%后发现,并把它在一组。

然后你用0.00代替你得到的。

+0

我不认为这适用于简单的'0.0'类型数字格式。你测试过了吗? – Spurious

+0

我测试了你所有的例子 –

+0

是的,但我希望这个工作的简单例子。看到我上面的代码。这些例子是我可以想到的最糟糕的数字格式。我仍然希望这可以像'0.00'这样简单的工作,如果数字格式为'General',则不会改变任何内容。 – Spurious