[[20140314170355]] 『エクセル VBA ソケット通信について』(VBA初心者) ページの最後に飛ぶ

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

 

『エクセル VBA ソケット通信について』(VBA初心者)

先輩方ご教授願います。

仕事でプレゼンに使う見本のプログラムをしているのですが
(本業は機械設計なので製品はプロにお願いするつもり)
FA機器とソケット通信をする所で困っています。

具体的にソケット通信でソケット接続は成功しています。
しかし、機器との通信部分でパソコンからコマンドとデーターを機器へ送信、
機器側で受信成功の返信を受信、次のコマンドとデーターを送信・・
のやり取りの部分でうまくいきません。送るのは送れますが、
受信がうまくできない状態です。

sendd(i)←機器を操作するコマンドとデーター
se(i) ←受信したデーターを格納

Dim i As Integer

        For i = 0 To 5
        Winsock1.senddata sendd(i)
        Winsock1.GetData se(i)
        MsgBox se(i)
Next i

(本来は、se(i)を検証してエラーなどを発生させるつもりですが確認用に
MsgBoxに表示させています。)

通信キャプチャーで確認するとちゃんと受信しているのですが、Msgboxには
表示がでません。また、時間的なものかとSleepを入れたりもしましたが、
変わりありませんでした。

原因と対策を教えてください。お願いします。

< 使用 アプリ:Excel2000、使用 OS:WindowsXP >


Excel2000でWinSockですか。

そもそも、ソケット通信は非同期であり、受信も決められたバイト数が一度に読めるわけでは
ありません。読めるところまで読み、続きを連結していき、区切りで1電文と解釈する、という
流れになります。

送りながら受けることを考えると、クラスモジュールにするのが必須かと思います。
どこかでWinSockの貼り方を見つけたのならば、コーディング例もあるはずですよ。
(???) 2014/03/14(金) 17:42


回答がありがとうございます。

分かる様な分からない様な感じです。
ネットで調べると

Private Sub Winsock_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strBuf As String
Winsock(Index).GetData strBuf
Text1.Text = "クライアントから「" & strBuf & "」を受信しました。"
Winsock(Index).SendData StrConv(strBuf, vbWide)

の様なサンプルプログラムを見つけてはいました。
しかし、これではモジュールを行ったり来たりする事になってしまうので
質問の様な形にしています。

クラスモジュールにするとは、上記をクラスモジュールにすると言う事でしょうか?
良く分からないので具体的に教えていただけると助かります。

(VBA初心者) 2014/03/17(月) 09:36


具体的にサンプルソースを作成するのは時間がかかるため、嫌です。
貴方の手元にある機器が、こちらでも使えるわけでもないし、
やりとりが長くなるのが目に浮かびます。

クラスを使ったサンプルも、探せば出てくるはずです。 機器メーカーが
提供するサンプルは無いのですか? 問い合わせ窓口はありませんか?

とりあえず、クラスにせずとも試せるはずなので、送信するブックと
受信するブック2つに分けてみるとか、1文字だけ送ってみるとか?
(???) 2014/03/17(月) 13:04


プログラム以前の話で、環境設定は適切でしょうか? IPアドレスやサブネットマスクは?
PC側のファイアウォールは? ポート番号は?

モニタでデータが飛んでいるところは見えるが、相手に届かない場合、受け側でそれが
受け取るべきデータではないと判断されている可能性は? 特にUDPの場合ですが。
(しかし、ソケット接続は成功、ということは、TCP/IPですかね?)
(???) 2014/03/17(月) 13:16


例えば、以下のページは参考になりませんか? クラスにせずとも、同期しながら
送って受けて…なら、これで十分に見えます。受信で何バイト受け取れるか判らないから
連結していって1つの電文にまとめる、とかも考慮されています。

http://homepage2.nifty.com/nonnon/Chinamini/20100001/20100301.html
(???) 2014/03/17(月) 13:25


皆様回答ありがとうございます。
私の説明が悪かったようで話がずれてしまいました。

まず、機器メーカーへは、サンプルお願いしてありますが現状出てきていません。
環境設定はちゃんとできています。受信部分のプログラムを変えれば受信もできます。
又、「http://homepage2.nifty.com/nonnon/Chinamini/20100001/20100301.html」ページを見て
元を作っていますのでこのページは知っています。

私が知りたい(したい)事は、上記HPの受信部分は
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Winsock1.GetData rdat
となっています。実行待ち状態でデーターが送られて来た時点でプロシージャが働く構造です。

例えばエクセルのボタン一つでFA機器をA⇒B⇒Cと動かそうとした場合
まず、A⇒Bコマンドを送信します。するとレスポンス(応答確認)が返信されて来るので
上記では、これを受信するために実行待ち状態にしなければなりません。

私の希望はボタン一つで、A⇒Bコマンド送信、レスポンス受信(レスポンスに異常が有れば停止)
B⇒Cコマンド送信、レスポンス受信(レスポンスに異常が有れば停止)、終了としたいのです。

ですので、データーを送信した後にデーターを受信、正常ならば次のデーター送信としたいので
すがgetdataだけではうまく受信できないので困っています。

説明分かり難くて申し訳ありませんが、なにとぞご教授よろしくお願いします。

(VBA初心者) 2014/03/17(月) 18:23


やりたいことは、実際のアプリと同等のことをExcelで実現したいのですね。そうなると、
やはりクラスモジュールへのコーディングになるでしょう。
(受信イベント時の割り込み先に、関数のアドレスが必要になるためです)

通信一般に、データを受信するとイベントが発生します。これは、相手がデータを送り始めると即発生するので、
データを読みにいくのが速いと、まだ相手が送り終わっていない状態になります。

なので、送る側は1回でも、受ける側は1回で受信完了するとは限らないので、データが無くなるまでデータを
連結しながら受信を繰り返す必要があります。

そして、上のサイトにあるサンプルの場合、プログラムを動かす前に、以下が必要です。

・VB6付属のMSWINSCK.OCXを参照設定(つまり、VisualStudio6.0のインストール)
・独自作成したNonComSck.ocx(上記サイトにダウンロードリンクあり。シェアウェア?)
・NonComSck.ocxのレジストリ登録(やり方はサイトに書いてますね)

これらが整ったならば、サンプルソースをExcelに貼って動かします。クライアント用とサーバ用がありますね。
なお、先頭に WithEvents とあるのが、受信イベント等を拾うための宣言であり、
これはクラスモジュールに記述する必要があります。たぶん、ソケット通信関連のプロシジャは
全てクラスモジュールに貼り、ボタンやシートのプロシジャはシートの方に貼るのでしょう。

なお、NonComSck.ocxを導入しなくとも、自分で全てコーディングすれば、MSWINSCK.OCXだけ
用意すれば実現可能ですが、コーディングはとても大変であり、私はそこまで暇じゃないわけです。
(???) 2014/03/18(火) 09:29


コメント返信:

[ 一覧(最新更新順) ]


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