ユーザーフォームから計算式を表示させるためのテキストボックスを作成したのですが、計算結果が10桁以上になる場合はエラーを表示し、計算を行わないようにしたいと思っていますが、うまくいきません。
↓必要そうな部分だけ抜粋してあります。
Dim miku1
Dim miku2 As Double
Dim frg As String
On Error GoTo myError
If Len(CStr(miku2)) >= 10 Then
GoTo myError
Else
Select Case frg
Case "1"
miku2 = miku2 + miku1
Case "2"
miku2 = miku2 - miku1
Case "3"
miku2 = miku2 * miku1
Case "4"
miku2 = miku2 / miku1
End Select
TextBox1 = miku2
miku1 = Null
miku2 = 0
End If
Exit Sub
myError: MsgBox "エラーが発生しました。"
End Sub
miku1はstringで認識されるので問題ないのですが、miku2に関してはdoubleで認識されるので字数制限がうまくかけられません。どなたか宜しくお願いします。
こんにちは。
こちらで、参考なるか分かりませんが、サンプルを作ってみました。
そのままだと、解決の見通しが立たないように思いました。
UserForm に4つのテキストボックス(TextBox)を置き、
TextBox1 と TextBox2 に数値を入れる。次に、TextBox3 に計算フラグをいれ、
TextBox4 に計算結果を出すように作ってみました。計算は、CommandButtonで作動します。作った範囲では、特に問題はないように思います。
今の時点では、9桁*9桁で指数表示は出るものの、エラーの発生するようには思いませんが、念のために、コメントブロックで置いておきました。
文字数制限は、前回書いたように、整数桁10 と 小数点第10位 両方を扱うことは現状では不可能です。
UserFormモジュールへ
'-----------------------------------------------
Private Sub CommandButton1_Click()
If TextBox1.Value = "" Or TextBox2.Value = "" Then
MsgBox "二つのTextBox 両方に値を入れてください。", vbCritical
Exit Sub
Else
TextBox4.Value = myCalc(TextBox1.Value, TextBox2.Value, TextBox3.Value)
End If
End Sub
Function myCalc(n1 As Variant, n2 As Variant, Flg As Variant)
Dim a1 As Variant
Dim a2 As Variant
Dim ret As Double
If Val(Flg) = 0 Then Flg = 1
If IsNumeric(n1) And IsNumeric(n2) Then
a1 = CDbl(n1)
a2 = CDbl(n2)
Else
myCalc = "Value Err "
Exit Function
End If
If Flg = 4 And n2 = 0 Then
myCalc = "0 /Div Err "
Exit Function
End If
'On Error GoTo ErrHandler
If Len(Replace(Abs(n1), ".", "")) >= 10 _
Or Len(Replace(Abs(n2), ".", "")) >= 10 Then
myCalc = "Digit Over Err "
Else
Select Case Flg
Case 1: ret = a1 + a2
Case 2: ret = a1 - a2
Case 3: ret = a1 * a2
Case 4: ret = a1 / a2
End Select
myCalc = ret
End If
' Exit Function
'ErrHandler:
' myCalc = Err.Number & " : " & Err.Description
End Function
こんにちは。
#2の回答者です。
>小数点も同様の処置がいるんです。
どのような計算なのでしょうか。
正直なところ、ご質問のコンピュータでの正規な処理の仕方は分かりません。整数の桁と同じように、少数桁というわけにはいかないはずです。
ワークシートには、Fixed 関数がありますが、VBAのFix 関数とは意味が違います。
例えば、Format 関数やCStr 関数では、丸められてしまいますから、使えません。また、少数には、無理数や循環小数がありますから、数値をそのままでは扱うことができません。
片方が、文字列で、もう片方が数値のDouble型というのは奇妙です。Double 型の数値は、一体、どういうインプットの経路から来るものなのでしょうか。ユーザー入力でしょうか。
電卓のような表示桁なら、その元の入力(TextBox)の段階で、文字列で調べるしかありません。VBAでは、安易に、少数 = 数値 - Int(数値) という計算が使えません。浮動小数点丸めが生じてしまいます。
便宜的にはこんな方法しか思いつかないです。
思ったようには簡単ではないと思います。
Sub Sample()
MsgBox DC(10.9999)
End Sub
Function DC(fig As Double)
'少数桁を取る
Dim i As Integer
If fig = 0 Then Exit Function
i = Int(Log(Abs(fig)) / Log(10#))
If i < 0 Then i = 0
DC = Len(Mid(Abs(fig), i + 3))
End Function
入力の少数桁が、Double型を扱う範囲を超えれば、上記の場合は、11として丸められてしまいます。だから、本来は文字列型でなければ、入力自体の桁を扱うことは意味がありません。
なお、#3さんのところで解決しているなら、あえて、こちらが書くことはありません。また、CStr では、丸められてしまいますから、正確には出ないはず。
別に、少しコメントを加えると、エラーというのは、単に、エラーを発生すると意味で、分岐するだけの意味と解釈しました。On Error GoTo myError の位置自体は、On Error Resume Next ではありませんから、先頭において、別に問題ではありません。単に、GoTo myError はエラー発生のために働いていないだけです。エラーが発生したら、直接、myError のラベルに飛びます。
VBAでは、エラー自体が発生しない場合は、If 分岐で可能です。今回の場合は、割り算の分母に、0 が入るためのエラーだと読みました。また、擬似的にError 発生するためには、Err.Raise (数字) というようにします。
質問者
お礼
Wendy02さん、度々申し訳ありません。
>Double 型の数値は、一体、どういうインプットの経路から来るものなのでしょうか。
本来であればVariantでやるべきなのだと思っているのですが、そうすると足し算をしたときに結果がおかしくなるので、Doubleにしてあります。ちなみに、足し算のときはこのようにやっています。
Private Sub plus_Click()
On Error GoTo myError
If miku2 = 0 Then
miku2 = miku1
Else
Select Case frg
Case "1"
miku2 = miku2 + miku1
Case "2"
miku2 = miku2 - miku1
Case "3"
miku2 = miku2 * miku1
Case "4"
miku2 = miku2 / miku1
End Select
End If
miku1 = Null
frg = "1"
Exit Sub
myError: MsgBox "エラーが発生しました。"
End Sub
お礼
たびたびありがとうございます。 仰るとおり、現在10桁の電卓を作っています。 分からないなりに何度も修正していくうちに、何がなんだか分からなくなってきたので、もう1度1からやり直してみようと思います。