sharepoint|ファイルダウンロードの自動化をvbaで行いたい!やり方は?

sharepoint|ファイルダウンロードの自動化をvbaで行いたい!やり方は?

VBAでSharePoint上のファイルをダウンロードしようとする場合、基本的には「Webからデータを取得する」というアプローチを取ることになります。しかし、通常のWebサイトとは異なり、SharePointには認証という大きな壁が存在します。

直接的なダウンロードの難しさ

VBAは、Webブラウザの操作を自動化したり、Webサーバーに直接HTTPリクエストを送ったりする機能を持っています。

  • Webブラウザの自動操作: かつてInternet Explorer(IE)を使えば比較的容易でしたが、IEは非推奨となり、ChromeやEdgeといったモダンブラウザの自動操作はVBAだけでは非常に困難です(Selenium Basicなどの外部ライブラリが必要になります)。
  • HTTPリクエストの送信: これはWebサーバーと直接通信する方法で、ファイルダウンロードには適していますが、SharePointの認証をクリアするのが難しいです。

 

認証が最大の壁

SharePoint、特にクラウドベースのSharePoint Online(Microsoft 365に含まれるもの)では、多要素認証(MFA)を含むモダン認証が主流です。

  • VBAはモダン認証を直接扱えない: VBAはOAuth2.0やMFAのような複雑な認証フローを直接処理する能力を持っていません。そのため、単にユーザー名とパスワードをVBAコードに書くだけでは、ほとんどの場合ログインできません。
  • セッションの再利用も限定的: 既にブラウザでSharePointにログインしていても、VBAからそのセッション情報を簡単に再利用することは難しいです。

 

どんな時にVBAを使うべきか?(限定的なシナリオ)

これらの課題を考えると、VBAでSharePointからの自動ダウンロードは、以下のような限定的なシナリオでしか現実的ではありません。

  • SharePoint Server (オンプレミス) で、かつレガシー認証 (AD認証など) を使っている場合。
  • 特定のファイルへの「匿名アクセスリンク」や「ゲストリンク」があり、認証が不要な場合。
  • ユーザーがブラウザでSharePointにログイン済みで、かつVBAがそのセッションを偶然再利用できるような特殊な環境 (稀)。
  • PowerShellなど、他のスクリプト言語とVBAを連携させる場合 (VBAはトリガー役)。

多くの場合、VBA単体でモダンSharePoint Onlineからの自動ダウンロードは非常に困難、または不可能です。


 

VBAを使ったダウンロードの主なアプローチ(とそれぞれの課題)

VBAでダウンロードを試みる際の、より具体的なアプローチを見ていきましょう。

アプローチ1:Internet Explorer(IE)の自動操作(非推奨・古いです)

かつてVBAでWeb操作を自動化する際の定番でしたが、現在ではほとんど使えません。

やり方(概念的)

VBAの CreateObject(“InternetExplorer.Application”) を使ってIEのインスタンスを立ち上げ、SharePointのURLにアクセスさせ、ログインフォームにユーザー名とパスワードを入力させ、ダウンロードリンクをクリックさせる、という手順を踏みます。

課題

  • IEが終了している: Microsoft EdgeがIEモードをサポートしている場合もありますが、IE自体はサポートが終了しており、セキュリティリスクも高いため、新しい環境で利用すべきではありません。
  • モダンブラウザ非対応: ChromeやEdgeなどのモダンブラウザは、VBAから直接自動操作することはできません。
  • モダン認証非対応: IEを使えたとしても、Microsoft 365のSharePoint Onlineで多要素認証が有効になっている場合、この方法ではログインできません。

 

アプローチ2:WinHTTP / XMLHTTP を使った直接的なダウンロード(より高度で複雑)

この方法は、VBAがWebサーバーと直接HTTP通信を行うため、ブラウザを立ち上げる必要がありません。ダウンロード自体には適していますが、認証の壁が非常に高いです。

やり方(概念的)

  1. VBAの CreateObject("MSXML2.XMLHTTP") または CreateObject("WinHttp.WinHttpRequest.5.1") を使ってHTTPリクエストオブジェクトを作成します。
  2. SharePointの認証をクリアするためのHTTPヘッダーやクッキーを設定します。
  3. これが最も難しい部分です。OAuthトークンやセッションクッキーなどを事前に取得し、それをリクエストに含める必要があります。これ自体がVBAの範疇を超えた複雑なWeb認証の知識を要求します。
  4. ダウンロードしたいファイルのURLに対してGETリクエストを送信します。
  5. レスポンスとして返ってきたファイルの内容をバイナリデータとして取得し、VBAでローカルファイルとして保存します。

 

課題

  • 認証の複雑さ: 前述の通り、モダンSharePoint Onlineの認証(特にMFA)をVBAで処理するのは事実上不可能です。仮に何らかの方法でトークンを別途取得できたとしても、そのトークンを管理・更新するロジックをVBAで書くのは非常に困難です。
  • APIの知識が必要: SharePointのREST APIや、ファイルダウンロードのURL構造に関する深い理解が必要になります。
  • エラーハンドリング: ネットワークエラー、認証エラー、ファイルが見つからないなどの様々なケースに対応するための堅牢なエラーハンドリングをVBAで実装する必要があります。

 

アプローチ3:OneDrive同期クライアントとの連携(最も現実的かつ簡単な「自動化」)

これは「VBAで直接ダウンロードする」というよりは、「VBAを使って、既にローカルにあるSharePointファイルにアクセスする」というアプローチです。VBA自身がダウンロードするわけではありませんが、結果的にローカルファイルとして自動的に利用できるようになるため、実用的な「自動化」と見なせます。

やり方

  1. 事前にOneDrive同期を設定する: まず、手動でSharePointの目的のドキュメントライブラリをOneDrive同期クライアントを使ってパソコンに同期設定しておきます。これにより、SharePoint上のファイルが自動的にパソコンの指定フォルダーに反映されるようになります。
  2. VBAからローカルフォルダーのファイルを操作する: VBAのコードでは、ネットワーク上のSharePointパスを直接指定するのではなく、OneDriveによって同期されたローカルフォルダーのパス(例: C:\Users\あなたのユーザー名\組織名\SharePointサイト名 - ドキュメントライブラリ名\ファイル名.xlsx)を指定してファイルを開いたり、コピーしたりします。

メリット

  • 認証の問題を回避: OneDriveクライアントが認証を処理してくれるため、VBA側で認証ロジックを書く必要がありません。
  • 文字化け回避: OneDriveクライアントが文字コードを適切に処理するため、ファイル名の文字化け問題もほとんど発生しません。
  • 常に最新: ファイルが自動で同期されるため、VBAで常に最新のファイルを扱えます。
  • 実装が非常に簡単: VBAから見れば、単なるローカルファイルの操作と何ら変わりありません。

課題

  • 事前設定が必要: OneDrive同期の初期設定は手動で行う必要があります。VBAでOneDrive同期自体を自動で設定することはできません。
  • ローカルストレージを消費: 同期するファイルが多いと、パソコンのストレージ容量を消費します。(「ファイルオンデマンド」機能で軽減可能)。
  • 同期タイミングの制御不可: VBAから「今すぐ同期!」と強制することはできません。OneDriveクライアントの自動同期に依存します。

 

VBAでWinHTTPを使ったダウンロードの概念的コード例

アプローチ2のWinHTTPを使ったダウンロードは、認証が最大の課題ですが、もし匿名アクセスリンクや特定の環境で認証不要でアクセスできる場合の概念的なコードの骨子を以下に示します。このコードはそのままではモダンSharePoint Onlineでは動作しない可能性が高いことをご理解ください。

VBA

Sub DownloadFileFromSharePoint()

    Dim objHTTP As Object
    Dim strURL As String
    Dim strSavePath As String
    Dim bytData() As Byte
    Dim lFileNum As Long

    ' --- 設定項目(ここを適切に設定してください) ---
    ' ダウンロードしたいSharePointファイルの直接リンクURL
    ' (例: SharePointのファイルを選択し、「リンクのコピー」で得られるURL。
    '      認証なしでアクセスできるURLである必要があります。)
    strURL = "https://yourcompany.sharepoint.com/sites/YourSite/Shared%20Documents/YourFolder/YourFile.xlsx"

    ' ファイルを保存するローカルパスとファイル名
    strSavePath = "C:\Users\あなたのユーザー名\Documents\DownloadedFile.xlsx"
    ' --- 設定項目ここまで ---

    On Error GoTo ErrorHandler

    ' WinHttpRequestオブジェクトを作成
    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    ' または Set objHTTP = CreateObject("MSXML2.XMLHTTP") ' より古いバージョン

    ' HTTP GETリクエストを送信
    objHTTP.Open "GET", strURL, False ' False は同期リクエスト
    
    ' (重要) 認証が必要な場合、ここに認証情報を設定するロジックが必要。
    ' 通常のSharePoint Onlineではこの部分が非常に複雑で、VBA単体では困難。
    ' objHTTP.SetRequestHeader "Authorization", "Bearer YourAccessToken" ' 例: OAuthトークンを使う場合
    ' objHTTP.SetRequestHeader "Cookie", "YourSharePointSessionCookie" ' 例: セッションクッキーを使う場合

    objHTTP.Send

    ' レスポンスのステータスを確認
    If objHTTP.Status = 200 Then ' HTTPステータスコード 200 は「OK」を意味する
        ' ファイルの内容をバイナリで取得
        bytData = objHTTP.ResponseBody

        ' ファイルとして保存
        lFileNum = FreeFile
        Open strSavePath For Binary Access Write As #lFileNum
        Put #lFileNum, 1, bytData
        Close #lFileNum

        MsgBox "ファイルのダウンロードが完了しました: " & strSavePath, vbInformation
    Else
        MsgBox "ファイルのダウンロードに失敗しました。" & vbCrLf & _
               "HTTPステータス: " & objHTTP.Status & " (" & objHTTP.StatusText & ")", vbCritical
    End If

    GoTo CleanUp

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical

CleanUp:
    Set objHTTP = Nothing

End Sub

コードの説明(概念):

  • Dim objHTTP As Object: Webサーバーと通信するためのオブジェクトを宣言します。
  • strURL: ダウンロードしたいファイルのURLを指定します。このURLは、認証なしで直接ファイルにアクセスできるものであるか、事前に認証がクリアされているセッションからのアクセスを想定しています。
  • strSavePath: ダウンロードしたファイルをパソコンのどこに、どのようなファイル名で保存するかを指定します。
  • objHTTP.Open "GET", strURL, False: 指定したURLに対してHTTPのGETリクエスト(ファイルを要求する)を送信する準備をします。Falseは、リクエストが完了するまでVBAコードの実行を一時停止する「同期」モードです。
  • objHTTP.Send: 実際にリクエストを送信します。
  • If objHTTP.Status = 200 Then: Webサーバーからの応答が成功(HTTPステータスコード200)だったかを確認します。
  • bytData = objHTTP.ResponseBody: サーバーから返されたファイルの内容をバイナリデータ(バイト配列)として取得します。
  • Open ... For Binary Access Write As #lFileNum: 取得したバイナリデータを、指定したローカルファイルパスに書き込みます。

 

認証の壁を乗り越えるには?(VBAの限界と他の現実的な選択肢)

前述の通り、VBA単体ではモダンなSharePoint Onlineの認証(特に多要素認証)を扱うのが非常に困難です。VBAで直接ダウンロードすることにこだわるよりも、以下のようなより現実的で推奨される自動化のアプローチを検討することをお勧めします。

1. PowerShellを使う(Microsoft推奨の自動化スクリプト)

PowerShellはMicrosoftが提供するスクリプト言語で、SharePoint Onlineの自動化に非常に適しています。モダン認証やMFAにも対応したモジュール(例: PnP.PowerShell)が提供されており、コマンドレットを使ってファイルのダウンロードが容易に実現できます。

メリット

  • モダン認証対応: Microsoft 365環境での自動化に最適です。
  • 強力な機能: SharePointの管理やファイル操作に関する豊富なコマンドレットがあります。
  • VBAと連携可能: VBAからPowerShellスクリプトを実行することも可能です。

課題

PowerShellの知識が必要です。

 Power Automateを使う(ノーコード/ローコードの自動化ツール)

Power Automate(旧Microsoft Flow)は、プログラミング知識がなくても、様々なサービス間の連携や自動化ワークフローを簡単に作成できるクラウドサービスです。SharePointコネクタとTeamsコネクタが非常に強力です。

メリット

  • ノーコード/ローコード: プログラミングなしで視覚的にフローを作成できます。
  • モダン認証を自動で処理: ユーザーが一度認証しておけば、Power Automateが裏側で認証を管理してくれます。
  • 様々なトリガー/アクション: ファイルが作成されたら、特定の条件を満たしたら、スケジュール実行など、多様な自動化が可能です。
  • Teams連携が強力: ファイルをダウンロードするだけでなく、Teamsに通知を送ったり、承認フローを組んだりするのも得意です。

課題

  • インターネット接続が必要です。
  • SharePoint上のファイルを直接ローカルPCの特定のパスに保存する、というよりも、SharePoint内の別の場所にコピーする、あるいはOneDriveに保存する、といったクラウド間連携が得意です。

 

3. Microsoft Graph APIを利用する(開発者向け)

より高度なカスタマイズやシステム連携が必要な場合、Microsoft Graph APIを直接利用する方法もあります。これはREST APIなので、Python、C#、JavaScriptなど、任意のプログラミング言語から呼び出すことができます。

メリット

  • 最大限の柔軟性: SharePointを含むMicrosoft 365のあらゆる機能にアクセスできます。
  • モダン認証対応: OAuth2.0フローをプログラムで実装できます。

課題

  • プログラミングの専門知識が必須です。
  • APIの認証やリクエストの構築に関する深い理解が必要です。

 

まとめ

VBAを使ってSharePointからファイルを自動ダウンロードしたいというご要望、承知いたしました。しかし、特にモダンなSharePoint Online環境では、多要素認証(MFA)が大きな障壁となり、VBA単体で直接ダウンロードを自動化するのは非常に困難であり、非推奨です。

最も現実的なVBAを使った「自動化」は、アプローチ3のように、OneDrive同期機能を活用し、VBAから既にローカルに同期されたファイルを操作することです。 これであれば、VBA側で複雑な認証処理を記述する必要がなく、文字化けの問題も回避できます。

もし、VBAにこだわらずに自動化を実現したいのであれば、

  • SharePointの自動化に最も推奨されるのは「PowerShell」です。 モダン認証に対応しており、ファイル操作も強力です。
  • プログラミングなしで簡単に自動化したい場合は、「Power Automate」が最適です。 クラウド間連携やTeams通知など、幅広い自動化が可能です。

VBAの特性とSharePointのセキュリティ強化を考慮し、皆さんの目的に合った最適な方法を選ぶことをお勧めします。もし、特定の目的でVBAにこだわりたい場合は、上記の概念的コードを参考に、認証部分を外部のPowerShellスクリプトに任せ、VBAからPowerShellを呼び出す、といった連携も検討できるかもしれません。