用 Power Automate 設計定期執行流程 ── 月底處理、營業日判定與提醒的實務

· · Power Automate, 雲端流程, 定期執行, 營業日, 國定假日, SharePoint, Microsoft 365, 業務自動化, 技術諮詢

「每逢月底將近,會計人員就會寄信給各部門說『費用結算的截止日是◯日』」「每天上班後打開受訂清單,用肉眼確認是否還有未處理的項目」「把逾期的送件文件對照台帳,一件一件催辦」。即使是已經導入 Microsoft 365 的公司,這種「靠人看行事曆與台帳來行動」的工作,殘留的數量意外地多。忘記處理就會出事,但用來避免遺忘的機制,卻只有承辦人的記憶與 Outlook 行事曆而已。

只要使用 Power Automate 的排程執行(Recurrence 觸發程序),這類定期作業就能自動化。不過,實際嘗試在日本的業務中建置時,很快就會碰到三面牆:時間的預設值是 UTC(協調世界時)、內建功能中並不存在「營業日」這個概念,以及「月底」「20 日結算」的判定必須自己用運算式來寫。本文將整理 Recurrence 觸發程序的規格與陷阱、日期運算的工具箱、以國定假日主檔判定營業日的方法、不過度催辦的提醒設計,以及定期執行流程特有的維運風險。

另外,關於和曆・國定假日・結算日這類日本的日期需求,在系統整體層面該如何處理,已在另一篇文章「業務應用程式的日本年號・國定假日・結算日處理 ── 抗改元設計與 JapaneseCalendar・營業日計算實務」中詳細說明過。本文則是把那套思考方式套用到 Power Automate 流程上的實踐篇。

1. 先講結論

  • Recurrence 觸發程序的時間,只要沒有指定時區就會視為 UTC。「原本想在每天早上 9 點執行」卻在日本時間 18 點動起來的事故,可以透過在時區欄位選擇「(UTC+09:00) 大阪、札幌、東京」,並明確指定開始時間來避免。12
  • 「僅在平日執行」可以用頻率「週」+ 指定星期(週一~週五)來達成。但不會考慮國定假日。「每月 20 日」這類固定日期,可以用開始日期時間 + 頻率「月」來達成;但像「每月底」「結算日若為假日則提前至前一個營業日」這類會變動的日期則無法指定,因此「每天執行、用運算式判定」才是實務上的解法。2
  • 運算式中的 utcNow() 也永遠是 UTC。日本時間的「今天」要先用 convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time') 轉換之後才能使用。在早上 8 點多執行的流程中若忘記轉換,「今天」就會變成前一天。34
  • 內建功能中並沒有判定日本國定假日的機制。運算式的函數清單中也沒有國定假日函數5,標準做法是自行維護國定假日主檔(SharePoint 清單等),在流程開頭判定「今天是不是營業日」,若不是營業日就結束執行。主檔的一次來源可以使用內閣府的國定假日 CSV。6
  • 提醒不要「1 件 1 封」,而是依承辦人彙整成 1 封。使用 Filter array、Create HTML table 等資料操作動作,就能避免 Apply to each 巢狀迴圈,組出更容易閱讀的流程。7
  • 定期執行流程很難讓人察覺「沒有在動」。請以連續失敗 14 天會關閉・90 天內未觸發會關閉・執行記錄預設只保留 28 天這些規格為前提,從一開始就設計失敗通知與執行記錄。89

2. 盤點「靠人看行事曆行動的業務」

最先該做的事,不是打造流程,而是先找出「靠看行事曆來行動的業務」,並判斷它是否適合定期執行。

業務 與定期執行的相性 補充
每天早上的未處理・異常檢查(受訂、申請、庫存) 適合 前提是判定條件能以清單欄位表達
月底・結算日前的一次性提醒(費用結算、出勤結算) 適合 需要把營業日調整(月底若為假日則提前至前一個營業日)規格化
逾期未送件的催辦(文件、報告、核准擱置) 適合 前提是台帳已經資料化(SharePoint 清單等)
定期報表的彙整・發送 有條件適合 彙整簡單就用流程,複雜就讓流程只負責發送
每月的請款・付款等確定處理(結算、紅沖藍複、重算) 多數不適合 分支與例外多,失敗時需要回滾(第 8 章)
跨核心系統的夜間批次處理 不適合 屬於開發領域。重跑・一致性的設計才是主體

分類的基準有三個:判定條件能否以資料表達(「感覺有點可疑的案件」是無法自動化的)、執行日的規則能否用語言描述即使失敗,隔天能否回復(做不到的屬於第 8 章的開發領域)。

其中第二點,在日本的業務中是最大的難關。就算說「每月底發送結算提醒」,實際上人在做的是「若月底是週六日或國定假日,就提前到前一個營業日;黃金週那年則在連假前發送」這類調整。請把「將這種默會知識寫成規格」這件事,視為打造流程的主體工作。若這部分含糊不清就直接做流程,就會發生「國定假日還發出催辦郵件」「連假前的提醒在連假中才寄出」這類狀況,進而失去信任。

3. Recurrence 觸發程序的基礎與陷阱

排程執行的雲端流程要建立為「排程雲端流程」,並透過 Recurrence(重複)觸發程序設定頻率與間隔。1 頻率可從秒・分・小時・日・週・月中選擇,間隔最小為 60 秒、最大為 500 天。8 規格本身很單純,但也是陷阱很多的觸發程序。

先用一張速查表整理全貌,依國內業務流程容易踩到的順序排列(第 6 項只在包含海外據點時才需要留意)。

# 陷阱 症狀 對策
1 開始時間預設為 UTC 原本想在每天早上 9 點動作,卻在日本時間 18 點執行 在觸發程序的時區欄位選擇「UTC+09:00 大阪、札幌、東京」
2 未指定開始日期時間,儲存時就會立即執行一次 傍晚儲存流程,當場就對所有人發出催辦郵件 務必指定開始日期時間。也要明確指定執行時間以防止偏移
3 無法指定月度的日期 「每月底」「結算日若為假日則提前至前一個營業日」無法用觸發程序表達 固定日期用開始日期時間 + 頻率「月」。變動的日期則每天執行 + 用運算式判定(第 4、5 章)
4 寫在觸發程序中的運算式會在儲存時被固定 明明寫了 utcNow(),卻永遠停留在儲存當天的值 不要在觸發程序的輸入中寫運算式。日期計算要放在流程內的動作中進行
5 關閉期間錯過的排程不會事後補跑 因改版而關閉了幾天,剛好跨過了本月的執行日,結果本月完全沒有動作 關閉前先確認下一次的執行日期,若已跨過就用手動執行補上
6 因夏令時間而產生 1 小時的落差 發給海外據點的通知,每次夏令時間切換都會偏移 1 小時 明確選擇該據點的時區(選好之後就會自動追隨季節變化)

陷阱 1:預設為 UTC ── 「明明是 9 點卻變成 18 點」

這是最常見的事故。Recurrence 觸發程序的開始時間,若未選擇時區,就會被解讀為結尾加上 Z 的 UTC 格式(YYYY-MM-DDThh:mm:ssZ)。若在時區欄位選擇日本,開始時間就會被視為該時區的當地時間(YYYY-MM-DDThh:mm:ss,不含 Z)。12 若要建立「每天早上 9 點發送通知的流程」,正確做法是把時區設為「(UTC+09:00) 大阪、札幌、東京」,並把開始時間設為 9:00。

陷阱 2:不指定開始時間,儲存的瞬間就會動作一次

若不指定開始日期時間,流程在儲存的當下就會立刻執行第一次。2 若是在測試階段還無妨,但若是把包含催辦郵件的流程在傍晚儲存,就可能演變成當場對所有人發出催辦通知的事故。請務必指定開始日期時間。

此外,若未指定進階選項中的「指定時間(這些小時/這些分鐘)」,第 2 次以後的執行時間會以上一次執行時間為基準相對計算,因此延遲會不斷累積,執行時間會逐漸產生偏移(drift)。2 若希望流程每天在固定時間執行,除了開始日期時間之外,也一併明確指定執行時間會比較保險。

陷阱 3:可以做到「僅平日」,但月度的詳細指定有限

把頻率設為「週」,就能選擇星期(週一~週五);若是「日」或「週」,還能指定執行時間(時・分)。也就是說,「只在平日早上 9 點」光靠觸發程序的設定就能達成。但另一方面,這些進階選項只有在頻率為「日」「週」時才能使用,頻率「月」並沒有像「每月 20 日」「每月底」這樣的日期指定欄位。2

不過,若是日期固定的月度處理,就不需要每天執行。只要把開始日期時間設為目標日期(例如:下個月的 20 日 9:00),並把頻率設為「月」,執行就會以開始日期時間為基準每月重複一次,因此「每月 20 日的 9 點」光靠觸發程序的設定就能達成。2 讓一年只需要 12 次的流程每天執行 365 次、再靠判定捨棄多餘的次數,會讓執行記錄變得難以閱讀,也白白消耗要求數,應該避免。

需要用到「每天執行 + 在流程開頭用運算式判定今天是否為目標日」這種架構的,是日期會變動的月度處理。像「每月底」(依月份不同為 28~31 日)、「20 日若為週六日或國定假日則提前至前一個營業日」、「每月第 N 個營業日」這類日期,都無法用觸發程序表達。這個判定式將在下一章處理。另外,以 29~31 日作為開始日的固定日期指定,需要透過實作確認該日不存在的月份會如何運作,因此月底附近的處理,一開始就採用「每天執行 + 判定」的做法會比較保險。

陷阱 4:寫在觸發程序中的運算式,會在儲存時被固定

若在觸發程序的輸入中寫下像 utcNow() 這樣的運算式,該值會在流程儲存的當下被計算並固定下來。並不會在每次執行時重新計算。10 請記住:「因為想把開始時間設為今天」就在觸發程序裡寫運算式,這種想法是行不通的。日期的計算應該放在流程內的動作中進行,而不是放在觸發程序裡(第 4 章)。

陷阱 5:關閉期間錯過的部分,事後不會補跑

Recurrence 觸發程序不會在重新開啟後,把流程關閉期間錯過的排程彙整處理,而是從下一個週期重新開始。11 可能會發生「因為要改版而把月底處理流程關閉了幾天,結果剛好跨過了月底的執行日,導致本月完全沒有動作」這種事故。要關閉定期執行流程時,請養成先確認下一次預定執行日期再關閉的習慣。

陷阱 6:夏令時間 ── 僅海外據點需要留意

若未選擇時區、直接以 UTC 時間撰寫,在有夏令時間(DST)的地區,每次切換時執行時間都會偏移 1 小時。若事先選好時區,排程就會自動追隨季節切換而維持不變。11 日本沒有夏令時間,因此只在國內使用不會有實際影響;但若同一個流程也要處理海外據點的通知,就必須明確選擇該據點的時區。

4. 日期運算工具箱 ── 用運算式判定月底・月初・結算日

流程內的日期計算,要用與 Logic Apps 共通的運算式(函數)撰寫。5 前提是 utcNow() 傳回的永遠是 UTC 的目前時間。12 因此,在流程一開始就建立「日本時間的今天」並放入變數(或 Compose)中,之後重複使用這樣的架構,能讓運算式更容易閱讀。

convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd')

convertTimeZone(時間戳記, 來源時區, 目標時區, 格式) 是用於轉換時區的函數13,時區名稱要使用 Windows 時區清單中的名稱。日本是「Tokyo Standard Time」。4 若不想自己寫運算式,也有一個功能相同的「轉換時區」動作可用。13

之所以必須轉換,是因為 UTC 與日本時間相差 9 小時。在日本時間早上 9 點之前,UTC 那邊都還是前一天。若在早上 8 點執行的流程中寫 formatDateTime(utcNow(), 'yyyy-MM-dd'),傳回的「今天」就會是前一天的日期。這種日期落差會依執行時間而時有時無,測試時很難察覺,往往是在正式環境中以「原本應該是月初的處理,卻在月底最後一天也動作了」這種形式才被發現。

這個運算式該寫在哪裡 ── 變數與 Compose,以及「運算式」分頁

剛開始接觸 Power Automate 時最容易在這裡卡關,因此先決定好。

  • 初始化變數(Initialize variable):在「新增動作」的「變數」分類中可以找到。指定名稱・類型(字串等)・值來建立,之後可用 variables('today') 的形式參照。迴圈中值會改變的資料,或之後想用「設定變數」覆寫的值,都適合用這個。
  • 建立(Compose):在「新增動作」中搜尋 compose,會出現在「資料操作」分類下,會直接保留「輸入」欄位中所寫運算式的結果。這是為了避免重複輸入相同內容而設計的動作7,像「日本時間的今天」這種計算一次之後就不會改變的值,很適合用這個。參照方式是以動作名稱指定,例如 outputs('Today')
  • 運算式本身該寫在哪裡:無論是哪種動作,只要選取值的輸入欄位,就會開啟選擇動態內容與運算式的面板,把上面的 convertTimeZone(...) 貼到「運算式」分頁(以 fx 圖示為標記)中並確定即可。雖然外觀會依設計工具版本而異,但「先點選輸入欄位,再切到運算式分頁」的順序是一樣的。
  • 由於動作名稱與變數名稱會被運算式參照,建議使用英數字命名比較保險(名稱中若包含空白,會被替換為底線)。

以下本文中,會把用這個運算式建立出來的「日本時間的今天」標記為 今天。實際的流程中請自行代換為 variables('today')outputs('Today')。以下整理建立之後可用的判定模式。

想做的事 運算式範例 補充
取得星期幾 dayOfWeek(今天) 0=週日、1=週一、…、6=週六。12
是否為週六日 or(equals(dayOfWeek(今天), 0), equals(dayOfWeek(今天), 6)) 若寫成「大於 5 則為週末」,會漏掉週日(0)12
是否為月初(1 日) equals(formatDateTime(今天, 'dd'), '01') 也可以用 startOfMonth() 直接取得月初日期本身5
是否為 20 日結算的結算日 equals(formatDateTime(今天, 'dd'), '20') 結算日不要寫死,改用環境變數或設定清單管理會更容易重複使用
是否為月底 not(equals(formatDateTime(今天, 'MM'), formatDateTime(addDays(今天, 1), 'MM'))) 「若今天的月份與明天的月份不同,今天就是月底」。無論 2 月或閏年都能正確運作
本月的月底日期 addDays(startOfMonth(addToTime(今天, 1, 'Month')), -1, 'yyyy-MM-dd') 以「下個月月初的前一天」推導。不需要考量該月有幾天
N 天前・N 天後 addDays(今天, -3) / addDays(今天, 7) 曆日的加減。以營業日為基準的做法見第 5 章

addDaysaddToTimestartOfMonthformatDateTimedayOfWeek 都是定義在 Logic Apps/Power Automate 共通運算式參考中的函數。5 表格中的組合運算式本身是筆者的實作模式,導入時請務必用跨越月底・月初・閏年(2 月 29 日)的日期測試過後,再上線正式環境。只在特定日期才會發作的日期臭蟲有多可怕、事前應該挑選哪些日期來測試,已在和曆・國定假日・結算日的文章的第 4 章寫過。

5. 營業日判定 ── 國定假日以主檔管理

內建功能中不存在國定假日判定

再說一次,Power Automate 並沒有判定日本國定假日的內建功能。Recurrence 觸發程序的星期指定,顧名思義只看星期幾,而運算式的函數清單頂多到日期加減、格式化、時區轉換,並沒有能傳回「這一天是不是國定假日」的函數。5 國定假日本來就無法用計算式求出(春分・秋分於前一年才確定,且會因法規修訂或特別措施法而變動)的原因,已在和曆・國定假日・結算日的文章的第 3 章詳細說明過。結論相同:國定假日要以資料(主檔) + 更新維運的方式管理才是正解。

在 Power Automate 中,最簡便的做法是在 SharePoint 清單中建立「國定假日主檔」(日期欄 + 名稱欄)。一次來源可以使用內閣府公布的、涵蓋昭和 30 年到隔年為止的國定假日月日・名稱 CSV(補假也會以資料列的形式包含在內)。6 由於公布的只有已確定的部分,每年一次、把隔年的資料匯入主檔這項作業要納入業務行事曆中,才算是完整的設計。若忘記更新,就會在隔年的國定假日照樣發出催辦通知,直接變成誤動作。此外,像夏季休業或創立紀念日這類公司休業日,請不要混入國定假日主檔,而是另建清單。因為「銀行匯款的期限判定只看國定假日」、「公司內部催辦則連公司休業日也要看」,依用途不同,該參照的休日集合也不一樣。

流程開頭的「營業日守門」

若希望流程只在營業日執行,除了 Recurrence 的星期指定(週一~週五)之外,還要在流程開頭放入以下判定。

  1. 建立「日本時間的今天」(第 4 章)
  2. 對國定假日主檔執行 SharePoint 的「取得多個項目(Get items)」,用篩選查詢以 HolidayDate eq '今天' 的形式搜尋今天的日期14
  3. 對公司休業日清單也執行相同的搜尋
  4. 只要有 1 筆命中,就用「終止(Terminate)」動作停止執行

Terminate 是一個能立即停止流程執行、並以指定狀態(成功/失敗/取消)結束的動作(不能放在 Apply to each 或 Do until 迴圈中)。15 若在這裡把狀態設為「已取消」,就能在執行記錄上一眼分辨出「因非營業日而跳過的日子」與「實際有處理動作的日子」。比起全部統一顯示為「成功」,事後追查會輕鬆許多。

「提前至前一個營業日」與「N 個營業日前」

月底結算提醒實際上需要的並非「每月底」,而是「月底若為假日,則提前至前一個營業日」。這可以用每個營業日都執行的流程,判定「今天是營業日,而且從明天到月底之間沒有任何一個營業日」來表達。換句話說,只要每天早上判定「今天是不是本月最後一個營業日」,提前的效果就會自動實現。

這是本文最不容易照抄的部分,因此連運算式與動作組成都會寫出來。前提是已經通過營業日守門(前一節) ── 也就是今天已確定為營業日。

0 件1 件以上通過營業日守門已確定今天是營業日建立本月休假清單對國定假日主檔與公司休業日執行 Get items計算剩餘天數用月底的日期減去今天的日期剩餘天數是否為 0今天是最後一個營業日執行月底處理・提醒建立明天到月底的日期陣列使用 range 與 addDays以 Filter array 排除週末與假日剩餘件數是否為 0Terminate 已取消今天不是前倒日

具體內容如下。

  1. 建立本月的休假清單。用 Get items 只取得國定假日主檔與公司休業日清單中本月的部分,再用「選取」(Select)整理成僅含 yyyy-MM-dd 格式字串的陣列,並以 union() 合併成一份。145 這個動作的名稱設為 Holidays
  2. 求出月底的日期與剩餘天數。直接沿用第 4 章的運算式。

    月底:     addDays(startOfMonth(addToTime(今天, 1, 'Month')), -1, 'yyyy-MM-dd')
    剩餘天數: sub(int(formatDateTime(月底, 'dd')), int(formatDateTime(今天, 'dd')))
    
  3. 若剩餘天數為 0,代表今天就是月底。既然已經通過營業日守門,今天就是最後一個營業日,直接進入處理即可。
  4. 若剩餘天數為 1 以上,就建立從明天到月底的日期陣列。在「選取」(Select)動作的起始值指定 range(1, 剩餘天數),對應中指定 addDays(今天, item(), 'yyyy-MM-dd')。由於 range() 的第 2 個引數必須為正整數5,因此務必先放置步驟 3 的分支(省略這一步的話,只有月底當天流程會因錯誤而中斷)。
  5. 排除週六日與假日。把步驟 4 的輸出傳給「篩選陣列」(Filter array),將條件切換為進階模式並寫入以下運算式。7 createArray(0, 6) 是週日與週六的星期編號12body('Holidays') 則是步驟 1 建立的休假清單。

    @and(not(contains(createArray(0, 6), dayOfWeek(item()))),
         not(contains(body('Holidays'), item())))
    
  6. 依剩餘件數判定。若步驟 5 的動作名稱設為 Filter array,其輸出可用 body('Filter_array') 參照(名稱中的空白會被替換為底線)。若 length(body('Filter_array')) 為 0,代表「今天之後沒有營業日」= 今天就是本月最後一個營業日,因此執行處理;若為 1 以上,代表今天不是提前日,因此以 Terminate(已取消)結束。515

像「每月 20 日,若為假日則提前至前一個營業日」這種結算日的提前,也是同樣的形式。只需要把月底日期換成結算日(20 日),把判定改讀成「今天在結算日以前,且從明天到結算日之間沒有營業日」,判定的結構就不會改變。導入時,請分別挑選結算日落在週一・週六・週日・國定假日的月份來測試。

像「付款期限的 3 個營業日前發出催辦」這種N 個營業日前,思路上也是相同的轉換。把「到了期限的 N 個營業日前」置換成「每個營業日都執行,計算從今天到期限的營業日數,若與 N 一致就執行」。營業日的計算方式,只需要統計「非週六日・不在國定假日主檔中・不在公司休業日中」的天數即可。不過,用流程的迴圈一天一天數日期的做法,一旦對象案件超過數百件,就會變成件數 × 天數的迴圈,執行時間與 API 呼叫次數都會暴增。到了這種規模,把營業日計算移出流程之外(資料庫的營業日資料表或小型 API),或是視為第 8 章所說的開發領域來處理,會比較健全。

6. 提醒・催辦的設計 ── 依承辦人彙整成一封

前提:台帳已經資料化

只有在「什麼事項・由誰負責・期限是何時」能以資料形式取得的情況下,才能把逾期催辦自動化。若台帳目前是共用資料夾中的 Excel、靠郵件附件流轉,請先考慮改用 SharePoint 清單(在「把 Excel 台帳替換成 SharePoint 清單」中討論過)。以下的前提是 SharePoint 清單已有「期限」「狀態」「承辦人」這幾個欄位。

在取得階段就先篩選

逾期項目的擷取,不要先取得清單全部項目再於流程內做條件分支,而是用 Get items 的篩選查詢(OData 篩選)在伺服器端先行篩選。14

DueDate lt '2026-07-18' and Status ne '完成'

日期的部分要嵌入第 4 章建立的「日本時間的今天」運算式。請注意,篩選查詢中的欄位名稱必須寫 SharePoint 的內部名稱,而非畫面上顯示的名稱;此外預設只會傳回 100 筆,項目數量多的清單需要指定上限(Top Count)或設定分頁。14

避免 Apply to each 地獄 ── 彙整成一封的做法

若直接把擷取結果丟進 Apply to each 逐筆寄信,只要承辦人 A 有 10 件未處理,每天早上就會收到 10 封信。這樣持續個幾週,通知肯定不會再被閱讀,提醒機制本身就會失效。依承辦人彙整成一封是原則。使用資料操作動作,可以照下面的流程組出來。7

  1. Select 從擷取結果建立承辦人電子郵件位址的陣列,再用 union() 去除重複,建立「今天應通知的承辦人清單」5
  2. 用 Apply to each 逐一跑過承辦人清單,在其中用 Filter array 擷取「僅屬於這位承辦人的項目」
  3. Create HTML table 整理成主旨・期限・狀態的表格,嵌入郵件(或 Teams 訊息)內文中只寄送一封(郵件的情況要啟用 HTML 顯示7)

全貌如下所示。

沒有Recurrence 觸發程序平日 早上9點 時區 - 大阪、札幌、東京建立日本時間的今天convertTimeZone國定假日主檔・公司休業日是否包含今天Terminate 已取消非營業日因此結束Get items擷取逾期且未完成的項目是否有符合對象結束 不發送通知以 Select 建立承辦人清單用 union 去除重複依承辦人逐一迴圈Filter array只擷取該承辦人的項目以 Create HTML table 整理成表格僅發送一封通知給承辦人Teams 或 Outlook將執行結果記錄到記錄用清單

Teams 與 Outlook 的使用區分

通知的出口,要依性質分別使用。

觀點 Teams(聊天・頻道) Outlook(郵件)
容易被注意到的程度 高。但容易被洗版埋沒 不容易讓人通知疲乏,但會被埋沒在收件匣中
記錄性 弱。事後不容易找到 會留存。可作為催辦的證據
收件對象 僅限公司內部 也能寄給公司外部
適合的通知 每天早上的未處理摘要等日常性的輕量通知 截止日的正式通知、需要留存催辦記錄的內容、寄給公司外部

常見的做法是:每日摘要用 Teams、結算日前的正式提醒與逾期催辦用郵件,如此區分。同一份內容兩邊都發,只會增加通知總量,並不建議這麼做。

不過度催辦的設計

提醒自動化最可怕的地方,是發送過量導致全部被忽視。人工催辦有「因為難以啟齒而自然抑制頻率」這種天然的煞車,但流程並沒有。必須靠設計把它加進去。

  • 設計總量。每天早上・對所有人・所有件數,是最糟糕的模式。日常發送只針對當天到期與逾期部分,事前提醒僅限 3 個營業日前與前一天這 2 次,像這樣收緊發送條件。
  • 加上分級。先只通知本人,若逾期持續 N 個營業日,再把主管加入收件人,像這樣分階段升級。若一開始就全部發給主管,通知就只會變成噪音。
  • 建立能停止的機制。務必準備一個出口:只要承辦人把清單的狀態欄位改成「完成」,隔天起就不再收到通知。若完成回報仍然停留在用郵件回覆的方式,流程就會持續催辦下去,承辦人也會開始討厭這個流程。
  • 維持「沒有收到通知=沒有問題」這件事值得信賴。這件事只有搭配下一章的監控才能成立。

7. 維運注意事項 ── 定期執行流程「停止了也不會被發現」

事件觸發的流程,業務端會察覺「明明申請了卻沒有動作」。但定期執行流程沒有這種偵測器。就算月底提醒停止運作,也不會有任何人反映,只會默默地延遲結算。維運設計上,請以以下規格為前提。

  • 流程有自動關閉的條件。觸發程序或動作持續失敗的流程會在 14 天後關閉,持續被節流的流程也同樣會在 14 天後關閉。此外,90 天內完全沒有被觸發過的流程也可能會被關閉(擁有進階授權或容量授權(Process 等)的擁有者不在此限;關閉前 30 天會通知擁有者・共同擁有者,重新開啟即可繼續)。8 若要建立「每季只動作一次的流程」,需要特別留意這個 90 天規則。
  • 執行記錄預設只能看到 28 天內的資料9 對月度流程來說,等於只能確認最近一次的紀錄。在流程最後加入一個步驟,把「執行日期時間・處理件數・結果」寫入一行到記錄用的 SharePoint 清單,就能不受執行記錄過期的影響,隨時確認「上個月是否有確實動作」。第 6 章圖示的最後放上記錄步驟,正是這個原因。
  • 讓流程本身具備察覺失敗的機制。若沒有加入失敗時通知管理員的分支(在執行條件設定中指定「失敗時」才執行的動作),在被自動關閉之前的 14 天內,不會有任何人發現失敗。錯誤處理與重試的組法,在「Power Automate 的錯誤處理與重試設計」中有詳細討論。
  • 擁有者離職・異動會連同排程一起停止。Recurrence 觸發程序的流程,是以流程建立者的連線來執行的。10 一旦擁有者的帳戶被停用,連線就會中斷,流程開始失敗,最終被關閉。請在啟用的第一天就完成共同擁有者的設定與連線的盤點。16 交接的實務做法整理在「Power Automate 的人員依賴對策 ── 讓建立者離職後流程也不會停止」中。
  • 關閉期間的部分不會補跑(第 3 章的陷阱 5)。因改版或故障應對而關閉流程時,要確認下一次的預定執行日期,若已跨過,就事先訂好用手動執行補上的維運方式。11

8. Power Automate 該做到什麼程度

定期執行是自動化很好的入口,但把「定期動作的東西」什麼都做成流程是很危險的。以下列出劃分界線的判斷基準。

情況 判斷
每天早上的未處理檢查、期限提醒、結算日前的一次性通知 Power Automate 的擅長領域。本文的架構就已足夠
包含營業日判定・提前至前一個營業日的通知 Power Automate + 國定假日主檔即可。需一併決定主檔更新的維運方式
數百件 × N 個營業日的計算、跨多個清單的比對彙整 用流程的迴圈會很吃力。應把邏輯移出流程,或歸入開發領域
結算日依交易對象而異、涉及紅沖藍複或重算的結算處理 分支會爆炸性增加,失敗時也需要回滾。屬於委外開發・專用系統的領域
跨核心系統資料庫的夜間批次處理 開發領域。交易・重跑・一致性的設計才是主體
只有一台伺服器、能在公司內部完結的檔案處理・資料庫處理定期執行 PowerShell + 工作排程器也是有力選項。比較請參考另一篇文章

感覺上,界線大概落在「讓人察覺到」為止用 Power Automate,「使其確定」(改寫核心資料)則交給開發。筆者見過好幾次想把結算處理本身用流程組出來、結果分支多到失控的案例,多數最後是重新拆分為「結算的執行交給既有系統或委外開發,只有防止漏結算的通知用流程」才穩定下來。另外,若是不經過雲端、能在伺服器內完結的定期處理,PowerShell 加工作排程器有時反而更單純、更容易維護。使用區分整理在「Power Automate 與 PowerShell、工作排程器的使用區分」中。

9. 總結

定期執行流程的設計,主體與其說是 Recurrence 觸發程序的設定,不如說在它的前面與後面。前面是把「靠看行事曆行動」的默會知識規格化。月底若遇到假日該怎麼辦?國定假日由誰在什麼時候登錄進主檔?沒有先決定好這些就做出來的流程,在日本的行事曆前必定會發生誤動作。後面則是用來察覺流程已經停止的維運:執行記錄 28 天、各種自動關閉的條件、擁有者離職導致排程停止。請以「定期執行流程會默默停止」為前提,從一開始就把失敗通知與執行記錄納入設計。

技術層面的要點可以歸納為三個:時間要明確指定時區(預設為 UTC)日期要先轉換成日本時間再判定國定假日以主檔管理,並在流程開頭用營業日守門擋下。掌握這三點之後,再把通知依承辦人彙整、為催辦加上分級與出口。做到這個地步,「靠人看行事曆行動」的業務中相當大一部分,就能放心地替換成定期執行流程。而當你開始想踏入結算處理、核心批次這類「使其確定」的處理時,就是該考慮切換到開發領域的時機了。

相關文章

相關諮詢領域

合同會社小村軟體的業務範圍,涵蓋以 Power Automate 進行的定期處理・提醒設計審查,到流程無法承擔的結算處理・營業日計算・核心系統連動批次的開發。

參考連結

  1. Microsoft Learn, Run a cloud flow on a schedule。關於建立排程雲端流程的步驟、在 Recurrence 觸發程序的時區欄位指定開始時間應視為哪個時區,以及開始時間的格式(YYYY-MM-DDTHH:MM:SSZ)的說明。  2 3

  2. Microsoft Learn, Schedule and run recurring workflows with the Recurrence trigger in Azure Logic Apps。關於未選擇時區時,開始時間會被解讀為結尾加 Z 的 UTC;頻率・間隔的指定;星期指定(weekDays)僅限頻率「週」使用、時間指定(hours/minutes)僅限頻率「日」「週」使用;未指定開始日期時間時,儲存的當下就會立即執行第一次;以及沒有詳細時間指定時,執行時間會依上一次執行的相對計算而產生偏移的說明。  2 3 4 5 6 7

  3. Microsoft Learn, Customize or format date and time values in a flow。關於 Power Automate 預設使用 UTC,以及結合 formatDateTime 與 convertTimeZone 處理當地時間的方法的說明。 

  4. Microsoft Learn, Default Time Zones。Windows 時區名稱清單。關於日本(UTC+09:00 大阪、札幌、東京)的時區名稱為「Tokyo Standard Time」的說明。  2

  5. Microsoft Learn, Reference guide to functions in expressions for workflows in Azure Logic Apps and Power Automate。關於運算式中可用的日期函數(utcNow、addDays、addToTime、startOfMonth、formatDateTime、dayOfWeek、convertTimeZone 等)與集合函數(union、createArray、contains、length 等)、range 函數的語法及第 2 個引數(個數)必須為正整數,以及數值函數(sub、int)的清單・語法的說明。也是確認不存在判定國定假日的函數的依據來源。  2 3 4 5 6 7 8 9

  6. 日本內閣府, 關於「國民的節日」。關於依國民的節日相關法律訂定的國定假日清單、春分之日・秋分之日於前一年確定並公布、補假的規定,以及提供自昭和 30 年至隔年為止的國定假日月日・名稱 CSV 的說明。  2

  7. Microsoft Learn, Use data operations。關於 Compose(建立)・Select・Filter array・Join・Create HTML table 等資料操作動作的用法與新增步驟;Compose 是用來避免重複輸入相同內容的動作、其輸出可供後續動作參照;Filter array 會把陣列篩選成僅符合條件的元素;以及以郵件寄送 HTML 表格時需要啟用 IsHtml 的說明。  2 3 4 5

  8. Microsoft Learn, Limits of automated, scheduled, and instant flows。關於重複間隔最小 60 秒・最大 500 天;觸發程序或動作持續失敗的流程會在 14 天後關閉;90 天內未被觸發的流程可能會被關閉(擁有進階・容量授權的擁有者除外,30 天前會通知擁有者・共同擁有者);以及持續被節流的流程會在 14 天後關閉的說明。  2 3

  9. Microsoft Learn, Missing runs or triggers history for a flow。關於流程的執行記錄預設只保存 28 天的說明。  2

  10. Microsoft Learn, Troubleshoot Power Automate trigger issues and errors。關於寫在觸發程序輸入中的運算式(utcNow() 等)會在流程儲存時被計算並固定、不會在每次執行時重新計算,以及 Recurrence 觸發程序的流程是以流程建立者的連線執行的說明。  2

  11. Microsoft Learn, Schedules for recurring workflow triggers in Azure Logic Apps。關於未選擇時區時,夏令時間切換會使執行時間偏移 1 小時;選擇時區後排程會自動追隨季節變化;以及 Recurrence 觸發程序不會把停止期間錯過的排程事後補跑、而是從下一個週期重新開始的說明。  2 3

  12. Microsoft Learn, Expression cookbook for cloud flows。關於 utcNow() 永遠傳回 UTC、dayOfWeek() 的傳回值為 0=週日~6=週六,以及用「大於 5」判定會漏掉週日的說明。  2 3 4

  13. Microsoft Learn, Convert a time zone。關於 convertTimeZone 運算式的引數(時間戳記・來源時區・目標時區・格式),以及具有相同功能的「轉換時區」動作的說明。  2

  14. Microsoft Learn, In-depth analysis into Get items and Get files SharePoint actions。關於 Get items 的 OData 篩選查詢(eq/ne/lt/gt 等、嵌入運算式)、預設取得件數為 100 筆可透過 Top Count 變更,以及超過 5,000 筆的清單需要設定分頁的說明。  2 3 4

  15. Microsoft Learn, Schema reference guide for trigger and action types in Azure Logic Apps。關於 Terminate 動作會停止執行並回傳指定的狀態(Succeeded/Cancelled/Failed),以及不能放在 Foreach 或 Until 迴圈中的說明。  2

  16. Microsoft Learn, Share a cloud flow。關於共同擁有者能做的事(編輯流程、更新連線的認證資訊等),以及連線與建立者帳戶綁定的說明。 

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

常見問題

整理諮詢這個主題時常見的問題。

要讓 Power Automate 的排程流程在日本時間每天早上 9 點執行,該怎麼做?
在 Recurrence 觸發程序的時區欄位選擇「(UTC+09:00) 大阪、札幌、東京」,並指定開始時間。若未指定時區,開始時間會被視為結尾加上 Z 的 UTC(協調世界時),因此若以為設定的是「9:00」,實際上會在日本時間 18 點執行。此外,運算式中的 utcNow() 也永遠傳回 UTC,因此在流程中使用「今天的日期」時,要先用 convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd') 轉換成日本時間之後再使用。
Power Automate 有判定日本國定假日的功能嗎?
內建功能中並未提供。雖然可以用 Recurrence 觸發程序的星期指定做到「僅在平日」執行,但不會考慮國定假日,運算式的函數中也沒有能傳回國定假日的函數。實務上的做法是自行準備一份保存國定假日日期的主檔(SharePoint 清單等),在流程開頭搜尋「今天是否在主檔中」,若不是營業日就結束執行。主檔的更新來源,可以使用內閣府公布的國定假日 CSV 作為一次來源。
可以做出只在每月底的營業日執行的流程嗎?
如果是「每月 20 日」這種固定日期,可以把開始日期時間設為目標日期,再把頻率設為「月」,就能以開始日期時間為基準,建立每月同一天・同一時間的執行。但另一方面,Recurrence 觸發程序並沒有能直接指定「每月底」的選項,而且能詳細指定星期或時間,也只限於頻率為「日」「週」的情況。像月底這種日期會變動的處理,要做成每天(或平日每天)執行的流程,在開頭用運算式判定「今天是不是月底」「今天是不是營業日」,不符合條件的日子就結束執行。月底的判定可以用「若今天的月份與明天的月份不同,今天就是月底」這樣的運算式來寫。「月底若逢週六日或國定假日則提前執行」,也是在同樣的架構上加入國定假日主檔的判定來表達。
定期執行流程不知不覺就被關閉了,這是為什麼?
Power Automate 有幾個會讓流程自動關閉的條件。觸發程序或動作持續失敗的流程會在 14 天後關閉,持續被節流(超過限制)的流程也同樣會在 14 天後關閉。此外,90 天內完全沒有被觸發過的流程也可能會被關閉(擁有者若持有進階授權或容量授權則不在此限,關閉前 30 天會通知擁有者・共同擁有者)。定期執行流程即使停止,也很難有人察覺,因此從一開始就把失敗通知與執行記錄納入設計非常重要。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽