2017-04-10 161 views
0

我在VBA中有一个函数,它是更大设置的一部分。该函数驻留在Class Module内,基本上只是一个美化的减法。我想知道为什么我得到了一些奇怪的结果,所以为了调试目的我(过)简化了函数。事实证明,其中一个变量没有被赋予它应该的值,而是一些看似随机的值。一个简单的分配怎么会出错?VBA将不正确的值赋给变量

甚至更​​怪,为什么它并不总是分配不正确的值?它只是有时会发生。其他时间是正确的。偶尔,似乎根本没有任何评估,而函数只返回0(零)。

从所有我可以看到它不能成为我的代码的问题,但与VBA的工作方式(幕后)rahter。但只要我不明白,就很难减轻。

代码:

Public Property Get MySubtractionFunction() As Double 
    Dim tmpValue1 As Double 
    Dim tmpValue2 As Double 
    Dim tmpOutput As Double 

    'When debugging, sometimes CDbl(Me.Value2) evaluates to approximately 18.000 
    'However tmpValue2 evaluates to approximately 10.000 
    tmpValue1 = CDbl(Me.Value1) 
    tmpValue2 = CDbl(Me.Value2) 

    tmpOutput = tmpValue1 - tmpValue2 'Breakpoint is set at this line 
    tmpOutput = Application.WorksheetFunction.Min(tmpOutput , tmpValue1) 

    'Return output 
    MySubtractionFunction= tmpOutput 

End Property 

更新1 当我到达断点前将鼠标悬停Me.Value2,它实际上表明,被分配到tmpValue2值。如果我然后删除鼠标,并再次将鼠标悬停在Me.Value2上,则会显示不同的值。一个属性值如何才能改变,没有任何代码被执行?

更新2 也许我应该提到,只有当我在循环中使用类对象时才会出现问题。它被这样调用:

For i = 1 To 1000 
    Dim myObject As myClass 
    Set myObject = New myClass 
    'Some initialization 
    result = myObject.MySubtractionFunction 
    'A bunch of other stuff 
    Set myObject = Nothing 
Next i 
+0

'Me.Value1'和'Me.Value2'是什么类型?他们是'String'类型的吗?如果是这样,在转换为Double之前它们的实际值是多少? – user3598756

+0

这两个属性都是“Double”类型。我只是将'CDbl'添加为调试尝试,这不是必需的。 – Noceo

+0

看来你正在计算时间值。这些值因转换不正确而臭名昭着。看看“01:10:15”这样的值如何在用户表单中以Dbl结尾。 – Variatus

回答

0

解决方案

正如我所说,我有一个问题的性质,是最后在众多的链条。所有调用类模块的其他属性(链中第一个除外)。问题起源很早,并且通过所有步骤链接起来。

它很难识别的原因是,最初不正确的属性值是在调试模式下将鼠标悬停在变量上以检查变量时更新的。

解决方案是扩展链中的所有步骤,方式类似于原始文章中的步骤。这并不总是必需的,因为这个问题只在我快速运行多个计算时才显示出来。但是,如果有人要求类似的问题,我会建议你尝试这个修复。

这不起作用:

Public Property Get myProperty() As Double 
    myProperty = Me.someOtherProperty + Me.aThirdProperty 
End Property 

这也:

Public Property Get myProperty() As Double 
    Dim tempSomeOtherProperty As Double 
    Dim tempAThirdProperty As Double 
    Dim tempResult As Double 

    tempSomeOtherProperty = Me.someOtherProperty 
    tempAThirdProperty = Me.aThirdProperty 
    tempResult = tempSomeOtherProperty + tempAThirdProperty 

    myProperty = tempResult 

End Property 
0

所有的计算机语言在处理双打(浮点)时都有一个很大的问题。因此,在C#中,您应该使用decimal来避免此问题。在Excel中,你应该轮流。

看看什么微软称它: https://support.microsoft.com/en-us/help/78113/floating-point-arithmetic-may-give-inaccurate-results-in-excel

+0

我试过在没有运气的情况下添加了'Round(,2)'而不是'CDbl'。在返回属性值之前,我也在属性内部尝试了'Round()'。 – Noceo

+0

为了看看会发生什么,你可以把'double'换成'long'吗? – Vityata

+0

'Me.Value1'可能是一个文本框或另一个基本上处理字符串的控件。所以,你将一个字符串转换为double,用纯文本将最不精确的算术表达式转换为最精确的Excel所提供的。但我怀疑这只是问题的一半。实际上,如果你将时间转换为一个字符串值,那么另一半就是double。无论是你的编码和你在这里提供的信息都太不精确,无法做出正确的答案。揭开“Me.Value1”的面纱,以及它的价值。 – Variatus