转换到/来自语言环境的行为不一致

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

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

所以我的解决方法是像这样使用它(通常string“0,5”被replace为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只允许我input'。' 作为小数点,然后在运行时它将被解释为1000倍的值。

对此有何看法?

Val函数只识别“。” 作为十进制分隔符(正如你可以在相应的MSDN文章中看到的那样); 等同的事情发生在其他VBAfunction。 因此,如果你修改小数分隔符被VBA / Excel占用,相当多的函数不会在乎(并且会继续使用“。”)。 我通常所做的是设置一个自定义函数来分析所有的input数据(它可以包含在你提到的基本的Replace中;但是我也可以利用这个函数来使数字格式适应我所期望的,例如:最大小数位数),确保计算过程中所有小数分隔符都是“。”。 一旦所有的计算完成,我有另一个function,以适应输出到预期的格式(通过修改Excel单元格或数字variables本身)。 如果你知道的话,这不是理想的情况,也不是一个难以解决的难题。

编辑 在这里find一个很好的例子,覆盖“区域语言环境数字设置”

您可以通过查看当地的环境variables来尝试适应欧洲或美国的分离器。

 '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的负载取决于你的支持。

这里在巴西,我们有相同的数字符号(“,”作为小数点分隔符,“。”作为成千上万的分隔符)。 我通常使用CDbl()转换数字,因为它考虑到区域的区域设置。 正如你已经提出的, val()对于我的任何真实世界的使用来说太不一致了。 它容易与逗号和点混淆。

这是我得到每个function。 请记住,该值是在区域设置中返回的(在这种情况下,逗号是小数点分隔符),但内部独立于符号。

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

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

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

在这里,一切都变得一团糟,你可以看到…再次val()停止阅读逗号(即使数字是在美国符号),并CDbl()混淆了“错位”千位分隔符后小数点分隔符,只是忽略它。