Проектирование регулярных потоков в Power Automate — практика обработки конца месяца, проверки рабочих дней и напоминаний
· Го Комура · Power Automate, Облачный поток, Регулярное выполнение, Рабочий день, Праздничные дни, SharePoint, Microsoft 365, Автоматизация бизнес-процессов, Техническая консультация
«Когда приближается конец месяца, бухгалтерия рассылает по отделам письма: “срок сдачи авансовых отчётов — такое-то число”». «Каждое утро после начала работы кто-то открывает список заказов и на глаз проверяет, не осталось ли необработанных». «Документы с истёкшим сроком подачи сверяют с реестром и по одному напоминают о просрочке». Даже в компаниях, уже внедривших Microsoft 365, подобной работы «человек смотрит в календарь и действует» остаётся на удивление много. Забыть об этом — значит создать проблему, а единственный механизм против забывчивости — память ответственного сотрудника и его календарь Outlook.
Плановое выполнение Power Automate (триггер Recurrence) позволяет автоматизировать такую регулярную работу. Но стоит только попытаться реально построить это под японские бизнес-процессы, как сразу натыкаешься на три препятствия: время по умолчанию — UTC (всемирное координированное время); понятия «рабочий день» во встроенном функционале не существует; а определение «конец месяца» или «20-е число — день закрытия» приходится писать выражениями самостоятельно. В этой статье разберём спецификацию и ловушки триггера Recurrence, набор инструментов для работы с датами, определение рабочих дней по мастер-списку праздников, проектирование напоминаний без излишней навязчивости и эксплуатационные риски, характерные именно для плановых потоков.
Также отметим: о том, как в целом обрабатывать в системах японские требования к датам — японский календарь эпох, праздники и дни закрытия, — подробно написано в отдельной статье «Японская эра, праздники и даты закрытия периода в бизнес-приложениях — устойчивый к смене эры дизайн, JapaneseCalendar и расчёт рабочих дней на практике». Эта статья — практическое применение тех же идей к потокам Power Automate.
1. Сначала вывод
- Время триггера Recurrence трактуется как UTC, если часовой пояс не указан явно. Чтобы избежать ситуации, когда «каждое утро в 9» на деле запускается в 18:00 по японскому времени, выбирайте в поле часового пояса «(UTC+09:00) Осака, Саппоро, Токио» и явно указывайте время начала.12
- «Выполнение только по будням» строится через частоту «Неделя» + выбор дней недели (пн–пт). Но праздники при этом не учитываются. Фиксированную дату вроде «20-го числа каждого месяца» можно задать датой начала + частотой «Месяц», но переменную дату — «в последний день месяца», «в предыдущий рабочий день, если день закрытия выпадает на выходной» — указать нельзя, поэтому практическое решение — «выполнять ежедневно и проверять выражением».2
utcNow()внутри выражений тоже всегда возвращает UTC. «Сегодня» по японскому времени нужно получать черезconvertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time'). Если забыть о преобразовании в потоке, работающем в районе 8 утра, «сегодня» окажется вчерашним днём.34- Встроенного механизма определения японских праздников не существует. Функции праздников нет и в списке функций выражений5, поэтому стандартный подход — завести собственный мастер-список праздников (например, список SharePoint) и в начале потока проверять, является ли сегодняшний день рабочим, завершая выполнение, если нет. В качестве первичного источника для мастер-списка можно использовать CSV с праздниками от Канцелярии Кабинета министров.6
- Напоминания стоит собирать не «одно письмо на запись», а одно письмо на ответственного, объединяя все его записи. Действия по работе с данными вроде Filter array и Create HTML table позволяют собрать это читаемо, избегая вложенных Apply to each.7
- Плановый поток трудно заметить, если он «не работает». Проектируйте уведомления о сбоях и журнал выполнения с самого начала, исходя из того, что поток отключается через 14 дней непрерывных сбоев, через 90 дней без единого срабатывания триггера, а история выполнения по умолчанию хранится всего 28 дней.89
2. Инвентаризация работы «человек смотрит в календарь и действует»
Первым делом нужно не строить поток, а выявить всю работу, «управляемую взглядом на календарь», и рассортировать её по пригодности для планового выполнения.
| Задача | Совместимость с плановым выполнением | Примечание |
|---|---|---|
| Ежеутренняя проверка необработанного и аномалий (заказы, заявки, склад) | Подходит | Предполагает, что условие можно выразить через столбец списка |
| Массовые напоминания перед концом месяца/днём закрытия (авансовые отчёты, закрытие табеля) | Подходит | Требует формализации корректировки по рабочим дням (перенос на предыдущий рабочий день, если конец месяца — выходной) |
| Напоминания о просроченных сроках подачи (документы, отчёты, зависшие согласования) | Подходит | Предполагает, что реестр уже представлен данными (например, список SharePoint) |
| Формирование и рассылка периодических отчётов | Подходит с оговорками | Если агрегация простая — подходит поток, если сложная — поток отвечает только за рассылку |
| Ежемесячные финализирующие операции вроде выставления счетов и оплаты (закрытие, сторно, пересчёт) | Чаще не подходит | Много ветвлений и исключений, при сбое требуется откат (глава 8) |
| Ночные пакетные задания, затрагивающие несколько базовых систем | Не подходит | Это область разработки; основа — проектирование повторного запуска и согласованности данных |
Критериев отбора три: можно ли выразить условие данными (случай «вроде бы что-то подозрительное» автоматизировать нельзя), можно ли сформулировать словами правило дня выполнения и можно ли восстановиться на следующий день после сбоя (то, что нельзя, — область разработки из главы 8).
Из этих трёх второй критерий в японской практике оказывается самым сложным. Даже фраза «напоминание о закрытии в конце каждого месяца» на деле означает, что человек вносит корректировки вроде «если конец месяца выпадает на выходной или праздник, перенести на предыдущий рабочий день, а в год с Golden Week отправить до начала долгих выходных». Считайте, что именно перевод этого неявного знания в явную спецификацию — и есть основная работа по созданию потока. Если оставить этот момент расплывчатым и просто построить поток, доверие будет потеряно в духе «напоминание о просрочке ушло в праздник» или «напоминание перед долгими выходными пришло уже во время них».
3. Основы и ловушки триггера Recurrence
Плановый облачный поток создаётся как «Запланированный облачный поток» (Scheduled cloud flow), а частота и интервал задаются триггером Recurrence (повторение).1 Частоту можно выбрать из секунд, минут, часов, дней, недель или месяцев; минимальный интервал — 60 секунд, максимальный — 500 дней.8 Сама спецификация проста, но именно у этого триггера немало ловушек.
Ловушка 1. По умолчанию UTC — «должно было быть в 9, а сработало в 18»
Это самая частая ошибка. Если часовой пояс не выбран, время начала триггера Recurrence трактуется в формате UTC с завершающей буквой Z (YYYY-MM-DDThh:mm:ssZ). Если в поле часового пояса выбрать Японию, время начала будет трактоваться как локальное время этого пояса (YYYY-MM-DDThh:mm:ss, без Z).12 Для потока, который должен «уведомлять каждое утро в 9», правильное решение — установить часовой пояс «(UTC+09:00) Осака, Саппоро, Токио» и время начала 9:00.
Ловушка 2. Без указания времени начала поток срабатывает сразу же при сохранении
Если дата и время начала не указаны, первое выполнение запускается сразу же в момент сохранения потока.2 Во время тестирования это не страшно, но может обернуться аварией, если поток с рассылкой напоминаний сохранят вечером — и напоминания тут же уйдут всем. Дату и время начала указывайте обязательно.
Кроме того, если не задать в дополнительных параметрах «время выполнения» (these hours/these minutes), время каждого следующего запуска рассчитывается относительно предыдущего, поэтому накопленные задержки постепенно сдвигают (дрейфуют) фактическое время выполнения.2 Для потока, который должен работать в фиксированное время каждый день, безопаснее явно указать и время выполнения в дополнение к дате начала.
Ловушка 3. «Только по будням» реализуемо, но детальная настройка для месяца ограничена
При частоте «Неделя» можно выбрать дни недели (пн–пт), а при частоте «День» или «Неделя» — задать и время выполнения (часы, минуты). То есть «только в 9 утра по будням» строится одними настройками триггера. А вот эти детальные опции доступны только для частот «День» и «Неделя»: у частоты «Месяц» нет поля для указания даты вроде «20-е число каждого месяца» или «последний день месяца».2
Впрочем, если дата фиксированная и месячная, запускать поток ежедневно не нужно. Если задать дату начала на нужный день (например, 20-е число следующего месяца, 9:00) и установить частоту «Месяц», выполнение будет происходить ежемесячно, отталкиваясь от даты начала, так что «9:00 20-го числа каждого месяца» строится только настройками триггера.2 Не стоит запускать 365 раз в день поток, которому достаточно 12 срабатываний в месяц, отбрасывая лишние проверкой условия, — это затрудняет чтение истории выполнения и впустую расходует лимит запросов.
Конструкция «выполнять ежедневно и проверять выражением в начале потока, является ли сегодня нужной датой» требуется для месячной работы с переменной датой. Такие даты, как «последний день месяца» (от 28 до 31 в зависимости от месяца), «предыдущий рабочий день, если 20-е число выпадает на выходной или праздник» или «N-й рабочий день каждого месяца», в триггере не выразить. Это выражение мы разберём в следующей главе. Кроме того, фиксированная дата начала на 29–31 число требует отдельной проверки поведения для месяцев, где такого дня не существует, поэтому обработку около конца месяца безопаснее с самого начала строить по схеме «ежедневный запуск + проверка».
Ловушка 4. Летнее время — актуально только для зарубежных офисов
Если задать время в UTC, не выбирая часовой пояс, то в регионах с летним временем (DST) при каждом переходе время выполнения сдвигается на час. Если же часовой пояс выбран, расписание автоматически следует за сезонными переходами.10 В Японии летнего времени нет, поэтому для чисто внутренних процессов реального вреда не будет, но если один и тот же поток обслуживает уведомления для зарубежного офиса, для него нужно явно выбрать соответствующий часовой пояс.
Ловушка 5. Выражение, записанное в триггере, фиксируется в момент сохранения
Если записать в поле ввода триггера выражение вроде utcNow(), его значение вычисляется и фиксируется в момент сохранения потока. При каждом выполнении оно заново не пересчитывается.11 Идея «впишу выражение в триггер, чтобы время начала стало сегодняшним» просто не сработает — это стоит запомнить.
Ловушка 6. Пропущенные во время отключения запуски задним числом не выполняются
Триггер Recurrence не обрабатывает задним числом пропущенные за время отключения запуски, а просто возобновляет работу со следующего цикла.10 Вполне возможна ситуация: поток обработки конца месяца отключили на несколько дней для доработки, а этот период как раз захватил дату выполнения — и в этом месяце обработка так и не запустилась. Поэтому, отключая плановый поток, заведите правило сначала проверять дату следующего запланированного выполнения.
4. Набор инструментов для расчёта дат — определяем конец месяца, начало месяца и день закрытия выражениями
Расчёт дат внутри потока выполняется теми же выражениями (функциями), что и в Logic Apps.5 Отправная точка: utcNow() всегда возвращает текущее время в UTC.12 Поэтому конструкция, при которой в самом начале потока создаётся «сегодня по японскому времени», сохраняется в переменную (или Compose) и используется повторно дальше, делает выражения гораздо более читаемыми.
convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd')
convertTimeZone(метка_времени, исходный_пояс, целевой_пояс, формат) — функция преобразования часового пояса13, а название часового пояса берётся из списка часовых поясов Windows. Для Японии это «Tokyo Standard Time».4 Если писать выражение не хочется, есть аналогичное по смыслу действие «Преобразование часового пояса» (Convert time zone).13
Преобразование обязательно потому, что между UTC и японским временем разница в 9 часов. До 9 утра по японскому времени в UTC всё ещё предыдущий день. Если в потоке, работающем в 8 утра, написать formatDateTime(utcNow(), 'yyyy-MM-dd'), в качестве «сегодня» вернётся вчерашняя дата. Такое расхождение проявляется или не проявляется в зависимости от времени выполнения, поэтому на тестировании его легко пропустить, и в продакшене оно всплывает в духе «обработка, предназначенная для начала месяца, сработала ещё и в последний день предыдущего месяца».
Ниже собраны шаблоны проверок после того, как создано «сегодня по японскому времени» (далее — Сегодня).
| Что нужно сделать | Пример выражения | Примечание |
|---|---|---|
| Получить день недели | 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'))) |
«Если месяц сегодня отличается от месяца завтра — сегодня конец месяца». Корректно работает и для февраля, и для високосных лет |
| Дата конца текущего месяца | addDays(startOfMonth(addToTime(Сегодня, 1, 'Month')), -1, 'yyyy-MM-dd') |
Выводится как «день перед началом следующего месяца» — не нужно учитывать число дней в месяце |
| N дней назад/вперёд | addDays(Сегодня, -3) / addDays(Сегодня, 7) |
Сложение/вычитание календарных дней. Расчёт по рабочим дням — в главе 5 |
Все функции addDays, addToTime, startOfMonth, formatDateTime, dayOfWeek определены в общем справочнике выражений Logic Apps и Power Automate.5 Сами комбинированные выражения из таблицы — авторский паттерн реализации, поэтому при внедрении обязательно протестируйте их на датах, захватывающих конец и начало месяца, а также високосный год (29 февраля), прежде чем выводить в продакшен. О том, насколько опасны датовые баги, проявляющиеся только в конкретный день, и как выбирать даты для предварительного тестирования, подробно написано в главе 4 статьи «Японская эра, праздники и даты закрытия периода в бизнес-приложениях».
5. Определение рабочего дня — храним праздники в мастер-списке
Встроенного определения праздников не существует
Повторим ещё раз: в Power Automate нет встроенной функции для определения японских праздников. Указание дня недели в триггере Recurrence буквально смотрит только на день недели, а в списке функций выражений есть лишь сложение/вычитание дат, форматирование и преобразование часовых поясов — функции, возвращающей «является ли этот день праздником», там нет.5 О том, что вычислить праздники формулой в принципе невозможно (дни весеннего и осеннего равноденствия утверждаются только в предыдущем году, а сами праздники сдвигаются из-за изменений законодательства и специальных мер), подробно написано в главе 3 статьи «Японская эра, праздники и даты закрытия периода в бизнес-приложениях». Вывод тот же: правильный подход — хранить праздники как данные (мастер-список) и поддерживать их актуальность операционно.
Проще всего организовать это в Power Automate через список SharePoint «Мастер-список праздников» (столбец с датой + столбец с названием). В качестве первичного источника подойдёт CSV дат и названий праздников с 1955 года по следующий год, публикуемый Канцелярией Кабинета министров (переносимые выходные дни включены туда же отдельными строками).6 Поскольку публикуются только уже утверждённые данные, проектирование должно включать и то, что раз в год задачу занесения дат следующего года в мастер-список нужно внести в производственный календарь. Если про обновление забыть, это напрямую превратится в сбой — напоминание уйдёт в праздничный день следующего года. Кроме того, нерабочие дни компании вроде летних каникул или дня основания компании не стоит смешивать с мастер-списком праздников — заведите для них отдельный список. Причина в том, что набор нерабочих дней, который нужно учитывать, различается в зависимости от задачи: «при определении срока банковского перевода смотрим только на праздники», а «для внутренних напоминаний нужно учитывать и нерабочие дни компании».
«Защита от нерабочего дня» в начале потока
Для потока, который должен работать только в рабочие дни, помимо указания дней недели в Recurrence (пн–пт), в начале потока размещают следующую проверку.
- Создать «сегодня по японскому времени» (глава 4)
- Выполнить SharePoint-действие «Получение нескольких элементов» (Get items) по мастер-списку праздников и найти сегодняшнюю дату через фильтр-запрос вида
HolidayDate eq 'Сегодня'14 - Выполнить такой же поиск по списку нерабочих дней компании
- Если найдено хотя бы одно совпадение, остановить выполнение действием «Завершение» (Terminate)
Terminate — это действие, которое немедленно останавливает выполнение потока и завершает его в указанном состоянии (успех/сбой/отмена); внутрь Apply to each или Do until его поместить нельзя.15 Если задать здесь состояние «Отменено» (Cancelled), в истории выполнения можно будет с первого взгляда отличить «день, пропущенный как нерабочий» от «дня, когда обработка реально выполнялась». Это заметно упрощает последующее расследование по сравнению с тем, если бы все запуски отмечались как «успешные».
«Перенос на предыдущий рабочий день» и «за N рабочих дней»
На практике для напоминания о закрытии в конце месяца нужен не «каждый конец месяца», а «предыдущий рабочий день, если конец месяца — нерабочий». Это выражается в потоке, выполняющемся каждый рабочий день, как условие «сегодня — рабочий день, и с завтра до конца месяца нет ни одного рабочего дня». Реализуется это перебором дат от завтра до даты конца месяца (выражение из главы 4): как только находится день, который не выходной и отсутствует в мастер-списке праздников, делается вывод «сегодня не последний рабочий день», и цикл прерывается.
За N рабочих дней, например «напомнить за 3 рабочих дня до срока оплаты», переосмысливается точно так же. «Наступило N рабочих дней до срока» заменяется на «выполнять каждый рабочий день, считать число рабочих дней от сегодня до срока и сравнивать с N». Подсчёт рабочих дней сводится к подсчёту дней, которые «не выходные, отсутствуют в мастер-списке праздников и отсутствуют в списке нерабочих дней компании». Однако обработка, в которой поток перебирает даты по одному дню в цикле, при количестве объектов свыше нескольких сотен превращается в цикл «количество записей × количество дней», раздувая и время выполнения, и число обращений к API. При таком масштабе разумнее вынести расчёт рабочих дней за пределы потока (в таблицу рабочих дней в базе данных или небольшой API) либо отнести его к области разработки из главы 8.
6. Проектирование напоминаний и уведомлений о просрочке — одно письмо на ответственного
Предпосылка: реестр должен быть представлен данными
Автоматизировать напоминания о просрочке можно только тогда, когда «что, за кем закреплено и каков срок» доступно в виде данных. Если реестр до сих пор существует как Excel-файл в общей папке, который рассылают вложением по почте, сначала стоит рассмотреть перенос на список SharePoint (это разобрано в статье «Замена Excel-реестра на список SharePoint»). Далее предполагается, что в списке SharePoint уже есть столбцы «Срок», «Статус» и «Ответственный».
Фильтрация уже на этапе получения данных
Записи с истёкшим сроком стоит отбирать не так, что сначала забирается весь список, а условие проверяется внутри потока, — фильтрацию нужно выполнять на стороне сервера через фильтр-запрос (OData-фильтр) действия Get items.14
DueDate lt '2026-07-18' and Status ne 'Выполнено'
В часть с датой подставляется выражение «сегодня по японскому времени» из главы 4. Учтите, что имена столбцов в фильтр-запросе нужно писать не отображаемыми на экране названиями, а внутренними именами SharePoint, а также что по умолчанию возвращается не более 100 записей, поэтому для больших списков нужно указывать лимит (Top Count) или настраивать пагинацию.14
Как избежать ада Apply to each — собираем всё в одно письмо
Если просто прогонять результаты выборки через Apply to each и отправлять письмо на каждую запись, то при 10 необработанных записях у сотрудника A каждое утро будет приходить 10 писем. Продержись это несколько недель — уведомления гарантированно перестанут читать, и сам механизм напоминаний умрёт. Принцип таков: уведомления объединяются в одно письмо на каждого ответственного. С помощью действий по работе с данными это строится так.7
- Действием Select создать из результатов выборки массив email-адресов ответственных, а функцией
union()убрать дубликаты и получить «список ответственных, которых нужно уведомить сегодня».5 - Прогнать список ответственных через Apply to each, а внутри с помощью Filter array отобрать «только записи этого ответственного».
- Действием Create HTML table оформить их в таблицу с темой, сроком и статусом, вставить в тело письма (или сообщения Teams) и отправить только одно сообщение (для писем нужно включить отображение HTML7).
Вот как выглядит всё в целом.
flowchart TD
Rec[Триггер Recurrence<br/>будни, 9:00 утра, часовой пояс: Осака, Саппоро, Токио] --> Today[Создать «сегодня» по японскому времени<br/>convertTimeZone]
Today --> Hol{Есть ли сегодняшняя дата<br/>в мастер-списке праздников/нерабочих дней компании}
Hol -- Есть --> Term[Terminate, Отменено<br/>завершение: не рабочий день]
Hol -- Нет --> Get[Get items<br/>отбор просроченных и незавершённых]
Get --> Any{Есть подходящие записи?}
Any -- Нет --> End([Завершение без уведомления])
Any -- Есть --> Sel[Select: составить список ответственных<br/>union для удаления дублей]
Sel --> Each[Цикл по каждому ответственному]
Each --> Filter[Filter array<br/>отобрать записи только этого ответственного]
Filter --> Table[Create HTML table: оформить в таблицу]
Table --> Send[Отправить ответственному одно уведомление<br/>Teams или Outlook]
Send --> Log[Записать результат выполнения в список-журнал]
Выбор между Teams и Outlook
Канал уведомлений выбирают исходя из характера сообщения.
| Критерий | Teams (чат/канал) | Outlook (письмо) |
|---|---|---|
| Заметность | Высокая, но легко теряется в потоке сообщений | Реже вызывает усталость от уведомлений, но может затеряться во входящих |
| Фиксация | Слабая, потом трудно найти | Сохраняется, годится как подтверждение напоминания |
| Получатели | Только внутри компании | Можно отправлять и вовне |
| Подходящие уведомления | Лёгкие ежедневные уведомления вроде утренней сводки необработанного | Официальные извещения о сроках, случаи, где нужна фиксация напоминания, внешние получатели |
Стандартная схема — ежедневные сводки через Teams, а официальные напоминания перед днём закрытия и уведомления о просрочке через почту. Дублировать одно и то же содержимое в оба канала не рекомендуется — это лишь увеличивает общий объём уведомлений.
Проектирование без излишней назойливости
Самое страшное при автоматизации напоминаний — разослать их так много, что их начнут игнорировать целиком. У напоминаний, которые отправляет человек, есть естественный тормоз — «неловко напоминать слишком часто», — а у потока его нет. Этот тормоз нужно закладывать в проектирование.
- Спроектировать общий объём. Худший вариант — каждое утро, всем, по всем записям. Сужайте условия отправки: например, ежедневно отправлять только по записям с сегодняшним сроком и просроченным, а предварительные напоминания ограничить двумя случаями — за 3 рабочих дня и накануне.
- Ввести градацию. Сначала уведомлять только самого ответственного, а после N рабочих дней просрочки добавлять в получатели руководителя — так разделяется эскалация. Если отправлять всё руководителю сразу с самого начала, уведомления превращаются в простой шум.
- Предусмотреть способ остановки. Обязательно оставьте выход: как только ответственный переводит столбец статуса в списке на «Выполнено», со следующего дня уведомления прекращаются. Если отчёт о выполнении так и остаётся ответом на письмо, поток продолжает слать напоминания, а ответственный начинает ненавидеть сам поток.
- Сохранять доверие к тому, что «нет уведомления = нет проблемы». Это работает только в связке с мониторингом из следующей главы.
7. Эксплуатационные нюансы — плановый поток «не даёт заметить, что остановился»
В потоке, запускаемом событием, бизнес-сторона сама заметит: «подал заявку, а ничего не произошло». У планового потока такого детектора нет. Если напоминание о конце месяца перестало работать, никто ничего не скажет — просто задержится закрытие. При проектировании эксплуатации исходите из следующих особенностей.
- Есть условия, при которых поток отключается автоматически. Поток, у которого триггер или действия продолжают завершаться ошибкой, отключается через 14 дней; поток, который постоянно подвергается троттлингу, тоже отключается через 14 дней. Кроме того, поток, который ни разу не сработал за 90 дней, может быть отключён (это не касается потоков, чей владелец имеет премиум-лицензию или лицензию на ёмкость, например Process; за 30 дней до отключения владельцу и совладельцам приходит уведомление, и включив поток заново, можно продолжить работу).8 Если вы создаёте «поток, который срабатывает раз в квартал», это правило 90 дней нужно обязательно учитывать.
- История выполнения по умолчанию видна только за 28 дней.9 Для ежемесячного потока это означает, что можно проверить только самый последний запуск. Если добавить в конце потока шаг, добавляющий одну строку «дата и время выполнения, число обработанных записей, результат» в список-журнал SharePoint, вопрос «действительно ли поток отработал в прошлом месяце» можно будет проверить независимо от истечения срока истории. Именно поэтому запись в журнал стоит последним шагом на схеме из главы 6.
- Дайте самому потоку механизм для обнаружения сбоя. Без ветки, уведомляющей администратора при сбое (действие, запускаемое условием выполнения «в случае сбоя»), никто не заметит сбой в течение 14 дней до автоматического отключения. Построение обработки ошибок и повторов подробно разобрано в статье «Обработка ошибок и повторные попытки в Power Automate».
- Уход или перевод владельца останавливает всё расписание целиком. Поток с триггером Recurrence выполняется через подключение создателя потока.11 Если учётная запись владельца отключена, подключение обрывается, поток начинает давать сбои и в итоге отключается. Настройку совладельцев и инвентаризацию подключений нужно завершить уже в первый день эксплуатации.16 Практика передачи дел разобрана в статье «Меры против привязки Power Automate к одному человеку — владельцы, подключения, передача дел».
- Пропущенные за время отключения запуски не выполняются позже (ловушка 6 из главы 3). Отключая поток для доработки или устранения сбоя, проверяйте дату следующего планового запуска и заранее решайте, как восполнить пропуск вручную, если период отключения его захватил.10
8. Насколько далеко доверять Power Automate
Плановое выполнение — отличная точка входа в автоматизацию, но превращать в поток вообще всё, что «работает регулярно», опасно. Вот примерные ориентиры для проведения границы.
| Ситуация | Решение |
|---|---|
| Ежеутренняя проверка необработанного, напоминания о сроках, массовые уведомления перед днём закрытия | Сильная сторона Power Automate. Схемы из этой статьи достаточно |
| Уведомления, включающие определение рабочего дня и перенос на предыдущий рабочий день | Реализуемо через Power Automate + мастер-список праздников. Нужно только заранее определить регламент обновления мастер-списка |
| Расчёты вида «несколько сотен записей × N рабочих дней», агрегация с сопоставлением нескольких списков | Циклы потока с этим справляются плохо. Логику нужно выносить наружу либо передавать в область разработки |
| Обработка закрытия, где срок различается по контрагентам и задействованы сторнирующие корректировки и пересчёт | Ветвления разрастаются лавинообразно, при сбое нужен откат. Область подрядной разработки или выделенной системы |
| Ночной пакетный процесс, затрагивающий базу данных базовой системы | Область разработки. Основа — проектирование транзакций, повторного запуска и согласованности |
| Плановая обработка файлов/БД, полностью укладывающаяся в один внутренний сервер | Сильный вариант — PowerShell + Планировщик заданий. Сравнение — в отдельной статье |
На уровне ощущения граница проходит примерно так: всё, что доходит до «дать заметить», — область Power Automate, а «зафиксировать окончательно» (переписать данные базовой системы) — область разработки. Не раз приходилось видеть проекты, где саму обработку закрытия пытались построить потоком и она обрастала ветвлениями до неузнаваемости; обычно всё стабилизировалось после разделения: «само выполнение закрытия — на существующей системе или через подрядную разработку, а поток отвечает только за уведомление, предотвращающее забывчивость». Кроме того, для плановой обработки, полностью укладывающейся в один сервер без выхода в облако, PowerShell и Планировщик заданий иногда оказываются проще и удобнее в поддержке. Выбор между ними разобран в статье «Выбор между Power Automate и PowerShell/Планировщиком заданий».
9. Итоги
Суть проектирования планового потока лежит не столько в настройке самого триггера Recurrence, сколько в том, что стоит до и после него. До — это формализация неявного знания «действовать, глядя в календарь»: что делать, если конец месяца выпадает на выходной, кто и когда вносит праздники в мастер-список. Поток, построенный без решения этих вопросов, обязательно даст сбой перед лицом японского календаря. После — это эксплуатационная практика, позволяющая заметить остановку: 28 дней истории выполнения, условия автоматического отключения, расписание, останавливающееся из-за ухода владельца. Стройте уведомления о сбоях и журнал выполнения с самого начала, исходя из того, что плановый поток останавливается молча.
Технические моменты сводятся к трём пунктам: явно указывать часовой пояс для времени (по умолчанию UTC), преобразовывать дату в японское время перед проверкой и хранить праздники в мастер-списке, отсекая нерабочие дни защитой в начале потока. Освоив эти три пункта, объединяйте уведомления по ответственным и снабжайте напоминания градацией и выходом. Сделав всё это, значительную часть работы «человек смотрит в календарь и действует» можно заменить плановым потоком, которому можно спокойно доверять. А момент, когда захочется вторгнуться в «окончательную фиксацию» — обработку закрытия или пакетные задания базовой системы, — самое время задуматься о переходе в область разработки.
Похожие статьи
- Автоматизация бизнес-процессов с Power Automate — выбор между облачным потоком и потоком рабочего стола, проектирование обработки ошибок
- Японская эра, праздники и даты закрытия периода в бизнес-приложениях — устойчивый к смене эры дизайн, JapaneseCalendar и расчёт рабочих дней на практике
- Обработка ошибок и повторные попытки в Power Automate — как не допустить, чтобы работающий поток незаметно остановился
- Меры против привязки Power Automate к одному человеку — владельцы, подключения, передача дел
- Выбор между Power Automate и PowerShell/Планировщиком заданий
Смежные области консультирования
KomuraSoft LLC (合同会社小村ソフト) занимается ревью проектирования регулярных процессов и напоминаний на Power Automate, а также разработкой обработки закрытия, расчёта рабочих дней и пакетных заданий интеграции с базовыми системами — там, где возможностей потока уже не хватает.
Справочные ссылки
-
Microsoft Learn, Run a cloud flow on a schedule. О процедуре создания запланированного облачного потока, о указании часового пояса, в котором трактуется время начала триггера Recurrence, и о формате времени начала (YYYY-MM-DDThh:mm:ssZ). ↩ ↩2 ↩3
-
Microsoft Learn, Schedule and run recurring workflows with the Recurrence trigger in Azure Logic Apps. О том, что при невыбранном часовом поясе время начала трактуется как UTC с завершающей Z, об указании частоты и интервала, о том, что выбор дней недели (weekDays) доступен только при частоте «Неделя», а указание времени (hours/minutes) — только при частоте «День»/«Неделя», о том, что без указания даты начала первое выполнение запускается сразу при сохранении, и о дрейфе времени выполнения при относительном расчёте от предыдущего запуска без детального указания времени. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, Customize or format date and time values in a flow. О том, что Power Automate по умолчанию использует UTC, и о комбинировании formatDateTime и convertTimeZone для работы с локальным временем. ↩
-
Microsoft Learn, Default Time Zones. Список названий часовых поясов Windows. О том, что название часового пояса Японии (UTC+09:00, Осака, Саппоро, Токио) — «Tokyo Standard Time». ↩ ↩2
-
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 и др.). Источник, подтверждающий отсутствие функции для определения праздников. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
Кабинет министров Японии, «О национальных праздниках». Перечень праздников согласно закону о национальных праздниках, о том, что дни весеннего и осеннего равноденствия утверждаются и публикуются в предыдущем году, о правиле переносимых выходных и о наличии CSV с датами и названиями праздников с 1955 года по следующий год. ↩ ↩2
-
Microsoft Learn, Use data operations. Об использовании действий по работе с данными Select, Filter array, Join, Create HTML table и др., а также о включении IsHtml при отправке HTML-таблицы по почте. ↩ ↩2 ↩3
-
Microsoft Learn, Limits of automated, scheduled, and instant flows. О минимальном интервале повторения в 60 секунд и максимальном в 500 дней, об отключении через 14 дней потоков с непрерывными сбоями триггера или действий, о возможном отключении потока, не срабатывавшего 90 дней (не касается владельцев премиум- и ёмкостных лицензий, уведомление владельцу и совладельцам приходит за 30 дней), и об отключении через 14 дней потоков с постоянным троттлингом. ↩ ↩2 ↩3
-
Microsoft Learn, Missing runs or triggers history for a flow. О том, что история выполнения потока по умолчанию хранится только 28 дней. ↩ ↩2
-
Microsoft Learn, Schedules for recurring workflow triggers in Azure Logic Apps. О сдвиге времени выполнения на час при переходе на летнее время без выбранного часового пояса, о том, что выбор часового пояса позволяет расписанию следовать за сезонными изменениями, и о том, что триггер Recurrence не обрабатывает задним числом пропущенные во время остановки расписания, а возобновляет работу со следующего цикла. ↩ ↩2 ↩3
-
Microsoft Learn, Troubleshoot Power Automate trigger issues and errors. О том, что выражение, записанное в поле ввода триггера (например, utcNow()), вычисляется и фиксируется в момент сохранения потока и не пересчитывается при каждом выполнении, а также о том, что поток с триггером Recurrence выполняется через подключение создателя потока. ↩ ↩2
-
Microsoft Learn, Expression cookbook for cloud flows. О том, что utcNow() всегда возвращает UTC, что dayOfWeek() возвращает значения от 0 (воскресенье) до 6 (суббота), и о том, что проверка «больше 5» пропускает воскресенье. ↩ ↩2 ↩3
-
Microsoft Learn, Convert a time zone. Об аргументах выражения convertTimeZone (метка времени, исходный пояс, целевой пояс, формат) и об эквивалентном действии «Преобразование часового пояса». ↩ ↩2
-
Microsoft Learn, In-depth analysis into Get items and Get files SharePoint actions. О фильтр-запросе OData действия Get items (eq/ne/lt/gt и др., подстановка выражений), о том, что по умолчанию возвращается 100 записей с возможностью изменения через Top Count, и о настройке пагинации для списков свыше 5000 записей. ↩ ↩2 ↩3
-
Microsoft Learn, Schema reference guide for trigger and action types in Azure Logic Apps. О том, что действие Terminate останавливает выполнение и возвращает указанное состояние (Succeeded/Cancelled/Failed), и о невозможности разместить его внутри циклов Foreach или Until. ↩
-
Microsoft Learn, Share a cloud flow. О том, что может делать совладелец (редактировать поток, обновлять учётные данные подключения и т. п.), и о привязке подключения к создавшему его пользователю. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Создание процесса согласования в Power Automate — переводим бумажные и почтовые заявки в электронный вид
Практическое руководство по переводу в электронный вид бумажных заявок на согласование и запросов из Excel-вложений с помощью Power Autom...
Автоматическая обработка PDF-файлов заказов и счетов, приходящих по почте, в Power Automate — проектирование сохранения, распределения, уведомлений и распознавания
Разбираем проектирование автоматизации сохранения, распределения и уведомлений для PDF-файлов заказов и счетов, приходящих по почте, сред...
Обработка ошибок и повторные попытки в Power Automate — как не допустить, чтобы работающий поток незаметно остановился
Сборник паттернов проектирования, которые не дают потокам Power Automate незаметно останавливаться: значения политики повторов по умолчан...
Перенос макросов Excel VBA на Power Automate — что можно заменить Office Scripts, а что оставить как VBA
Разбираем, можно ли перенести макросы Excel VBA на Power Automate: что заменяется Office Scripts, что умеет только VBA, ограничения конне...
Автоматизация бизнес-процессов с Power Automate — выбор между облачным потоком и потоком рабочего стола, проектирование обработки ошибок
Разбираем различия между облачными потоками и потоками рабочего стола в Power Automate, выбор между PowerShell и VBA, лицензирование, обр...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Как настроить в Power Automate плановый поток на запуск каждое утро в 9:00 по японскому времени?
- В поле часового пояса триггера Recurrence выберите «(UTC+09:00) Осака, Саппоро, Токио» и укажите время начала. Если часовой пояс не указан, время начала трактуется как UTC (всемирное координированное время) с завершающей буквой Z, поэтому значение, заданное «как 9:00», на самом деле запустится в 18:00 по японскому времени. Кроме того, utcNow() в выражениях тоже всегда возвращает UTC, поэтому, используя «сегодняшнюю дату» внутри потока, сначала конвертируйте её в японское время выражением вида convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd').
- Есть ли в Power Automate функция для определения японских праздничных дней?
- Встроенной функции нет. Указание дней недели в триггере Recurrence позволяет выполнять поток «только по будням», но праздники при этом не учитываются, и среди функций выражений тоже нет ни одной, возвращающей праздничный день. На практике нужно самостоятельно завести мастер-список с датами праздников (например, список SharePoint) и в начале потока искать, есть ли сегодняшняя дата в этом списке, завершая выполнение, если день не является рабочим. В качестве первичного источника для обновления мастер-списка можно использовать CSV с праздниками, публикуемый Канцелярией Кабинета министров Японии.
- Можно ли построить поток, который выполняется только в последний рабочий день месяца?
- Для фиксированной даты, например «20-го числа каждого месяца», достаточно задать дату начала на нужный день и установить частоту «Месяц» — тогда выполнение будет происходить ежемесячно в тот же день и то же время, отталкиваясь от даты начала. А вот прямой опции «в последний день месяца» в триггере Recurrence нет, и детальное указание дня недели или времени доступно только при частоте «День» или «Неделя». Для обработки с переменной датой, как конец месяца, поток нужно запускать ежедневно (или каждый будний день), а в начале выражением определять, является ли сегодняшний день концом месяца и рабочим днём, завершая выполнение в дни, не подходящие под условие. Определение конца месяца можно выразить так: «если месяц сегодня отличается от месяца завтра, значит сегодня — конец месяца». А «выполнить в предыдущий рабочий день, если конец месяца выпадает на выходной или праздник» получают, добавив к этой же схеме проверку по мастер-списку праздников.
- Мой плановый поток отключился без моего ведома. Почему так произошло?
- В Power Automate есть несколько условий, при которых поток отключается автоматически. Поток, у которого триггер или действия продолжают завершаться ошибкой, отключается через 14 дней; поток, который постоянно попадает под троттлинг (превышение лимитов), тоже отключается через 14 дней. Кроме того, поток, который ни разу не сработал за 90 дней, может быть отключён (это не касается потоков, чей владелец имеет премиум-лицензию или лицензию на ёмкость, а за 30 дней до отключения владельцу и совладельцам приходит уведомление). Остановку планового потока трудно заметить, поэтому важно с самого начала встроить уведомления о сбоях и журнал выполнения.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.
Публичные ссылки