Excel + VBA 与货币格式之间的精度问题
Posted
技术标签:
【中文标题】Excel + VBA 与货币格式之间的精度问题【英文标题】:Precision issues between Excel + VBA with currency formats 【发布时间】:2019-07-30 10:25:13 【问题描述】:我有一个用户定义函数 (UDF),它接受两个输入。两个输入都被声明为类型Double
。但是,虽然输入具有大量小数位数,但一旦传递给 UDF,小数位数就会被截断。
奇怪的是,我似乎无法在干净的工作簿中重现这种行为(即,我想知道这个特定的工作簿是否有什么问题......)。
(简化的)UDF 如下。
Function Wage(HourlyWage As Double, HoursWorked As Double) As Double
Wage = HourlyWage
End Function
以及正在发生的事情的屏幕截图。
编辑栏显示 UDF 调用。它将 C 列和 D 列作为输入。 HourlyWage 在 C 列中为 25.30364372+,但一旦传递给 UDF 工资,尽管声明为类型 Double
,但 HourlyWage 被截断为 25.30360000。
我了解浮点精度的一般要点,但这肯定同样适用于 C 列中的输入和 UDF 一样(实际上,C 列实际上是另一个 UDF 的输出,它已被声明为类型 @ 987654329@)。
Why can't decimal numbers be represented exactly in binary?
Why are floating point numbers inaccurate?
有关 EXCEL 工作簿的其他信息。
我使用的是 Windows 7 Professional 和 Microsoft Office 365 ProPlus 64 位版本。 工作簿是 .xlsb 格式。我还保存为 .xlsm,但无法解决问题。 我无法在干净的工作簿中重现。 工作簿包含大量相互关联的用户定义函数(可能有 40 个) 工作簿包含 11 个工作表。其中 5 个是带有许多参数的数据表,但我不会在总体方案中说大(大约 100 行和 30 列)。 3 张纸有大量的 UDF 和计算(同样,100 行可能 40-50 列) 我不会说工作簿很大。它是 369Kb (.xlsb) 和 525KB (.xlsm) 但是,当输入参数发生更改时,重新计算工作簿的时间出乎意料地长(比如大约 10 秒,我觉得这很令人惊讶,因为从总体上看,计算量并不大)关于如何解决这个问题的任何想法?精度的损失给我带来了问题......
【问题讨论】:
我无法复制它。我使用您的 UDF 代码得到25.30364372
作为输出。
您的工作簿中是否有事件触发的宏正在对 E 列进行舍入?
@brb Debug.Print [C6], [E6]
的结果是什么,只是为了确保没有奇数格式。
如果您的计算涉及数据类型为 Currency 的任何 VBA 变量,那么这些变量在小数点右侧最多只能有 4 位数字 - 请参阅 here 这似乎与您的行为相匹配正在看
谢谢大家的帮助,尤其是@barrowc - 这是货币格式的问题。我会写下答案来帮助别人,但如果你想写下答案或重新粘贴我的答案,我会接受你的版本。
【参考方案1】:
这个答案基于上面的 barrowc 和 Peh 的 cmets。谢谢你们的帮助。
货币数据类型最多有 4 个小数点 (https://docs.microsoft.com/en-gb/office/vba/language/reference/user-interface-help/currency-data-type)。
C 列已使用自定义货币格式进行格式化。输入 VBA UDF 函数时,尽管变量在 UDF 中声明为 Double
类型,但小数点后第 4 位的小数点会被截断。
更改数字格式可以解决问题,如下图所示。
这可以使用 Debug.Print 进行验证
Sub brb()
Debug.Print [C6], [E6]
Debug.Print [C8], [E8]
End Sub
【讨论】:
以上是关于Excel + VBA 与货币格式之间的精度问题的主要内容,如果未能解决你的问题,请参考以下文章