
だいぶ以前に、VB6を使ってマニュアル片手にtcpやudpによるLAN内での双方向データ転送(チャットごっこ)ができるものを作った経験があります。
最近、Excel2010のVBAを使って当時のようなものを作ってみたいと考え、CQ出版の「VBAによるTCP/IPプログラミング入門」を購入しました。読んだ限りではなんとかなりそうに思ったのですが、その中で、「Winsockコントロールはプログラム開発し配布するためにはそのライセンスが必要でライセンスなしではWinsockコントロールを配置してダイアログを作成できない」という記述がありました。つまりはVB6などのライセンスがある環境でないと作り始めることができないようです。
幸いVB6はうちの古いパソコンに入っていますから、そちらに入っているExcelでWinsockコントロールを配置しただけのVBAファイルを作り、今のExcel2010に持って来て修正していくのであれば作業は可能らしいのですが、いずれは破棄するであろうパソコンに依存しないといけないという流れがしっくり来ません。
また、VB6を今の環境に移せば解決する話だとも思いますが、今後VBAは使ってもVB6を使うことはないだろうということと、容量等の事情から、できればこちらに入れるようなことはしたくありません。
必要に迫られてもいなく少々わがままな事情も合わせての話ですが、何か解決方法がありましたら提案・指摘などをお願いいたします。
No.1ベストアンサー
- 回答日時:
直接WinSockのDLLを使えば問題ありません。
DLLの関数は必ずクラスモジュール上で定義し、
インスタンス化してから使います。
'定数
Private Const AF_INET As Long = 2
Private Const SOCK_STREAM As Long = 1
Private Const IPPROTO_TCP As Long = 6
Private Const INVALID_SOCKET As Long = -1
Private Type sockaddr_in
アドレスファミリ As Integer
ポート番号 As Integer
IPアドレス As Long
予備(7) As Byte
End Type
'初期化
Private Declare Function WSAStartup Lib "WS2_32" _
(ByVal バージョン As Integer,データ As Byte) As Long
'クリア
Private Declare Function WSACleanup Lib "WS2_32" _
() As Long
'ソケット作成
Private Declare Function socket Lib "WS2_32" _
(ByVal アドレスファミリ As Long, ByVal ソケット形式 As Long, _
ByVal プロトコル As Long) As Long
'アドレス変換
Private Declare Function inet_addr Lib "WS2_32" _
(ByVal IPアドレス As String) As Long, _
'接続
Private Declare Function connect "WS2_32" _
(ByVal ソケット As Long, アドレス As sockaddr_in, _
ByVal アドレス長 As Long) As Long, _
'送信(文字列)
Private Declare Function sendA "WS2_32" Alias "send" _
(ByVal ソケット As Long, ByVal データ As String, _
ByVal データ長長 As Long, ByVal フラグ As Long) As Long, _
'送信(バイナリ)
Private Declare Function sendB "WS2_32" Alias "send" _
(ByVal ソケット As Long, データ As Byte, _
ByVal データ長長 As Long, ByVal フラグ As Long) As Long, _
'受信(バイナリ)
Private Declare Function recvB "WS2_32" Alias "send" _
(ByVal ソケット As Long, データ As Byte, _
ByVal データ長長 As Long, ByVal フラグ As Long) As Long, _
'ソケット閉鎖
Private Declare Function closesocket Lib "WS2_32" _
(ByVal ソケット As Long) As Long
サンプル
Public Sub サンプル()
Dim 戻り値 As Long
Dim ソケット As Long
Dim アドレス As sockaddr_in
'初期化する
ReDim データ(397) As Byte
戻り値 = WSAStartup(&H202, データ(0))
Erase データ '初期化で返されるデータは不要なので棄てる
If 戻り値 <> 0 Then
MsgBox "初期化エラー Code=" & Err.LastDllError
Exit Sub
End If
'必ずクリーンアップを通るよう制御する
Do
'TCPIPストリーム(HTTPやFTP用)のソケットを作る
ソケット = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
If ソケット = INVALID_SOCKET Then
MsgBox "ソケット作成エラー Code=" & Err.LastDllError
Exit Do
End If
'サーバに接続する
アドレス.アドレスファミリ = AF_INET
アドレス.ポート番号 = 23 '★FTPのポート番号
アドレス.IPアドレス = inet_addr("192.168.0.1")
戻り値 = connect(ソケット, アドレス, Len(アドレス))
If 戻り値 <> 0 Then
MsgBox "接続エラー Code=" & Err.LastDllError
Exit Do
End If
Dim コマンド As String
Dim 応答 As String
Dim 文字 As Byte
Do
'1バイトずつ受信する
戻り値 = recvB(ソケット, 文字, 1, 0)
'戻り値は受信バイト数なので0以下はエラー(切断)である
If 戻り値 <= 0 Then
MsgBox "受信エラー Code=" & Err.LastDllError
Exit Do
End If
応答 = 応答 & Chr(文字)
'FTPでは応答の末尾は改行なので、検出したらループを抜ける
If 文字 = 10 Then Exit Do
Loop
'その後はプロトコルに従い、sendやrecvでデータを送受信する
'ソケットを閉じる
closesocket ソケット
Loop Until True
WSACleanup
End Sub
実際のプログラム例はネットに沢山あります。
但し、殆どがC言語用なので、上記のようにVBに
定義して使います。
データ型はint→Long、WORD→Integer、char→StringまたはByte
ByVal/ByRefの使い分けは単に変数を使う所はByVal、*のある
ポインタならByRefです。
少し厄介なのが受信です。recvはブロック型で、指定バイト数を
受信するまで制御が戻りません。非ブロック型にするか、受信の
有無を調べるか、あるウィンドウに受信を通知してもらってから、
受信するようにします。この3個の方法でWindowsライクなのは
3番目ですが、VBAでは難しいので1番目の方法がよいでしょう。
クラスモジュールにする理由は障害発生時にDLL内部データが
破壊され、その後回復しないためです。標準モジュール内に
関数を定義すると、VBA空間にデータが残るため、プログラムから
解放する方法がありません。クラスモジュールで定義した場合は
クラスを解放(Set 変数 = Nothing)すればデータも解放されます。
次に新しいクラスのインスタンスを作ればDLLも新たにロードされ
るので、障害をひきずりません。
丁寧なソースまで載せていただきありがとうございます。
なかなか難易度は高そうですが、コメントしていただいてますので、比較しながらなんとかなりそうです。
どうもありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(開発・運用・管理) マイクロソフト製品のライセンス販売で困ってます 1 2022/06/30 19:52
- その他(Microsoft Office) ピボットテーブルへの集計フィールド挿入 1 2023/02/26 11:33
- C言語・C++・C# ActiveXコントロールを.NETにインポートできない??? 2 2023/05/02 02:50
- Visual Basic(VBA) VBA アドインについて お詳しい方 ご教授をお願いします。 相談事項 現在以下の対応を実施した所、 1 2022/11/02 16:53
- Visual Basic(VBA) M365環境での動作エラー、及び対応相談 1 2023/01/27 04:18
- Excel(エクセル) エクセル バーコード作成で他のシートを参照するには? 2 2023/05/03 16:57
- その他(パソコン・周辺機器) Windows10Proの正規ライセンスキーはどこで買える? 6 2023/04/03 15:36
- その他(Microsoft Office) Office(Windows版,Word/Excel/PowerPoint等)にログインできません 4 2022/07/24 15:18
- その他(データベース) Accessフォームからパラメーターで表示したレコードを指定のExcelのセルへ転送する方法について 2 2022/08/22 18:04
- Excel(エクセル) Excel 表の作成について 3 2022/06/16 12:15
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VMWare仮想ソケット数とソケッ...
-
中古品のグラボやCPUの動作チェ...
-
コピー機の電源コードをなくし...
-
シャープPC-XG50JのCPU交換
-
マイクロSDカードの抜き差し回...
-
コネクタ(D-sub、HDMIなど)の、...
-
CPUとマザーボードに詳しい...
-
10A-250Vの電源コード
-
PowerMac8600/250で、ロジック...
-
ソケットIDって何ですか?
-
ノートパソコンのCPU交換について
-
Windows11にバージョンアップす...
-
マザーボードを交換しようと思...
-
cpu交換 ryzenからintel
-
こちらのノートPCのグラボは交...
-
CPUの8世代と10世代はどうで...
-
ゲームにはi7?i5?
-
インテル(R) P55 Express チッ...
-
CPUの交換
-
CPUの交換手順について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VMWare仮想ソケット数とソケッ...
-
コネクタ(D-sub、HDMIなど)の、...
-
i5-2520Mをi7-2670QMに変えよう...
-
I7-4700 MQの互換性のあるCPUは?
-
丸ソケットの外し方
-
ExcelVBAでのwins...
-
中古品のグラボやCPUの動作チェ...
-
配管継手のバルブ用ソケットに...
-
マイクロSDカードの抜き差し回...
-
TCP/IPポートの最大接続数は
-
蛍光灯を壊してしまいました。...
-
初めまして、こんばんは。 DELL...
-
排水枡高さ調整アジャスター
-
EPROMに27C256ついて教えてくだ...
-
AM 4のソケットに ryzen の向き...
-
パソコンに繋いだイヤホンが抜...
-
PCIe 2.0のSSDをPCIe 3.0のソケ...
-
CPU換装 セレロン575 2GHz から
-
ソケットIDって何ですか?
-
デスクトップパソコンのCPU換装...
おすすめ情報