- ベストアンサー
Excel2000のVBAでわからないことがあります。
こんなものを作ってみました。 Sub 理想体重() Dim Sin As Long Dim Tai As Long Sin = InputBox("あなたの体重は?", "体重") Tai = InputBox("あなたの身長は?", "身長") If Tai >= Sin * Sin * 21 / 10000 + 3 Then MsgBox "太りすぎです" ElseIf Tai <= Sin * Sin * 21 / 10000 - 3 Then MsgBox ("痩せすぎです") Else MsgBox ("標準です") End If End Sub 結果はきちんと出てくるのですが、最初の変数宣言のところがわかりません。 最初は、Longではなく、Integerにしたのですが、オーバーフローのエラーが出たので、Longに変更したところ、きちんと出てくるようになりました。 しかし、なぜ、Integerではだめなのかがわかりません。私としては、Integerは32,767までの数字が入るのだから、身長や体重を入れたぐらいだと、オーバーフローにはならないのではないかと考えています。 きっと、根本的なものがわかっていないんだとは思うのですが、違いを教えていただければうれしいです。 よろしくお願いいたします。 (VBAを勉強したばかりです。)
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
#6ですが、ちょっと追加です。 > 私としては、Integerは32,767までの数字が入るのだから、身長や体重を入れたぐらいだと、 > オーバーフローにはならないのではないかと考えています。 まったくその通りです。 決しって入れ物が小さいのでは、ありません。 でもエラーになるのは、順番に演算している時点のエラーなのです。 Integer * Integer * Integer = Integer でエラーになっているのを (Sin) (Sin) (21) Integer * Integer * Double = Double になるように1つでも大きなタイプのものを使って (この結果が、Integerになるようでは大変ですよね。) If Tai >= Sin * Sin * 21# / 10000 + 3 Then のように 21 を Doubleにしてやると、演算されます。 (他に ! とか & #6のレス参照)
その他の回答 (8)
- ja7awu
- ベストアンサー率62% (292/464)
> 両方をLongしなくても、片方をLongにすればよいということになりますか? > もし、間違えているようであれば、ご指摘いただけないでしょうか? その通りです。 間違っておりません。 普通は、 If Tai >= Sin ^ 2 * 21 / 10000 + 3 Then のように書きますが、 変数 Sin 自体は、Integerで大丈夫なのですが、これを計算するのに、 Integer用の¥980の電卓を使うものですから、桁数が足りなくてオーバーフローに なってしまう訳です。 それで、計算式の中にLog が入っていると、ちょっと桁の多い\1,980のLog 用の電卓で 計算されますので、エラーにならない。 ということだと思います。 #2のtinu2000さんが仰っている様に、計算する用紙が小さすぎて、答えを出せる状態 ではない ということと同じですね。 基本が大事です。デバックの方法を習得し、エラーの原因を突き止めることが上達に つながるものと思います。 ところで、この体重、InputBoxに入力する単位は、何ですか? 当方、痩せているのですが、「太りすぎ」と出ますが・・・? 適当に可也スリムな数値を入力しても、「太りすぎ」になってしまいます。 どっか、計算式、おかしくありません?
お礼
本当にありがとうございます。最初はぜんぜんわからなくて、くじけそうになったのですが、やっと理解ができました。 ご指摘の件ですが、 Sin = InputBox("あなたの体重は?", "体重") Tai = InputBox("あなたの身長は?", "身長") Sinのところに体重を入れるInputBoxになってしまっています。正しくは Sin = InputBox("あなたの身長は?", "身長") Tai = InputBox("あなたの体重は?", "体重") です。スミマセン。
- popesyu
- ベストアンサー率36% (1782/4883)
あと追加で。 Dim x As Long x = 35000 * 100 x = 3500 * 1000 この例では上はエラーになりませんが、下のはエラーになります。上のは32767以上なので仮Xの型が自動でLongになるからです。下の仮XはIntegerになってしまうのでオーバーフローします。この辺はVBの癖ということで丸覚えしましょう。ちなみにこんな知識は他の言語には何の役にもたちませんw
お礼
>仮Xの型が自動でLongになるからです うーん・・わかってきたような・・・(?) 変数宣言の問題ではないということですか? Longということは、長整数型ですので、いっぱい入りますね(アバウトな言い方ですいません) なのにもかかわらず、 x = 3500 * 1000 がエラーになるということは、入れ物(変数)がいくら大きいものを使っていても、計算途中で、 3500(Integer)*1000(Integer)はInteger以下の結果にならないと、オーバーフローが出るということでしょうか?だから、long*IntegerだったらLong以下の結果を出せるということですか? お礼の箇所に書いてしまいましたが・・・すみません。回答ありがとうございます。
- ja7awu
- ベストアンサー率62% (292/464)
変数が Integerの場合、こんな感じで如何でしょうか。 If Tai >= Sin * Sin * 21& / 10000 + 3 Then ついでに次のコードを実行して確認してみると良いでしょう。 Sub GetType() Debug.Print VarType(21) ' ----> 1=Integer Debug.Print VarType(21&) ' ----> 3=Long Debug.Print VarType(21!) ' ----> 4=Single Debug.Print VarType(21#) ' ----> 5=Double End Sub
お礼
上記の式で解決できます。 ありがとうございます。 Get Typeも確認してみました。(イミディエイトウィンドウで確認すればよいのですね。) でも、まだまだ勉強が足りないようです。
- popesyu
- ベストアンサー率36% (1782/4883)
4番です。 記述が分かりにくい、かつミスがあるということで再度書き直します。 --- ヘルプにありますが 数値計算で数値が内部的に整数型として処理されている場合に、計算結果が整数型の範囲を超えているとオーバーフローします。 エラーが出る例 Dim x As Long x = 2000 * 365 エラーが出ない例 Dim x As Long x = CLng(2000) * 365 今回の事例なら If Tai >= Clng(Sin) * Sin * 21 / 10000 + 3 Then で解決です。 VBは型変換がいい加減というか処理が自動化されすぎているため、自覚することが少ないのですが、上の例では2000は仮にInteger型のXという変数の中に入っているのです。で掛け算の計算途中でその仮Xがオーバーフローしています。
お礼
実際に確認してみました。解決はしたのですが・・まったく理解ができず、くじけそうです。(苦笑) Dim x As Long x = 2000 * 365 は 長整数型の変数 x を宣言します 変数 x に 2000*365 に代入 という意味にどうしても考えてしまうのです。 長整数型は2147483647までの整数まで処理ができるのに、なぜ エラーが出るのかが・・・ もう少し勉強が必要ですね。 ありがとうございました。
- popesyu
- ベストアンサー率36% (1782/4883)
ヘルプにありますが 数値計算で数値が内部的に整数型として処理されている場合に、計算結果が整数型の範囲を超えているとオーバーフローします。 Dim x As Long x = 2000 * 365 計算途中がオーバーフローなのです。 この場合は計算途中も明示的に型を示す必要があります。 Dim x As Long x = CLng(2000) * 365 今回の事例なら If Tai >= Clmg(Sin) * Sin * 21 / 10000 + 3 Then で解決です。 VBは型変換がいい加減というか処理が自動化されすぎているため、自覚することが少ないのですが、上の例では2000は仮にInteger型のXという変数の中に入っているのです。で掛け算の結果そのXがオーバーフローしています。
- imogasi
- ベストアンサー率27% (4737/17069)
SINなどは三角関数と混同されるかも。 INPUTBOX関数は文字列を返すはずです。 VBでは数字と演算すると数値化してくれるかも知れないが、そう言う意識は必要では。VAL関数で数値化しておいたほうが良いのでは。
お礼
>INPUTBOX関数は文字列を返すはずです。 まったく知りませんでした。 勉強になりました。ありがとうございました。
- tinu 2000(@tinu2000)
- ベストアンサー率40% (147/366)
こんばんは。 たぶん、 If Tai >= Sin * Sin * 21 / 10000 + 3 Then の所でエラーが出たと思います。 コンピューターは計算をいっぺんにするのではなく、 一つ一つ順番に計算をします、 ちょうど、人間が紙を使って計算して行くようにです。 計算の相手が小さければ小さい作業用の紙を用意し、 大きければ大きい作業用の紙を用意します。 ここでは、Tai と Sin の大きさを見て紙の大きさを決めています。 Integer と指定したら、Integerの紙を用意します。 例えば、身長を170Cmと入れると、 170*170*21 の計算結果(=606900)をIntegerの紙に書いて置こうとして、オーバーフローになります。 たぶん。
お礼
回答ありがとうございます。 もう少し勉強が必要なようです。 >例えば、身長を170Cmと入れると、170*170*21 の計算結果(=606900)・・・ という表現はわかるのですが、 >Integerの紙に・・ というのがなぜInteferの紙に書かれてしまうのかが、理解ができないのです(勉強不足です) この170*170*21の結果を何かの変数に代入するのであれば、理解ができるのですが、論理式を作って比較しているだけなのに・・と考えてしまうのです。 変数の考え方がそもそも違うのですね。勉強しなおします。丁寧に教えていただいてありがとうございました。
- pppc88
- ベストアンサー率43% (40/93)
ご投稿のマクロを試していませんが、怪しいところが2つあります。 1.変数名に"sin"はこのましくありません。 三角関数サインの予約関数で同じ関数名があるためです。 2.式的に変数sinを2乗しているところがあります。 √32768≒181なので、単純に約182以上で演算上オーバーフローになります。
お礼
アドバイスありがとうございます。 Sinという変数名はよくありませんね。よくわかりました。 しかし、他の名前に変えてみましたが、解消はされませんでした。 でも、変数名を変えたときに、SINの引数が・・・などのエラーが出ていましたので、名前がよくなかったのも理解できます。 ありがとうございます。
お礼
再度の回答ありがとうございます。 ということは、変数宣言を Dim Sin As Long Dim Tai As Integer というふうに、両方をLongしなくても、片方をLongにすればよいということになりますか? (一応確認してみましたが、エラーは出ませんでした。) もし、間違えているようであれば、ご指摘いただけないでしょうか?よろしくお願いいたします。