SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

VBAでファイルをダウンロードする

Windows APIを使ってWebからファイルをダウンロードする

  • X ポスト
  • このエントリーをはてなブックマークに追加

まとめてファイルへ書き込む

 前ページの例では1024バイトごとにデータをダウンロードしファイルへ書き込んでいますが、ファイルへの書き込み回数が多いため非効率的です。ダウンロードしたデータをまとめて1度でファイルへ書き込む方法を紹介します。

 配列の先頭要素を「参照渡し」で渡すと配列全体のメモリアドレスを渡すことになると先ほど書きましたが、同様に、配列の途中の要素を「参照渡し」で渡すと、その要素のメモリアドレスが関数に渡されます。

 例えば、「Dim a(1 To 100) As Byte」と宣言された長さ100の配列aがある場合、a(51)を「参照渡し」で渡すと配列aの51バイト目のメモリアドレスを関数は受け取ります。これを利用して、ダウンロードしたデータをまとめて1度にファイルへ書き込むプログラムを作成します。

 なお、Declareステートメントは前項の例と同じなので割愛します。

動的配列を使ったサンプル2
Sub バナーのダウンロード2()
    'バナー画像のURL
    Const URL = "http://codezine.jp/img/banner/forlink/lbanner_l.gif"
    
    Dim s As String
    Dim FileName As String
    Dim FileNumber As Integer
    Dim hOpen As Long
    Dim hConnect As Long
    Dim buf() As Byte '動的配列
    Dim dwSize As Long
    Dim total As Long 'ダウンロード済みのデータのサイズ

    'WinInetを初期化
    hOpen = InternetOpen("Excel VBA", INTERNET_OPEN_TYPE_DIRECT, _
                         vbNullString, vbNullString, 0)

    'URLを開く
    hConnect = InternetOpenUrl(hOpen, URL, vbNullString, 0, _
                               INTERNET_FLAG_RELOAD, 0)

    total = 0
    ReDim buf(1 To 1000000) '十分な大きさの配列のサイズを確保する

    Do
        '1024バイトずつデータを取得する
        
        '配列のダウンロード済みのデータの次の要素を渡す
        InternetReadFile hConnect, buf(total + 1), 1024, dwSize
  
        'データ取得サイズが0になったら終了
        If dwSize = 0 Then
            Exit Do
        Else
            'ダウンロード済みのデータのサイズを計算していく
            total = total + dwSize
        End If
    Loop

    'ハンドルを開放
    InternetCloseHandle hConnect
    InternetCloseHandle hOpen
            
    '動的配列の大きさを再定義
    'Preserve を指定してデータが消えないようにする
    ReDim Preserve buf(1 To total)
    
    '保存する.gifファイルのパスを取得
    'マクロ含むExcelファイルと同じフォルダに保存する
    s = ThisWorkbook.FullName
    FileName = Left(s, InStrRev(s, "\", , vbBinaryCompare)) & _
               "banner2.gif"
    
    '保存用にファイルを開く
    FileNumber = FreeFile
    Open FileName For Binary Access Write As #FileNumber
    
    'ファイルへ書き込み
    Put #FileNumber, , buf
    
    'ファイルを閉じる
    Close #FileNumber

    '配列を消去
    Erase buf
End Sub

まとめ

 以上で説明を終わりますが、今回のバイト型(Byte)配列の使い方は、WinInet関数だけでなく他のメモリバッファを必要とするAPI関数でも利用できます。

 VBAでバイナリデータを扱うときに選択肢の1つとして検討してもよいでしょう。

 それでは。

参考資料

  1. Win32 インターネット拡張機能 (WinInet)」:MSDN
  2. InternetReadFile を使用してファイルを取り込む方法」:Microsoftサポートオンライン
  3. InternetReadFile インターネット上のファイルの読み込み」:MASAPICO's PAGE
  4. WinInet API で HTTP 上のデータを読む」:林道の鬼
  5. Wininet Programing

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

さなみ(サナミ)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/2149 2008/02/26 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング