- ベストアンサー
Excel VBA TEXTBOXの字数制限
- Excel VBAを使用してテキストボックスの字数制限を実装する方法について教えてください。
- ユーザーフォームから計算式を表示させるためのテキストボックスを作成しましたが、計算結果が10桁以上になる場合にエラーを表示し、計算を行わないようにしたいです。
- miku2というdouble型の変数には字数制限をかけたいのですが、うまく実装できません。どうすればいいでしょうか?
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 >>どういうインプットの経路から来るものなのでしょうか。 TextBox のユーザーインプットなのですか?それとも、ワークシートからなのですか?それが分かりません。 >本来であればVariantでやるべきなのだと思っているのですが、そうすると足し算をしたときに結果がおかしくなるので、Doubleにしてあります。ちなみに、足し算のときはこのようにやっています。 小数点が混じる計算は、非常に難しいです。 どのように結果がおかしくなるのですか? やはり、丸められてしまうのではないでしょうか。 miku1, miku2 の最初の変数の取得部分が見えません。 それに、コードをみると、単なる四則演算ですね。それにしては、全体的なロジックには問題点があります。おそらく、On Error トラップを使って、実際のエラー部分に気が付いていない可能性があるからです。(今さらですが) 失礼ですが、何をされているのでしょうか?電卓を実現させようとでもするのですか? ただ、実際、整数10桁~小数点第10位までを扱うとなると、特殊なコードを使わないと解決しないだろうと思います。通常のコードでは解決できません。「符号+小数点+10桁」で、合わせて12文字のスペースの中で使うというなら、また話は別です。 #4のコードで解決していなかったようですから、正直なところ、ご希望の仕様自体を確認して、もう一度、最初の数値の取得部分から見直したほうが良さそうな気がします。 それと、Variant で問題はないはずです。Excelの既存の関数の引数のほとんどは、Double型ではなくて、Variant 型なのです。
その他の回答 (7)
- Wendy02
- ベストアンサー率57% (3570/6232)
補足: >「電卓」と同じ仕様にするには、たぶん、変数のDouble 型は違うような気がします。 調べてみましたが、通常の電卓では、Double型でよいようでした。いくつか、作っている人のサイトを見てみました。関数電卓など、それぞれの設計があるようです。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 >仰るとおり、現在10桁の電卓を作っています。 そうでしたか。#6 で一例は示しましたが、ちょっと違いますね。 難しいことに手を出しましたね。 回答とは直接離れますが、少し、書かせていただきます。 VBAの練習で「電卓を作る」というのは聞いたことがあります。誰かに勧められましたか? 私が、初めてVBAを始めた頃に、VBAで「電卓を作る」ということを聞かされましたが、それから、丸8年経ちますが、一度も手を付けたことがありません。知れば知るほど難しい部分があるのです。正直なところ、私は、きちんとしたものの作り方を知りません。 どの程度のものを望むかは分かりませんが、「電卓」と同じ仕様にするには、たぶん、変数のDouble 型は違うような気がします。特別にモジュールが必要のようです。VB6の資料は残っていますので、この期に少し調べてみようと思います。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 こちらで、参考なるか分かりませんが、サンプルを作ってみました。 そのままだと、解決の見通しが立たないように思いました。 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
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 #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
- rukuku
- ベストアンサー率42% (401/933)
はじめまして 「うまくいきません」の内容が分からないのですが、 少なくとも以下のことが言えます。 質問は >計算結果が10桁以上になる場合はエラー となっていますが、 If Len(CStr(miku2)) >= 10 Then の入っている位置では 「計算前」のmiku2 を判定に使っています。
お礼
ありがとうございます。 If文をSelect後ろに付けたらうまく働きました。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんにちは。 Double 型ということは、小数点が入るという意味でしょうか。 If Len(CStr(miku2)) >= 10 Then ↓ If Int(Log(Abs(miku2)) / Log(10#)) >= 9 Then 数値のままなら、Log で桁をと取ります。 ただし、これは、miku2 には「0」が入りません。 Double 型ですから、 If Abs(miku2) > (10 ^ 10 - 1) Then というのは使えません。 という方法ぐらいと思います。そのまま文字列にすると、丸められてしまいますので、CStr やFormat ですと、 9999999999.9999 は、1000000000 になってしまいます。 この場合、Int関数や Fix 関数と言う関数になります。 Fix(Abs(miku2))
お礼
ありがとうございます。 整数10桁までの問題は解決したのですが、小数点も同様の処置がいるんです。 小数点なので、-9か1/9を左側に入れればよいかと思いましたが、そういうわけでもないのでしょうか?(高校数学を忘れてしまったので申し訳ありません) お手数をおかけしますが、宜しくお願いします。
- pkh4989
- ベストアンサー率62% (162/260)
こんにちは。 以下のように文字列に変換してからチェックするのは如何でしょうか。 Dim wk On Error GoTo myError wk = Format(miku2, "#") If Len(wk) >= 10 Then GoTo myError Else '・・ End If
お礼
たびたびありがとうございます。 仰るとおり、現在10桁の電卓を作っています。 分からないなりに何度も修正していくうちに、何がなんだか分からなくなってきたので、もう1度1からやり直してみようと思います。