お世話になります。使用環境はWinXP(SP2)+VB6(SP6)です。
質問はVBエラーのひとつの”オーバーフローしました。(Error 6)”に関してです。
例えば、VBヘルプにも記載されている↓
Dim x As Long
x = 2000 * 365 ' エラー: 値がオーバーフローします。
このようなエラーでは、次のように対処してください。
Dim x As Long
x = CLng(2000) * 365
というものなんですが、この点で下記の2点が分かりません。
①変数xはLong型の32 ビット(-2,147,483,648 〜 2,147,483,647) の範囲の値をとれるのに、
代入値(2000*365=730,000)がなぜ代入・計算ができないのか。
②VBヘルプでは”CLng関数を使用して対処”してくれということですが、
どのくらいCLng関数を付加して対処すればいいのかという基準が分からない。
過去ログ・VBヘルプ・ネットで調べていましたがいまいち理解できませんでした。
よろしくお願いします。
VB6 まででは、数値は暗黙的に Short として理解されます。
当然、リテラル(コードにベタ書きした数値)もそうですから、2000 と 365 はどちらも Short です、
同じ型同士の演算結果は同じ型で返されます。Short 同士である 2000 と 365 の積も Short として返そうとします。
当然、オーバーフローです。
演算結果の格納先が Long じゃないか、と言う疑問があると思いますが、手順としてまず演算を行い、その結果を変数に代入するわけで、この場合一歩目でこけているので二歩目に意味はありません。
> どのくらいCLng関数を付加して対処すればいいのか
Short の範囲内では収まらなさそうな箇所についてです。第三者には判断できません。
演算する値がIntegerの範囲だと結果もIntegerになるみたいです。
Integer * IntegerだとInteger
Long * IntegerだとLong
が帰ってくるみたいですね。
MSDNにそれらしきものが載っていたので参考までに
http://msdn2.microsoft.com/ja-jp/library/ms235255(VS.80).aspx
#みるとこ間違ってないことを祈ります|o_o;
うおお、色々調べてたらHongliangさんがピシャリ orz
しかし VB6 では Short ではなく Integer でしたね orz
私の投稿の Short は全て Integer と読み替えてください。
型宣言文字として、
「%」→Integer
「&」→Long
「@」→Currency
「!」→Single
「#」→Double
「$」→String
などが用意されているので、これらを使うのも有効です。
たとえば、CLng 関数を使った
>> x = CLng(2000) * 365
という式を、
x = 2000& * 365&
のようにしても、Long型の精度で演算されます。
ちなみに、
MsgBox TypeName(2000)
MsgBox TypeName(2000&)
MsgBox TypeName(2000& * 365&)
などとすれば、データ型をチェックできます。
> どのくらいCLng関数を付加して対処すればいいのかという基準が分からない。
「演算の精度」で判断することになりますが、整数同士の加減算程度なら、
よほど大きい数でない限り、大抵は Long で大丈夫でしょう。
注意するべきは、「除算演算」が含まれる場合ですね。
値が浮動小数になりやすいため、金額計算などにおいては演算誤差や丸め誤差に注意が必要です。
Hongliangさん、KGさん、魔界の仮面弁士さんありがとうございます。
つまり”x=2000*365”という式には
”計算結果(変数へ代入する前の値)としての型”
”代入先の変数の型”
の2種類が存在しているということですね。
また、下記のように理解しました。
①////////////////////
x=2000*365
演算型×(Integer型のオーバーフロー)
代入型○
//////////////////////
②////////////////////
x=2000&*365&
演算型○
代入型○
//////////////////////
あと、魔界の仮面弁士さんが書いてくれた
TypeNameという便利な関数は今後使っていきたいと思います。
みなさんの早レスで次へ進めそうです。
本当にありがとうございました!
ツイート | ![]() |