4

我注意到excel中的奇怪和讨厌的行为可能是由于比利时的数字符号不同。当我在即时窗口中键入此内容时,我得到了违反直觉的结果:

 ?val("0,5")
 0
 ?val("0.5")
 0,5

所以我的解决方法是像这样使用它(通常字符串"0,5"被替换为textbox.value

 val(replace("0,5",",","."))

此外,当使用 numberformat() 函数时,这会让我陷入这种麻烦。

起初,我在文本框中有一个 KeyPresses,如下所示:

Select Case KeyAscii
  Case vbKey0 To vbKey9, vbKeyBack, vbKeyClear, vbKeyDelete, vbKeyLeft, _
  vbKeyRight, vbKeyUp, vbKeyDown, vbKeyTab, vbDecimal
  Case Else
    KeyAscii = 0
    Beep
  End Select

但是 vbDecimal 只允许我输入 '.' 作为小数点,然后在运行时它将被解释为乘以 1000 的值。

对此有任何启示吗?

4

4 回答 4

2

Val函数仅识别“。” 作为小数分隔符(您可以在相应的MSDN 文章中阅读);其他 VBA 函数也会发生类似的事情。因此,如果您修改由 VBA/Excel 计算的小数分隔符,很多函数都不会关心(并且会继续使用“.”)。我通常做的是设置一个自定义函数来分析所有输入数据(它可以只包含在基本Replace您在问题中指的是;但我也利用这一点并将数字格式调整为我期望的格式,例如:最大小数位数),确保在计算过程中考虑的所有小数分隔符都是“.”。完成所有计算后,我有另一个函数可以将输出调整为预期格式(通过修改 Excel 单元格或数值变量本身)。如果您知道,这不是理想的情况,也不是太难解决的问题。

于 2013-09-12T16:07:29.570 回答
1

编辑在这里 找到了一个很好的例子覆盖'Regional Locale Numeric Settings'

您可以通过查看本地环境变量来尝试适应欧洲或美国的分隔符。

'Locale support
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Const LOCALE_ICOUNTRY = &H5         '  country code
Const LOCALE_SENGCOUNTRY = &H1002      '  English name of country
Const LOCALE_USER_DEFAULT = &H400

然后在你的代码中做这样的事情:

If getLocale <= 1 Then  'US
  'use commas
else 'UK
  'use period
End If

我确信有一种更有效的方法,但是如果您加载一个 dll,您现在可以根据您的支持有两个不同的 dll 加载。

于 2013-09-12T16:18:50.580 回答
1

在巴西,我们使用相同的数字符号(“,”作为小数分隔符,“.”作为千位分隔符)。我通常CDbl()用来转换数字,因为它考虑了区域语言环境设置。正如您已经提出的那样,val()对于我来说,对于任何现实世界的使用来说都太不一致了。它很容易与逗号和点混淆。

这就是我从每个功能中得到的。请记住,该值是在区域设置中返回的(在这种情况下,逗号作为小数分隔符),但在内部它与符号无关。

? val("2.500,50")
 2,5 
? cdbl("2.500,50")
 2500,5 

在这里,val()停止读取逗号上的字符串 - 因此只读取“2.500”,并将点视为小数分隔符。另一方面,CDbl()完全识别号码。

? val("2,500.50")
 2     
? cdbl("2,500.50")
 2,5005 

在这里,你可以看到一切都变得一团糟......再次val()停止阅读逗号(即使数字是美国表示法),并且CDbl()与小数分隔符后面的“错位”千位分隔符混淆并忽略它.

于 2013-09-12T17:00:57.343 回答
-1
            Public Function GetNumber(ByVal Subject As String, ByVal Default As Double) As Double
            GetNumber = Default
            On Error GoTo EndNow
            Subject = Replace(Subject, ",", ".")
            Subject = Trim(Subject)
            Dim SplitArray() As String
            SplitArray = Split(Subject, ".", 2)

            Dim FirstNumber As Double
            Dim SecondNumber As Double

            SecondNumber = 1

            Dim IndexOne As Long
            Dim IndexTwo As Long
            Dim PowerLength As Long

            IndexOne = LBound(SplitArray)
            IndexTwo = UBound(SplitArray)
            FirstNumber = CDbl(SplitArray(IndexOne))
            GetNumber = FirstNumber

            If (IndexTwo > IndexOne) Then
                SecondNumber = CDbl(SplitArray(IndexTwo))

                PowerLength = Len("" & CDbl("1" & SplitArray(IndexTwo)))
                PowerLength = PowerLength - 1

                If (FirstNumber < 0) Then
                    SecondNumber = SecondNumber * -1
                End If
                GetNumber = GetNumber + (SecondNumber / Application.WorksheetFunction.Power(10, PowerLength))
            End If



            EndNow:
            End Function
于 2019-02-06T18:01:09.427 回答