2017-04-10 8 views
0

私は大きなセットアップの一部であるVBAの機能を持っています。この関数はClass Moduleの内部にあり、基本的には賞賛される減算です。私はなぜ奇妙な結果が得られたのか疑問に思ったので、デバッグのために関数を単純化しました。変数の1つには値が割り当てられるのではなく、一見ランダムな値が割り当てられることが分かります。どのように単純な割り当てが間違って行くことができますか?VBAは変数に不正な値を割り当てます

さらに奇妙なことに、なぜそれが間違った値を割り当てるのではないのですか?それはときどき起こるだけです。それ以外の時は正しい。そして時々、何も評価されていないようで、関数はちょうど0(ゼロ)を返します。

私のコードでは問題ではありませんが、VBAの仕組み(舞台裏で)は非常に面白いです。しかし、私がそれを理解していない限り、軽減することは非常に困難です。

コード:

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

ソリューション

私が述べたように、私はとの問題を持っていた財産は、多くのチェーンで最後でした。クラスモジュールの他のプロパティをすべて呼び出します(チェーン内の最初のプロパティを除く)。問題はかなり早く起きて、すべてのステップで連鎖していました。

私が変数を検査するために変数の上にマウスを置いたとき、最初に間違っていたプロパティ値がデバッグモードで更新されたため、識別が非常に困難でした。

解決策は、元のポストと同様の方法でチェーンのすべてのステップを拡張することでした。これは、複数の計算を高速に実行したときに問題が示されただけなので、必ずしも必要というわけではありません。しかし、誰かが同様の問題をexpeirence場合は、私はこの修正プログラムを試すことをお勧めします。

これは動作しませんでした:

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では、あなたはラウンドする必要があります。

は、Microsoftがそれについて言っていることを見てみましょう: https://support.microsoft.com/en-us/help/78113/floating-point-arithmetic-may-give-inaccurate-results-in-excel

+0

私は運がない 'CDbl'ではなく' Round(、2) 'を追加しようとしました。また、プロパティ値を返す前に、プロパティ内で 'Round()'を試しました。 – Noceo

+0

何が起こるかを見るために 'double'を' long'に切り替えることができますか? – Vityata

+0

'Me.Value1'は、おそらく文字列や基本的に文字列を扱う別のコントロールです。したがって、文字列を倍精度に変換しています。プレーンテキストでは、最も不正確な算術式を最も正確なExcelに変換する必要があります。しかし、私はそれが問題の半分に過ぎないと思う。残りの半分は、実際には、文字列値として表される時間を倍精度に変換する場合です。コーディングとここで提供した情報の両方が不正確すぎて正しい答えが得られません。 'Me.Value1'とは何か、それがどんな価値を持っているのか、ベールを上げてください。 – Variatus

関連する問題