インターネットからファイルやデータのダウンロードを行うには

VBAを使ってインターネットのデータをダウンロードする方法にはいくつかあります。

ここで紹介するWin32APIを使う方法や、WshShellやShell関数で他アプリケーションを呼び出す方法や、InternetExplorerの仕組みを利用する方法や、XMLHTTPRequestを利用したりなど様々です。

それぞれ一長一短がありますが、一般的にブラウザで行う「右クリック+名前を付けて保存」でのファイルダウンロードと同じ動作をVBAで一番簡単に実現できるWin32APIでの方法を紹介します。

なお、高速にダウンロードしたい場合や、よりカスタマイズしたい場合などはVBAではなくC#やPythonやPHPなどを利用した方がよいと思われますので、そちらを探してみてください。

実際私自身もネットから必要なデータを落とすプログラムを作っていますが、圧倒的にコーディングがラクなのと結果的に高速に動作することからC#のSystem.Netクラスで実装することが多いです。

サーバ負荷を増大させるような連続アクセスは控える

インターネットからファイルをダウンロードする際に注意すべき点があります。

それは、サーバーに対して休み無く連続でアクセスすることを控える、という点です。

あまりに高頻度でのアクセスはそういう意図が無かったとしてもDDoS攻撃とみなされる恐れがあります。

以降のサンプルコードでは1ファイルしか処理をしませんが、拡張後に連続してダウンロードを行う場合を考慮して、Sleep関数で1秒休止するようにしています。

サイトによっては自動取得(スクレイピング)自体を禁止していることもあります。Yahooのファイナンス情報などはそのようです。

そのあたりを確認した上でファイルのダウンロードを行ってください。

Win32APIを使う

VBAでインターネットからファイルのダウンロードを行うにはWin32APIの3つの関数を使います。

URLDownloadToFile 指定URLのファイルをダウンロードする
DeleteUrlCacheEntry 指定URLのキャッシュをクリアする
Sleep 指定ミリ秒だけ処理を止める

これらのAPIは今ではVBAぐらいでしか利用されないかもしれません。それぐらい今では他の言語ではインターネット操作の仕組みが充実しています。

サンプルコード

Win32APIを利用して、PNGファイルをダウンロードするサンプルコードです。説明しやすいように3つに分けていますが、1つのモジュールに繋げて書いて利用できます。

実行すると、PNG画像ファイルをダウンロードします。ダウンロードするPNGファイルは当サイトのあるページで使っているエラーダイアログのPNG画像ファイルです。

動作させるには2つ目のコードのDownloadFileTest関数を実行します。

1. Win32APIの宣言

3つのWin32APIを標準モジュール等のコードの先頭あたりに書きます。DownloadFile関数より上に書いておく必要があります。

2. 任意のURLを指定してDownloadFile関数を呼び出す関数

この関数が最初に動かす関数です。

URLと保存先パスを指定してDownloadFile関数を呼び出します。

ここでは保存先パスにファイル名まで指定していますが、これはURLDownloadToFile関数の第三引数の形式に合わせているためです。

フォルダパスだけにしたい場合であればファイル名部分をURLからもってくるなどの対応が必要になります。

 

引数のURLのファイルをダウンロードする関数

URLのファイルをダウンロードする関数です。本体ともいえる関数です。

5行目で指定URLのキャッシュをクリアし、古いファイルのダウンロードを防ぎます。

ここでは戻り値を取得していませんが、もし戻り値の判定を行う場合はキャッシュが無い場合はキャッシュのクリアが出来ないため、DeleteUrlCacheEntry関数の戻り値はFALSE(失敗)になることの考慮が必要です。

8行目で指定URLのファイルをダウンロードします。ダウンロードに失敗した場合はイミディエイトウィンドウにそのURLを出力します。

URLDownloadToFile関数の使い方ですが、1番目の引数は0固定、2番目がURL、3番目が保存先パス、4番目と5番目も0固定です。URLと保存先パスを指定しているだけです。