2010-03-07
Excel VBAでメッセージ送信を行うWinsockクライアント「clsWinsockClient」
目次
- 概要
- 事前準備
- 使い方
- ソースコード
- サンプル
- 参考
概要
Excel VBAでメッセージ送信を行うWinsockクライアント「clsWinsockClient」を作成しました。
clsWinsockClientを利用すると、別途作成したWinsockサーバ「clsWinsockServer」に対してメッセージを送信できます。
事前準備
本クライアントを使用するには、以下の手順で「Microsoft Winsock Control 6.0」への参照設定を追加する必要があります。
- Visual Basic Editorの「ツール」メニューから「参照設定」ダイアログを開きます。
- 参照設定ダイアログ上の「参照」ボタンを押し、「ファイルの参照」ダイアログを開きます。
- ファイルの参照ダイアログで「c:\Windows\system32\MSWINSCK.OCX」を選択し、「開く」ボタンを押します。
- 参照可能なライブラリファイルに「Microsoft Winsock Control 6.0」が追加されたことを確認し、「OK」ボタンを押します。
使い方
clsWinsockClientをクラスモジュールとしてプロジェクトに追加し、標準モジュール等から以下のように利用します。
'// 1. Winsockクライアントを生成する。
Set wkClient = New clsWinsockClient
'// 2. メッセージを送信する。
If wkClient.SendMessage("192.168.1.20", 1500, "Test Message", wkDescription) = 9 Then
'// エラー時の処理:
Call MsgBox("メッセージ送信に失敗しました。(" & wkDescription & ")", vbCritical)
Exit Sub
End If
Call MsgBox("メッセージ送信に成功しました。", vbInformation)
1. Winsockクライアントを生成する。
まず最初に、Newを使ってclsWinsockClientのインスタンスを生成します。
2. メッセージを送信する。
メッセージを送信するには、clsWinsockClientのインスタンスのSendMessageメソッドを呼び出します。
SendMessageメソッドの1番目から3番目の引数は入力値です。1番目に送信先のIPアドレス、2番目に送信先のポート番号、3番目にメッセージを指定します。
上記の例の場合、IPアドレス「192.168.1.20」のポート番号「1500」に対してメッセージ「Test Message」を送信します。
4番目の引数は出力値で、メッセージ送信結果の詳細が格納されます。そのため、4番目の引数には変数を指定する必要があります。
SendMessageメソッドの戻り値はメッセージ送信の成功・失敗を表します。成功した場合には「0」が、失敗した場合には「9」が返却されます。
ソースコード
以下、clsWinsockClientのソースコードです。
clsWinsockClientクラスモジュール
Option Explicit
Private WithEvents mdl_winsock_client As Winsock '// ソケット
Private mdl_arrived_data As String '// 受信データ
'//////////////////////////////////////////////////////
' クラス初期化時の処理
'//////////////////////////////////////////////////////
Private Sub Class_Initialize()
'// ソケットを生成する。
Set mdl_winsock_client = New Winsock
End Sub
'//////////////////////////////////////////////////////
' SendMessage
' 概要 : メッセージを送信する。
' 引数 : IN :(String) i_remote_host 接続先ホスト
' IN :(Intger) i_remote_port 接続先ポート番号
' IN :(String) i_message メッセージ
' OUT:(String) o_description 送信結果の詳細
' 戻り値: 正常時: 0、エラー時: 9
'//////////////////////////////////////////////////////
Public Function SendMessage(i_remote_host As String, i_remote_port As Integer, i_message As String, o_description As String) As Integer
Dim wkEndTime As Date '// タイムアウト時刻
Dim wkResult As Integer '// 処理結果(-1: タイムアウト、0: 成功、1: エラー)
On Error GoTo ERR_PROC
SendMessage = 9
'//////////////////////////////////////////////////////
' ソケットの接続先を設定する。
'//////////////////////////////////////////////////////
'// 接続先のIPアドレスを設定する。
mdl_winsock_client.RemoteHost = i_remote_host
'// 接続先のポート番号を設定する。
mdl_winsock_client.RemotePort = i_remote_port
'//////////////////////////////////////////////////////
' ソケットの接続要求を行う。
'//////////////////////////////////////////////////////
'// ソケットの接続要求を行う。
Debug.Print "ソケットの接続要求を行います。"
Call mdl_winsock_client.Connect
'//////////////////////////////////////////////////////
' 接続が完了したことを確認する。
'//////////////////////////////////////////////////////
'// 処理結果をタイムアウトに初期化する。
wkResult = -1
'// 接続が完了したことを確認する。
'// ただし、一定時間経過しても接続が完了しない場合はタイムアウトとする。
wkEndTime = Now() + TimeValue("00:00:03")
Do While Now() < wkEndTime
'// OSに制御を移し、接続処理を実行させる。
DoEvents
If mdl_winsock_client.State = sckConnected Then
'// 接続完了:
'// 処理結果を成功にする。
wkResult = 0
Exit Do
End If
If mdl_winsock_client.State = sckError Then
'// 接続エラー:
'// 処理結果をエラーにする。
wkResult = 1
Exit Do
End If
Loop
If wkResult = -1 Then
'// タイムアウト:
Debug.Print "接続要求でタイムアウトしました。"
o_description = "接続要求でタイムアウトしました。"
GoTo END_PROC
End If
If wkResult = 1 Then
'// エラー:
Debug.Print "接続要求でエラーが発生しました。"
o_description = "接続要求でエラーが発生しました。"
GoTo END_PROC
End If
Debug.Print "接続要求に成功しました。"
'//////////////////////////////////////////////////////
' メッセージを送信する。
'//////////////////////////////////////////////////////
'// サーバからの返信をリセットする。
mdl_arrived_data = ""
'// メッセージを送信する。
Debug.Print "メッセージを送信します。"
Call mdl_winsock_client.SendData(i_message)
'//////////////////////////////////////////////////////
' メッセージ送信の結果を確認する。
'//////////////////////////////////////////////////////
'// 処理結果をタイムアウトに初期化する。
wkResult = -1
wkEndTime = Now() + TimeValue("00:00:03")
Do While Now() < wkEndTime
'// OSに制御を移し、送信処理を実行させる。
DoEvents
If mdl_arrived_data <> "" Then
'// サーバからの返信を受信:
'// 処理結果を成功にする。
wkResult = 0
Exit Do
End If
If mdl_winsock_client.State = sckClosing Then
'// メッセージ送信中に接続先がクローズ:
'// 処理結果をエラーにする。
wkResult = 1
Exit Do
End If
Loop
If wkResult = -1 Then
'// タイムアウト:
Debug.Print "メッセージ送信でタイムアウトしました。"
o_description = "メッセージ送信でタイムアウトしました。"
GoTo END_PROC
End If
If wkResult = 1 Then
'// エラー:
Debug.Print "メッセージ送信に失敗しました。"
o_description = "メッセージ送信に失敗しました。"
GoTo END_PROC
End If
Debug.Print "メッセージ送信に成功しました。"
o_description = "メッセージ送信に成功しました。"
SendMessage = 1
GoTo END_PROC
ERR_PROC:
o_description = Err.Description
Debug.Print Err.Description
END_PROC:
'//////////////////////////////////////////////////////
' ソケットを切断する。
'//////////////////////////////////////////////////////
Debug.Print "ソケットをクローズします。"
Call mdl_winsock_client.Close
'// OSに制御を移し、クローズ処理を実行させる。
DoEvents
End Function
'//////////////////////////////////////////////////////
' 接続先からデータを受信した時の処理
'//////////////////////////////////////////////////////
Private Sub mdl_winsock_client_DataArrival(ByVal bytesTotal As Long)
'// サーバから受信したデータを取得し、受信データ用変数に格納します。
Call mdl_winsock_client.GetData(mdl_arrived_data)
End Sub
'//////////////////////////////////////////////////////
' 接続先からソケットをクローズされた時の処理
'//////////////////////////////////////////////////////
Private Sub mdl_winsock_client_Close()
'// ソケットをクローズする。
Debug.Print "接続先からソケットをクローズされたため、ソケットをクローズします。"
Call mdl_winsock_client.Close
'// OSに制御を移し、クローズ処理を実行させる。
DoEvents
End Sub
'//////////////////////////////////////////////////////
' ソケット通信中にエラーが発生した時の処理
'//////////////////////////////////////////////////////
Private Sub mdl_winsock_client_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
'// ソケットをクローズする。
Debug.Print "ソケット通信中にエラーが発生したため、ソケットをクローズします。"
Call mdl_winsock_client.Close
'// OSに制御を移し、クローズ処理を実行させる。
DoEvents
End Sub
サンプル
clsWinsockClientを使用するサンプルを作成しました。このサンプルはエクセルシートと標準モジュールで構成されています。
エクセルシート
接続先ホスト名、接続先ポート番号、メッセージを入力してメッセージ送信ボタンを押すと、メッセージを送信できます。
なお、メッセージ送信ボタンに標準モジュールのSendMessage関数を関連付けています。
標準モジュール
Option Explicit
'//////////////////////////////////////////////////////
' メッセージを送信する。
'//////////////////////////////////////////////////////
Public Sub SendMessage()
Dim wkSheet As Worksheet '// シート(Winsockクライアントプログラム)
Dim wkHostName As String '// 接続先ホスト名
Dim wkPort As Integer '// 接続先ポート番号
Dim wkMessage As String '// メッセージ
Dim wkClient As clsWinsockClient '// Winsockクライアント
Dim wkDescription As String '// メッセージ送信結果の詳細
'// シートを取得する。
Set wkSheet = ThisWorkbook.Sheets("Winsockクライアントプログラム")
'// 接続先ホスト名を取得する。
wkHostName = wkSheet.Cells(4, 4)
'// 接続先ポート番号を取得する。
wkPort = wkSheet.Cells(6, 4)
'// メッセージを取得する。
wkMessage = wkSheet.Cells(8, 4)
'// Winsockクライアントを生成する。
Set wkClient = New clsWinsockClient
'// メッセージを送信する。
If wkClient.SendMessage(wkHostName, wkPort, wkMessage, wkDescription) = 9 Then
'// エラー:
Call MsgBox("メッセージ送信に失敗しました。(" & wkDescription & ")", vbCritical)
Exit Sub
End If
Call MsgBox("メッセージ送信に成功しました。", vbInformation)
End Sub
参考
- 300 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cts=1331474110887&ved=0CCkQFjAA&url=http://d.hatena.ne.jp/nattou_curry_2/20100307/1267971499&ei=la5cT_u4JYOJmQXApfD-DQ&usg=AFQjCNHjf5mwvCAyyC-_b6xp8LGzgthGiA&sig2=7aNbJSASXR5HoV9
- 264 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1461979074
- 245 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGLL_jaJP356JP356&q=VBAでwinsock32を使用する
- 180 https://www.google.co.jp/
- 165 http://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&frm=1&source=web&cd=1&cts=1331095840170&sqi=2&ved=0CC0QFjAA&url=http://d.hatena.ne.jp/nattou_curry_2/20100307/1267971499&ei=GulWT7rYB-XWmAWAzZjhCQ&usg=AFQjCNHjf5mwvCAyyC-_b6xp8LGzgthGiA&sig2=E1m
- 94 http://www.google.co.jp/url?sa=t&rct=j&q=vba+ソケット通信&source=web&cd=2&ved=0CDAQFjAB&url=http://d.hatena.ne.jp/nattou_curry_2/20100307/1267971499&ei=vl_UTurWHevTmAXO5cVx&usg=AFQjCNHjf5mwvCAyyC-_b6xp
- 86 http://www.google.co.jp/url?sa=t&rct=j&q=エクセル ソケット通信&source=web&cd=2&ved=0CC8QFjAB&url=http://d.hatena.ne.jp/nattou_curry_2/20100307/1267971499&ei=2JerTtLA
- 83 http://www.google.co.jp/url?sa=t&rct=j&q=VBA+WINSOCK&source=web&cd=1&ved=0CCQQFjAA&url=http://d.hatena.ne.jp/nattou_curry_2/20100307/1267971499&ei=CfbKTsyvBajYmAWp0NzNDQ&usg=AFQjCNHjf5mwvCAyyC-_b6xp8LGzgthGiA
- 78 http://search.yahoo.co.jp/search?p=エクセル VBA winsock&search.x=1&fr=top_ga1_sa&tid=top_ga1_sa&ei=UTF-8&aq=&oq=
- 66 http://search.yahoo.co.jp/search?p=vba+ソケット&tid=top_ga1_sa&ei=UTF-8&pstart=1&fr=top_ga1_sa&b=11






