Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


8301 / 13646 ツリー ←次へ | 前へ→

【34060】バリアントでもオーバーフロー よっちゃん 06/1/25(水) 18:21 質問[未読]
【34064】Re:バリアントでもオーバーフロー inoue 06/1/25(水) 18:44 発言[未読]
【34078】Re:バリアントでもオーバーフロー よっちゃん 06/1/26(木) 4:07 質問[未読]
【34080】Re:バリアントでもオーバーフロー ichinose 06/1/26(木) 7:56 発言[未読]
【34082】Re:バリアントでもオーバーフロー やっちん 06/1/26(木) 8:06 回答[未読]
【34084】Re:バリアントでもオーバーフロー よっちゃん 06/1/26(木) 9:33 質問[未読]
【34089】Re:バリアントでもオーバーフロー やっちん 06/1/26(木) 10:50 発言[未読]
【34125】Re:バリアントでもオーバーフロー よっちゃん 06/1/27(金) 8:35 お礼[未読]

【34060】バリアントでもオーバーフロー
質問  よっちゃん  - 06/1/25(水) 18:21 -

引用なし
パスワード
   変数がバリアントなのにオーバーフローしたのですが、
こういことってありえますか?
オーバーフローというのは他に何か原因って考えられるのでしょうか?

【34064】Re:バリアントでもオーバーフロー
発言  inoue E-MAILWEB  - 06/1/25(水) 18:44 -

引用なし
パスワード
   ▼よっちゃん さん:
>変数がバリアントなのにオーバーフローしたのですが、
>こういことってありえますか?
Variantだから絶対オーバーフローしないわけではありませんが、
データ型が明示されての転記なのでしょうか。
VarTypeで調べてみてはいかがでしょう。

【34078】Re:バリアントでもオーバーフロー
質問  よっちゃん  - 06/1/26(木) 4:07 -

引用なし
パスワード
   ▼inoue さん:

どこがオーバーフローになるのか分かりました。
しかし、なぜそのような現象になるのかエクセル自体が壊れているとしか
考えれない現象です。現象を説明しますと。
1.金2 = 100000 * 10ではオーバーフローしません。
2.金2 = 10000 * 10ではなぜかオーバーフローします。
3.金2 = 1000 * 10はしません。
4.金2 = 100000 は合計は2と同じはずなのですがオーバーフローしません。
5.金2 = 1E+15 * 10 めちゃくちゃ多いのにオーバーフローしません。
なぜなのでしょうか?なぞの現象について知っている方がいたら
教えてください。

【34080】Re:バリアントでもオーバーフロー
発言  ichinose  - 06/1/26(木) 7:56 -

引用なし
パスワード
   よっちゃん さん、inoue さん、おはようございます。

以下のコードを実行してみて下さい
'======================================================
Sub test1()
  On Error Resume Next
  Dim ans As Variant
  '**************************************************
  Err.Clear
  MsgBox 32767 & " = " & TypeName(32767) & vbCrLf & _
      1 & " = " & TypeName(1)
  ans = 32767 + 1
  If Err.Number <> 0 Then
    MsgBox "32767+1= " & Err.Description
  Else
    MsgBox "32767+1= " & ans
    End If
  '**************************************************
  
  Err.Clear
  MsgBox 32767 & " = " & TypeName(32767) & vbCrLf & _
        0.5 & " = " & TypeName(0.5)
  ans = 32767 + 0.5
  If Err.Number <> 0 Then
    MsgBox "32767 + 0.5= " & Err.Description
  Else
    MsgBox "32767 + 0.5= " & ans
    End If
  '**************************************************
  Err.Clear
  MsgBox 32768 & " = " & TypeName(32768) & vbCrLf & _
      1 & " = " & TypeName(1)
  ans = 32768 + 1
  If Err.Number <> 0 Then
    MsgBox "32768 + 1= " & Err.Description
  Else
    MsgBox "32768 + 1= " & ans
    End If
  On Error GoTo 0
End Sub

ans=32767+1

32767----Integer
1--------Integer

よってこの場合は、計算結果もInteger型のメモリーに一度格納した後、
変数ansに代入されます。
このとき32768は、Integer型では、納まりきらないのでエラーが発生します。

ans=32768+1では
32768-----Long
1---------Integer

となります。
この場合は、計算結果はLong型のメモリーに一度格納した後、
変数ansに代入されます。

よってエラーにはなりません。


因みに

'=============================
Sub test2()
  On Error Resume Next
  Dim ans As Variant
  MsgBox 32767 & " = " & TypeName(32767) & vbCrLf & _
      1 & " = " & TypeName(1 / 1)
  ans = 32767 + 1 / 1
  If Err.Number <> 0 Then
    MsgBox "32767 + 1/1= " & Err.Description
  Else
    MsgBox "32767 + 1/1= " & ans
    End If
  On Error GoTo 0
End Sub

これは、エラーになりません。

こういう場合,
'=======================
Sub test3()
  Dim ans As Variant
  ans = 32767 + 1&
  ans = CLng(32767) + 1
End Sub

こんな方法をとります。

計算結果がどの範囲の値になる可能性があるかを
予測しないといけませんね!!

【34082】Re:バリアントでもオーバーフロー
回答  やっちん  - 06/1/26(木) 8:06 -

引用なし
パスワード
   ▼よっちゃん さん:
>どこがオーバーフローになるのか分かりました。
>しかし、なぜそのような現象になるのかエクセル自体が壊れているとしか
>考えれない現象です。現象を説明しますと。
壊れてませんよ(^^
右辺の式で一番大きい型で計算されているだけです。
2番の10000と10はIntegerで計算され
その結果Integerの範囲を超えオーバーフローするのです。
なので2番は金2の型に関係なくオーバーフローになります。
Long型を表す&を10000か10のどちらか一方にでも付けると
Long型で計算されるのでオーバーフローになりません。
ちなみに1E+15 * 10はDoubleで計算されているのでこれも
オーバーフローになりません。

【34084】Re:バリアントでもオーバーフロー
質問  よっちゃん  - 06/1/26(木) 9:33 -

引用なし
パスワード
   みなさん、返信ありがとうございます!
やっちんさん!僕ではやっちんさんの説明わかったようなわからないような
感じです。
できたらもう少し、簡単な説明でお願いできませんか?
よろしくお願いします。

【34089】Re:バリアントでもオーバーフロー
発言  やっちん  - 06/1/26(木) 10:50 -

引用なし
パスワード
   ▼よっちゃん さん:
ichinoseさんの説明にあるように適当な型のメモリーに一度格納されます。
金2 = 10000 * 10 の場合
10000・・・Integer
10・・・Integer
自分でIntegerの変数を宣言して10000と10を入れて計算するのと変わりません。
どちらもIntegerなので計算結果もIntegerの型のメモリに入りその表現できる数値の範囲を超えているのでオーバーフローになります。
金2への代入はこの後になるので金2をVariantやLong型で宣言していてもオーバーフローは起こります。
つまり今回のオーバーフローは式の右側で起こっているのです。

次の場合
金2 = 10000 * 10&
10000・・・Integer
10&・・・Long (&を付けるとLong型の数値として扱われます)
IntegrよりLongの型の方が表現できる数値の範囲が大きいのでLongで計算され
オーバーフローになりません。

同様に
金2 = 1E+15 * 10
1E+15・・・Double
10・・・Integer
IntegrよりDoubleの型の方が表現できる数値の範囲が大きいのでDoubleで計算され
オーバーフローになりません。

次の式はオーバーフローになります。
金2 = (30000 + 30000) * 10&
30000・・・Integer
30000・・・Integer
10&・・・Long
()の中が先に計算されるのでIntegerで計算されその時点でオーバーフローです。

こんな説明で大丈夫でしょうか?(^^;

【34125】Re:バリアントでもオーバーフロー
お礼  よっちゃん  - 06/1/27(金) 8:35 -

引用なし
パスワード
   わざわざサンキュです♪
ありがとうございました。

8301 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free