excel - CLng() 和 CDbl() 正在舍弃小数
问题描述
如果我CLng("22.14")
在我的 PC 的 Excel VBA 编辑器中运行,我会得到预期的结果,22
. 如果我在一些国际同事的 PC 上执行此操作,它会产生2214
.
CDbl
正在做类似的事情。我得到22.14
,他们得到2214
。
我的想法:我假设一些设置定义了十进制字符(我的正确的是“。”而他们的则是别的东西)。我的搜索没有产生任何其他想法或解决方案。
解决方案
VBA 中的所有数字转换函数都支持区域设置,因此它们将忽略千位分隔符和货币符号。该IsNumeric
函数的行为方式相同:
Public Sub Example()
'en-US locale
Debug.Print IsNumeric("$1,1,1,1,1,") 'True
Debug.Print CLng("$1,1,1,1,1,") '11111
End Sub
我知道处理这个问题的唯一与主机无关的解决方法(除了不将数字存储为String
数据)是完全绕过内置的 VBA 转换并直接使用硬调用oleaut32.dll 中的底层转换函数-编码的区域设置 ID。例如,Double
要从 en-US 本地化字符串中获取 a:
Public Declare PtrSafe Function VarR8FromStr Lib "oleaut32" _
(ByVal strIn As LongPtr, ByVal lcid As Long, ByVal dwFlags As Long, ByRef pdblOut As Double) As Long
Public Const EN_US As Long = 1033
Public Function DoubleFromEnUsString(converting As String) As Double
Dim converted As Double, result As Long
result = VarR8FromStr(StrPtr(converting), EN_US, 0, converted)
If (result = 0) Then
DoubleFromEnUsString = converted
Else
Err.Raise 5
End If
End Function
...或一个Long
:
Public Declare PtrSafe Function VarI4FromStr Lib "oleaut32" _
(ByVal strIn As LongPtr, ByVal lcid As Long, ByVal dwFlags As Long, ByRef plOut As Long) As Long
Public Const EN_US As Long = 1033
Public Function LongFromEnUsString(converting As String) As Long
Dim converted As Long, result As Long
result = VarI4FromStr(StrPtr(converting), EN_US, 0, converted)
If (result = 0) Then
LongFromEnUsString = converted
Else
Err.Raise 5
End If
End Function
示例用法:
Public Sub Sample()
Debug.Print LongFromEnUsString("12.34") '12
Debug.Print DoubleFromEnUsString("12.34") '12.34
End Sub
推荐阅读
- sql - 查询根据 PARALLEL 提示返回不同的结果
- java - Android:使用 RxJava 的 API 调用返回空响应
- matlab - 大矩阵中的空单元格问题:MATLAB
- django - 生产中的 Django 迁移问题
- python - 如何(Python 从 json 对象数组迭代)
- docker - 如何分发 docker-compose 文件?
- c - 我可以使用 `va_list` 两次,如下所示:
- javascript - 使用 javascript 和 php 登录帐户时无法重定向
- python - Python:叶地图没有出现
- typescript - 如何在打字稿中获得严格的值类型?