• 締切済み

VBA 加算演算時のトラブル

事務処理用に準備したVBA処理の数値合計チェックにて本来イコールとなるべきところ、ノットイコールと判定されてしまいます。当該部分を抜き出し、わかりやすくしたものが下記のロジックですが、ここで、test2,test4は結果がイコールとなるものの、test3の場合、ノットイコールとなってしまいます。どなたか、原因につき教えていただけませんか? Dim aaa As Double Dim bbb As Double sub test2() bbb = 16.67 + 16.67 aaa = 33.34 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test3() bbb = 16.67 + 16.67 + 16.67 aaa = 50.01 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test4() bbb = 16.67 + 16.67 + 16.67 + 16.67 aaa = 66.68 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End sub

みんなの回答

  • kiki_s
  • ベストアンサー率59% (147/248)
回答No.2

小数点以下4桁まで精度が必要でしたら通貨型(Currency)にすれば正しく計算されます。 浮動小数点数の誤差 http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.shtml 他の方法として、 小数点以下の桁数が2桁までなら、100倍して計算して、100で割れば単純です。 通貨型も内部で10000倍(小数点以下4桁)しています。 ANo.1さんの通り、厳密なら10進型ですね。

uo3-uo3
質問者

お礼

A No.1さんともども、ありがとうございました。 助かりました。

  • noah7150
  • ベストアンサー率46% (116/251)
回答No.1

2進法を御存知か? コンピュータの世界は基本は2進法で実行されています 小数点以下の場合は近似値でしか表現できないのです 印刷や表示上は適当なところで丸められ表示されているので視覚上同じですが比較が厳密にやられる為です。 有効桁で丸めて比較しましょう If Format(aaa,"#0.00;-#0.00") = Format(bbb,"#0.00;-#0.00") Then 通常なら下記のような形でも問題は起きません If CStr(bbb) = CStr(aaa) Then If CDec(bbb) = CDec(aaa) Then 厳密に行うなら10進型が良いでしょうね Option Explicit Dim aaa Dim bbb Sub test2() bbb = CDec(16.67) + CDec(16.67) aaa = CDec(33.34) If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test3() bbb = CDec(16.67) + CDec(16.67) + CDec(16.67) aaa = CDec(50.01) If bbb = aaa Then ' If Format(bbb, "#0.00;-#0.00") = Format(aaa, "#0.00;-#0.00") Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test4() bbb = CDec(16.67) + CDec(16.67) + CDec(16.67) + CDec(16.67) aaa = CDec(66.68) If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub

uo3-uo3
質問者

お礼

目からウロコです。ありがとうございます。 全てクリア、質問してよかったです!!!

関連するQ&A

  • IFステートメントの使い方 どちらでもないならば

    「出金も入金も0じゃないならば」としたい場合、どのようなifステートメントを作ればいいでしょう? Sub test() Dim 出金 As Currency Dim 入金 As Currency 出金 = 0 入金 = 0 '(1) If Not (出金 = 0) And Not (入金 = 0) Then MsgBox "出金0入金0ではありません" End If '(2) If (出金 = 0) And (入金 = 0) Then Else MsgBox "出金0入金0ではありません" End If End Sub (1)だとうまくいきません。 (2)のように Elseを使って対応するしかないのでしょうか? (2)でいけますが、今後の勉強の為にelseを使わずに、「どちらでもないならば」の方法を教えてください。

  • Excel VBAを簡素化したいのですが動きません

    お世話になります。VBA初心者です。 下記TESTは動くのですが、『If myINT= Then』が永遠に続くので簡素化したく 『Rows("myINT : myINT").Select』これを入れてみたのですが全く動きません。 簡素化した記述を教えて下さい。宜しくお願い致します。 Sub TEST() Dim myINT As Integer myINT = ActiveSheet.Cells.SpecialCells(xlLastCell).Row   If myINT = 1 Then    Rows("1:1").Select    ElseIf myINT = 2 Then    Rows("2:2").Select   ElseIf myINT = 3 Then    Rows("3:3").Select   Else MsgBox "TEST" End If End Sub

  • VBAのinputboxで何もいれずに[OK]を押した時エラーになります

    よろしくお願い致します。 EXCELのVBAで「inputbox」を使ってセルを選択させたいと考えております。 下記のコードだと「キャンセル」や「×」で閉じられた時はmsgbox「キャンセル」が出てExit subするのですが、何も入力しないで「OK」を押した場合がどうしてもエラー(入力した数式は正しくありません)になります。 いろいろ調べて試したのですがどうしてもできず困っています。 どなたか教えてください。 Sub test() Dim myAns As Range On Error Resume Next Set myAns = Application.InputBox(Prompt:="セルを選択してください。", Title:="セル選択", Type:=8) On Error GoTo 0 If myAns Is Nothing Then MsgBox "キャンセル" Exit Sub ElseIf myAns = "" Then MsgBox "最低1つは選択してください" Exit Sub Else MsgBox myAns.Address(0, 0) End If End sub

  • エクセルVBAでApllication.Caller

    エクセル2000です。 マクロをワークシート上に貼ったフォームのボタンなどから呼び出す場合、ボタンの名前はApllication.Callerでわかるので、同じ一つのマクロでも呼び出されたボタンに応じた動きができるのですが、他のマクロから呼び出した場合、Apllication.Callerではエラーになってしまいます。 例 Sub test() x = Application.Caller If x = "AAA" Then MsgBox "AAA" If x = "BBB" Then MsgBox "BBB" Cells(1, 1).Value = "1" End Sub 他のマクロから呼び出された場合、エラーとしないためにはOn Error Resume Next以外ではどのようにすればいいでしょうか?

  • エクセルのInputBoxについて教えてください。

    エクセル2010です。 InputBoxについて教えてください。  負数以外の数値を受け取りたいのです。 以下のようにやってみました。 Sub test001() Dim ans As Double ans = Application.InputBox("数値を入力", Type:=1) If ans = False Then MsgBox "キャンセル" Exit Sub ElseIf ans < 0 Then MsgBox "負数は不可。" Call test Else MsgBox ans & "を受け取りました。" End If End Sub 一応、これで動くのですが、問題は数値0を入力された場合です。 0はFalseと認識されるようで、キャンセルとなってしまいます。0は0という数値で受け取りたいのです。 試行錯誤の結果、Type:=1をやめ、変数ansをVariantにして If ans = “False” Then と、Falseをダブルクォーテーションでくくると、0を数値としてくれるようです。でも理屈がわかりません。変数ansにキャンセルボタンで帰ってくるのはBooleanのFalseであり、Stringの”False”ではないと思うのですが。 Sub test002() Dim ans ans = Application.InputBox("数値を入力") If ans = "False" Then MsgBox "キャンセル" & TypeName(ans) Exit Sub ElseIf ans = "" Then MsgBox "未入力" & TypeName(ans) Call test002 ElseIf Not IsNumeric(ans) Then MsgBox "数値ではありません。" & TypeName(ans) Call test002 ElseIf ans < 0 Then MsgBox "負数は不可。" & TypeName(ans) Call test002 Else MsgBox ans & "を受け取りました。" & TypeName(ans) End If End Sub あと、もうひとつ質問は、数値以外の入力があった場合、再度入力させるためいちいちCall test002 を入れてますが、このやり方でただしいのでしょうか?

  • VBAでワイルドカードを使った文字列検索

    初めて投稿いたします。 環境は、WinXP Access2000 下記のVBAモジュールで、文字列検索がヒットしません。 数字の比較でヒットするのはナゼでしょうか? ちなみに、変数に導入したのは、全角半角どちらも入れてみました。 この疑問・・・どなたか解決お願いします。 Sub TEST() Dim AAA As String Dim BBB As String Dim YYY As String AAA = "0" BBB = "2" YYY = AAA & BBB Select Case YYY Case "0*" MsgBox "ココを通り過ぎないで!" Case "15" MsgBox "やったね" Case Is > 0 MsgBox "なぜかココでヒットします??" End Select End Sub

  • (VBA)フィルタがかかっているかどうかの判断方法

    フィルタがかかっているかどうかを取得したいのですが フィルタがかかっているシートにて Sub test1() If ActiveSheet.FilterMode Then MsgBox "フィルタがかかってます" End If End Sub Sub test1の1() If ActiveSheet.FilterMode = True Then MsgBox "フィルタがかかってます" End If End Sub を実行しても"フィルタがかかってます"は表示されません。 Sub test2() If Rows(1).FilterMode Then MsgBox "フィルタがかかってます" End If End Sub Sub test3() If ActiveSheet.Rows(1).FilterMode Then MsgBox "フィルタがかかってます" End If End Sub こちらは オブジェクトは、このプロパティまたはメソッドをサポートしていません。(Error 438) になってしまいます。 フィルタがかかっているか調べる方法はありますか? よろしくお願いします。

  • VBAでif文にorを使う場合の仕様

    http://www.relief.jp/itnote/archives/vba-if-or.php このページにも書かれてあるのですが、 Sub textss() aaa = 2 If aaa = 0 Or 1 Then bbb = 1 ElseIf aaa = 2 Then bbb = 2 End If ccc = bbb End Sub を実行すると cccには2が代入されそうなのですが、実際には1が代入されてしまいます。 If aaa = 0 Or aaa = 1 Then と入力する必要があります。 それでは、 If aaa = 0 Or 1 Then とした時、プログラムではどういう処理がなされているのでしょうか?

  • 【1】と【2】のvbaは同じ意味ですか?

    【1】 Option Explicit Sub test1() Call test2("aaa") End Sub Sub test2(MyStr As String) MsgBox MyStr End Sub 【2】 Option Explicit Dim MyStr As String Sub test1() MyStr = "aaa" Call test2 End Sub Sub test2() MsgBox MyStr End Sub 結果は同じですが、中身が違います。 今後コードを作っていく上で どちらの方式の方が良いのでしょうか?

  • エクセルVBAについて

    お世話になりなります。 以下のように条件が合わない場合、何もせずにNの値を増やして同じくIF文で判断する場合 ***にどのように書けばいいのでしょうか? よろしくお願いします。 Sub ボタン1_Click() Dim a As String For n = 1 To 30 a = Cells(n, 1) aa = Left(a, 1) aaa = Val(aa) If aaa = "" Then *** If aaa <= cha(30) Then *** If aaa >= cha(40) Then *** Else Cells(n, 3) = a Next End Sub

専門家に質問してみよう