vba - CDec:带小数的参数字符串的国际语法
问题描述
我的 Excel 为所有内容(公式、界面、指南)设置了英文。我的 Windows 设置为“,”作为十进制符号和“。” 用于区域设置中的数字分组符号,因为我住在意大利。
如果我写这段代码:
Dim v As Variant
v = CDec("12345678901234567000,123456789")
v = v + 50
结果在 Locals 窗口中显示为“12345678901234567050,123456789”(变量/十进制)。如果我将它发送到 msgbox,则相同。
如果我使用“。” 而不是“,”,结果是 12345678901234567000123456839。
在 VBA 中,当写数字时(以数字的形式,而不是字符串),我必须使用英文语法,即“。” 为十进制符号。
我相信我的示例代码会被具有英语区域设置的 Windows 错误地运行。
我怎样才能(修改它)使它在任何区域设置下正确运行?
解决方案
C*
转换函数(CInt
、等CLng
)CStr
都设计为在计算机的当前语言环境中工作。他们将使用当前的小数分隔符,因此您正确地假设CDec
将无法正确处理,
具有不同小数点的系统上的硬编码。
相反,Str
始终Val
使用英文分隔符,但它们不支持Decimal
.
所以想到的一种选择是在运行时获取小数点:
Dim v As Variant
v = CDec("12345678901234567000" & Application.International(xlDecimalSeparator) & "123456789")
但是应该注意的是,如果Application.UseSystemSeparators
是False
并且Application.DecimalSeparator
已经被更改,那么Application.International(xlDecimalSeparator)
将返回更改后的分隔符,而不是来自计算机语言环境的分隔符。因此,如果您不能保证UseSystemSeparators
是,请不要使用此方法True
。
另一种选择是以十的幂除的形式表示小数位,这对于精确的定点Decimal
数据类型很好:
Dim v As Variant
v = CDec("12345678901234567000123456789") / CDec("1000000000")
另一种选择是有一个自定义的“CDec”,它在某个语言环境中明确工作,并始终硬编码该语言环境中的字符串:
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function VarDecFromStr Lib "OleAut32.dll" (ByVal strIn As LongPtr, ByVal lcid As Long, ByVal dwFlags As Long, ByRef pdecOut As Variant) As Long
#Else
Private Declare Function VarDecFromStr Lib "OleAut32.dll" (ByVal strIn As Long, ByVal lcid As Long, ByVal dwFlags As Long, ByRef pdecOut As Variant) As Long
#End If
Private Const LOCALE_INVARIANT As Long = &H7F&
Private Const S_OK As Long = &H0
Public Function ParseDecimalFromEnUsString(ByVal s As String) As Variant
Dim hr As Long
hr = VarDecFromStr(StrPtr(s), LOCALE_INVARIANT, 0, ParseDecimalFromEnUsString)
If hr <> S_OK Then
Err.Raise 5, , "Cannot parse the string. Error " & Hex$(hr)
End If
End Function
? ParseDecimalFromEnUsString("12345678901234567000.123456789")
12345678901234567000,123456789
? TypeName(ParseDecimalFromEnUsString("12345678901234567000.123456789"))
Decimal
(有关此代码的版本,该版本可以更好地控制允许包含的字符串,请参阅此答案的修订版 3。NUMPRS_STD
接收的参数是要更改的参数。)
推荐阅读
- javascript - 在js中查找并返回带有特定单词的字符串
- javascript - 设置两个元素之间所有文本的范围选择
- jquery - 根据名称转换 JSON 的输出
- laravel - 将 CURL 转换为 Http 门面 laravel
- javascript - 如何从 Node JS 应用程序控制台日志调用中删除所有换行符
- visual-studio-code - 如何在 VSCode 扩展中从 Git 获取修改后的文件
- sql - 为什么cte返回不存在的错误?
- installation - wxMaxima 无法检测到最大值安装
- angular - 没有带有弹簧后端、角度应用程序和 nginx 的“Access-Control-Allow-Origin”标头
- discord - Discord.JS - 嵌入未出现