tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルMSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11770
投稿日: 2008/03/14(Fri) 13:09
投稿者BamChan
 組み込み経験だけの豊富な、なかなか初心者の出口が見えない程度の理解度ですが、
ご存知の方、教えて下さい。

<現在の私の課題>
1)MSComm1_OnComm()の受信イベントで、収集したデータ(1〜4バイト)を、文字列に編集して、
文字列配列に入れます。
更に、次のデータを受信するべく、送信処理も行います。
2)タイマーイベントの処理で、周期的にその文字列配列を1レコード(.csv形式)にして、
Print でシーケンシャルファイル出力します。

<お尋ねしたいこと>
1)タイマーイベントというのは、(組み込みで言う)タスクレベルで動作し、他方、
MSComm1_OnComm()イベントというのは、(同じく)ハード割り込みレベルで呼び出されているなぁ、とデバッグを通じて、感じています。正しいでしょうか?
2)上記の送信処理とPrint処理に、内容の異なるエラー処理(On Errorステートメント)を
定義しているのですが、VBの内部では、エラーハンドラーは、複数個同時に定義&実効できるのでしょうか?何か、制限があるのでは無いでしょうか?
極端な例を書いてしまえば、On Errorは、同時には1つしか使用できなくて、
Print文実行中に(受信ハード割り込みが生じて)MSComm1_OnComm()が実行されて、
多重に、On Error文が実効された時、双方のエラーハンドラーは正しく動作できないのでは?
という疑問です。

宜しくお願い致します。
(組み込み用語が飛び交ってしまうのは、ご容赦下さい。)

[ツリー表示へ]
タイトルRe: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11774
投稿日: 2008/03/14(Fri) 17:39
投稿者K.J.K.
> 1)タイマーイベントというのは、(組み込みで言う)タスクレベルで動作し、
> 他方、MSComm1_OnComm()イベントというのは、(同じく)ハード割り込みレベルで
> 呼び出されているなぁ、とデバッグを通じて、感じています。正しいでしょうか?

そうとは言えないでしょう。呼び出される側からみれば、どちらもシングルスレッド時代
からの仕様をそのまま受け継いだ実装になっているので、メッセージキューに該当する
メッセージが入れられて、それが処理する余裕のあるときに処理される、というだけ
のことでしかありません。たとえそもそもの発端がハード割り込みレベルのもので
あってもです。

VB6のコード記述を見ればわかりますが、受動的な処理の基本はイベントドリブンであって、
割り込みではありません。割り込みに該当する機能はせいぜい後述する例外処理ぐらい
しか存在していません。

> 2)上記の送信処理とPrint処理に、内容の異なるエラー処理(On Errorステートメント)を
> 定義しているのですが、VBの内部では、エラーハンドラーは、複数個同時に定義&実効で
> きるのでしょうか?何か、制限があるのでは無いでしょうか?

「例外処理中にその処理が原因で例外が発生すること」を除くと、「同時」に複数の例外を
処理することはありません。例外の情報は常に1つしか保持しません。プローシージャ内で
例外が処理されなかった場合に限り、その外(メソッドの呼び出し元)へ例外が運び出され
ます。

> Print文実行中に(受信ハード割り込みが生じて)MSComm1_OnComm()が実行されて、

Printステートメントのあるプローシージャを抜けるまで、OnCommイベントは生じません。
但し、DoEventsがある場合は、そこでイベントが発生する可能性があります。

で、シビア(というほどでもないけど、UIによる影響を受けたくない場合)なケースでは、
VB6を使うことは勧められません。COMMに対する処理とUIに対する処理を同じスレッド
で行うからです。COMMに限らず、外部機器を使う場合やネットワーク、時間のかかる
ファイル操作などではUI周りだけVBであとは別スレッドを生成するDLLをC++などで作って
使うのが無難なところでしょう。

[ツリー表示へ]
タイトルRe^2: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11777
投稿日: 2008/03/14(Fri) 21:46
投稿者BamChan
> > 1)タイマーイベントというのは、(組み込みで言う)タスクレベルで動作し、
> > 他方、MSComm1_OnComm()イベントというのは、(同じく)ハード割り込みレベルで
> > 呼び出されているなぁ、とデバッグを通じて、感じています。正しいでしょうか?
>
> そうとは言えないでしょう。呼び出される側からみれば、どちらもシングルスレッド時代
> からの仕様をそのまま受け継いだ実装になっているので、メッセージキューに該当する
> メッセージが入れられて、それが処理する余裕のあるときに処理される、というだけ
> のことでしかありません。たとえそもそもの発端がハード割り込みレベルのもので
> あってもです。
>
> VB6のコード記述を見ればわかりますが、受動的な処理の基本はイベントドリブンであって、
> 割り込みではありません。割り込みに該当する機能はせいぜい後述する例外処理ぐらい
> しか存在していません。

一々の丁寧なご回答を有難く受けさせて頂きました。有難う御座います。
問題をややこしくさせてしまい申し訳ないですが、
現在、小生が戸惑っておりますのは、(VB6.0環境ですが)
「上記のPrint文すら、エラーハンドラの書き換えに因って(?)、
まともに動作できなくなってしまうんじゃないか?」という、
本日のランニング結果に基づいての、判断です。
因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」というトラブルを招いています。

 まだ、ランニング時間は、充分ではありませんが、
On Errorステートメントを、対象であるデバイス(これも組み込み用語)毎に
排他的に使えば(Print中の受信イベントはリトライさせる様にして)、
本不具合は、再現していません。(現在のところ。)

>
> > 2)上記の送信処理とPrint処理に、内容の異なるエラー処理(On Errorステートメント)を
> > 定義しているのですが、VBの内部では、エラーハンドラーは、複数個同時に定義&実効で
> > きるのでしょうか?何か、制限があるのでは無いでしょうか?
>
> 「例外処理中にその処理が原因で例外が発生すること」を除くと、「同時」に複数の例外を
> 処理することはありません。例外の情報は常に1つしか保持しません。プローシージャ内で
> 例外が処理されなかった場合に限り、その外(メソッドの呼び出し元)へ例外が運び出され
> ます。
>
> > Print文実行中に(受信ハード割り込みが生じて)MSComm1_OnComm()が実行されて、
>
> Printステートメントのあるプローシージャを抜けるまで、OnCommイベントは生じません。
> 但し、DoEventsがある場合は、そこでイベントが発生する可能性があります。
>
> で、シビア(というほどでもないけど、UIによる影響を受けたくない場合)なケースでは、
> VB6を使うことは勧められません。COMMに対する処理とUIに対する処理を同じスレッド
> で行うからです。COMMに限らず、外部機器を使う場合やネットワーク、時間のかかる
> ファイル操作などではUI周りだけVBであとは別スレッドを生成するDLLをC++などで作って
> 使うのが無難なところでしょう。

この「無難」という単語に思わず斬り込みたくなるのが、「組み込み屋」のサガでして、
「なんでや?」となる訳です。
たとえ、今後のソースの継承性を犠牲にしてでも、根拠を知っておきたいのです。
 週明けに、もう少し踏み込んだデータを示せれば、と思っています。
レス、参考にさせて頂きます。
有難う御座いました。

[ツリー表示へ]
タイトルRe: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11779
投稿日: 2008/03/15(Sat) 09:29
投稿者K.J.K.
> 因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
> そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」
> というトラブルを招いています。

それは、単に前のレコードが書き込まれずに次へ行っただけなのでしょう。
巻き戻して書き込むなんて「高尚」な機能を備えていませんし。

> この「無難」という単語に思わず斬り込みたくなるのが、「組み込み屋」のサガでして、
> 「なんでや?」となる訳です。

それは"Windows"だからです。"Windows"は"Window"の複数形ですし、"Window"
は"Message"を"Queue"に置き、それを置かれた時刻とは「無関係」に処理して
いくものだからです。
# 中にはQueueに置かずに直接送られるMessageもありますが、スレッドを
# 跨ぐ際にはそれでもQueueチェックが入ります。

簡単な例として、
1,Form1にTimer1を貼り付けて、Timer1.Intervalを250(ms)程度に設定しておく。
2,Timer1_Timerイベントプロシージャ中で
  Caption = CStr(Now)
  と記述し、コンパイルする。(P-CodeでもNative-CodeでもどちらでもOK)
3,コンパイルしたEXEを実行し、そのタイトルバー(Captionが出るところ)の
  上にカーソルを合わせて、右ボタンを押しっぱなしにする。
これだけで、Timerイベントが抑制されることが確認できます。
# Timerイベントの元は、WM_TIMERメッセージ。

リアルタイムに反応することをアプリに要求するのならば、少なくとも
その反応するスレッドは負担のかかるUserInterface(以降UIと略します)
を保持するスレッドとは別のスレッドにするべきですよね。で、そういう
アプリだと、VB6の機能のみでは作りにくいのが現状です。UIを持たない
ActiveX EXEとして作るという手もありますが、それでもUIを持つEXEとの
通信がネックになります。

[ツリー表示へ]
タイトルRe^2: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11783
投稿日: 2008/03/16(Sun) 05:57
投稿者BamChan
> > 因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
> > そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」
> > というトラブルを招いています。
> それは、単に前のレコードが書き込まれずに次へ行っただけなのでしょう。
(私としては、不意に核心をつかれた感じです。)
この「次へ行っただけ」の発生条件はなんなのでしょうか?
(組み込み用語での)リアルタイムOSでいう「ディスパッチ」に当たる様な
事態を招いているのでしょうか? 換言すれは、
「Print文実行中である占有権を奪うような事象ってVBの世界に存在するのですか?
尚、
一つ一つのイベント処理は(特にUI部は私なりにある程度、下記の内容を見越して)
努めて軽く作っているつもりだったのですが‥。
それとも、MSComm1_OnComm()だけでも(十分に)重くなってしまっているのでしょうか?
因みに今回の通信プロトコルはPCからのポーリング方式ですので、
MSComm1_OnComm()内で次の送信の前にDoEventsすることは可能ではありますが、
(現在は一切使っていません)これで、タイマーイベントを走行させやすくできる
ものなのでしょうか?

> それは"Windows"だからです。"Windows"は"Window"の複数形ですし、"Window"
> は"Message"を"Queue"に置き、それを置かれた時刻とは「無関係」に処理して
> いくものだからです。
> # 中にはQueueに置かずに直接送られるMessageもありますが、スレッドを
> # 跨ぐ際にはそれでもQueueチェックが入ります。
>
はい。
> 簡単な例として、
> 1,Form1にTimer1を貼り付けて、Timer1.Intervalを250(ms)程度に設定しておく。
> 2,Timer1_Timerイベントプロシージャ中で
>   Caption = CStr(Now)
>   と記述し、コンパイルする。(P-CodeでもNative-CodeでもどちらでもOK)
> 3,コンパイルしたEXEを実行し、そのタイトルバー(Captionが出るところ)の
>   上にカーソルを合わせて、右ボタンを押しっぱなしにする。
> これだけで、Timerイベントが抑制されることが確認できます。
> # Timerイベントの元は、WM_TIMERメッセージ。
>
これそのものを実験した訳ではありませんが、これは納得させて頂けます。

> リアルタイムに反応することをアプリに要求するのならば、少なくとも
> その反応するスレッドは負担のかかるUserInterface(以降UIと略します)
> を保持するスレッドとは別のスレッドにするべきですよね。で、そういう
> アプリだと、VB6の機能のみでは作りにくいのが現状です。UIを持たない
> ActiveX EXEとして作るという手もありますが、それでもUIを持つEXEとの
> 通信がネックになります。
最後の部分、「UIを持つEXEとの通信がネック」とは、理論的には
「スレッド間でなんらかのハンドシェイクが必要になってくる」という意味ですね?

 VBの範囲に留まらず、Windowsプログラミングの極意の様な解説を頂きました。
(私にとっては。)
有難う御座いました。
(あとは、上記の現象が治まってくれれば‥。)

[ツリー表示へ]
タイトルRe: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11784
投稿日: 2008/03/16(Sun) 09:04
投稿者K.J.K.
> > > 因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
> > > そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」
> > > というトラブルを招いています。
> > それは、単に前のレコードが書き込まれずに次へ行っただけなのでしょう。
> (私としては、不意に核心をつかれた感じです。)
> この「次へ行っただけ」の発生条件はなんなのでしょうか?

そこもしくはそこ以前で例外が発生し、そのPrintステートメントが実行されなかった
もしくは失敗した、のでしょう。

例外発生以外では、命令文がスキップされることはないはずです。

> それとも、MSComm1_OnComm()だけでも(十分に)重くなってしまっているのでしょうか?
> 因みに今回の通信プロトコルはPCからのポーリング方式ですので、

OnCommイベントを使っているのならば、ポーリングは避けられませんか?
状態遷移を意識したイベントドリブンなコードにできないか模索してみては。
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9802/winsock/
などが参考になるかもしれません。(WinSockのAPI関数版でのサンプル)

ポーリングはMSCommやInet、WinSockコントロールでよく問題になりますので、
Googleなどで検索してみるといいかも知れません。
# 問題の根本は、前回記述したMessage処理との兼ね合いが主です。

> MSComm1_OnComm()内で次の送信の前にDoEventsすることは可能ではありますが、
> (現在は一切使っていません)これで、タイマーイベントを走行させやすくできる
> ものなのでしょうか?

送信ではほとんど関係がないでしょう。
イベントドリブンに徹するならば、DoEventsはほとんど必要になりません。
# そのコンポーネントが、そう作られているという条件下で、ですが。

> > リアルタイムに反応することをアプリに要求するのならば、少なくとも
> > その反応するスレッドは負担のかかるUserInterface(以降UIと略します)
> > を保持するスレッドとは別のスレッドにするべきですよね。で、そういう
> > アプリだと、VB6の機能のみでは作りにくいのが現状です。UIを持たない
> > ActiveX EXEとして作るという手もありますが、それでもUIを持つEXEとの
> > 通信がネックになります。
> 最後の部分、「UIを持つEXEとの通信がネック」とは、理論的には
> 「スレッド間でなんらかのハンドシェイクが必要になってくる」という意味ですね?

です。一方的にMessageを送り付けあうだけならばいいのですが、ActiveXの
場合は同期処理を行いますので、そこで片方の時計が止まるのに引きずられ
やすくなります。

こういうときはむしろ、昔ながらのDDE通信のがうまく行ったりしますが、
なにせデータ量や形、速度に制限がありすぎますし。
# API関数で直接行うのであれば、そうでもないけど、相当面倒。

[ツリー表示へ]
タイトルRe^2: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11786
投稿日: 2008/03/16(Sun) 09:54
投稿者BamChan
> > > > 因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
> > > > そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」
> > > > というトラブルを招いています。
> > > それは、単に前のレコードが書き込まれずに次へ行っただけなのでしょう。
> > (私としては、不意に核心をつかれた感じです。)
> > この「次へ行っただけ」の発生条件はなんなのでしょうか?
>
> そこもしくはそこ以前で例外が発生し、そのPrintステートメントが実行されなかった
> もしくは失敗した、のでしょう。
> 例外発生以外では、命令文がスキップされることはないはずです。
なるほど、明日、もう少し踏み込んで調べてみたいと思います。
確かに、現在は理由があって意図的に「On Error Resume Next」にしております。

(なにせ、この現象は、通信処理に約15mSec/1Byte、1Sec/csvファイル1レコード出力
のレートに対して、2〜3時間に1回発生、という頻度ですので、
事前の作戦立てに、結構検討を要しています。
先ずは、もう少しデータ収集をお待ち願えますでしょうか。

> > それとも、MSComm1_OnComm()だけでも(十分に)重くなってしまっているのでしょうか?
> > 因みに今回の通信プロトコルはPCからのポーリング方式ですので、
>
> OnCommイベントを使っているのならば、ポーリングは避けられませんか?
> :
> :
> 送信ではほとんど関係がないでしょう。
> イベントドリブンに徹するならば、DoEventsはほとんど必要になりません。
> # そのコンポーネントが、そう作られているという条件下で、ですが。
>
スミマセン、言葉が不十分でした。ここで言う「通信プロトコルのポーリング方式」とは、
MSCommのポーリング方式のことではなく、「PC側が送信しない限り、相手側が自発的に
送信してくることは無い」という「通信用語でのポーリング方式」のことです。
MSCommは仰せの通り、100%イベントドリブンの形で使っております。
 ですので、もし「MSComm1_OnComm()が重くなっている様であれば、
その間にタイマーイベントを拾い易くできないか?」と、
DoEventsの有効性をお聞きしたいのです。
(Byte型→String型に加え中間的にSingle演算などの編集とかやってますので。)

> > > リアルタイムに反応することをアプリに要求するのならば、少なくとも
> > > その反応するスレッドは負担のかかるUserInterface(以降UIと略します)
> > > を保持するスレッドとは別のスレッドにするべきですよね。で、そういう
> > > アプリだと、VB6の機能のみでは作りにくいのが現状です。UIを持たない
> > > ActiveX EXEとして作るという手もありますが、それでもUIを持つEXEとの
> > > 通信がネックになります。
> > 最後の部分、「UIを持つEXEとの通信がネック」とは、理論的には
> > 「スレッド間でなんらかのハンドシェイクが必要になってくる」という意味ですね?
>
> です。一方的にMessageを送り付けあうだけならばいいのですが、ActiveXの
> 場合は同期処理を行いますので、そこで片方の時計が止まるのに引きずられ
> やすくなります。
>
> こういうときはむしろ、昔ながらのDDE通信のがうまく行ったりしますが、
> なにせデータ量や形、速度に制限がありすぎますし。
> # API関数で直接行うのであれば、そうでもないけど、相当面倒。

なるほど、一々合点がいきます。本当に有難う御座います。

では、明日、実機にてデータ収集に努めます。

[ツリー表示へ]
タイトルRe^2: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11787
投稿日: 2008/03/16(Sun) 10:53
投稿者BamChan
> > > > 因みに、このPrint文では csv形式の1レコード(CR.LF付き)を書き込んでいますが、
> > > > そのレコードの途中で、前のレコードを潰して、次のレコードの先頭が書き込まれている」
> > > > というトラブルを招いています。
> > > それは、単に前のレコードが書き込まれずに次へ行っただけなのでしょう。
> > (私としては、不意に核心をつかれた感じです。)
> > この「次へ行っただけ」の発生条件はなんなのでしょうか?
>
> そこもしくはそこ以前で例外が発生し、そのPrintステートメントが実行されなかった
> もしくは失敗した、のでしょう。
>
> 例外発生以外では、命令文がスキップされることはないはずです。
>

一部、ウォッチされているかも知れない方へ、コーディング概要を明かしておきます。

Private Rec As String, Item(256) As String, Limit As Integer
 :
Timer1〜()        'インターバルは100mSec
    static cnt As Integer
    Dim i As integer
    if cnt >= 10 then
        cnt = 0
        Rec = Date & "," & Time & ","
        for i = 0 To Limit
            Rec = Rec & Item(i) & ","
        Next i
        On Error Resume Next
        Print #1, Rec
        On Error GoTo 0
    End If
End Sub

です。

<現象の復唱です>
この内容で、2〜3時間に1回くらいの頻度で、
n件目のレコードの文字列の途中で、(CR.LFも挿入されないまま)
n+1件目のレコードがDate/Timeから書き込まれてしまっています。
因みにこのファイルの拡張子は、*.csv ですが、
Excelだけでなく、MIFESなどテキストエディタでも参照しています。

以上、宜しくお願い致します。

[ツリー表示へ]
タイトルRe: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11788
投稿日: 2008/03/16(Sun) 12:59
投稿者K.J.K.
> この内容で、2〜3時間に1回くらいの頻度で、
> n件目のレコードの文字列の途中で、(CR.LFも挿入されないまま)
> n+1件目のレコードがDate/Timeから書き込まれてしまっています。

Item(i)に適切ではない文字列が入っている可能性を調べてみるとか。
# Printステートメントで取り扱うことのできない文字、という意味です。

[ツリー表示へ]
タイトルRe^2: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11795
投稿日: 2008/03/17(Mon) 10:20
投稿者BamChan
> Item(i)に適切ではない文字列が入っている可能性を調べてみるとか。
> # Printステートメントで取り扱うことのできない文字、という意味です。

<問題の部分の調査用変更>
下記の様に、暫定変更して、ランニング中です。
これで、現象を絞り込めると考えています。
Private OrgVal(256) As String
  :
    OrgVal(CrntNo) = ""        '逐次、全項目をHex文字列にして退避しておく
    For i = TblFact(CrntNo).Size - 1 To 0 Step -1
        If ch(i) = 0 Then
            OrgVal(CrntNo) = OrgVal(CrntNo) & "00"
        ElseIf ch(i) < 16 Then
            OrgVal(CrntNo) = OrgVal(CrntNo) & "0" & Hex(ch(i))
        Else
            OrgVal(CrntNo) = OrgVal(CrntNo) & Hex(ch(i))
        End If
    Next i
    OrgVal(CrntNo) = OrgVal(CrntNo) & "Z"  '"Z" をマークにしておく
  :
   Item(CrntNo) に対し、本来の編集を行う。 '(この中に問題の部分がありそう?)
  :
Private Sub Timer1_Timer()
    Dim i As Integer
    Rec = Date & "," & Time & ","
    Print #1, Rec;
    FOr i = 0 To Limit
        On Error GoTo ERR
        Print #1, Item(i);
        On Error GoTo 0
        Print#1, ",";
    Next i
    Print #1, ""          ' CR/LF を出力して、csvファイル1レコードとする
    Exit Sub
ERR:
    Print #1, OrgVal(i);  ' 本来の文字列の代わりに、Hex文字列を出力する。
    Resume Next
End Sub

これで、出力された.csv ファイルで、"Z"を検索すれば、どのItemにどの様な値が入力され
どの様な文字編集を行った際に、Printできなくなるか、が特定されると思います。
これで、結論に近づけると思います。

 色々、寄り道の多いやりとりになりましたが、私にとって意味深い寄り道でした。
本当に有難う御座いました。

[ツリー表示へ]
タイトル削除
記事No11801
投稿日: 2008/03/17(Mon) 20:37
投稿者GOD
削除

[ツリー表示へ]
タイトル削除
記事No11802
投稿日: 2008/03/17(Mon) 20:37
投稿者GOD
削除

[ツリー表示へ]
タイトルRe^3: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11803
投稿日: 2008/03/17(Mon) 20:37
投稿者GOD
単純に受信バッファがオーバーフローしていることはないですか?
また、Sleep関数を使用しているとかないですか。
提示されてるPGはファイル出力部しかないですが、バッファへの格納部は大丈夫ですか。
上記PGのタイマー部だけを動作させた場合でも同様のエラーは発生しますか。(1ファイ
ルの最大容量は2GBだったはず)

#DoEventsもあまり良くないが今回は使用していないということでいいんですよね。

[ツリー表示へ]
タイトルRe^3: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11823
投稿日: 2008/03/19(Wed) 09:01
投稿者BamChan
> > Item(i)に適切ではない文字列が入っている可能性を調べてみるとか。
> > # Printステートメントで取り扱うことのできない文字、という意味です。
>
> <問題の部分の調査用変更>
> Private OrgVal(256) As String
>   :
>     OrgVal(CrntNo) = ""        '逐次、全項目をHex文字列にして退避しておく
>     For i = TblFact(CrntNo).Size - 1 To 0 Step -1
>         If ch(i) = 0 Then
>             OrgVal(CrntNo) = OrgVal(CrntNo) & "00"
>         ElseIf ch(i) < 16 Then
>             OrgVal(CrntNo) = OrgVal(CrntNo) & "0" & Hex(ch(i))
>         Else
>             OrgVal(CrntNo) = OrgVal(CrntNo) & Hex(ch(i))
>         End If
>     Next i
>     OrgVal(CrntNo) = OrgVal(CrntNo) & "Z"  '"Z" をマークにしておく
>   :
>    Item(CrntNo) に対し、本来の編集を行う。 '(この中に問題の部分がありそう?)
>   :
> Private Sub Timer1_Timer()
>     Dim i As Integer
>     Rec = Date & "," & Time & ","
>     Print #1, Rec;
>     FOr i = 0 To Limit
>         On Error GoTo ERR
>         Print #1, Item(i);
>         On Error GoTo 0
>         Print#1, ",";
>     Next i
>     Print #1, ""          ' CR/LF を出力して、csvファイル1レコードとする
>     Exit Sub
> ERR:
>     Print #1, OrgVal(i);  ' 本来の文字列の代わりに、Hex文字列を出力する。
>     Resume Next
> End Sub
>
> これで、出力された.csv ファイルで、"Z"を検索すれば、どのItemにどの様な値が入力され
> どの様な文字編集を行った際に、Printできなくなるか、が特定されると思います。
> これで、結論に近づけると思います。
>
>  色々、寄り道の多いやりとりになりましたが、私にとって意味深い寄り道でした。
> 本当に有難う御座いました。

っと、事実上の収束宣言を出してしまいましたが、今度は上の例外事象が発生しなくなって
しまいました。ランニング時間は、上記の対処前の概ね発生間隔の倍時間を越えています。
更に、この部分以外のソースやハードも含めた環境は、一切変えていないつもりです。
(「見ようとすると現象が変わる」のは、組み込みではよく出会う事項ではありますが‥。)
 単に捉えると、「変更前ソースNo.11781の
 Rec = Rec & Item(i)
の1行が怪しい」、となるわけですが、まさか‥‥です。

確かに、RS232Cで繋いでいる相手から受信しているデータまでは「同じ」とは言い切れませんが、
そういう傾向の現象でも無さそうに思われます。

[ツリー表示へ]
タイトルRe^4: MSCommの動作実態と多重On Error文に関して教えて下さい。
記事No11837
投稿日: 2008/03/19(Wed) 15:21
投稿者BT6
> (「見ようとすると現象が変わる」のは、組み込みではよく出会う事項ではありますが‥。)

ファームだろうがソフトだろうが、実環境だけで評価を行うには限界がありますよね。
組込み分野なら任意波形発生器などで擬似データを入力したり、サーバの負荷テストならそれなりのツールで負荷をかけたり、、、

本件の場合はもっと単純で、他のPCなどから誤動作の可能性がある擬似データを網羅的に送信してみては如何ですか?

また、その前に、Printで書き込んでいる文字列に問題があるのなら、受信データを文字列に変換している関数をもう一度コード・レビューしてみては如何ですか?

[ツリー表示へ]
タイトル「シュレディンガーの猫」の首を絞めていたのは、私自身でした。
記事No11846
投稿日: 2008/03/21(Fri) 11:17
投稿者BamChan
 1レコード書き込みのPrintのまさにその時点で、Excelを読み出し専用にして
このファイルをアクセスした時に、
ご指摘のあった「例外事象」が働き、エラーハンドラへ飛んでいることが、判明しました。
因みに、Err.Numberは「70」でした。
「事象があったかどうか確かめる操作が、事象を起こしていたのです。」

 対策としてファイルポインタを戻す術もありませんので、
その1行は、コメントを付加&改行して、運用側で黙殺してもらい、
改めて、本来の1行をPrintすることで対処致しました。

 複数の皆さんに、ご助言を頂き、有難う御座いました。

「寄り道」の御話、有難かったです。(且つ、楽しかったです。)
又、ドン臭い質問をさせて頂くかと思いますが、今後とも宜しくお願い致します。

[ツリー表示へ]
タイトルRe: 「シュレディンガーの猫」の首を絞めていたのは、私自身でした。
記事No11858
投稿日: 2008/03/22(Sat) 00:19
投稿者GOD
>  対策としてファイルポインタを戻す術もありませんので、
>
Seekステートメントを使用すれば戻りますよ。

[ツリー表示へ]