19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【レベル1】Power Automate × Office スクリプトで稼働入力表を自動作成する

Last updated at Posted at 2025-10-30

PowerAutomate から特定の Office ファイルの Office スクリプトを実行する、ということをこれまでやってこなかったので、自身の勉強がてらタイトルの取り組みをしてみることにしました。
もちろんチュートリアルを読めば何ができるかは一通り書いてあるのですが、今一つ「うむ、これは便利だ」という納得のいく内容が見つからなかったので、この度記事にしてみようと思い立った次第でした。

Office スクリプトとは

Office ファイル内のデータ入力・更新を自動化する機能です。
VBA によく似たこと(例えば Excel ファイル上の特定の操作を自動化する)ができますが、本記事で取り上げる最大の特徴の一つとして、「Power Automate を使用して実行できる」という点が挙げられます。
それの何がうれしいんだ? というところが今回の核となる部分です。

基本的には VBA で書かれた自動化は、Excelファイルを開き何らかの操作を行うことをトリガーとしますが、Office スクリプトを用いれば Power Automate に設定されたトリガー(例:月末になったら、Teams の通知があったら、特定のメールが届いたら など)が発火すればファイルを開くことなく自動化できます。作り方によっては、ユーザー側に一切の操作を必要せず、その自動化を起動するためのマニュアルを用意することすら不要です。

こんな Office スクリプトの魅力をお伝えするため、今回はこんなお題を用意してみました。

今回の題材:稼働入力表の自動作成 について

皆様こんな表を見たことはないでしょうか。この表は筆者が担当している案件の稼働時間を入力するための Excel ファイルです。実はこの度たまたま次月の稼働表を作成する用事があったのですが、土日祝日を調べたり曜日を確認したりするのが意外と面倒なわけです。また、この表自体は稼働入力の際に無いと改めて作成する必要があるため、少なくともその月が開始するまでには用意しておきたいものです。(そして大体そういう時に限ってみんな忙しい)

image.png

そこで、「月の中旬になったら次月の稼働入力表(シフト表)を作成する」という動作を実現してみます。
そしてこのシフト表の作成にあたって、Excel ファイルを開く必要はないように作ってみましょう。

なお、Office スクリプトを使用するにはライセンスが必要なのでもしご自身の環境で試される方は一度下記をご確認ください。

Office スクリプトを動かしてみよう

Office スクリプトは、Excel ファイルから直接エディタを使用して設定することが可能です。
自動化リボンからスクリプトのコードエディターを開きます。

image.png

内容の詳細な説明は割愛しますが、現在の日付を取得して次の月の名称のシート名を作り、その中に前述の稼働入力表を作成、土日祝日のセルを着色する、というスクリプトです。
ユーザーを別管理にする、祝日を自動取得するといった工夫をすることでさらにリッチにできそうですが、今回は Office スクリプトを活用する趣旨のためかなりシンプルな実装です。

function main(workbook: ExcelScript.Workbook) {
    const users = ["田中", "佐藤", "鈴木", "高橋"];

    const today = new Date();
    const nextMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);
    const year = nextMonth.getFullYear();
    const month = nextMonth.getMonth(); // 0-indexed
    const daysInMonth = new Date(year, month + 1, 0).getDate();

    // シート名を「2025年11月」形式で作成
    const sheetName = `${year}${month + 1}月`;
    let sheet = workbook.addWorksheet(sheetName);

    // 祝日一覧(ISO形式)
    const holidays: string[] = [
        "2025-01-01", "2025-01-13", "2025-02-11", "2025-02-23", "2025-02-24",
        "2025-03-20", "2025-04-29", "2025-05-03", "2025-05-04", "2025-05-05", "2025-05-06",
        "2025-07-21", "2025-08-11", "2025-09-15", "2025-09-23", "2025-10-13",
        "2025-11-03", "2025-11-23", "2025-11-24"
    ];

    // 横軸に日付を並べる処理。土日はグレー、祝日は赤で着色する
    for (let day = 1; day <= daysInMonth; day++) {
        const date = new Date(year, month, day);
        const formatted = `${date.getMonth() + 1}/${day}`;
        const isoDate = date.toISOString().split("T")[0];
        const dayOfWeek = date.getDay(); // 0:日, 6:土

        const headerCell = sheet.getCell(0, day);
        headerCell.setValue(formatted);

        const columnRange = sheet.getRangeByIndexes(0, day, users.length + 1, 1);

        // 色分け
        if (dayOfWeek === 0 || dayOfWeek === 6) {
            columnRange.getFormat().getFill().setColor("#D3D3D3"); // グレー(土日)
        } else if (holidays.includes(isoDate)) {
            columnRange.getFormat().getFill().setColor("#FADBD8"); // 薄赤(祝日)
        }

        // 罫線
        columnRange.getFormat().getBorders().forEach(border => {
            border.setStyle(ExcelScript.BorderLineStyle.continuous);
            border.setWeight(ExcelScript.BorderWeight.thin);
            border.setColor("black");
        });
    }

    // 縦軸にユーザーを並べる。
    for (let i = 0; i < users.length; i++) {
        const cell = sheet.getCell(i + 1, 0);
        cell.setValue(users[i]);

        const rowRange = sheet.getRangeByIndexes(i + 1, 0, 1, daysInMonth + 1);
        rowRange.getFormat().getBorders().forEach(border => {
            border.setStyle(ExcelScript.BorderLineStyle.continuous);
            border.setWeight(ExcelScript.BorderWeight.thin);
            border.setColor("black");
        });
    }

    // ヘッダー行にも罫線
    const headerRange = sheet.getRangeByIndexes(0, 0, 1, daysInMonth + 1);
    headerRange.getFormat().getBorders().forEach(border => {
        border.setStyle(ExcelScript.BorderLineStyle.continuous);
        border.setWeight(ExcelScript.BorderWeight.thin);
        border.setColor("black");
    });
}

上記の内容をエディタにペーストできたら、「スクリプトを保存」をクリックの上ファイルを保存します。
Excel Online で編集している場合は自動保存されているため、そのまま PowerAutomate からスクリプトを呼び出す設定に移りましょう。

image.png

自動化フロー、スケジュールされたフロー、インスタント フローの制限事項 - Power Automate | Microsoft Learn
https://learn.microsoft.com/ja-jp/power-automate/limits-and-config?source=recommendations

PowerAutomate から Office スクリプトを呼び出す(「スクリプトの実行」アクション)

今回の内容の核となる Power Automate フローから Office スクリプトを呼び出すための構成を行っていきます。
今回作成するフローはユーザーの操作起点ではなく特定のスケジュールにもとづき起動してほしいため「スケジュール済みクラウドフロー」を新たに作成します。

作成後、以下のように 1 ヵ月ごとに実行されるように設定しておきましょう。

image.png

「スクリプトの実行(Run Script)」を使用することで、特定の SharePoint サイトに格納されている Excel ファイルのスクリプトを呼び出すことが可能です。
先ほど設定したトリガーの直後のアクションとして、Excel コネクタの「スクリプトの実行」を選択します。(スクリプトの実行の初回作成時、Excel Online への接続を作成のため必要に応じてサインインしてください)
実行するファイルとして、先ほど保存したスクリプトを指定しましょう。Location/Document Library/File には先ほど作成した Excel ファイルの格納先を指定します。
本記事の動作確認時は、SharePoint サイトのドキュメントライブラリに保存しています。

image.png

image.png

スクリプトの指定ができたら、「保存」してください。

動作確認

ここまでの設定内容により、1か月ごとに次の月の稼働入力表を作成する Office スクリプトが実行される動作になっています。

本来はスケジュールされている月末まで待つ必要がありますが、Power Automate のテスト機能で任意のタイミングでトリガーされたのと同様にフローを起動できます。

「フローの実行」からフローを実行して、検証用のExcelファイルを見てみましょう。先ほどは作成されていなかった 11月分の稼働入力表が、土日祝日も反映された状態で作成されています。これが毎月自動的に作られたら、ちょっと嬉しくないですか?(うれしくなかったらすみません)

image.png

スクリプトの更新後、もし 429 エラーが出る場合は、コネクタから再度スクリプトを指定するとうまくいく場合があります。

まとめ

いかがでしょうか。意外と実用的なものができて個人的には満足なのですが、記事内でも紹介した通り祝日やユーザーの設定の機能についてはまだまだ改善の余地があります。
Power Automate による自動化の検討の中では、どうしてもなかなか優先度が下がりがちなこの Office スクリプトですが、基本的に Power Automate のクラウドフローからは Excel ファイルなどの UI を触ることができなかったりするため、意外と活用するチャンスがあったりします。
また、すでに VBA で自動化されている業務を完全に自律的にしたい場合も、ぜひ Office スクリプトを選択肢の一つとして検討してみてください。

19
6
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
19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?