在标准的 Excel VBA 代码模块中,我创建了自定义公式MyLog10()
以获得10个基数的对数:
Public Function MyLog10(ByVal dbl_Input As Double) As Double
MyLog10 = Log(dbl_Input) / Log(10)
End Function
测试值1000并得到准确的结果3.令人惊讶的是,当Int()
VBA函数应用于MyLog10()
的结果时,它显示为2.同样的观察结果与Fix()
VBA函数(参见以下测试Sub):
Sub TestIntMyLog10()
Debug.Print MyLog10(1000) 'Result 3 (accurate)
Debug.Print Int(MyLog10(1000)) 'Result 2 (inaccurate)
Debug.Print Fix(MyLog10(1000)) 'Result 2 (inaccurate)
End Sub
更令人惊讶的是,我的自定义函数MyLog10(1000)
在Excel工作表中输入为=MyLog10(1000)
,=INT(MyLog10(1000))
在两种情况下都返回正确的结果3。
对此VBA /工作表不一致的任何解释(可能是错误)?
此外,通过向自定义VBA MyLog10()
的输出添加一个非常小的数字(1E-12),在两种情况下都生成了正确的结果(有/无额外Int()
):
Debug.Print Int (Log10(1000)+1E-12) 'Result 3 (accurate)
答案 0 :(得分:2)
尝试多种类型转换后,找到了解决方案:它使用Decimal
类型作为自定义日志函数MyLog10Decimal
返回类型。以下是包含通用VBA解决方案并测试Sub TestIntMyLog10()
:
' SOLUTION: using output type decimal : Int() and Fix() return correct value
Public Function MyLog10Decimal(ByVal dbl_Input As Double) As Variant
MyLog10Decimal = CDec(Log(dbl_Input) / Log(10))
End Function
'Problem: using output type double: Int() and Fix() may return incorrect
Public Function MyLog10(ByVal dbl_Input As Double) As Double
MyLog10 = Log(dbl_Input) / Log(10)
End Function
Sub TestIntMyLog10()
' ** test sample: input number 1000
'using Log output type double: Int() and Fix() produces incorrect results
Debug.Print MyLog10(1000) 'Result 3 (accurate)
Debug.Print Int(MyLog10(1000)) 'Result 2 (inaccurate)
Debug.Print Fix(MyLog10(1000)) 'Result 2 (inaccurate)
'using Log output type decimal: Int() and Fix() produces correct results
Debug.Print Int(MyLog10Decimal(1000)) 'Result 3 (accurate)
Debug.Print Int(MyLog10Decimal(1000)) 'Result 3 (accurate)
Debug.Print Fix(MyLog10Decimal(1000)) 'Result 3 (accurate)
' ** test sample: input number 0.001
'using Log output type double: Fix() produces incorrect results
Debug.Print MyLog10(0.001) 'Result -3 (accurate)
Debug.Print Int(MyLog10(0.001)) 'Result -3 (accurate)
Debug.Print Fix(MyLog10(0.001)) 'Result -2 (inaccurate)
'using Log output type decimal: Int() and Fix() produces correct results
Debug.Print Int(MyLog10Decimal(0.001)) 'Result -3 (accurate)
Debug.Print Int(MyLog10Decimal(0.001)) 'Result -3 (accurate)
Debug.Print Fix(MyLog10Decimal(0.001)) 'Result -3 (accurate)
End Sub
一点解释。 VBA不支持Decimal类型作为Function参数/输出,因此它被声明为应用了CDec转换的Variant。到目前为止,它已经在多个输入(> 1和< 1)上进行了测试并返回了正确的结果。此外,Excel Worksheet包含内置函数LOG10(),但VBA不包含。因此,此VBA解决方案可以在其他Office应用程序中使用,而无需Excel对象库引用。
答案 1 :(得分:1)
你可以在excel中使用= LOG10来获得相同的效果,而不必自己动手(我有Excel 2013,我不确定旧版本是否有这个公式)。
如果您在VBA中需要该公式,则可以使用Application.WorksheetFunction.Log10(
数字或变量名称)
我知道这并没有真正回答你的问题,但它是一个可靠的解决办法