ISBNの書かれたテーブルにPower Queryのカスタム関数で書誌情報を追加する


# はじめに
下の図のようにISBNコードが書かれたテーブルに対して、タイトル、著者、出版社などの書誌情報を Power Query で追加することができました
このカスタム関数を使う方法に気づくまでは Python を使っていたのですが json の構造をたどって欲しい情報を選ぶのに苦労していました。 Power Query だとローコード（コードを触ったのは３か所だけ！）で実現できるし json から欲しい情報を選ぶのも超簡単です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/4bdeb301-b857-31fc-4554-5300863945c8.png)

# Power Query で openBD の書誌情報を読み込んでみる
書誌情報の取得には [openBD](https://openbd.jp/) を使わせていただきました
openBD の API では `isbn=` の後にISBNコードをカンマ区切りで並べて書くことで複数の書誌情報を一度に取得できます。


https://api.openbd.jp/v1/get?isbn=9784899774921,9784802511025,9784802511216,9784798055909,9784798059822


> 実装上の要点
> • なるべくまとめて取得する（HTTPのペイロードを減らす）

と[openBDセミナーのプレゼン資料](https://openbd.jp/pdf/api20170123.pdf)に書かれていたので複数のISBNコードが書かれたテーブルから上記のようなURLを一つだけ作成して一気に取得する方法にしています


まずはこのURLをPower Queryで読み込んでみます
Power Query の新しいクエリで 「Web から」の URL に先ほどの URL を入力して OK をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/35935310-df1e-54a3-56f2-65abb4462cb9.png)

テーブルへの変換をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/83eb2b8c-1cc7-4662-46ec-0e694184a0d1.png)

そのままで OK をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/0b4f1280-8585-37ba-8282-92ed20dfd990.png)

展開するボタンをクリックし、summaryの列を選択し、元の列名を～のチェックを外してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/b4367beb-b7b3-5d28-4ef1-df7d5c4da03f.png)

展開するボタンをクリックし、全ての列を選択してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/5f84c1f0-5652-6592-2ea9-7557c5a4284f.png)

書誌情報をまとめて取得できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/5da31ab5-1e9a-f240-5c9e-1b16fba87d24.png)

# このクエリをカスタム関数に置き換える
つぎにこのクエリをISBNコードをパラメータとした関数に置き換えます

詳細エディタを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/0c00c478-03c2-e99c-6971-218ea6c597dc.png)

let の上に `(IsbnList as text) =>` と入力する（コードを触る１か所目）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/cef33b74-1929-567d-2976-00fec2ecb45d.png)

URL の中のISBNコードの数字部分を下記のように変更する（コードを触る２か所目）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/9c4bda64-c8fd-cbd7-0b81-d8353cd67a08.png)

変更後のコード

```
(IsbnList as text) =>
let
    ソース = Json.Document(Web.Contents("https://api.openbd.jp/v1/get?isbn="& IsbnList)),
    テーブルに変換済み = Table.FromList(ソース, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    #"展開された Column1" = Table.ExpandRecordColumn(テーブルに変換済み, "Column1", {"summary"}, {"summary"}),
    #"展開された summary" = Table.ExpandRecordColumn(#"展開された Column1", "summary", {"isbn", "title", "volume", "series", "publisher", "pubdate", "cover", "author"}, {"isbn", "title", "volume", "series", "publisher", "pubdate", "cover", "author"})
in
    #"展開された summary"
```
詳細エディタの完了を押すとこのように関数に変換されるので関数名 getBookInfo としておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/8f0c3f00-128e-fe00-885f-d1a811e0e3b7.png)

カスタム関数の動作テストをしてみます
IsbnListの部分に `9784899774921,9784802511025,9784802511216,9784798055909,9784798059822` と入力して呼び出しをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/756556f7-f99b-177b-29ad-d57ce954ed48.png)

カスタム関数で５冊分の書誌情報が取得できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/e0d13229-ddff-f220-22e5-99702a88fa3f.png)

#ISBNコードが書かれたテーブルからカスタム関数を呼び出す
このようなテーブルを元にしてに先ほどのカスタム関数で書誌情報をとってみます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/41e317a2-4c8e-e56f-f087-786d8e21e72b.png)

型の変換でテキストになっているか確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/2f887419-1ade-04e9-83ab-12a0edeb7bf8.png)

行と列とを入れ替えます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/7b5146c4-a01c-33ec-969d-281d457089fe.png)

全ての列を選択して列のマージを行います。区切り文字はコンマを選んでOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/0b2c8ebf-75ef-4b60-38eb-a3becba5905a.png)

列のマージを行う際に `{"Column1", "Column2", "Column3", "Column4", "Column5"}` とコラム名が指定されていますがISBNデータの個数が変わったときにこのままではうまく動かなさそうなので・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/dab89b23-a869-57b4-a4ac-1c93130100e1.png)
`Table.ColumnNames(転置されたテーブル)` に書き換えます（コードを触る３か所目）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/f7e3e63a-6114-5d70-e853-454c3589c8f0.png)

列の追加タブのカスタム関数の呼び出しをクリックし、ダイアログで関数クエリに getBookInfo を選び、IsbnList に結合済みの列を選択してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/4f23a337-d6c0-e54e-9c1b-03c071886ba2.png)

展開するボタンをクリックし、すべての列を選択してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/4ef9cdf3-82db-61d1-4a9d-fa28301857e2.png)

「結合済み」の列を削除します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/edf7ddb5-8738-bcee-23a2-5db6b8bcec45.png)

Power Queryでの作業完了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/004f6cd3-182b-6c76-26ad-e38732637e8c.png)

# まとめ
この方法に気づくまでは Python を使っていて json の構造をたどってほしい情報を選ぶのに苦闘していました。 Power Query だとローコード（コードを触ったのは３か所だけ！）で json の構造を追うのも超簡単に同じことを実現できました！
ISBNコードの行数が増えた時も更新ボタン一発です。openBD で情報が見つからない場合もエラーで途中終了したりしないで空白行で返ってくるのも助かります！
Power Query のカスタム関数は超便利＆超強力ですね！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433170/aa57d121-0b65-1ac6-03e5-a288a3a65ee1.png)

# 参考
カスタム関数の作成についてはこちらのページを参考にさせていただきました
[[Power BI / Excel] 複数にまたがる Web ページからデータを取得する](https://road2cloudoffice.blogspot.com/2017/07/power-bi-excel-web.html)