0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowerAutomate「スクリプトの実行」→JSONで結果を返したい!

Posted at

はじめに

2024年秋ごろの初心者奮闘記。
このころはまだ(自分の置かれた環境では)生成AIにコードを書いてもらうことが難しく、四苦八苦していた思い出があります。

前提

対象となる帳票を日付等でフィルターし、期日を過ぎた対象案件だけを抽出するスクリプトを作成しました。
PowerAutomateと組み合わせ、対象案件の担当者にはアラートメールを送る業務改善に使用します。

Excelブックの概要

[申請]シート    … 承認を貰いたい案件について各担当者が記入するシート
[社員マスタ]シート … 社員の社員コードや氏名等のマスタ
[申請フロー]シート … 担当者がどの上長に承認を求めるか?が記載されたシート

改修前のスクリプトと課題

最初に作ったOffice Scriptsでは、フィルター後のデータを新しいSheet(Sheet1)に出力していました。

let sheet1 = workbook.addWorksheet();
sheet1.getRangeByIndexes(...).setValues(...);

この方法、動くには動くのですが…

  • 他の人が先に Sheet1 を作ってしまうとエラー
  • PowerAutomateのフロー内で Sheet1 を削除する別スクリプトが必要
  • その別スクリプトも(なんらかの理由で) Sheet1 が無いとエラー

上記の理由から、運用が不安定という問題がありました。

改修の方針

そこで、「Sheet1を使わず、JSON形式で返す」という方針に変更しました。

目的

PowerAutomateで後続処理がしやすくなる
エラーが減る
スクリプトの実行が2回→1回になる

実装で苦労した点

今回の改修で一番苦労したのは、他シートの情報を紐づけてJSONにまとめる処理でした。特に以下の4つのポイントでつまずきました。

1. Map の使い方がわからない
[社員マスタ]シートの情報を社員コードで引けるようにしたかったのですが、Map の使い方が最初は全然ピンときませんでした。

const memberMap = new Map(memberData.map(row => [String(row[0]), row]));

この書き方で、row[0] をキーにして、row 全体を値として格納しているのですが、
row[0] が何列目の何の情報なのか?
row[1] や row[5] を取り出すときに、どの列が何を意味しているのか?
というのが、Excelの列構成と照らし合わせながらでないと理解できず、何度も console.log() で中身を確認しました。

2. undefined に悩まされる
Map.get() で値を取り出すとき、キーが存在しないと undefined が返ってきます。

let name = memberMap.get(original社員コード) ? String(memberMap.get(original社員コード)[2]) : "";

このように三項演算子で undefined を避けるようにしましたが、最初は TypeError: Cannot read properties of undefined が頻発していました。

  • Map に正しくデータが入っていない
  • キーが文字列になっていない(String() を忘れていた)
  • row[2] が空だった

など、原因が複数あり、デバッグに時間がかかりました。

3. 複数の Map を使うと混乱する
[承認フロー]シートから「苗字 → 社員コード」「苗字 → 社員コード → メールアドレス」といった紐づけをするために、listMap1 と listMap2 を作りました。

const listMap1 = new Map(listData.map(row => [String(row[0]), String(row[1])]));
const listMap2 = new Map(listData.map(row => [String(row[2]), String(row[3])]));

この2つの Map を使って、承認者やリーダーのアドレスを引く処理を書いたのですが、

どっちの Map がどの紐づけなのか?
row[0]〜row[3] が何の列なのか?
が混乱して、何度もExcelの元データを見返しました。

4. 日付の変換も地味に難しい
Excelの日付はシリアル値で格納されているため、JavaScriptの Date オブジェクトに変換する必要があります。

let date = new Date((Number(values7[i][0]) - 25569) * 86400 * 1000);
納入期日 = date.toISOString().split('T')[0];

この「25569を引いて、86400×1000を掛ける」という変換式も、最初は意味がわからず、調べながら書きました。

改修後のスクリプトのポイント

最終的には、以下のような形でJSONを返すようにしました。

jsonData.push({
  社員コード: 社員コード,
  担当者氏名: 担当者氏名,
  申請No: String(values3[i][0]),
  件名: String(values4[i][0]),
  担当者アドレス: 担当者アドレス,
  承認者アドレス: 承認者アドレス,
  リーダーアドレス: リーダーアドレス,
  納入期日: 納入期日,
});
return jsonData;

これで、PowerAutomate側でJSONを受け取って処理できるようになり、Sheet1を使わない運用が実現できました。

おわりに

約1年前に書いたOfficescriptsなので今見ると粗が目立ちますが、粗と感じることができるなら、それもまた成長なのかもしれません。
最後まで読んでいただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?