投稿時間: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エラーが出る原因が皆目見当 がつきません。
長文ですみませんが、よろしくお願いします。
|