[[20180511165944]] 『エラーが起こるのはなぜ』(hiro) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『エラーが起こるのはなぜ』(hiro)

Dim a As Integer
a = 32767
Msgbox a + 1

これだとエラーが起こるようですが、その理由がわからないのです。
変数の値がデータ型の値の範囲を超えているわけではありませんよね?
なぜエラーが発生するのですか?

よろしくお願いします。

< 使用 Excel:unknown、使用 OS:unknown >


Msgbox a + 1
で変数aに対しさらに1を加算した結果
Integerの許容範囲32767 を超えたためと推測されます。32768になった。 ^^
Integer型が扱える数字の範囲は、-32,768 〜 +32,767 だった様な記憶が
御座います。

(隠居じーさん) 2018/05/11(金) 18:25


隠居じーさん様、今日は何度もありがとうございます。
確かにInteger型Integer型が扱える数字の範囲は、32767までです。
でもその値を超えるのは、変数aでなく、MsgBoxでの計算結果ですよね。
変数が計算に使われた場合、その結果も変数のデータ型と関係するのでしょうか。

うまく伝わっていなかったらすみません。
(hiro) 2018/05/11(金) 19:21


https://msdn.microsoft.com/ja-jp/vba/language-reference-vba/articles/msgbox-function
msgboxの説明です。
prompt 必ず指定します。ダイアログ ボックスにメッセージとして表示される 文字列式です。 prompt の最大長は約 1,024 文字です。これは、使用される文字の幅によって異なります。 prompt が複数の行で構成される場合、各行の間でキャリッジ リターン文字 ( Chr( 13 ) )、ラインフィード文字 ( Chr( 10 ) )、またはキャリッジ リターン文字とラインフィード文字の組み合わせ ( Chr( 13 ) と Chr( 10 ) ) を使用することで、各行を分割できます。
なので
a+1
変数にaに1を加算後の変数aを表示していると思います。
a=a+1
Msgbox a
と同じかと。
数値なのに文字列なら表示出来ないのではとの疑問は
エクセル様が気を利かして文字列に変換してくださっていると推測されます。ソースコードが
オープンでないので調べようがない。。。オープンでも私では理解できないかも^^;
許してくれない言語も有りますよ。a.tostring とか書きたいような気がしますね。
外していましたらお許しを

(隠居じーさん) 2018/05/11(金) 19:43


単純に考えると。 ^^
msgboxのパラメーターとして 計算結果の a+1 を渡しています。
受け取ったパラメーターをmsgboxは単に表示しているだけ。
だと思います。
では
m(_ _)m

それと勉強材料UPさせて頂きます。お暇な時にでも、ご覧になると良いかもです。
[[20180221163017]]

(隠居じーさん) 2018/05/11(金) 19:56


 これは私も不思議に思うんですけど、

  a + 1 の結果は、関係する数値の一番大きな型に格納されるようです。

 ・・で、「1」の型が何だか分からないけども、結果的に分かるのはIntegerなんでしょうね。

 ・・で、試しに・・としてやるとオーバーフローしません。
           ↓
     MsgBox a + 1#  'Double型
     MsgBox a + 1&  'Longe型
     MsgBox a + 1!  'Single型

 因みに
    MsgBox a + 1% 'Intege型 をやろうとしたら

     MsgBox a + 1 ’←こうなった。「%」は強制的に外された。

(半平太) 2018/05/11(金) 20:28


 被ったが。
 計算時には計算した結果を一時的に格納するためのワークエリアがとられる。
 そのワークエリアがとられる際には計算される値の大きい方の型でとられる。
 aも1もInteger型のため作業エリアもInterger型でとられるため計算結果が範囲いエラーとなる。
 試しにlong型の変数を定義してそれに1を代入してからそのふたつを足してMsgboxで表示してみてくれ。
(ねむねむ) 2018/05/11(金) 20:33

以前同じような質問をみた記憶があるのですが探せませんでした。
でも、結論は、ねむねむさんのコメントのようなことだったと思います。
以下だと、最後の行でエラーになります。

 Sub teet()
    Dim a As Long

    a = 300000 + 300000
    a = 30000 + 30000

 End Sub

(マナ) 2018/05/11(金) 20:48


皆様ありがとうございます。少し理解に時間がかかりそうなので、すぐにすべてに反応できなくて申し訳ないのですが。

ねむねむ様

念のためですけど、こういうことですよね。
(2,3行目の説明は理解できたのに、最後だけ理解できなかったので…。)
Dim myLg As Long
myLg = 1
MsgBox myLg + 1
(hiro) 2018/05/12(土) 14:37


 こんにちは ^^
いや〜! エクセル様は型キャストも自動でやってくれるようですね。すばらしぃ〜 ^^; ?
勉強になりますね。私も驚きでしたです。
ねむねむ さん はきっと下記のようなことを説明されたと思います。
ふつ〜に 1 足すと オーバーフローするのに、ロング型変数に代入して足すと、同じ1でもエラーにならないですね。
半平太さんが既に例を提示されていますけど。

 Option Explicit
Sub test()
    Dim a As Integer
    Dim mylong As Long
    a = 32767
    mylong = 1
    MsgBox a + mylong
End Sub
マナさんの例も驚きでしたです。
気をつけないといけないなと思いました。
ロング型定義しててもインテジャーになるのですね〜@@;
(隠居じーさん) 2018/05/12(土) 17:10

 hiroさん、便乗ですみません
Sub test02()
    Dim a%
    a = 100000 + 100000
End Sub
では。。。。普通と云えば普通ですけど。。。。。オーバーフローです。
どうなんでしょうね。。。ロングにはしてくれないですね。
私の勘違いでしょうか。。だんだん分からなくなってきました。^^;
何か法則の様なものがあるのでしょうか。
(隠居じーさん) 2018/05/12(土) 19:30

右辺の計算は成功していますが
aに代入できていないだけで

a = 200000

と同じ、普通のエラーではないでしょうか。

(マナ) 2018/05/12(土) 19:55


 マナさん ありがとうございます。^^
注意深く。。エラー出さない様にテストし
あまり気にせず頑張ります。
Sub main()
    Dim a%
    MsgBox a + 100000 + 100000
End Sub
はエラーでません。^^v〜#$%&!@@?
(隠居じーさん) 2018/05/12(土) 22:05

便乗はご自由に。その方が私も勉強になります(笑)

>隠居じーさん様
ありがとうございます。かなり外していて、お恥ずかしい限りです。半平太様が同じ例を出されているとのコメントもありがとうございます。半平太様の回答は私にはさっぱりわからなかったので、それを踏まえてもう一度読み直してみます。マナ様の回答もまだダメなのですが、きっと似たようなことをおっしゃってるのでしょうね。頑張って理解したいです。

あと少し、理解に自信がないので、念のため書いておきます。
ねむねむ様の「計算される値の大きい方の型」は、値の範囲が広い型という意味ですよね。

 >計算時には計算した結果を一時的に格納するためのワークエリアがとられる。
 >そのワークエリアがとられる際には計算される値の大きい方の型でとられる。
 >aも1もInteger型のため作業エリアもInterger型でとられるため計算結果が範囲いエラーとなる。

足し算する二つの数値の比較ではないですよね(P+QでP>Q(P,Qは整数)だから、「ワークエリア」でとられるのはPのデータ型…という意味ではないですよね)。

Dim a As Integer
a = 32767
Msgbox a + 1

1はそもそも型がないから値の範囲もない
→Integer型の方が値の範囲が大きいと言える
→a + 1の計算結果はInteger型と認識される
→a + 1の計算結果はIntegeer型の値の範囲に収まらないのでエラーが発生

みたいな理解で合っているでしょうか。
もし誤っていましたら、どなたか、ご指摘いただけると大変ありがたいです。
(hiro) 2018/05/14(月) 22:54


 >半平太様の回答は私にはさっぱりわからなかったので、

 すごく分かり易い例として書いたんですがねぇ(とほほ)

  MsgBox a + 1#  'Double型  ←1を単なる1じゃなく、ダブル型と認識させたので範囲のより広い方はダブル型になるので、計算結果が32767より大きくても問題が起きない
  MsgBox a + 1&  'Longe型   ←1を単なる1じゃなく、ロング型と認識させたので範囲のより広い方はロング型になるので、計算結果が32767より大きくても問題が起きない
  MsgBox a + 1!  'Single型  ←1を単なる1じゃなく、Single型と認識させたので範囲のより広い方はSingle型になるので、計算結果が32767より大きくても問題が起きない

  因みに
  MsgBox a + 1% 'Intege型 をやろうとしたら
  MsgBox a + 1 ’←こうなった。「%」は強制的に外された。←1を単なる1じゃなく、Integer型と認識させようとしたが、単なる1と同じなので、%をつけることさえ無意味として、蹴られた。

 >1はそもそも型がないから値の範囲もない  
 上の結果から逆算すると、Integerと同じ扱いであり、範囲はいずれにしてもIntegerの域に留まる。だからオーバーフローする。

(半平太) 2018/05/14(月) 23:16


 >ねむねむ様の「計算される値の大きい方の型」は、値の範囲が広い型という意味ですよね。 
 すまない、表現の仕方が悪かった。
 hiroさんの書かれた通り範囲が広いとしてくれ。
(ねむねむ) 2018/05/15(火) 09:00

 試しに、こんなのをイミディエイトウィンドウでテストしてみると、Integerと返ってきます。
      ↓
   ? typename(1)

(半平太) 2018/05/15(火) 09:11


ねむねむ様、うまく文意が汲めず、申し訳ないです。ありがとうございます、この理解で良いのですね。

半平太様も、わざわざありがとうございます。先の回答と合わせて読ませていただきます。
(hiro) 2018/05/15(火) 09:36


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.