投稿日 | : 2005/08/01(Mon) 17:39 |
投稿者 | : エデン |
URL | : |
タイトル | : 分母が固定値なのに「0で除算」!? |
VBアプリを開発していますが、以下のような現象に遭遇し、原因究明に手こずっています。
原因究明の手がかりを得たく、投稿させていただきました。よろしくお願いします。
まず、状況説明ですが、規模の大きいアプリケーションなので、関連しそうな部分だけを抜き出して
説明します。
(1)実行プラットフォームは Windows2000Pro.SP4, 開発環境は VB6 SP5
(2)GUIはMDI構成
(3)MDI子ウィンドウのうちの1つに、バーグラフを描画表示する自作のActiveXコンポーネントが貼っ
てあり、描画更新のタイマコントロールが同一のフォームに貼ってあり、このタイマイベントで0.5秒
ごとに描画更新します。また、複数ページ表示に対応させるため、「ページ送り」と「ページ戻り」
のボタンが同一のフォームに貼り付けてあります。表示用のActiveXコンポーネント自体は1つで、ボ
タンクリックによって表示させる内部データを切り替えて表示させる仕組みです。
(4)同一LAN上の別PCにデータを送信するため、MDIの親フォームにソケットコントロールとタイマコン
トロールを貼ってあります。データ送信先PCがソケットサーバ(Listen)、このアプリがクライアント
です。タイマーコントロールのタイマイベントで、5秒ごとに所定のフォーマットのバイナリデータを
送信します。
以上のような状況で以下のような現象が発生しました。
■バーグラフフォームのページ送り/戻りボタンを連打(1秒に2〜3回程度)すると、「あるタイミン
グ」で「実行時エラー'11': 0で除算しました。」のVBエラーが発生します(赤バッテンのダイアロ
グではありません)。VisualStudio からデバッグ実行してこのVBエラーを発生させ、[デバッグ]ボタ
ンでVBエラー発生ポイントのソースを見ると、決まって以下のプログラム行を指します。
stSocketFrame.bytDigAlarm(1) = CByte((nStatusData(0) And &HFF00) / &HFF)
これは、(4)で説明した、ソケット送信用タイマコントロールのTimerイベントのサブルーチンから
Callで呼ばれた、ソケット送信用データを作成する関数の中の1行です。 nStatusData()は 0〜1の2要
素のInteger型配列、Type で定義したstSocketFrameはソケット送信データ格納用の構造体で、
bytDigAlarm は 0〜1 の2要素のByte型配列です。
このままこの行からデバッグステップ実行すると、今度はVBエラーを起こすことなくそのまま実行さ
れ、連続実行すると何事もなくまたアプリが動きます。
VBエラーの起こる「あるタイミング」ですが、これまで調べた限りでは、ソケット送信のタイマイベ
ントと、バーグラフのページ送り/戻りボタンクリックによってバーグラフフォームを書き換える処理
が重なるようなタイミングで多く発生しているような傾向です。
それで、このソケット送信タイマコントロールのTimerイベントサブルーチンの1行目で、このタイマ
コントロールのEnableプロパティをFalseにし、Timerイベントサブルーチンの出口でEnableプロパテ
ィをTrueにして、ソケット送信のTimerイベントが重複起動されないようにすると、このVBエラーは起
きなくなります。
以上の内容から疑問点をまとめますと、
(A)なぜ分母固定値の割り算処理で「0で除算」などというVBエラーが起こるのか?
(B)一度VBエラーで止まった行がなぜステップ実行で再び正常に実行できるのか?
(C)ソケット送信タイマの重複起動を禁止すると、なぜVBエラーが出なくなるのか?
という3点です。特に分母が固定値の割り算処理で「0で除算」というVBエラーが出る原因が皆目見当
がつきません。
長文ですみませんが、よろしくお願いします。