ENGINEER BLOG

ENGINEER BLOG

Microsoft Graphを使ってExcel Online(Microsoft 365)のデータを読み書きする

こんにちは、イノベーション本部の朝日です。

今回はMicrosoft 365の機能を使ってExcel Onlineのデータを読み書きしてみたいと思います。
開発系の機能としてPower Apps、Office Script、Power Automateなど色々ありますが、今回はその中の一つMicrosoft Graphを使ってみます。

Microsoft Graphとは

Microsoft Graphとは、

Microsoft Graph は、Microsoft 365 のデータとインテリジェンスへの入り口です。 Microsoft Graph は、Microsoft 365、Windows 10、および Enterprise Mobility + Security の膨大な量のデータにアクセスする際に使用できる統合型プログラミング モデルを提供します。 Microsoft Graph の豊富なデータを使用して、数百万人のユーザーを操作する組織やコンシューマー向けのアプリを作成できます。

…だそうです。
 REST APIを通してMicrosoft 365内のデータにアクセスすることができます。

【準備】Microsoft 365 開発者プログラム

個人のMicrosoft365アカウントでもいいのですが、色々便利なので今回はMicrosoft 365 開発者プログラムを使ってみます。

開発者プログラムを使うと

無料の Microsoft 365 E5 インスタント サンドボックス
開発用に 25 個のユーザー ライセンス

などを使うことができます。 利用開始手順は特に迷う所はないと思いますので割愛します。

途中「Microsoft 365 E5 サンドボックスをセットアップする」では「インスタント サンドボックス」を選択しました。
img01

セットアップが完了したら、途中で作成された管理アカウントでMicrosoft 365 管理センターにアクセスして、作成された架空ユーザーアカウントを確認してください。

img02
※架空ユーザーなので人によって異なったりするのかもしれませんが、ここでは最初のAdele Vanceさん(AdeleVアカウント)を使うことにします。 なお、登録時に架空ユーザーに代替パスワードを設定していなければ、管理者パスワードと同じになっています。

それから、普段利用しているアカウントと取り違えるとやっかいなので、以降はブラウザのシークレット ウィンドウで作業するのがおすすめです。

Graph エクスプローラー

Microsoft GraphについてはGraph エクスプローラーというオンラインでAPIを試せるツールがあるので、それを触ってみると理解しやすいと思います。

APIの詳細はMicrosoft Graph REST API v1.0 リファレンスを参照してください。

Graph エクスプローラーにアクセスして、左上の「Microsoftの職場または学校のアカウントで」から先ほど確認したAdeleVアカウントに切り替えます。
img03

サンプルクエリの「自分のプロファイル」をクリックしてこんな応答が返ってきていれば正常に動作しています。

img04

Excelファイルの読み取り

AdeleVアカウントのOneDriveにExcelファイルを適当に作ってください。

Excelからの読み込みは「サンプルクエリ」→「Excel」→「ワークシートの使用範囲」を選択すると

https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/worksheets('Sheet1')/usedRange

ということが確認できるのですが、対象のExcelファイルの「drive-item-id」を調べる必要があります。

「drive-item-id」を調べるために「サンプルクエリ」→「はじめに」→「自分のドライブ内のすべての項目」

https://graph.microsoft.com/v1.0/me/drive/root/children

をリクエストすると、最初は

{
    "error": {
        "code": "itemNotFound",
        "message": "Item not found",
~~~

という応答で、ファイルが見つかりません。 わかりにくいのですが、実は権限が不足しています。

左上のアカウント名の横の「…」から「アクセス許可を選択する」を選択して、
img05
Files.ReadWrite.Allにチェックを入れて同意してください。(ここでのリクエストだけならFiles.Readだけで大丈夫ですが、以降で必要になるのでFiles.ReadWrite.Allにしています)
img06

そうして「自分のドライブ内のすべての項目」再度実行すると、

~~~
            "id": "**********************************",
            "lastModifiedDateTime": "****-**-**T**:**:**Z",
            "name": "Book.xlsx",
~~~

という感じで、OneDrive中のファイル情報が得られます。
ここで得られた「id」の値で

https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/worksheets('Sheet1')/usedRange

の中の{drive-item-id}を置き換えてリクエストすると、

~~~
    ],
    "columnIndex": 0,
    "text": [
        [
            "ID",
            "Name"
        ],
        [
            "1",
            "あああ"
        ],
        [
            "2",
            "いいい"
        ],
        [
            "3",
            "ううう"
        ],
        [
            "4",
            "えええ"
        ],
        [
            "5",
            "おおお"
        ]
    ],
    "formulas": [
~~~

のようにExcelファイルの内容が読むことができます。 今回は下記のようなExcelファイルで試したので、正しく読み取れていることが分かります。

img07

Excelファイルへの書き込み

次はExcelへの書き込みを試してみます。 Excelのテーブルである必要があるので、まだの場合、Excel上で「テーブルとして書式設定」でテーブル化しておきましょう。
img09

サンプルクエリには適当なものがないため、リファレンス(Microsoft Graph での Excel の操作)を元にリクエストを作成します。
書き込みの方法はいくつかありますが、今回はTableRow を作成するを使ってみます。 「HTTP 要求」の項を見ると、

POST https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/tables/{table-id}/rows

となっているので、table-idを調べるため先にテーブルを一覧表示するで確認します。

https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/tables

サンプルクエリではないので、右上のクエリ欄に直接書き込んで「クエリの実行」で実行します。
img08

成功すると、

~~~
            "name": "テーブル1",
            "showFilterButton": true,
            "id": "{********-****-****-****-*************}",
            "highlightLastColumn": false,
~~~

のようにidが取得できます。
「table-id」が無事取得できたので、改めて

POST https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/tables/{table-id}/rows

をリクエストしますが、

  • Graphエクスプローラーではデフォルトで「GET」が選択されているので、「POST」に変更します
  • 「要求本文」の所に追加したいデータをJSONで記述します
{
  "values": [
    [6, "かかか"],
    [7, "ききき"]
  ]
}

を設定してから実行してください。
img10
Excelファイルを開くと行が追加されていることが分かると思います。

共有ファイルへのアクセス

共有されたファイルの場合は、上記のリクエストでは成功しません。

  • AdeleVアカウントで作成したファイルを、2つめのアカウントのAlexWに共有します
  • AlexWアカウントでGraphエクスプローラーにサインインします
  • Files.ReadWrite.All権限を付与します

を実行したあと、最初のExcel読み取りのリクエストを実行してみます。

https://graph.microsoft.com/v1.0/me/drive/items/{drive-item-id}/workbook/worksheets('Sheet1')/usedRange

すると、AdeleVアカウントの時とは異なり

{
    "error": {
        "code": "itemNotFound",
        "message": "The resource could not be found.",
~~~

という結果になります。 自分のOneDriveではないファイルにアクセスする時には、格納先のdrive-idが必要なためです。

「サンプルクエリ」→「OneDrive」→「自分と共有したファイル」を実行してdrive-idを確認すると、以下のように得られます。

~~~
            },
            "remoteItem": {
                "createdDateTime": "****-**-**T**:**:**Z",
                "id": "**********************************",
                "lastModifiedDateTime": "****-**-**T**:**:**Z",
                "name": "Book.xlsx",
~~~
                },
                "parentReference": {
                    "driveId": "*****************************************************************",
                    "driveType": "business",
                    "id": "**********************************"
                },
~~~

得られたdrive-idを使ってExcelファイルにアクセスするには、サインイン ユーザーと共有しているアイテムを一覧表示する-注釈にあるように、下記のリクエストで行います。

https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{drive-item-id}/workbook/worksheets('Sheet1')/usedRange

/me/drive/の部分が/drives/{drive-id}/に変わっただけなので、わかりやすいですね。
なお、作成者のAdeleVアカウントでも上記リクエストで大丈夫なので、基本的にはこちらの記述にしておく方が汎用的ですね。

【おまけ】一度設定した権限の削除

Graph エクスプローラーを色々触っていると、一度許可した権限を取り消したいことがあると思います。
そんなときはマイ アカウントから、「アプリの権限の変更」を選択し、
img11

「Graph Explorer」の「取り消し」を実行することで権限を取り消すことができます。
img12

さいごに

今回はGraphエクスプローラーを使ってMicrosoft Graphを触ってみました。
ローコード開発ツールで問題ないケースも多いと思いますが、複雑なアプリケーションや柔軟なアクセスを行いたい時には役に立つのではないでしょうか。
次回はWebアプリから実際にアクセスしてみたいと思います。