パソコン活用研究5番街(Visual Basic、Excel(VBA)、BASIC プログラミング研究)

VBアプリ実例集 (RS232C通信)その2

-----------------------------------------------------------------------------------------------
Visual BasicによるRS232C通信プログラム(自作のシリアル転送Ver0.2.0)のFORM3(Form3serial020.frm)
について解説します。ファイルの保存、入力、送信といった機能をFORM3に実装しておりまず。

シリアル通信の基本機能はFORM1に実装しており。FORM1の説明はVBアプリ実例集(RS232C通信)
あります

-----------------------------------------------------------------------------------------------


1 FORM3
1) デザイン

  


  「Drive」 はドライブリストボックス

  「Directory」はディレクトリリストボックス





  「File name」 はファイルリストボックス














2) コード

(1) 「保存」ボタン
Form1の送受信テキストエリアのテキストデータを、new File nameで指定されたファイル名(Text1.Text)
で保存します。

Private Sub Command1_Click()
fname$ = File1.Path + "\" + Text1.Text
Open fname$ For Output As #1
t$ = Form1.Text1.Text
a = Len(t$)
For i = 1 To a
b$ = Mid(t$, i, 1)
Print #1, b$;
Next
Close #1
Unload Form3
End Sub

(2) 「入力」ボタン
new File nameで指定されたファイルを、読み込みForm1の送受信テキストエリアに表示します。
バイナリーモードでファイルをオープンし、バイト型配列p( )に一挙にデータを読み込みます。
Get #1,,p()  で配列p()にファイルの全データをよみこみます。(*2の行)
ここで、 p() という記述は配列p 全体を表します。(旧Basicではこういう記述の仕方はできなかったので
旧Basicプログラマには理解しがたいコードかもしれません。VBのどの解説書にもこのコードの記述について
解説がないので、正確にはわかりませんが、この記述はC言語風に言えば、配列pのポインタ=先頭アドレス
を表していると解釈していいでしょう。)

その前に、ReDim p(1 To LOF(1)) でp()の配列の大きさをファイルサイズと同じに指定しています。(*1の行)
StrConv関数で読み込まれたデータp()を、Visual Basicで使用されている文字コード(Unicode)に変換し
Form1の送受信テキストエリアに表示します。(*3の行)

Private Sub Command2_Click()
Dim p() As Byte
fname$ = File1.Path & "\" & File1.filename
Open fname$ For Binary As #1
l = LOF(1)
ReDim p(1 To LOF(1))         ' *1
MsgBox ("File Size:" + Str$(l))
Get #1, , p()                ' *2


Form1.Text1.Text = StrConv(p(), vbUnicode)  ' *3
Close #1
Unload Form3
End Sub

(3) 「バイナリー保存」ボタン
バイナリーモード(Binary Mode)で受信したデータを保存します。
q()に受信データが格納されています。

Private Sub Command4_Click()
f$ = File1.Path + "\" + Text1.Text
Open f$ For Binary As #1

MsgBox Str(y)
For i = 0 To y - 1
Put #1, , q(i)
Next

Close #1
End Sub

(4) 「バイナリーファイル送信」ボタン
バイナリーファイルを送信します。
まず、バイト型配列f()の大きさをReDim f(1 To LOF(1))で決定し、f()にファイルを読み込みます。(*1の行)
Get #1,,f() という記述で、配列f()にファイル全体をいっぺんに読み込ますことができます。
このプログラムでは伝送バッファサイズ(OutBufferSizeプロパティで設定)は、デフォルトの512に
設定してあるので、512バイトづつ送信します。具体的には、512バイトづつ、配列g()にコピーして
Form1.MSComm1.Output=g() で送信しています。最後に、残った部分を送信します。

Private Sub Command5_Click()
Dim f() As Byte
Dim g() As Byte
fname$ = File1.Path & "\" & File1.filename
Open fname$ For Binary As #1
l = LOF(1)
ReDim f(1 To LOF(1))       ' *1
Get #1, , f()
k = 0
Do While l > 512
ReDim g(1 To 512)
For i = 1 To 512
g(i) = f(k * 512 + i)
Next
Form1.MSComm1.Output = g()
l = l - 512: k = k + 1
DoEvents
Loop
ReDim g(1 To l)
For i = 1 To l
g(i) = f(k * 512 + i)
Next
Form1.MSComm1.Output = g()

Close #1
Unload Form3
End Sub

(5) 「テキストファイル送信」ボタン
テキストファイルを送信します。(が、2バイト文字は文字化けします)
実際は、「バイナリファイル送信」で全て用が足りるので、あえてこの「テキストファイル送信」を
使う必要性はほとんどありません。
ちょっとわかりにくいコードになっていますが、ディレイ(text2.textの値)を設定し、その分送信に
ディレイをかけています。これは、旧型のPCとRS232C通信をする場合、旧型PCの処理能力が低い
ので、ディレイをかけてデータの処理まちをしてやる必要があるためです。

Private Sub Command3_Click()
Dim f(1) As Byte
fname$ = File1.Path & "\" & File1.filename
Open fname$ For Binary As #1
delay = Val(text2.Text) / 100
i = 0: text3.Text = Str$(i)
Do Until EOF(1) = True
Get #1, , f(1)
Form1.MSComm1.Output = Chr$(f(1))
start = Timer
L2:
If Timer - start > delay Then
GoTo L1
Else
GoTo L2
End If
L1:
i = i + 1
If i Mod 20 = 0 Then DoEvents
text3.Text = Str$(i)
Loop
Close #1
Unload Form3
End Sub

(6) 「データファイル転送」ボタン
カンマ( , )でデータが区切られたシーケンシャルデータファイルを転送します。
この「データファイル転送」は受信側は主に旧Basicで作成されたプログラムを想定しています。
データの読み込みは Input #1, f$ で行い、送信は Form1.MSComm1.Output = f$ + Chr$(13) で
行います。送信の最後にChr$(13) (CRコード)を付加しているのは、旧Basicでは通常CRコードを受信すると
ひとつのデータとして受信バッファから変数に読み込むようになっているためです。(各Basicの仕様を確認
して下さい。)

その他、ディレイの部分は「テキストファイル転送」と同じです。

Private Sub Command6_Click()
'旧Basicにデータ送信するための特別なルーチン
fname$ = File1.Path & "\" & File1.filename
Open fname$ For Input As #1
delay = Val(text2.Text) / 100
i = 0: text3.Text = Str$(i)
Do Until EOF(1) = True
Input #1, f$
Form1.MSComm1.Output = f$ + Chr$(13)
start = Timer
L2:
If Timer - start > delay Then
GoTo L1
Else
GoTo L2
End If
L1:
i = i + 1
If i Mod 20 = 0 Then DoEvents
text3.Text = Str$(i)
Loop
Close #1
Unload Form3
End Sub

(7) ドライブリストボックス、ディレクトリリストボックス、ファイルリストボックス
ファイル名を指定するお決まりのコードです。

Private Sub Drive1_Change()
Dir1.Path = Drive1.Drive
End Sub

Private Sub Dir1_Change()
File1.Path = Dir1.Path
End Sub

Private Sub File1_Click()
Text1.Text = File1.filename
End Sub


TopPage/Visual Basic&Excel活用研究目次