- ベストアンサー
マクロにおける条件文の作成の件
以下の様に条件付きの計算式を作成しました。CommandButton3を押しても 計算しなかったり、TextBox3.Value > TextBox1 ではないときでもエラー メッセージが出ます。どこに欠点があるのか教えて下さい。 Private Sub CommandButton3_Click() Dim row As Integer If TextBox1.Value = Empty Then MsgBox ("Aが空欄です") Exit Sub End If If TextBox2.Value = Empty Then MsgBox ("Bが空欄です") Exit Sub End If If TextBox3.Value = Empty Then MsgBox ("Cが空欄です") Exit Sub End If If TextBox4.Value = Empty Then MsgBox ("Dが空欄です") Exit Sub End If If TextBox3.Value > TextBox1.Value Then MsgBox ("Cの値をAの値より小さくしましょう!") Exit Sub End If If TextBox4.Value > TextBox2.Value Then MsgBox ("Dの値をBの値より小さくしましょう!") Exit Sub End If TextBox5 = Round(TextBox1 * TextBox2 - (TextBox1 - TextBox3) * (TextBox2 - TextBox4) / 2, 0) End Sub
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 基本的なことですが、TextBox の値は、文字列型なのですから、直接、TextBoxの比較をすれば、文字の比較になってしまいます。 数字以外は入れないというのでしたら、Clng で変換したり、文字も間違えて入れてしまうなら、Val 関数を使います。しかし、文字列は、0になります。本来、それぞれの入力データは変数で受けたほうが分かりやすいです。 なお、数値を調べるのは、IsNumeric です。 VBA のRoundは、偶数丸めですから、用途が違います。 Int(数値 +0.5) を使います。
その他の回答 (2)
かなりオセッカイな回答です。 ですからスルーしてもらっても結構です。 数字かどうかを判定した結果の絶対値は 0 ないし 1 です。 その結果を連結すると "_0_0_0_0"、"_1_0_0_0"などの文字列が生成されます。 最初に0が見つかった桁を2で除したら 1、2、3、4番目のどれが非数字かが判ります。 先ず、非数字テキストボックスかどうかを判定します。 次に、最初の非数字テキストボックスを確定します。 それの有無で全体をIF THEN - ELSE 文で分岐します。 問題がなければ、変数に取り込みます。 比較テストを行って必要なメッセージを出します。 全ての比較テストをクリアしていたならば第5テキストボックスを更新します。 全体をこういう組み立てにすれば、一目瞭然の構造的なコードが出来上がります。 あちらこちらで Exit Sub する手法は、これで追放できます。 Private Sub CommandButton1_Click() Dim N(3) Dim intEmpty As Integer Dim strEmpty As String strEmpty = Str(Abs(IsNumeric(TextBox1))) + _ Str(Abs(IsNumeric(TextBox2))) + _ Str(Abs(IsNumeric(TextBox3))) + _ Str(Abs(IsNumeric(TextBox4))) intEmpty = InStr(1, strEmpty, "0", vbTextCompare) If intEmpty > 1 Then MsgBox (Mid("ABCD", intEmpty \ 2, 1) & "が空欄です") Else N(0) = Val(TextBox1.Value) N(1) = Val(TextBox2.Value) N(2) = Val(TextBox3.Value) N(3) = Val(TextBox4.Value) If N(2) > N(0) Then MsgBox ("Cの値をAの値より小さくしましょう!") ElseIf N(3) > N(1) Then MsgBox ("Dの値をBの値より小さくしましょう!") Else TextBox5 = Rounds(N(0) * N(1) - (N(0) - N(2)) * (N(1) - N(3)) / 2, 四捨五入) End If End If End Sub ところで、VBA の Round関数が Excel のそれと違うのは実にややこしいです。 そういう場合は、自作するのが一番です。 下に案内している Rounds関数は、次のように使います。 エクセルの Round、RoundDown、RoudUp の統合タイプです。 [イミディエイト] ? Rounds(1252.34, 四捨五入, 1) 12.3 ? Rounds(1252.34, 切り捨て, 1) 12.3 ? Rounds(1252.34, 切り上げ, 1) 12.4 ? Rounds(1252.34, 四捨五入, -2) 1300 ? Rounds(1252.34, 切り捨て, -2) 1200 ? Rounds(1252.34, 切り上げ, -2) 1300 Option Explicit <標準モジュール> ' ' Rounds関数用 ' Public Const 四捨五入 = 0 Public Const 切り捨て = 1 Public Const 切り上げ = 2 Public Function Rounds(ByVal M As Currency, _ ByVal A As Integer, _ Optional D As Integer = 0) As Variant Rounds = Sgn(M) * Fix(Abs(M) * 10 ^ D + Abs((A = 0) * 0.5@ + (A = 2) * (Int(M * 10 ^ D) <> (M * 10 ^ D)))) / 10 ^ D End Function
- bdr
- ベストアンサー率43% (35/80)
想定外の結果がでるパターンがわからないので、なんとも言えませんが、テキストボックスの値は、数値でも数値以外でも比較することになるので、想定外の動きをしているのでは?と推測します。 始めにCdbl関数などを使って、テキストボックスの値を数値として変数に格納したのち処理してみては如何でしょう? ちなみに数値に変換可能かはIsNAなどで調べることもできます。