4.7 各種の設定を変更・参照する
InternetSetOptionは、WinInetで通信を行うときの各種設定を変更するときに使います。例えば、HTTPサーバは常に応答を返すとは限りません。仮に接続先のHTTPサーバがダウンしていると、InternetConnectやHttpSendRequestあたりでプログラムが固まってしまうことがあります。しかし、InternetSetOptionでタイムアウト値を設定しておけば、このような予期せぬ不具合を防げます。

また、WinInetの現在の設定を確認するときは、InternetQueryOptionを使います。

参考までに、この技はAccess VBA以外に、Excelマクロなど他のVBAでも使用することができます。
API関数/InternetSetOptionを定義する
API関数を使うとき、まずはこの関数がどこにある・どんな関数であるかといった、この関数を使うための準備(API関数の宣言)が必要です。また、定義する場所はフォーム、モジュール、クラスモジュールの(General)(Declarations)です。

次の例は、API関数/InternetSetOptionを使うときの記述例です。API関数を使用するときは、ついでにAPI関数で使用する定数も定義しておきましょう。

'(General)(Declarations)へ記述します
Public Declare Function InternetSetOption _
            Lib "wininet.dll" _
          Alias "InternetSetOptionA" _
         (ByVal hInternet As Long _
        , ByVal lOption As Long _
        , ByRef sBuffer As Any _
        , ByVal lBufferLength As Long) As Integer

'lOption(オプションの種類/代表例)
Public Const INTERNET_OPTION_CONNECT_TIMEOUT As Long = 2 '接続タイムアウト
Public Const INTERNET_OPTION_RECEIVE_TIMEOUT As Long = 6 '受信タイムアウト
Public Const INTERNET_OPTION_SEND_TIMEOUT As Long = 5 '送信タイムアウト
Public Const INTERNET_OPTION_CONNECT_RETRIES As Long = 3 'リトライ回数
 ※決まり事なので、悩まずにコピペして使ってしまいましょう

この関数の戻り値には設定できたか、できなかったかが返ります。Trueが設定できた、Falseが設定できなかったを意味します。ただし、戻り値をCBool関数で変換してからTrue/Falseで判定しましょう。

 ◆InternetSetOptionの引数
ByVal hInternet As Long InternetOpenで取得したインターネットハンドルを指定します。
ByVal lOption As Long 設定するオプション種類(定数で定義した内容)を指定します。
ByRef sBuffer As Any オプションの設定値を指定します。
ByVal lBufferLength As Long sBufferに指定したデータの大きさ(バイト数)を指定します。
API関数/InternetSetOptionを定義する
API関数を使うとき、まずはこの関数がどこにある・どんな関数であるかといった、この関数を使うための準備(API関数の宣言)が必要です。また、定義する場所はフォーム、モジュール、クラスモジュールの(General)(Declarations)です。

次の例は、API関数/InternetQueryOptionを使うときの記述例です。API関数を使用するときは、ついでにAPI関数で使用する定数も定義しておきましょう。

'(General)(Declarations)へ記述します
Public Declare Function InternetQueryOption _
        Lib "wininet.dll" _
          Alias "InternetQueryOptionA" _
         (ByVal hInternet As Long _
        , ByVal lOption As Long _
        , ByRef sBuffer As Any _
        , ByRef lBufferLength As Long) As Integer

'lOption(オプションの種類/代表例)
':これ以外はInternetSetOptionと同じものを使う
Public Const INTERNET_OPTION_VERSION As Long = 40 'バージョン情報

'INTERNET_OPTION_VERSIONでバージョンを取得するときの構造体
Public Type WinInetDLLVersion
    lMajorVersion As Long
    lMinorVersion As Long
End Type
 ※決まり事なので、悩まずにコピペして使ってしまいましょう

この関数の戻り値には取得できたか、できなかったかが返ります。Trueが取得できた、Falseが取得できなかったを意味します。ただし、戻り値をCBool関数で変換してからTrue/Falseで判定しましょう。

 ◆InternetQueryOptionの引数
ByVal hInternet As Long InternetOpenで取得したインターネットハンドルを指定します。
ByVal lOption As Long 参照するオプション種類(定数で定義した内容)を指定します。
ByRef sBuffer As Any 取得したオプション値を保存する変数を指定します。
ByVal lBufferLength As Long sBufferに指定した変数の大きさ(バイト数)を指定します。
オプションを設定・参照する例
WinInetのオプションを設定・参照する例です。サンプルの内容は「4.2 HTTPサーバからの応答を取得する」をベースに、HTTPヘッダーの設定を追加する処理を加えています。

このサンプルでは、接続・送信・受信タイムアウト値の設定を行っています。このサンプルでは、これらの設定を一律15秒にしていますが、単位は1/1000秒のため設定した値は15000です。さらに、設定前後の変化が分かるように、InternetQueryOptionで設定前後の情報を取得しイミディエイトウィンドウに出力しています。

なお、オプション設定は(InternetSetOption)はプロシージャ「fcSetOption」で、オプションの参照(InternetQueryOption)は「sReadOption」行っています。

'変数の定義 ※(General)(Declarations)です
Private lngWinINet As Long 'インターネットハンドルの保存用
Private lngHttpHnd As Long 'HTTPハンドルの保存用
Private lngReqHnd  As Long 'HTTPリクエストハンドルの保存用
Private strBuffer  As String * 1024 'サーバからの応答保存用
Private lngLength  As Long '応答結果のデータ長


Sub prcHTTPQueryInfoSample()

    Dim lngRC As Long

    'インターネットサービスをオープンします
    lngRC = fcInternetOpen

    'オープンに成功したらHTTPサーバとの接続と切断を行います
    If lngRC = 0 Then

       Debug.Print "●変更前タイムアウト値"
       Debug.Print "INTERNET_OPTION_CONNECT_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_CONNECT_TIMEOUT)
       Debug.Print "INTERNET_OPTION_RECEIVE_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_RECEIVE_TIMEOUT)
       Debug.Print "INTERNET_OPTION_SEND_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_SEND_TIMEOUT)

       Call fcSetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 15 * 1000)
       Call fcSetOption(INTERNET_OPTION_RECEIVE_TIMEOUT, 15 * 1000)
       Call fcSetOption(INTERNET_OPTION_SEND_TIMEOUT, 15 * 1000)

       Debug.Print "◆変更後タイムアウト値"
       Debug.Print "INTERNET_OPTION_CONNECT_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_CONNECT_TIMEOUT)
       Debug.Print "INTERNET_OPTION_RECEIVE_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_RECEIVE_TIMEOUT)
       Debug.Print "INTERNET_OPTION_SEND_TIMEOUT"
       Call sReadOption(INTERNET_OPTION_SEND_TIMEOUT)

       'HTTPサーバへ接続します
       lngRC = fcHTTPConnect("www.uso-web-server.net")

       '接続に成功したらリクエストを初期化します
       If lngRC = 0 Then
          lngRC = fcHTTPOpenRequest("GET", "/cgi/test/get.cgi")
       End If

       'リクエストの初期化に成功したら、リクエストを送信します
       If lngRC = 0 Then
          lngRC = fcHTTPSendRequest
       End If

       'サーバからの応答を取得します(サーバ情報を取得する例)
       If lngRC = 0 Then
          lngRC = fcHTTPQueryInfo(HTTP_QUERY_SERVER)
          MsgBox Left(strBuffer, lngLength)
       End If

       'HTTPリクエストをクローズします
       Call fcHttpRequestClose

       'HTTPサーバから切断します
       Call fcHTTPDisConnect

    End If

    'インターネットサービスをクローズします
    Call fcInternetClose

End Sub


Sub sReadOption(pOption As Long)

    Dim lngTime As Long

    Call InternetQueryOption(lngWinINet, pOption, lngTime, LenB(lngTime))
    Debug.Print lngTime
    
End Sub


Function fcSetOption(pOption As Long, pValue As Long) As Long

    Dim lngRC As Long

    lngRC = InternetSetOption(lngWinINet, pOption, pValue, LenB(pValue))

    fcSetOption = CBool(lngRC)

End Function


Function fcHTTPQueryInfo(lngInfoLevel As Long) As Long

    Dim tmpIndex As Long

    lngLength = 1024 '初期値はstrBufferの長さ
    strBuffer = vbNullString '受け取り領域は必ず初期化すること
    tmpIndex = 0

    'APIの実行/サーバからの応答を取得
    Call HttpQueryInfo(lngReqHnd _
                     , lngInfoLevel _
                     , ByVal strBuffer _
                     , lngLength _
                     , tmpIndex)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPQueryInfo = Err.LastDllError

End Function


Function fcHTTPSendRequest() As Long

    'APIの実行/リクエストを送信
    Call HttpSendRequest(lngReqHnd _
                       , vbNullString _
                       , 0 _
                       , vbNullString _
                       , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPSendRequest = Err.LastDllError

End Function


Function fcHTTPOpenRequest(strMethod As String, strURL As String) As Long

    Dim tmpURL    As String * 255

    'URLは255バイトの固定長文字列で渡す
    tmpURL = strURL

    'APIの実行/リクエストを初期化
    lngReqHnd = HttpOpenRequest(lngHttpHnd _
                              , strMethod _
                              , tmpURL _
                              , "HTTP/1.1" _
                              , vbNullString _
                              , 0 _
                              , INTERNET_FLAG_RELOAD _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPOpenRequest = Err.LastDllError

End Function


Function fcHttpRequestClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngReqHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHttpRequestClose = Err.LastDllError

End Function


Function fcHTTPConnect(Server As String) As Long

    'APIの実行/HTTPサーバへ接続
    lngHttpHnd = InternetConnect(lngWinINet _
                              , Server _
                              , INTERNET_DEFAULT_HTTP_PORT _
                              , vbNullString _
                              , vbNullString _
                              , INTERNET_SERVICE_HTTP _
                              , 0 _
                              , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPConnect = Err.LastDllError

End Function


Function fcHTTPDisConnect() As Long

    'APIの実行/HTTPサーバから切断
    Call InternetCloseHandle(lngHttpHnd)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcHTTPDisConnect = Err.LastDllError

End Function


Function fcInternetOpen() As Long

    'APIの実行/インターネットサービスをオープン
    lngWinINet = InternetOpen(vbNullString _
                            , INTERNET_OPEN_TYPE_PRECONFIG _
                            , vbNullString _
                            , vbNullString _
                            , 0)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetOpen = Err.LastDllError

End Function


Function fcInternetClose() As Long

    'APIの実行/インターネットサービスをクローズ
    Call InternetCloseHandle(lngWinINet)

    'この関数の戻り値には、APIの処理結果コードを返します
    fcInternetClose = Err.LastDllError

End Function
 ※この他に、API関数を定義する必要があります。
 ※www.uso-web-server.net、www.uso-server.netは架空のドメイン名です。
Copyright(C) 1999-2006 結城圭介。 All rights reserved