VB6でActiveXファイルを作成し、データの送信はできるが受信データが取得できない問題の解決方法

このQ&Aのポイント
  • VB6でActiveXファイルを作成し、データの送信はできるが受信データが取得できない問題が発生しています。
  • CABファイルを作成してファイルをダウンロードすると、データの送信はできるが受信データが取得できない問題が発生しています。
  • Do - Loop処理を繰り返しているが、受信データが取得できない問題が発生しています。
回答を見る
  • ベストアンサー

MSComm; 必要なファイル、設定

VB6で、ActiveXファイルを作成しています。 デバッカーでは、問題なく動作します。 CABファイルを作成して、ファイルをダウンロードさせて動作させると データ送信は、できるのですが受信データが取得できません。 Do - Loop処理を繰り返しているようです。 必要なファイル、プロパティ設定などございますか? ご意見をお願いします。 CABの中身; TEST.OCX ASYCFILT.DLL COMCAT.DLL MSMASK32.OCX MSMSKjp.DLL MSPRPJP.DLL msstdfmt.dll MSSTKPRP.DLL MSVBVM60.DLL OLEAUT32.DLL OLEPRO32.DLL VB6JP.DLL MSComm1.CommPort = 1 MSComm1.Settings = "9600,N,8,1" MSComm1.PortOpen = True MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 '-----Outputプロパティによるデータ受信 MSComm1.Output = (STX) & "CMD" & (CR) '-----Inputプロパティによるデータ受信 Dim Buffer$ Do DoEvents If MSComm1.InBufferCount Then Buffer$ = Buffer$ & MSComm1.Input Select Case Buffer$ Case Chr(13) Exit Do Case Else End Select End If Loop

noname#187796
noname#187796

質問者が選んだベストアンサー

  • ベストアンサー
  • tsunji
  • ベストアンサー率20% (196/958)
回答No.5

あなたが書いたプログラムは30回forループした後受信バイト数に関わらず、すぐに抜けています。 なのでデータを受信しないことがあります。 30バイト受信するまで待つのであれば以下の方法にした方がいい。 Dim Buffer$ Do DoEvents Loop Until MSComm1.InBufferCount >= 30 Buffer$ = MSComm1.Input

noname#187796
質問者

お礼

ありがとうございました。

その他の回答 (4)

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.4

>1. >>DoEventsは高速で回るforループ内で使うと不具合の元なので注意してください。 >どのような不具合が考えられるのでしょうか? >DoEvents()は使用しないほうが良いのですか? どんな症状だったか忘れましたが、不具合は有りました。 >2. >申し訳ございません。 >下例で、先頭から30桁までのデータを取得したいのですができません。 >30桁目のデータは不定です。 >対策はございますか? > 不定というのがどういう意味なのかわかりませんが、 テキストデータ以外のバイナリデータをあつかうなら MSComm1.InputMode = comInputModeBinary を追加してください。

noname#187796
質問者

補足

返信が遅れて申し訳ございません。 扱うのはテキストデータだけです。 パーフォマンスを良くする為に、下例のように必要データだけを取りたいのですが1桁もデータ取得できません。 どこがいけないのでしょうか? ターミネータは、50桁目です。 MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 Dim Buffer$ Dim I As Integer For I = 0 To 29 DoEvents If MSComm1.InBufferCount Then Buffer$ = Buffer$ & MSComm1.Input End If Next

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.3

いつ受信するかわからない場合、タイマーイベントの中に受信ルーチンを書きます。 Buffer$はグローバル化し、送信前にBuffer$ = ""でバッファをクリアとタイマーを起動してから送信処理。 タイムアウトは、タイマーイベントに入った回数でカウントして、タイマーを停止しタイムアウト処理ルーチンを実行する。 イメージ的にはこんな感じ↓タイムアウト処理等は追加してません。 Private Buffer$ As String Private Sub Timer1_Timer() Dim i As Integer If MSComm1.InBufferCount <> 0 Then  Buffer$ = Buffer$ & MSComm1.Input  I = InStr(Buffer$, Chr(3))  Select Case i  Case i <> 0  Case Else  End Select End If End Sub あと、DoEventsは高速で回るforループ内で使うと不具合の元なので注意してください。

noname#187796
質問者

補足

ありがとうございました。 1. >DoEventsは高速で回るforループ内で使うと不具合の元なので注意してください。 どのような不具合が考えられるのでしょうか? DoEvents()は使用しないほうが良いのですか? 2. 申し訳ございません。 下例で、先頭から30桁までのデータを取得したいのですができません。 30桁目のデータは不定です。 対策はございますか? MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 Dim Buffer$ Dim I As Integer For I = 0 To 29 DoEvents If MSComm1.InBufferCount Then Buffer$ = Buffer$ & MSComm1.Input End If Next

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.2

通信プログラムの場合は、1バイト以上受信してもいいようにプログラムするのが基本です。 そのへんを考えてcase文を組み直した方がいい。 あとテキストボックスとか表示出来るのであれば、タイムアウト後に受信内容を表示するようにしておけば、どうしてダメなのかがわかるはず。 2.デバッガが良くて、というのはコンパイルしたとき最適化されるかというオプションにチェックが入っていると、ありえる話です。最適化をしない様にしてコンパイルしてみてください。

noname#187796
質問者

補足

ありがとうございました。 1. □通信プログラムの場合は、1バイト以上受信してもいいようにプログラムするのが基本です。 □文字を検索するのであればInstr関数を使うべき。 下例のようなすれば良いですか? Dim Buffer$ Dim i As Integer Do DoEvents If MSComm1.InBufferCount <> 0 Then Buffer$ = Buffer$ & MSComm1.Input I = InStr(Buffer$, Chr(3)) Select Case i Case i <> 0 Exit Do Case Else End Select End If If Timer > .....'1秒待ち Exit Do End If Loop 2. パフォーマンスを良くしたいのですが、InputLen = 0なので、一括受信して、1文字ずつコードを判定すれば良いのですか? イメージが湧かないのでサンプルコードなどございますか? ご意見をお聞かせ下さい。

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.1

Buffer$ = Buffer$ & MSComm1.Input Buffer$に受信文字列を格納しているのに、SelectでBuffer$を指定してCaseで1文字しか判定していない。 Buffer$にゴミが入っていたらその時点でアウト。 文字を検索するのであればInstr関数を使うべき。 またVBで待ちループするのであれば、timerイベントを使った方がいい。

noname#187796
質問者

補足

ありがとうございます。 説明不足で申し訳ございません、Timer()を使用して1秒待ちして、Do-Loopを抜けるようにしてあります。 1. コミとは、IsNullで定義しておけば良いでしょうか? Dim Buffer$ Do DoEvents If MSComm1.InBufferCount Then Buffer$ = Buffer$ & MSComm1.Input Select Case Buffer$ Case Chr(13) Exit Do Case IsNull Exit Do Case Else End Select End If Loop If Timer > .....'1秒待ち Exit Do End If 2. 分からないことが、1つございますので質問させてください。 デバッカーでは、問題なく動作します。 ボタンクリック後、実行するとデータ受信ができません。 ボタン関数中で、このデータ送受信の関数をコールすれば良いのでしょうか? この点、何かございますでしょうか? 以上 宜しくお願い致します。

関連するQ&A

  • MSCommについて

    ↓例の桁数、データブロックが不定で連続して受信されます。 最後の1桁は(ETX)です。 (STX)XXXXXX...(ETX)(STX)XXXXX...(FS)XXXXX...(ETX)(STX)XXXXX.......(FS)XXXX...............(ETX) すべての桁数、データブロックが対象なので一度に受信します。 1. 質問はInputプロパティで1桁ずつデータをREC変数に読み込んで、ある条件で、Loop分を抜けたいのですが、 VB6の定義方法がわかりません。 1-1.最後の(ETX)の読み込み 1-2.先頭30桁  MSComm1.InBufferCount = 0 MSComm1.InputLen = 1 Dim REC As String Do DoEvents If MSComm1.InBufferCount Then REC = REC & MSComm1.Input If ..... '最後の(ETX)の読み込み '先頭30桁 Exit Do End If   End If Loop 2. スピート重視で処理するために、InBufferCountに値があったら、すべての受信データをRECにいれたいのですが 取得できていません。 アドバイスはございますか? MSComm1.InBufferSize = 2048 MSComm1.InBufferCount = 0 MSComm1.InputLen = 0 Dim REC As String Do DoEvents If MSComm1.InBufferCount >= 1 Then Exit Do End If Loop REC = MSComm1.Input

  • MSCommのCommEventプロパティ

    質問させてください。 ↓コードで、通信エラーのイベントを取得したいのですが、COMポートは正常に機能しているのですが、comEvReceiveに正しい値(0)が 入らずにデータ受信ができません。 対策を教えていただけませんか? Dim Buffer As String Do '5桁受信するまで待機 DoEvents Loop Until MSComm1.InBufferCount >= 5 MSComm1.RThreshold = 1 Select Case MSComm1.CommEvent '通信ポートのチェック Case comEvReceive 'OK Buffer$ = MSComm1.Input Case Else 'NG ・ ・ End Select

  • データ送信

    MSCommのOutPutプロパティを使用して送信します。 Dim Buffer As String  Buffer = "Dummy" MSComm1.Output = Buffer RS-232C接続をしたデバイスにデータを送信します。 このとき、受信するデバイスがいないとMSComm1.Outputステートメントの処理に約4-5秒かかります。 これは仕様ですか? MSComm1.Iutputプロパティを含めて、タイムアウトに関して参考になるドキュメントやサイトがございましたら教えていただけませんか?

  • rs232cでの受信データ(mscomm)の受信方法VB6

    VB6で、シリアル通信プログラムを作っています。 機器からレスポンスが、02 00 44 03 61 62 63 03 72 0Dと9バイトくるのですが、 8バイト受信した後に、また、最後の0Dを1バイト目として受信しているので困っています。 on commイベントで以下のようにして受信データをテキストボックスに表示しているのですが、 Select Case MSComm1.CommEvent   Case comEvReceive       Dim Buffer() As Byte       Buffer() = MSComm1.Input       For t = 0 To 6 + Buffer(3)  ,BUffer(3)はデータ長です。       Text1.Text = Text1.Text & Hex$(Buffer(t)) & Chr(&H3A)       Next t 8バイト表示した後、1バイト受信が起こるので、Buffer(3)が範囲外となりエラーが起こります。 inputLenは0にしています。 この問題は解決するにはどうしたらよいでしょうか? 0Dは終了コードです。0Dを受信するまで、きちんと1バイトづづ格納していくなどというようにできたらよいのですが、、、 他にも簡単な方法があったらよいのですが、、、 よろしくお願いいたします。

  • コンポーネント’MSCOMM32.ocx’のエラー

    VB2010Expressをインストールして、 VB6.0のソフトを使おうとexeファイルをクリックしたら、 下記のエラーがでます。 どうしたらよいか、どなたかご存知ないでしょうか? おしえてください。どうぞよろしくお願いします。 【エラー表示内容】 コンポーネント’MSCOMM32.ocx’ またその依存関係の1つが適切に登録されていません。 ファイルが存在しないか不正です。 【試したこと】 1.窓の森より、VB6ランタイム(WinXP対応)をインストール 2.以下の方法でファイルを貼付け >また、実際必要なファイルは「MSCOMM32.OCX」という物なのですが、 >インターネット上からダウンロード出来ます。 >Googleで「MSCOMM32.OCX」、「DOWNLOAD」みたいな感じで >検索してファイルを落としてくださいね。 >そのファイルを「c:\windows\system32\」の中にコピーすれば完了です★

  • こんにちは、VBはじめたての初心者です。MSCommコマンドを利用して

    こんにちは、VBはじめたての初心者です。MSCommコマンドを利用してマイコンと 通信するプログラムを作成中なのですが、わからないことがあるので質問させていただきます。 public aub form_load() MSComm1.CommPort = 3 'ポート番号設定 MSComm1.Settings = "115200,N,8,1" '設定 MSComm1.PortOpen = True 'ポートオープン MSComm1.Handshaking = comNone 'フロー制御無し MSComm1.RTSEnable = False 'RTS制御無し MSComm1.RThreshold = 1 '1バイト受信毎にOnCommイベント発生 Dim txBuffer As String End sub 'テキストに表示した受信文字列を変数に格納、さらに必要な文字列だけ抽出する Private Sub botan_Click() txBuffer = Text2.Text x = InStr(1, txBuffer, "e" & vbCrLf, 1) txBuffer = Mid(txBuffer, x + 3, (Len(txBuffer) - (x + 2))) Text1.Text = txBuffer 'txBufferの内容確認用 End Sub Private Sub cmdr_Click() Text2.Text = "" MSComm1.Output = "r a0 s 00 j ff" & Chr(13) 'マイコンのデータを読み込むコマンド End Sub Private Sub MSComm1_OnComm() Select Case MSComm1.CommEvent Case comEvReceive Buffer = MSComm1.Input Text2.Text = Text2.Text & Buffer ・ ・ ・ End Select End Sub おおざっぱですがこのようなプログラムをつくりました。 目的は受信された文字列(テキストに表示)を変数に格納、さらに必要な文字列だけ抽出する ことなのですが、このプログラムだとデータを読み込むコマンドを送るボタンとそのデータを 変数に格納して必要な部分を抽出するボタンを二回押さなければならず面倒なので、botan_Click() の中の命令をそのままcmdr_Click()に入れたのですが、そうするとエラーが出てしまいます。 いろいろと試したのですがどうやらtxBufferの中に受信データが入ってくれないみたいです。 原因は何か。何かいい方法がないかアドバイスいただけたら幸いです。 やりたいことは、一回のボタンクリックで変数に受信データのほしいとこだけを格納させることです。 よろしくお願いします。

  • MSCOMM32.OCXがWinXPで使用不可

    VB6で開発を行っておりますが、Win98SE 及びWin2000ではOSがMSCOMM32.OCXを配布しておりましたが、WinXPでは、Windows\System 又はSystem32に入っておりません。 シリアルポートでのデータのやり取りを行いたいのですが、MSCOMM32.OCXは使用できないのでしょうか。 また、それにかわる部品はありませんでしょうか。 ちなみに、Win2000で配布しているMSCOMM32.OCXをWinXPのWINDOWS\SYSTEM32フォルダにコピーし、レジストリに登録しましたが、正常に動作(データのやり取り不可)しませんでした。

  • MSCommでoutputできない

    VB6.0でMSCommを用いてシリアル(レーダとつながってる)にデータを送りたいんですがどうもうまく送れません.outputしてすぐoutbuffercountをチェックしてもcnt=0(cntは下記プログラム参照)のままでバッファにちゃんとデータが送れていないのでは?と悩んでいます. なにが原因なんでしょうか?もしくは,他に送信バッファにデータが届いてるかどうかをチェックする方法などご存知でないでしょうか?よろしくおねがいします. MSComm1.CommPort = 2 MSComm1.InputMode = 1 MSComm1.InputLen = 0 MSComm1.Settings = "9600,N,8,1" MSComm1.RThreshold = 1 MSComm1.PortOpen = True MSComm1.InBufferCount = 0 MSComm1.OutBufferCount = 0 Dim s(16) As Byte   ’←以下のデータを送りたいんですが・・ s(0) = &H2 s(1) = &H0 s(3) = &HA s(4) = &H0 s(5) = &H20 s(6) = &H0 s(7) = &H53 s(8) = &H49 s(9) = &H43 s(10) = &H4B s(11) = &H5F s(12) = &H4C s(13) = &H4D s(14) = &H53 s(15) = &HBE s(16) = &HC5 For j = 0 To 16 MSComm1.Output = s(j) cnt = MSComm1.OutBufferCount Next j End Sub あと,レーザーの説明書に ・レーザーに送信する2バイト間の時間間隔は6msを超えないように ・レーザーに送信する2バイト間の最小時間は55μs以上としてください という記述があるんですが,これを満たしてないという可能性も疑ってます. どうやれば,この時間のタイミングで送れるんでしょうか? 長くなってすいません,なにかヒントなどおねがいします.

  • VB6.0のGPSシリアル通信について

    はじめまして。 VB6.0で、GPSシリアル通信を行っています。 シリアル設定は、MSComm1.Settings = "4800,n,8,1" にしています。 1秒毎にGPSデータは受信でき、すべて受信できています。 ただし、このGPSデータは、1秒間に下記のように6行分受信されます。 $GPRMC,131850,A,3603.5404,N,14008.5746, $GPGGA,131850,3603.5404,N,14008.5746, $GPGSA,A,3,27,09,02,05,21,29,10,15,,,, $GPGSV,3,1,11,27,27,193,33,09,13,199, $GPGSV,3,2,11,21,18,317,23,29,14,259,22, $GPGSV,3,3,11,07,01,033,00,18,00,295,00,28 そこで、上記6行分のデータのうち、初めの2行分だけを取り出したいと思っていますが、どうもうまくいきません。 どのようにすれば、初めの2行分だけを取り出すことができるでしょうか? 下記がソースです。 Private Sub MSComm1_OnComm() Dim Buffer1 As Variant Select Case MSComm1.CommEvent Case comEvReceive Buffer1 = MSComm2.Input If (InStr(Buffer1, "GPRMC")) Then Debug.Print Buffer1; Else (InStr(Buffer1, "GPGGA")) Then Debug.Print Buffer1; End If End Sub どなたか教えてください。 よろしくお願いします。

  • VB4のWin2000、WinXP対応

    VB4で作成したプログラムがWin2000やWinXPで実行できないようで 私もそのような環境を持ち合わせておらず困っています。 DLLファイルかOCXファイルの読み込みの際にエラーが起こるようなのですが 下記のファイルが各OSに対応しているかどうかおわかりになる方おられますか? もしくはファイルをいれる場所が悪いのでしょうか? また、対応させる手段はありますか? 1.VB4JP32.dll 96/03/09 2.VB40032.dll 96/01/12 3.MSCOMM32.ocx 98/06/24 4.COMCTL32.ocx 98/06/24 5.RICHTX32.ocx 96/03/09 6.TABCTL32.ocx 96/09/04 どうかよろしくお願いします。

専門家に質問してみよう