初めて投稿します。よろしくお願いします。
現在、MScommを使用して2次元バーコードのデータを受信する、というプログラムを組んでいるのですが、受信データの表示でつまずいています。
初期設定は以下の通りです。
MSComm1.CommPort = 2 'ポートの指定
MSComm1.Settings = "38400,N,8,1" '通信条件
MSComm1.InputMode = comInputModeText 'テキストで受信
MSComm1.Handshaking = comRTS 'ハンドシェイク有り
MSComm1.RThreshold = 1
MSComm1.InputLen = 0 'Input で受信バッファから全バイト取得
MSComm1.PortOpen = True 'ポートオープン
そして、受信したデータの表示部分は以下の通りです。
受信データの例:田中n東京都j....
Dim Str_Data As String,Data As String, Buffer As String
Dim Num As Integer
If MSComm1.CommEvent = comEvReceive Then
Buffer = MSComm1.Input
Data = Data & Buffer
'名前の取得と表示
Num = InStr(Data, "n")
Str_Data = Left(Data, Num - 1)
txtname.Text = Str_Data
Data = Mid(Data, Num + 1)
'住所の取得と表示
Num = InStr(Data, "j")
Str_Data = Left(Data, Num - 1)
txtjusho.Text = Str_Data
Data = Mid(Data, Num + 1)
.
.
End If
Dataの中に受信データが格納されてくれません。しかも、まったく格納されない時と、受信データの半分ほどを格納する時があり、非常に不安定です。
さらに、If MSComm1.CommEvent = comEvReceive Then の箇所で
ブレークポイントを打ち、データを追っていくとエラーが出ません。
データを追っても解決できないのは始めての事で、途方に暮れています。
どなたか、問題の原因・解決策をご存知の方がいらっしゃったら
ご教授お願い致します。よろしくお願いします。
長文失礼しました。
これはループ内の処理でしょうか?
受信バッファに1バイト以上入ったら,CommEvent = comEvReceiveなので,
ループにしないと,1発で「田中n東京都j....」を受信できることは,
まずないと思います.
Ifの行でブレークすると,止まっている間に1行分を受信できるので,
期待通りの動きになるのではないでしょうか?
ピントはずれだったらごめんなさい.
宇治金時さん、レスありがとうございます。
私の考えも宇治金時さんと同じです。
そして、お察しの通りこれはループではありません。
プログラムを実行させた時、
Dim a as integer
a=MSComm1.InBufferCount
の形で格納されている値を調べたところ、
aには8、MSComm1.InBufferCountには116
と入っていました。
受信データの総バイト数は124バイトです。
この時点で、ループさせなくては駄目なのかな?
と思い、いろいろ試してみているのですが
結局できないまま現在にいたります。
ループさせなくてはいけないことはわかっているのですが、
どのような条件でループさせればいいのかがわかりません。
もし何か良い方法をご存知でしたら、
ぜひ、ご教授お願い致します。
追記:
以下は私なりに考えて作ってみたものです。
受信データの例:田中n東京都j....
If MSComm1.CommEvent = comEvReceive Then
a:
If MSComm1.InBufferCount = 0 Then
GoTo b
Else
buffer = MSComm1.Input
Data = Data & buffer
If MSComm1.CommEvent = comEvReceive Then
GoTo a
End If
End If
End If
b:
Dim Str_Data As String
Dim Num As Integer
'名前の取得と表示
Num = InStr(Data, "n")
Str_Data = Left(Data, Num - 1)
txtname.Text = Str_Data
Data = Mid(Data, Num + 1)
'住所の取得と表示
Num = InStr(Data, "j")
Str_Data = Left(Data, Num - 1)
txtjusho.Text = Str_Data
Data = Mid(Data, Num + 1)
.
.
Data = ""
Num = 0
Str_Data = ""
buffer = ""
といった感じです。
初回起動時はエラーなく通ることが多いのですが、
2回目以降ほとんど通ってくれません。
'こんばんは
'最近ここを見つけて始めて投稿します。
'私もMSComm1を勉強中の身の上です。
'イベントドリブン方式でしょうか?
'1 回目を受信した後すこし時間をおいて再度受信してみたらどうでしょう
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'省略
If MSComm1.InBufferCount <> 0 Then
buffer = MSComm1.Input
Data = Data & buffer
Sleep 500 '単位ミリ秒 この時間プログラムが停止します。
buffer = MSComm1.Input
Data = Data & buffer
End If
MsgBox Data
'もしOKならタイマー(Timer1)を貼り付けるとかで・・・・・
一連の文字列に区切りがありますか?たとえばCRが入っているとか?
もしあるのなら,こんな感じでどうでしょう.
Start:
Do 'とりあえずループで一行分を受信
DoEvents 'おまじない
If MSComm1.CommEvent = comEvReceive Then
Buffer = MSComm1.Input
Data = Data & Buffer '受信した文字列のかけらをどんどんつないでいく
Loop Until InStr(Data, vbCR)<>0 '最終文字かどうかチェック
'---ここにデータ処理を記述
GoTo Start
単純にするとこんな感じでは?
一行分をまとめて受信してから,
文字列を切り出して,各データを変数に格納
これはLeft関数や,Mid関数でできますね.
で,これらの処理が終了したら,
再度Doに戻って,次の受信データを取得したらどうでしょう.
それから,最終文字が無い場合は,
Loop Until InStr(Data, vbCR)<>0 '最終文字かどうかチェック
を文字数を数えるなどの方法でもいいんじゃないでしょうか.
Loot Until Len(Data)>=10 '1データが10文字の場合
>= を = とすると,無限ループから脱出不能になるのでご注意を!
DoEventsはおまじないです.
これがないとループから脱出不可能になる可能性があります.
おまじないとして入れておくように本に書いてありました.
頑張ってください!!
とろろジョージさん、宇治金時さん、こんな丁寧なレスを書いて頂き
本当にありがとうございます!!
今日は別の予定がありまして、VBをいじれないので
明日さっそく試したいと思います!
結果などは後日またカキコします。
本当にありがとうございます!!!
無事解決しました!
とろろジョージさん、宇治金時さんのどちらの方法でも
プログラムは通ってくれました。
今回は、二次元バーコードのサイズを少しでも
小さくしたいという考えがありましたので
とろろジョージさんの方法を使わせて頂きます。
とろろジョージさん、宇治金時さん
本当にありがとうございましたm(_ _)m
本気で助かりました!!
ツイート | ![]() |