Office関連

Office 365 APIをVBAから呼び出す(3)

前々回の記事でOffice 365とAzure ADの紐づけを、前回の記事でAPIを呼び出すアプリケーションの下準備として、リダイレクト URIの設定とクライアント IDの取得、アプリケーションの権限設定を行いました。
今回はいよいよVBAマクロからOffice 365 APIを呼び出してみます。

APIを呼び出す流れ

Office 365 APIを利用するには、authorization codeを取得してaccess tokenを取得して…といった作業が必要になりますが、どのような工程を経れば良いのかは「Office 365 app authentication concepts」にある表を見ると分かりやすいです。

Office_365_API_VBA_03_01

大雑把に言うと、

  1. Azure ADのエンドポイントにアクセスします。
  2. 無事に認証できるとauthorization codeが取得できます。
  3. 取得したauthorization codeを使って、Azure ADのエンドポイントにPOSTします。
  4. 問題が無ければaccess tokenやrefresh tokenを取得することができます。
  5. access tokenを使ってAPIを呼び出します。

こんな感じです。
よくあるOAuth 2.0 認証のWeb APIと大体同じ流れですので、Web APIの呼び出しに慣れている人には難しくないだろうと思います。

VBAマクロのコード

上記の流れを踏まえて書いたコードが下記になります。
Outlook Mail REST API」を使ってユーザーのメール一覧を取得するマクロです。

実行する際は「client_id」と「redirect_uri」をそれぞれ自分が取得・設定したものに置き換えてください。

また、コード中ScriptControlを使っているため、64ビット版のOfficeではエラーが発生します。

Option Explicit

Public Sub SampleOutlookAPI()
'サンプル - Outlook Mail REST API呼び出し
'※ ScriptControlを使っているため、32ビット環境のみ対応
'※ リダイレクト URIをlocalhostにしている場合は、ローカルサーバー(XAMPP他)の起動が必要な場合があります。
  Dim url_auth As String
  Dim url_token As String
  Dim url_api As String
  Dim q As String
  Dim code As String
  Dim js As String
  Dim access_token As String
  Dim dat As Variant
  Dim ary As Variant, ary2 As Variant
  Dim messages As Object
  Dim message As Object
  Dim i As Long
  Dim value, Subject, BodyPreview 'JSONパース用ダミー
  Const READYSTATE_COMPLETE = 4
  
  '**********************************************************************
  'クライアント ID & リダイレクト URI
  Const client_id As String = "(取得したクライアント ID)"
  Const redirect_uri As String = "(設定したリダイレクト URI)"
  '**********************************************************************
  
  'authorization code取得
  code = "" '初期化
  url_auth = "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code" & _
             "&redirect_uri=" & EncodeURL(redirect_uri) & _
             "&client_id=" & client_id & _
             "&resource=" & EncodeURL("https://outlook.office365.com/")
  With CreateObject("InternetExplorer.Application")
    .Visible = True
    .Navigate url_auth
    While .ReadyState <> READYSTATE_COMPLETE Or _
          .Busy = True Or _
          (StrComp(Left(.LocationURL, Len(redirect_uri)), redirect_uri) <> 0)
      DoEvents
    Wend
    q = .document.parentWindow.Location.Search
    q = Mid(q, 2) '"?"削除
    ary = Split(q, "&")
    For i = LBound(ary) To UBound(ary)
      ary2 = Split(ary(i), "=")
      If LCase(ary2(0)) = "code" Then
        code = ary2(1)
        Exit For
      End If
    Next
    .Quit
  End With
  If Len(Trim(code)) < 1 Then Exit Sub
  
  'access token取得
  js = "": access_token = "" '初期化
  url_token = "https://login.microsoftonline.com/common/oauth2/token"
  dat = "grant_type=authorization_code" & _
        "&code=" & code & _
        "&client_id=" & client_id & _
        "&redirect_uri=" & EncodeURL(redirect_uri)
  With CreateObject("MSXML2.XMLHTTP")
    .Open "POST", url_token, False
    .setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    .send dat
    Select Case .Status
      Case 200: js = .responseText
    End Select
  End With
  If Len(Trim(js)) < 1 Then Exit Sub
  js = "(" & js & ")"
  With CreateObject("ScriptControl")
    .Language = "JScript"
    access_token = .CodeObject.eval(js).access_token
  End With
  If Len(Trim(access_token)) < 1 Then Exit Sub
  
  'Outlook Mail REST API呼び出し
  js = "" '初期化
  url_api = "https://outlook.office365.com/api/v1.0/me/messages"
  With CreateObject("MSXML2.XMLHTTP")
    .Open "GET", url_api, False
    .setRequestHeader "Authorization", "Bearer " & access_token
    .send
    Select Case .Status
      Case 200: js = .responseText
    End Select
  End With
  If Len(Trim(js)) < 1 Then Exit Sub
  js = "(" & js & ")"
  With CreateObject("ScriptControl")
    .Language = "JScript"
    Set messages = .CodeObject.eval(js).value
    For Each message In messages
      Debug.Print message.Subject, message.BodyPreview '件名・本文プレビュー列挙
    Next
  End With
End Sub

Private Function EncodeURL(ByVal Target As String) As String
'URLエンコード
  With CreateObject("ScriptControl")
    .Language = "JScript"
    EncodeURL = .CodeObject.encodeURIComponent(Target)
  End With
End Function

上記コードを実行すると、下図のようなログイン画面が表示され、

Office_365_API_VBA_03_02

認証に成功するとauthorization codeやaccess tokenの取得が行われ、APIの実行結果としてユーザーが受信したメールの件名と本文の一部がイミディエイト ウィンドウに表示されます。

Office_365_API_VBA_03_03

APIの実行結果はJSON形式で返ってきますが、どのような構造になっているかは下記Webサイトをご参照ください。

・Outlook Mail REST API reference
https://msdn.microsoft.com/office/office365/APi/mail-rest-operations#GetMessages

さて、これでようやくVBAからOffice 365 APIを呼び出すことができるようになりました。
これまで3回に渡って記事を書いてきたわけですが、今回の記事には元ネタがあります。

それは、Microsoftの松崎さんが書いたサンプルコードで、“Office 365 API を Excel VBA から使う”というものです。

今回の記事は、この元ネタとやっていることはほぼ同じですが、自分で実際に手を動かしてみることで、365 APIへの理解は深まったように思います。

特に、SDKも用意されておらず、何をやるにも一々機能を実装しないといけないVBAでコードを書くことによって、APIを呼び出すにはどんな機能が必要なのかが分かるようになりました。

JSONのパース等手間が掛かるため、“VBAからの365 API呼び出しは便利!”と、胸を張って人に薦められるものではありませんが、開発環境は手軽なものなので、興味がある方は試してみてください。

参考Webサイト

関連記事

Office 365 APIをVBAから呼び出す(2)前のページ

Office 365 unified APIをVBAから呼び出す次のページ

関連記事

  1. Office関連

    Microsoft Graph SDK for PHPを使ったAPIの呼び出しサンプル

    知らない間に(恐らくBuild 2017のタイミングに合わせて)Mic…

  2. Office関連

    Office 2019のインストール方法

    下記ニュースサイトにある通り、永続ライセンス版のOffice 2019…

  3. Excel

    既存の機能の代わりにマクロを実行する方法をまとめてみました。

    「既存の機能の代わりにマクロを実行する」の関連になりますが、Offic…

  4. Office関連

    Adobe Reader XIを利用してPDFファイルのページ数を取得するVBAマクロ

    先日Adobe Readerを利用してPDFファイルのページ数を取得す…

  5. Office関連

    Excel Web Appのブック埋め込みを試してみました。

    Microsoftが提供しているOffice Web Appsはいわば…

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP