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関連

    カウントダウンタイマーを作成するPowerPointマクロ

    大分前に書いた記事について問い合わせがありましたので、マクロを作成しな…

  2. Office アドイン

    [Office用アプリ]TechEd North America 2013のセッション資料

    アメリカ・ニューオリンズで現地時間6月3日から6日にかけて開催された開…

  3. Office関連

    文書が互換モードかどうかを判定するWordマクロ

    古いバージョンのWordで作成された文書を開くと、タイトル バーに「互…

  4. Office アドイン

    [Office用アプリ]野良アプリのススメ

    「Office 用アプリの概要」にもある通り、Office用アプリを公…

  5. Office関連

    Excel 2013で駅すぱあとWebサービス APIの「経路探索」を使ってみました。

    「「駅すぱあとWebサービス API無償提供」を利用してみました。」で…

コメント

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

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

Time limit is exhausted. Please reload CAPTCHA.

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

Translate

最近の記事

アーカイブ

PAGE TOP