こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Excel VBA TEXTBOXの字数制限

ユーザーフォームから計算式を表示させるためのテキストボックスを作成したのですが、計算結果が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で認識されるので字数制限がうまくかけられません。どなたか宜しくお願いします。

投稿日時 - 2009-03-12 13:54:13

QNo.4790329

すぐに回答ほしいです

質問者が選んだベストアンサー

こんにちは。

>>どういうインプットの経路から来るものなのでしょうか。
TextBox のユーザーインプットなのですか?それとも、ワークシートからなのですか?それが分かりません。

>本来であればVariantでやるべきなのだと思っているのですが、そうすると足し算をしたときに結果がおかしくなるので、Doubleにしてあります。ちなみに、足し算のときはこのようにやっています。

小数点が混じる計算は、非常に難しいです。
どのように結果がおかしくなるのですか?
やはり、丸められてしまうのではないでしょうか。

miku1, miku2 の最初の変数の取得部分が見えません。
それに、コードをみると、単なる四則演算ですね。それにしては、全体的なロジックには問題点があります。おそらく、On Error トラップを使って、実際のエラー部分に気が付いていない可能性があるからです。(今さらですが)

失礼ですが、何をされているのでしょうか?電卓を実現させようとでもするのですか?
ただ、実際、整数10桁~小数点第10位までを扱うとなると、特殊なコードを使わないと解決しないだろうと思います。通常のコードでは解決できません。「符号+小数点+10桁」で、合わせて12文字のスペースの中で使うというなら、また話は別です。

#4のコードで解決していなかったようですから、正直なところ、ご希望の仕様自体を確認して、もう一度、最初の数値の取得部分から見直したほうが良さそうな気がします。

それと、Variant で問題はないはずです。Excelの既存の関数の引数のほとんどは、Double型ではなくて、Variant 型なのです。

投稿日時 - 2009-03-13 13:47:53

お礼

たびたびありがとうございます。
仰るとおり、現在10桁の電卓を作っています。
分からないなりに何度も修正していくうちに、何がなんだか分からなくなってきたので、もう1度1からやり直してみようと思います。

投稿日時 - 2009-03-13 15:27:08

ANo.5

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(8)

ANo.8

補足:
>「電卓」と同じ仕様にするには、たぶん、変数のDouble 型は違うような気がします。

調べてみましたが、通常の電卓では、Double型でよいようでした。いくつか、作っている人のサイトを見てみました。関数電卓など、それぞれの設計があるようです。

投稿日時 - 2009-03-16 13:10:39

ANo.7

こんばんは。

>仰るとおり、現在10桁の電卓を作っています。

そうでしたか。#6 で一例は示しましたが、ちょっと違いますね。
難しいことに手を出しましたね。

回答とは直接離れますが、少し、書かせていただきます。

VBAの練習で「電卓を作る」というのは聞いたことがあります。誰かに勧められましたか?

私が、初めてVBAを始めた頃に、VBAで「電卓を作る」ということを聞かされましたが、それから、丸8年経ちますが、一度も手を付けたことがありません。知れば知るほど難しい部分があるのです。正直なところ、私は、きちんとしたものの作り方を知りません。

どの程度のものを望むかは分かりませんが、「電卓」と同じ仕様にするには、たぶん、変数のDouble 型は違うような気がします。特別にモジュールが必要のようです。VB6の資料は残っていますので、この期に少し調べてみようと思います。

投稿日時 - 2009-03-13 20:54:31

ANo.6

こんにちは。

こちらで、参考なるか分かりませんが、サンプルを作ってみました。
そのままだと、解決の見通しが立たないように思いました。

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

投稿日時 - 2009-03-13 14:23:19

ANo.4

こんにちは。
#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 (数字) というようにします。

投稿日時 - 2009-03-13 10:22:21

お礼

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

投稿日時 - 2009-03-13 11:02:09

ANo.3

はじめまして

「うまくいきません」の内容が分からないのですが、
少なくとも以下のことが言えます。

質問は
>計算結果が10桁以上になる場合はエラー
となっていますが、
If Len(CStr(miku2)) >= 10 Then
の入っている位置では
「計算前」のmiku2
を判定に使っています。

投稿日時 - 2009-03-12 17:13:11

お礼

ありがとうございます。
If文をSelect後ろに付けたらうまく働きました。

投稿日時 - 2009-03-12 23:14:52

ANo.2

こんにちは。

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))

投稿日時 - 2009-03-12 17:06:41

お礼

ありがとうございます。
整数10桁までの問題は解決したのですが、小数点も同様の処置がいるんです。
小数点なので、-9か1/9を左側に入れればよいかと思いましたが、そういうわけでもないのでしょうか?(高校数学を忘れてしまったので申し訳ありません)
お手数をおかけしますが、宜しくお願いします。

投稿日時 - 2009-03-12 23:23:52

ANo.1

こんにちは。
以下のように文字列に変換してからチェックするのは如何でしょうか。
  Dim wk
  
  On Error GoTo myError
  wk = Format(miku2, "#")
  If Len(wk) >= 10 Then
    GoTo myError
  Else
    '・・
  End If

投稿日時 - 2009-03-12 16:23:37

あなたにオススメの質問