Diseñar flujos programados en Power Automate — procesamiento de fin de mes, determinación de días hábiles y recordatorios
· Actualizado el: · Go Komura · Power Automate, Flujo en la nube, Ejecución programada, Días hábiles, Días festivos, SharePoint, Microsoft 365, Automatización de procesos empresariales, Consultoría técnica
«A medida que se acerca el fin de mes, el departamento de contabilidad envía un correo a cada área diciendo: “la fecha límite para la liquidación de gastos es el día X”». «Cada mañana, al empezar la jornada, alguien abre la lista de pedidos y revisa visualmente si queda algo sin procesar». «Los documentos que superan el plazo de entrega se comparan uno por uno con el libro de registro para reclamarlos». Incluso en empresas que ya usan Microsoft 365, este tipo de trabajo —«una persona que mira el calendario y el libro de registro y actúa en consecuencia»— sigue siendo sorprendentemente habitual. Es un trabajo en el que olvidarse provoca un incidente, pero cuyo único mecanismo para no olvidarse es la memoria del responsable y el calendario de Outlook.
La ejecución programada de Power Automate (el disparador Recurrence) permite automatizar este tipo de tareas periódicas. Sin embargo, en cuanto se intenta implementar algo así en el contexto de una empresa japonesa, aparecen enseguida tres obstáculos: que la hora predeterminada es UTC (Tiempo Universal Coordinado), que el concepto de «día hábil» no existe de forma integrada, y que hay que escribir mediante fórmulas la determinación de «fin de mes» o «cierre del día 20». En este artículo se ordenan la especificación y las trampas del disparador Recurrence, el conjunto de herramientas de cálculo de fechas, la determinación de días hábiles mediante una maestra de festivos, el diseño de recordatorios que no abrumen a nadie, y los riesgos operativos propios de los flujos de ejecución programada.
Sobre cómo tratar en general, a nivel de sistema, los requisitos de fecha propios de Japón —calendario japonés, festivos y fechas de cierre—, hemos escrito en detalle en el artículo «Tratamiento del calendario japonés, los festivos y las fechas de cierre en aplicaciones de negocio — diseño resistente a cambios de era y cálculo de días hábiles con JapaneseCalendar». Este artículo es la puesta en práctica de esas ideas dentro de un flujo de Power Automate.
1. Conclusión inicial
- La hora del disparador Recurrence se interpreta como UTC si no se especifica una zona horaria. El incidente de que «se supone que es a las 9 de la mañana» pero en realidad se ejecuta a las 18:00 hora de Japón se evita seleccionando «(UTC+09:00) Osaka, Sapporo, Tokio» en el campo de zona horaria e indicando explícitamente la hora de inicio.12
- «Ejecutar solo en días laborables» puede lograrse con frecuencia «semanal» + selección de días (de lunes a viernes). Sin embargo, los festivos no se tienen en cuenta. Una fecha fija como «el día 20 de cada mes» puede crearse con fecha de inicio + frecuencia «mensual», pero no es posible indicar una fecha variable como «fin de mes» o «el día hábil anterior si el cierre cae en festivo»; la solución práctica es «ejecutar todos los días y determinarlo mediante una fórmula».2
- utcNow() dentro de una fórmula también es siempre UTC. Para obtener el «hoy» en hora de Japón hay que convertirlo primero con convertTimeZone(utcNow(), ‘UTC’, ‘Tokyo Standard Time’). Si se olvida la conversión en un flujo que se ejecuta a las 8 de la mañana, «hoy» pasa a ser el día anterior.34
- No existe ningún mecanismo integrado para determinar los festivos de Japón. Tampoco hay ninguna función de festivos en el listado de fórmulas,5 así que la práctica habitual es mantener una maestra propia de festivos (por ejemplo, una lista de SharePoint), determinar al inicio del flujo si «hoy es día hábil» y terminar la ejecución si no lo es. Como fuente primaria de esa maestra puede usarse el CSV de festivos de la Oficina del Gabinete.6
- Los recordatorios no deben enviarse «un mensaje por caso», sino un solo mensaje agrupado por responsable. Usando acciones de manipulación de datos como Filter array o Create HTML table se puede evitar anidar bucles Apply to each y mantener el flujo legible.7
- Es difícil notar que un flujo programado ha dejado de funcionar. Hay que diseñar desde el principio las notificaciones de fallo y el registro de ejecuciones asumiendo la especificación de que el flujo se desactiva a los 14 días de fallos continuos, a los 90 días sin dispararse, y de que el historial de ejecuciones se conserva por defecto 28 días.89
2. Inventario de «trabajos en los que una persona mira el calendario y actúa»
Lo primero que hay que hacer no es crear un flujo, sino identificar los trabajos que dependen de que alguien mire el calendario, y clasificar cuáles se prestan a la ejecución programada.
| Trabajo | Aptitud para la ejecución programada | Notas |
|---|---|---|
| Revisión matutina de pendientes o anomalías (pedidos, solicitudes, inventario) | Adecuado | Requiere que la condición de determinación pueda expresarse con columnas de una lista |
| Recordatorio masivo antes de fin de mes o fecha de cierre (liquidación de gastos, cierre de asistencia) | Adecuado | Requiere formalizar el ajuste de día hábil (si el fin de mes cae en festivo, el día hábil anterior) |
| Reclamación por incumplimiento del plazo de entrega (documentos, informes, aprobaciones pendientes) | Adecuado | Requiere que el libro de registro sea datos (una lista de SharePoint, etc.) |
| Agregación y distribución de informes periódicos | Adecuado con condiciones | Si la agregación es simple, hágala el flujo; si es compleja, que el flujo solo se encargue de la distribución |
| Procesos de cierre mensuales que consolidan datos (cierre, correcciones en rojo/negro, recálculo) | A menudo no adecuado | Muchas ramificaciones y excepciones, y se necesita poder revertir en caso de fallo (capítulo 8) |
| Procesos por lotes nocturnos que cruzan sistemas centrales (core) | No adecuado | Es terreno de desarrollo. Lo esencial es diseñar la reejecución y la coherencia |
El criterio de clasificación tiene tres ejes: si la condición de determinación puede expresarse con datos (un «caso que da mala espina» no se puede automatizar), si la regla del día de ejecución puede formalizarse en palabras, y si es posible recuperarse al día siguiente en caso de fallo (lo que no cumple esto último es terreno de desarrollo, capítulo 8).
De estos tres, el segundo es el mayor escollo en las empresas japonesas. Cuando se dice «recordatorio de cierre a fin de mes», lo que en realidad hace la gente es un ajuste del tipo «si el fin de mes cae en fin de semana o festivo, se adelanta al día hábil anterior, y en años con la Golden Week se envía antes de esos días consecutivos». Escribir este conocimiento implícito como especificación es, en realidad, el núcleo del trabajo de construir el flujo. Si se construye el flujo dejando esto ambiguo, se pierde confianza en la forma de «se envió un correo de reclamación en un día festivo» o «el recordatorio previo a los días consecutivos se envió durante esos mismos días».
3. Fundamentos y trampas del disparador Recurrence
Un flujo en la nube de ejecución programada se crea como «flujo en la nube programado», configurando la frecuencia y el intervalo con el disparador Recurrence (recurrencia).1 La frecuencia puede elegirse entre segundos, minutos, horas, días, semanas y meses; el intervalo mínimo es de 60 segundos y el máximo de 500 días.8 La especificación en sí es sencilla, pero es un disparador con muchas trampas.
Primero, una tabla resumen con la vista general. Está ordenada según la frecuencia con la que se cae en cada trampa en flujos de negocio orientados a Japón (el punto 6 solo aplica si hay sedes en el extranjero).
| # | Trampa | Síntoma | Solución |
|---|---|---|---|
| 1 | La hora de inicio predeterminada es UTC | «Se supone que es a las 9 de la mañana» pero se ejecuta a las 18:00 hora de Japón | Seleccionar «UTC+09:00 Osaka, Sapporo, Tokio» en el campo de zona horaria del disparador |
| 2 | Si no se indica fecha y hora de inicio, se ejecuta de inmediato al guardar | Si se guarda por la tarde, el correo de reclamación se envía a todos en ese mismo instante | Especificar siempre la fecha y hora de inicio. Indicar también explícitamente la hora de ejecución para evitar el desvío |
| 3 | No se puede indicar una fecha mensual variable | «Fin de mes» o «día hábil anterior si el cierre cae en festivo» no se pueden expresar en el disparador | Para fechas fijas: fecha de inicio + frecuencia «mensual». Para fechas variables: ejecución diaria + determinación por fórmula (capítulos 4 y 5) |
| 4 | Las fórmulas escritas en el disparador quedan fijadas al guardar | Se escribió utcNow(), pero siempre conserva el valor del día en que se guardó | No escribir fórmulas en la entrada del disparador. El cálculo de fechas se hace en una acción dentro del flujo |
| 5 | Los períodos en que el flujo estuvo desactivado no se ejecutan después | Si se desactivó unos días por una modificación y se cruza con el día de ejecución del mes, ese mes no se ejecuta | Antes de desactivar, comprobar la próxima fecha de ejecución y, si se cruza, compensar con una ejecución manual |
| 6 | El horario de verano desplaza la ejecución una hora | Las notificaciones para sedes en el extranjero se desvían una hora en cada cambio de horario | Seleccionar explícitamente la zona horaria de la sede (al seleccionarla, se ajusta automáticamente a los cambios estacionales) |
Trampa 1: el valor predeterminado es UTC — «se supone que a las 9, pero es a las 18»
Es el incidente más frecuente. Si no se selecciona una zona horaria, la hora de inicio del disparador Recurrence se interpreta en formato UTC con «Z» al final (YYYY-MM-DDThh:mm:ssZ). Si se selecciona Japón en el campo de zona horaria, la hora de inicio se trata como hora local de esa zona horaria (YYYY-MM-DDThh:mm:ss, sin Z).12 Para crear «un flujo que notifique todas las mañanas a las 9», lo correcto es poner la zona horaria en «(UTC+09:00) Osaka, Sapporo, Tokio» y la hora de inicio en 9:00.
Trampa 2: si no se indica la hora de inicio, se ejecuta una vez en el instante de guardar
Si no se indica la fecha y hora de inicio, la primera ejecución se dispara de inmediato en el momento de guardar el flujo.2 Esto está bien durante las pruebas, pero puede convertirse en un incidente si se guarda por la tarde un flujo que incluye un correo de reclamación y este se envía a todos en ese mismo instante. La fecha y hora de inicio deben especificarse siempre.
Además, si no se indica la «hora configurada» (estas horas/estos minutos) en las opciones avanzadas, las ejecuciones posteriores a la primera se calculan de forma relativa a la ejecución anterior, de modo que la acumulación de retrasos hace que la hora de ejecución se vaya desviando (drift) poco a poco.2 En un flujo que debe ejecutarse siempre a una hora fija, lo seguro es especificar también la hora de ejecución además de la fecha de inicio.
Trampa 3: «solo días laborables» es posible, pero la especificación mensual detallada es limitada
Si se pone la frecuencia en «semanal», se pueden elegir días de la semana (de lunes a viernes), y si la frecuencia es «diaria» o «semanal» también se puede indicar la hora de ejecución (hora y minuto). Es decir, «solo las mañanas de los días laborables a las 9» puede crearse solo con la configuración del disparador. Sin embargo, estas opciones detalladas únicamente están disponibles cuando la frecuencia es «diaria» o «semanal»; la frecuencia «mensual» no tiene ningún campo para indicar una fecha como «el día 20 de cada mes» o «fin de mes».2
Sin embargo, si el mes tiene una fecha fija, no hace falta ejecutarlo todos los días. Configurando la fecha y hora de inicio en el día objetivo (por ejemplo, el día 20 del mes siguiente a las 9:00) y la frecuencia en «mensual», la ejecución avanza cada mes a partir de la fecha de inicio, de modo que «el día 20 de cada mes a las 9» puede crearse solo con la configuración del disparador.2 Ejecutar 365 veces al año un flujo que en realidad solo hace falta 12 veces al año, descartando el resto con una condición, dificulta la lectura del historial de ejecuciones y consume solicitudes de forma innecesaria, así que conviene evitarlo.
La estructura de «ejecución diaria + fórmula al inicio del flujo que determina si hoy es el día objetivo» hace falta cuando la fecha mensual es variable. Fechas como «fin de mes» (que va de 28 a 31 según el mes), «el día hábil anterior si el 20 cae en fin de semana o festivo», o «el N-ésimo día hábil de cada mes» no pueden expresarse en el disparador. Esta fórmula de determinación se trata en el próximo capítulo. Cabe señalar que, si se usa como fecha fija de inicio un día entre el 29 y el 31, hay que verificar de forma explícita el comportamiento en los meses en que ese día no existe, así que es más seguro inclinarse desde el principio, para el procesamiento cercano a fin de mes, hacia el enfoque de «ejecución diaria + determinación».
Trampa 4: las fórmulas escritas en el disparador quedan fijadas al guardar
Si se escribe en la entrada del disparador una fórmula como utcNow(), ese valor se calcula y queda fijado en el momento de guardar el flujo. No se vuelve a calcular en cada ejecución.10 Conviene recordar que la idea de «poner una fórmula en el disparador porque quiero que la hora de inicio sea hoy» no funciona. El cálculo de fechas se realiza mediante una acción dentro del flujo, no en el disparador (capítulo 4).
Trampa 5: los períodos en que estuvo desactivado no se ejecutan después
El disparador Recurrence no procesa después, de una sola vez, las programaciones que pasaron mientras el flujo estaba desactivado; reanuda a partir del siguiente ciclo.11 Puede darse el incidente de «se desactivó unos días el flujo de proceso de fin de mes por una modificación, y justo se cruzó con el día de ejecución de fin de mes, así que este mes no se ejecutó». Al desactivar un flujo programado, la práctica correcta es comprobar antes la próxima fecha de ejecución prevista.
Trampa 6: horario de verano — atención solo si hay sedes en el extranjero
Si se escribe la hora en UTC sin seleccionar zona horaria, en regiones con horario de verano (DST) la hora de ejecución se desvía una hora en cada cambio. Si se selecciona la zona horaria, la programación se mantiene siguiendo los cambios estacionales.11 Japón no tiene horario de verano, así que dentro del país no hay ningún perjuicio real, pero si el mismo flujo maneja notificaciones para sedes en el extranjero, es necesario seleccionar explícitamente la zona horaria de esa sede.
4. El conjunto de herramientas de cálculo de fechas — determinar fin de mes, inicio de mes y fecha de cierre con fórmulas
El cálculo de fechas dentro del flujo se escribe con las mismas fórmulas (funciones) que Logic Apps.5 Como premisa, utcNow() siempre devuelve la hora actual en UTC.12 Por eso conviene crear al principio del flujo un «hoy en hora de Japón», guardarlo en una variable (o en un Compose) y reutilizarlo después: así las fórmulas resultan más legibles.
convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd')
convertTimeZone(marca de tiempo, origen, destino, formato) es la función de conversión de zona horaria,13 y el nombre de la zona horaria se toma del listado de zonas horarias de Windows. Japón es «Tokyo Standard Time».4 Si no se quiere escribir la fórmula, también existe la acción «Convertir zona horaria», que hace lo mismo.13
La razón por la que la conversión es imprescindible es que hay una diferencia de 9 horas entre UTC y la hora de Japón. Hasta las 9 de la mañana en hora de Japón, en UTC todavía es el día anterior. Si en un flujo que se ejecuta a las 8 de la mañana se escribe formatDateTime(utcNow(), ‘yyyy-MM-dd’), el «hoy» que se obtiene es la fecha del día anterior. Este desfase de fecha aparece o no según la hora de ejecución, así que es difícil detectarlo en pruebas, y suele descubrirse en producción en la forma de «un proceso que debía ejecutarse a principio de mes también se ejecutó el último día del mes anterior».
Dónde escribir esta fórmula — variables, Compose y la pestaña de fórmula
Este es el punto en el que se suele dudar al empezar a usar Power Automate, así que conviene aclararlo desde ahora.
- Inicializar variable (Initialize variable): es una acción que aparece dentro de «Variable» al añadir una acción. Se crea indicando nombre, tipo (cadena, etc.) y valor, y después se referencia como variables(‘today’). Es la opción adecuada para valores que cambian dentro de un bucle o que se quieren sobrescribir más adelante con «Establecer variable».
- Crear (Compose): al buscar
composeen «Agregar una acción» aparece bajo «Operaciones de datos»; conserva tal cual el resultado de la fórmula escrita en «Entradas». Es una acción pensada para no tener que escribir el mismo contenido varias veces,7 así que es adecuada para valores como el «hoy en hora de Japón», que una vez calculados ya no cambian. Se referencia por el nombre de la acción, como outputs(‘Today’). - Dónde escribir la fórmula en sí: en cualquiera de las dos acciones, al seleccionar el campo de entrada del valor se abre un panel para elegir contenido dinámico y fórmulas; hay que pegar el convertTimeZone(…) anterior en la pestaña «Fórmula» (identificada por el icono
fx) y confirmarlo. El aspecto varía según la versión del diseñador, pero el orden de «hacer clic en el campo de entrada y luego ir a la pestaña de fórmula» es siempre el mismo. - Como los nombres de acción y de variable se referencian desde fórmulas, es más seguro ponerles nombres alfanuméricos (los espacios en el nombre se sustituyen por guiones bajos).
En el resto de este artículo, denotaremos como hoy a este «hoy en hora de Japón» creado con la fórmula anterior. En un flujo real, sustitúyalo por variables(‘today’) u outputs(‘Today’) según corresponda. A continuación se resumen los patrones de determinación una vez creado ese valor.
| Qué se quiere hacer | Ejemplo de fórmula | Notas |
|---|---|---|
| Obtener el día de la semana | dayOfWeek(hoy) |
0 = domingo, 1 = lunes, …, 6 = sábado.12 |
| Saber si es fin de semana | or(equals(dayOfWeek(hoy), 0), equals(dayOfWeek(hoy), 6)) |
Escribir «si es mayor que 5, es fin de semana» deja fuera el domingo (0)12 |
| Saber si es inicio de mes (día 1) | equals(formatDateTime(hoy, 'dd'), '01') |
Con startOfMonth() también se obtiene directamente la fecha de inicio de mes5 |
| Saber si es el día de cierre del 20 | equals(formatDateTime(hoy, 'dd'), '20') |
En lugar de fijar el día de cierre en el código, conviene sacarlo a una variable de entorno o a una lista de configuración, para reutilizarlo |
| Saber si es fin de mes | not(equals(formatDateTime(hoy, 'MM'), formatDateTime(addDays(hoy, 1), 'MM'))) |
«Si el mes de hoy y el mes de mañana son distintos, hoy es fin de mes». Funciona correctamente también en febrero y en años bisiestos |
| Fecha del último día del mes actual | addDays(startOfMonth(addToTime(hoy, 1, 'Month')), -1, 'yyyy-MM-dd') |
Se deriva como «el día anterior al inicio del mes siguiente». Evita tener que pensar en cuántos días tiene el mes |
| N días antes o N días después | addDays(hoy, -3) / addDays(hoy, 7) |
Suma y resta de días naturales. La base de días hábiles se trata en el capítulo 5 |
addDays, addToTime, startOfMonth, formatDateTime y dayOfWeek son todas funciones definidas en la referencia de fórmulas común a Logic Apps y Power Automate.5 Las fórmulas combinadas de la tabla son un patrón de implementación propio del autor, así que, al introducirlas, pruébelas antes con fechas que crucen fin de mes, inicio de mes y años bisiestos (29 de febrero) antes de llevarlas a producción. Sobre lo peligrosos que son los errores de fecha que solo se manifiestan en días concretos, y cómo elegir de antemano las fechas que conviene probar, ya se escribió en el capítulo 4 del artículo sobre calendario japonés, festivos y fechas de cierre.
5. Determinación de días hábiles — mantener los festivos en una maestra
No existe una determinación de festivos integrada
Insistimos: Power Automate no tiene ninguna función integrada para determinar los festivos de Japón. La selección de días de la semana del disparador Recurrence literalmente solo mira el día de la semana, y en el listado de funciones de fórmulas solo hay suma y resta de fechas, formateo y conversión de zona horaria; no hay ninguna función que devuelva «si esta fecha es festiva».5 El hecho de que calcular los festivos mediante una fórmula sea, en principio, imposible (el equinoccio de primavera y el de otoño se confirman el año anterior, y los propios festivos pueden cambiar por reformas legales o leyes especiales de medidas extraordinarias) se explicó en detalle en el capítulo 3 del artículo sobre calendario japonés, festivos y fechas de cierre. La conclusión es la misma: lo correcto es mantener los festivos como datos (una maestra) más una operación de actualización.
En Power Automate, la forma más sencilla de hacerlo es crear una «maestra de festivos» (columna de fecha + columna de nombre) en una lista de SharePoint. Como fuente primaria puede usarse el CSV que publica la Oficina del Gabinete con las fechas y nombres de los festivos desde el año Showa 30 hasta el año siguiente (incluye también los días de descanso compensatorio como filas).6 Como solo se publica la parte ya confirmada, el diseño debe incluir hasta el punto de incorporar una vez al año, dentro del calendario de trabajo, la tarea de cargar en la maestra los festivos del año siguiente. Si se olvida esa actualización, el resultado será directamente un mal funcionamiento en forma de un correo de reclamación enviado en un festivo del año siguiente. Además, los días de cierre de la empresa, como el descanso de verano o el aniversario de fundación, no deben mezclarse con la maestra de festivos: conviene ponerlos en una lista aparte, porque el conjunto de días de descanso que hay que consultar varía según el uso («la determinación del plazo de una transferencia bancaria solo mira los festivos», «la reclamación interna también mira los días de cierre de la empresa»).
El «control de día hábil» al inicio del flujo
Un flujo que solo debe ejecutarse en días hábiles, además de la selección de días de la semana del disparador Recurrence (de lunes a viernes), debe incluir la siguiente determinación al principio del flujo.
- Crear el «hoy en hora de Japón» (capítulo 4)
- Ejecutar «Obtener elementos» (Get items) de SharePoint contra la maestra de festivos, buscando en la consulta de filtro la fecha de hoy, por ejemplo con
HolidayDate eq 'hoy'14 - Realizar la misma búsqueda también en la lista de días de cierre de la empresa
- Si hay al menos una coincidencia, detener la ejecución con la acción «Terminar» (Terminate)
Terminate es una acción que detiene la ejecución del flujo en ese punto y la finaliza con el estado indicado (correcto, con error o cancelado); no puede colocarse dentro de un bucle Apply to each o Do until.15 Si aquí se pone el estado en «Cancelado», en el historial de ejecuciones se puede distinguir de un vistazo entre «el día en que se omitió porque no era hábil» y «el día en que realmente se ejecutó el proceso». Es más fácil investigar más adelante que si todo queda marcado como «correcto».
«Adelantar al día hábil anterior» y «N días hábiles antes»
Lo que realmente hace falta en un recordatorio de cierre de fin de mes no es «cada fin de mes», sino «el día hábil anterior si el fin de mes cae en día de descanso». Esto puede expresarse en un flujo que se ejecuta cada día hábil, determinando que «hoy es día hábil, y no hay ningún día hábil entre mañana y el fin de mes». Dicho de otro modo, basta con determinar cada mañana si hoy es el último día hábil del mes actual, y el adelanto se logra de forma automática.
Es la parte más difícil de trasladar a código de todo el artículo, así que se detalla hasta la fórmula y la estructura de acciones. La premisa es haber pasado el control de día hábil del apartado anterior; es decir, que ya está confirmado que hoy es día hábil.
flowchart TD
Start[Pasó el control de día hábil<br/>hoy está confirmado como día hábil] --> Hol[Crear la lista de días de descanso del mes<br/>Get items de la maestra de festivos y los días de cierre de la empresa]
Hol --> Days[Calcular los días restantes<br/>restar el día de hoy al día de fin de mes]
Days --> Zero{¿Los días restantes son 0?}
Zero -- Sí --> Run[Hoy es el último día hábil<br/>ejecutar el proceso de fin de mes o el recordatorio]
Zero -- No --> Range[Crear el arreglo de fechas de mañana hasta fin de mes<br/>range y addDays]
Range --> Filter[Excluir fines de semana y días de descanso con Filter array]
Filter --> Len{¿Quedaron 0 elementos?}
Len -- 0 elementos --> Run
Len -- 1 o más --> Skip[Terminate Cancelado<br/>hoy no es el día de adelanto]
El contenido concreto es el siguiente.
- Crear la lista de días de descanso del mes. Obtener con Get items solo los del mes actual, tanto de la maestra de festivos como de la lista de días de cierre de la empresa, convertirlos con «Seleccionar» (Select) en un arreglo de solo cadenas con formato
yyyy-MM-dd, y unirlos en uno solo con union().145 LlamaremosHolidaysa esta acción. -
Obtener la fecha de fin de mes y los días restantes. Se usa directamente la fórmula del capítulo 4.
Fin de mes: addDays(startOfMonth(addToTime(hoy, 1, 'Month')), -1, 'yyyy-MM-dd') Días restantes: sub(int(formatDateTime(Fin de mes, 'dd')), int(formatDateTime(hoy, 'dd'))) - Si los días restantes son 0, hoy es fin de mes. Como ya se pasó el control de día hábil, hoy es el último día hábil. Se continúa directamente con el proceso.
- Si los días restantes son 1 o más, crear el arreglo de fechas desde mañana hasta fin de mes. En la acción «Seleccionar» (Select), indicar
range(1, Días restantes)como inicio yaddDays(hoy, item(), 'yyyy-MM-dd')como asignación. Como el segundo argumento de range() debe ser un entero positivo,5 es imprescindible colocar antes la ramificación del paso 3 (si se omite, el flujo falla con un error justo el día de fin de mes). -
Excluir fines de semana y días de descanso. Pasar la salida del paso 4 a «Filtrar matriz» (Filter array), poner la condición en modo avanzado y escribir la siguiente fórmula.7 createArray(0, 6) son los números de día de la semana de domingo y sábado,12 y body(‘Holidays’) es la lista de días de descanso creada en el paso 1.
@and(not(contains(createArray(0, 6), dayOfWeek(item()))), not(contains(body('Holidays'), item()))) - Determinar según el número de elementos restantes. Si la acción del paso 5 se llama
Filter array, su salida se referencia como body(‘Filter_array’) (los espacios del nombre se sustituyen por guiones bajos). Si length(body(‘Filter_array’)) es 0, significa que «no hay ningún día hábil después de hoy», es decir, hoy es el último día hábil del mes, así que se ejecuta el proceso; si es 1 o más, hoy no es el día de adelanto, así que se termina con Terminate (Cancelado).515
El adelanto de la fecha de cierre, como en «el día 20 de cada mes, o el día hábil anterior si cae en descanso», tiene la misma forma. Basta con usar el día de cierre (el 20) en lugar de la fecha de fin de mes y reformular la condición como «hoy es igual o anterior al día de cierre, y no hay ningún día hábil entre mañana y el día de cierre»; la estructura de la determinación no cambia. Al implementarlo, pruebe por separado los meses en que el día de cierre cae en lunes, sábado, domingo y festivo.
«N días hábiles antes», como en «reclamar 3 días hábiles antes de la fecha límite de pago», se plantea con la misma reformulación de la idea. «Cuando falten N días hábiles para la fecha límite» se sustituye por «ejecutar cada día hábil, contar los días hábiles entre hoy y la fecha límite, y comparar si coincide con N». Contar días hábiles consiste simplemente en contar los días que no son fin de semana, no están en la maestra de festivos ni en los días de cierre de la empresa. Ahora bien, un procesamiento que cuenta las fechas día por día dentro de un bucle del flujo, cuando el número de casos supera varios cientos, se convierte en un bucle de casos por días, y tanto el tiempo de ejecución como las llamadas a la API se disparan. Al llegar a esa escala, es más sano sacar el cálculo de días hábiles fuera del flujo (una tabla de días hábiles en una base de datos o una API pequeña) o tratarlo como terreno de desarrollo, según el capítulo 8.
6. Diseño de recordatorios y reclamaciones — un solo mensaje agrupado por responsable
Premisa: que el libro de registro sea datos
Solo se puede automatizar la reclamación por incumplimiento de plazo si «qué es, a cargo de quién y cuándo vence» puede obtenerse como datos. Si el libro de registro es un Excel en una carpeta compartida que circula como adjunto de correo, considere primero sustituirlo por una lista de SharePoint (esto se trata en «Sustituir un libro de registro en Excel por una lista de SharePoint»). A continuación se asume que la lista de SharePoint ya tiene las columnas «Fecha límite», «Estado» y «Responsable».
Filtrar en el momento de la obtención
La extracción de casos vencidos no debe hacerse trayendo toda la lista y ramificando la condición dentro del flujo, sino filtrando en el servidor mediante la consulta de filtro (filtro OData) de Get items.14
DueDate lt '2026-07-18' and Status ne 'Completado'
En la parte de la fecha se inserta la fórmula del «hoy en hora de Japón» creada en el capítulo 4. Tenga en cuenta que los nombres de columna de la consulta de filtro deben escribirse con el nombre interno de SharePoint, no con el nombre que se muestra en pantalla, y que, por defecto, solo se devuelven 100 elementos, así que en listas con muchos casos hace falta especificar un límite superior (Top Count) o configurar la paginación.14
Evitar el infierno de Apply to each — cómo agrupar en un solo mensaje
Si el resultado de la extracción se recorre tal cual con Apply to each y se envía un correo por cada caso, un responsable con 10 casos pendientes recibirá 10 correos cada mañana. Si esto se mantiene varias semanas, las notificaciones dejan de leerse sin remedio y el propio mecanismo de recordatorio queda muerto. El principio es agrupar la notificación en un solo mensaje por responsable. Usando acciones de manipulación de datos, se puede construir con el siguiente flujo.7
- Con Select, crear a partir del resultado de la extracción un arreglo de correos de responsables y, con union(), eliminar duplicados para obtener el «listado de responsables a notificar hoy»5
- Recorrer el listado de responsables con Apply to each y, dentro de él, usar Filter array para extraer «solo los casos de este responsable»
- Con Create HTML table, dar formato de tabla con asunto, fecha límite y estado, e insertarlo en el cuerpo de un correo (o de un mensaje de Teams) para enviar un único mensaje (en el caso del correo, hay que habilitar la visualización HTML7)
La visión de conjunto queda así.
flowchart TD
Rec[Disparador Recurrence<br/>Días laborables 9:00 h Zona horaria: Osaka, Sapporo, Tokio] --> Today[Crear el hoy en hora de Japón<br/>convertTimeZone]
Today --> Hol{¿Hoy está en la maestra<br/>de festivos o en los días de cierre?}
Hol -- Sí --> Term[Terminate Cancelado<br/>termina porque no es día hábil]
Hol -- No --> Get[Get items<br/>extraer vencidos e incompletos]
Get --> Any{¿Hay casos objetivo?}
Any -- No --> End([Finaliza sin notificación])
Any -- Sí --> Sel[Crear el listado de responsables con Select<br/>eliminar duplicados con union]
Sel --> Each[Recorrer por cada responsable]
Each --> Filter[Filter array<br/>extraer solo los casos de este responsable]
Filter --> Table[Dar formato de tabla con Create HTML table]
Table --> Send[Enviar un único mensaje al responsable<br/>por Teams u Outlook]
Send --> Log[Registrar el resultado de la ejecución en la lista de registro]
Cuándo usar Teams y cuándo Outlook
La salida de la notificación se elige según su naturaleza.
| Aspecto | Teams (chat/canal) | Outlook (correo) |
|---|---|---|
| Facilidad para notarlo | Alta. Aunque tiende a perderse entre el flujo de mensajes | Menor fatiga por notificaciones, pero se pierde en la bandeja de entrada |
| Capacidad de registro | Débil. Difícil de buscar después | Queda guardado. Sirve como constancia de la reclamación |
| Destinatario | Solo dentro de la empresa | También puede enviarse fuera de la empresa |
| Notificación adecuada | Resúmenes diarios ligeros, como los pendientes de cada mañana | Aviso formal de fecha límite, casos que necesitan constancia de la reclamación, envíos externos |
Lo habitual es separar el resumen diario en Teams, y el recordatorio formal antes del cierre y la reclamación por vencimiento en correo. No se recomienda enviar el mismo contenido por ambos canales, porque solo aumenta el volumen total de notificaciones.
Un diseño que no reclame en exceso
Lo más peligroso al automatizar recordatorios es enviar tanto que todo termine siendo ignorado. La reclamación hecha por una persona tiene un freno natural («da reparo, así que se modera la frecuencia»), pero un flujo no lo tiene. Hay que incorporarlo en el diseño.
- Diseñar el volumen total. Lo peor es «todas las mañanas, a todos, todos los casos». Conviene limitar las condiciones de envío: por ejemplo, que la notificación diaria solo incluya lo que vence hoy y lo ya vencido, y que el recordatorio previo se envíe solo dos veces, 3 días hábiles antes y el día anterior.
- Establecer niveles. Notificar primero solo al propio responsable y, si el vencimiento persiste durante N días hábiles, añadir al superior como destinatario: así se separa la escalada por niveles. Si desde el principio se envía todo al superior, la notificación se convierte en simple ruido.
- Crear un mecanismo que detenga la reclamación. Es imprescindible ofrecer siempre una salida por la que, en cuanto el responsable ponga la columna de estado de la lista en «Completado», las notificaciones se detengan a partir del día siguiente. Si el informe de finalización sigue haciéndose solo por respuesta de correo, el flujo seguirá reclamando y el responsable acabará detestándolo.
- Mantener la confianza en que «si no llega notificación, no hay problema». Esto solo se logra en conjunto con la supervisión que se trata en el próximo capítulo.
7. Precauciones operativas — un flujo programado es difícil de notar cuando se detiene
Un flujo iniciado por un evento hace que el área de negocio note «lo solicité y no se ejecutó». Un flujo programado no tiene ese detector. Aunque el recordatorio de fin de mes se haya detenido, nadie dice nada y el cierre simplemente se retrasa. En el diseño operativo hay que asumir las siguientes especificaciones.
- Existen condiciones que desactivan el flujo automáticamente. Un flujo cuyo disparador o acciones fallan de forma continuada se desactiva a los 14 días, y lo mismo ocurre con un flujo sometido a limitación (throttling) continua. Además, un flujo que no se dispara ni una sola vez en 90 días puede desactivarse (esto no aplica a flujos cuyo propietario tenga una licencia premium o de capacidad, como Process; se notifica al propietario y a los copropietarios 30 días antes de la desactivación, y volver a activarlo permite continuar).8 Si va a crear «un flujo que se ejecuta solo una vez por trimestre», tenga en cuenta esta regla de los 90 días.
- El historial de ejecuciones solo se ve, por defecto, durante 28 días.9 En un flujo mensual, esto equivale a solo poder confirmar la última ejecución. Añadir al final del flujo un paso que agregue una fila (fecha y hora de ejecución, número de casos procesados, resultado) a una lista de SharePoint dedicada al registro permite confirmar «si funcionó bien el mes pasado», independientemente de la expiración del historial. Por eso, en el diagrama del capítulo 6, el registro se coloca al final.
- El flujo debe tener su propio mecanismo para detectar el fallo. Si no se incluye una ramificación que notifique al administrador en caso de fallo (una acción que se ejecute en «si falló», dentro de la configuración de condiciones de ejecución), nadie notará el fallo durante los 14 días que faltan para que se desactive. Cómo estructurar el manejo de errores y los reintentos se trata en detalle en «Diseño de manejo de errores y reintentos en Power Automate».
- La baja o el cambio de puesto del propietario detiene toda la programación. Un flujo con disparador Recurrence se ejecuta con la conexión de quien creó el flujo.10 Si la cuenta del propietario se deshabilita, la conexión se corta, el flujo empieza a fallar y con el tiempo se desactiva. Complete la configuración de copropietarios y el inventario de conexiones desde el primer día de operación.16 La práctica del traspaso se resume en «Cómo evitar la dependencia de una sola persona en Power Automate — para que un flujo no se detenga aunque quien lo creó se vaya».
- Lo que ocurrió durante un período de desactivación no se ejecuta después (trampa 5 del capítulo 3). Al desactivar el flujo por una modificación o para atender un incidente, es necesario comprobar de antemano la próxima fecha de ejecución prevista y, si se cruza, decidir de antemano compensarlo con una ejecución manual.11
8. Hasta dónde llegar con Power Automate
La ejecución programada es una excelente puerta de entrada a la automatización, pero convertir en flujo cualquier cosa que «se repita periódicamente» es peligroso. A continuación, algunas pautas para trazar la línea.
| Situación | Decisión |
|---|---|
| Revisión matutina de pendientes, recordatorio de plazos, notificación masiva antes del cierre | Terreno natural de Power Automate. La estructura de este artículo es suficiente |
| Notificaciones que incluyen determinación de días hábiles o adelanto al día hábil anterior | Posible con Power Automate + maestra de festivos. Hay que definir a la vez la operación de actualización de la maestra |
| Cálculos con varios cientos de casos × N días hábiles, agregaciones que cruzan varias listas | Es duro con los bucles de un flujo. Sacar la lógica fuera o pasarla a terreno de desarrollo |
| Procesos de cierre donde la fecha límite varía por cliente y hay correcciones en rojo/negro o recálculos | Las ramificaciones se disparan y también hace falta poder revertir en caso de fallo. Terreno de desarrollo a medida o sistema dedicado |
| Procesos por lotes nocturnos que cruzan bases de datos de sistemas centrales | Terreno de desarrollo. Lo esencial es diseñar transacciones, reejecución y coherencia |
| Ejecución periódica de procesamiento de archivos o de base de datos que se completa dentro de un único servidor de la empresa | PowerShell + el Programador de tareas también es una opción sólida. Consulte la comparación en otro artículo |
Como criterio general, la línea está más o menos en que «hacer notar algo» es terreno de Power Automate, y «confirmar algo» (reescribir datos del sistema central) es terreno de desarrollo. Hemos visto varias veces casos en los que intentar construir el propio proceso de cierre dentro de un flujo termina lleno de ramificaciones; en la mayoría de esos casos, la estabilidad llegó al separar de nuevo «la ejecución del cierre queda en el sistema existente o en un desarrollo a medida, y el flujo solo se encarga de la notificación para evitar olvidos de cierre». Además, si el proceso periódico se completa dentro del propio servidor sin pasar por la nube, PowerShell junto con el Programador de tareas puede resultar más sencillo y fácil de mantener. Esta elección se ordena en «Cuándo usar Power Automate y cuándo PowerShell/el Programador de tareas».
9. Resumen
El diseño de un flujo programado tiene su núcleo no tanto en la configuración del disparador Recurrence como en lo que hay antes y después de esa configuración. Antes está la formalización del conocimiento implícito de «actuar mirando el calendario»: qué hacer si el fin de mes cae en festivo, quién y cuándo actualiza la maestra de festivos. Un flujo construido sin resolver esto antes acabará fallando, sin excepción, frente al calendario japonés. Después está la operación necesaria para notar cuando el flujo se detiene: los 28 días de historial de ejecuciones, las distintas condiciones de desactivación automática, la programación que se detiene al causar baja el propietario. Un flujo programado se detiene en silencio: parta de esa premisa e incorpore desde el principio las notificaciones de fallo y el registro de ejecuciones.
Los aspectos técnicos clave pueden resumirse en tres puntos: especificar siempre la zona horaria en la hora (el valor predeterminado es UTC), convertir la fecha a hora de Japón antes de hacer cualquier determinación, y mantener los festivos en una maestra y descartarlos con el control de día hábil al inicio del flujo. Una vez cubiertos estos tres puntos, agrupe las notificaciones por responsable y añada niveles y una salida a las reclamaciones. Con esto, buena parte del trabajo de «una persona que actúa mirando el calendario» puede confiarse tranquilamente a un flujo programado. Y cuando llegue el momento de querer entrar en procesos que «confirman» algo, como el cierre o los procesos por lotes del sistema central, será el momento de considerar el paso al terreno de desarrollo.
Artículos relacionados
- Automatizar procesos de negocio con Power Automate — cuándo usar flujos en la nube o de escritorio, y diseño del manejo de errores
- Tratamiento del calendario japonés, los festivos y las fechas de cierre en aplicaciones de negocio — diseño resistente a cambios de era y cálculo de días hábiles con JapaneseCalendar
- Diseño de manejo de errores y reintentos en Power Automate
- Cómo evitar la dependencia de una sola persona en Power Automate — para que un flujo no se detenga aunque quien lo creó se vaya
- Cuándo usar Power Automate y cuándo PowerShell/el Programador de tareas
Áreas de consultoría relacionadas
KomuraSoft LLC se ocupa desde la revisión del diseño de procesos periódicos y recordatorios con Power Automate hasta el desarrollo de procesos de cierre, cálculo de días hábiles y lotes de integración con sistemas centrales que no caben en un flujo.
Referencias
-
Microsoft Learn, Run a cloud flow on a schedule. Sobre el procedimiento para crear un flujo en la nube programado, la especificación de en qué zona horaria se trata la hora de inicio mediante el campo de zona horaria del disparador Recurrence, y el formato de la hora de inicio (YYYY-MM-DDTHH:MM:SSZ). ↩ ↩2 ↩3
-
Microsoft Learn, Schedule and run recurring workflows with the Recurrence trigger in Azure Logic Apps. Sobre que, si no se selecciona zona horaria, la hora de inicio se interpreta como UTC con «Z» al final; la especificación de frecuencia e intervalo; que la selección de día de la semana (weekDays) solo está disponible con frecuencia «semanal» y la hora (hours/minutes) solo con frecuencia «diaria» o «semanal»; que si no se indica la fecha y hora de inicio, la primera ejecución se dispara de inmediato al guardar; y que, sin una especificación horaria detallada, la hora de ejecución se calcula de forma relativa a la ejecución anterior y se desvía (drift). ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Microsoft Learn, Customize or format date and time values in a flow. Sobre que Power Automate usa UTC de forma predeterminada, y cómo combinar formatDateTime y convertTimeZone para manejar la hora local. ↩
-
Microsoft Learn, Default Time Zones. Listado de nombres de zona horaria de Windows. Sobre que el nombre de zona horaria de Japón (UTC+09:00 Osaka, Sapporo, Tokio) es «Tokyo Standard Time». ↩ ↩2
-
Microsoft Learn, Reference guide to functions in expressions for workflows in Azure Logic Apps and Power Automate. Sobre las funciones de fecha disponibles en las fórmulas (utcNow, addDays, addToTime, startOfMonth, formatDateTime, dayOfWeek, convertTimeZone, etc.), las funciones de colección (union, createArray, contains, length, etc.), la sintaxis de la función range y el requisito de que su segundo argumento (la cantidad) sea un entero positivo, y el listado y la sintaxis de las funciones numéricas (sub, int). Fuente que confirma que no existe ninguna función para determinar festivos. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
-
Oficina del Gabinete de Japón, «国民の祝日」について. Sobre el listado de festivos nacionales conforme a la Ley de Festivos Nacionales, que el equinoccio de primavera y el de otoño se confirman y publican el año anterior, la regulación del descanso compensatorio, y la disponibilidad del CSV con las fechas y nombres de los festivos desde el año Showa 30 hasta el año siguiente. ↩ ↩2
-
Microsoft Learn, Use data operations. Sobre el uso y el procedimiento de las acciones de manipulación de datos como Compose (Crear), Select, Filter array, Join y Create HTML table; que Compose es una acción para no tener que escribir el mismo contenido varias veces y que su salida puede referenciarse desde acciones posteriores; que Filter array reduce un arreglo solo a los elementos que cumplen la condición; y sobre habilitar IsHtml al enviar una tabla HTML por correo. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Limits of automated, scheduled, and instant flows. Sobre el intervalo mínimo de 60 segundos y máximo de 500 días de la recurrencia, que un flujo cuyo disparador o acciones fallan de forma continuada se desactiva a los 14 días, que un flujo no disparado en 90 días puede desactivarse (no aplica a flujos con licencia premium o de capacidad; se notifica al propietario y a los copropietarios 30 días antes), y que un flujo sometido a limitación continua también se desactiva a los 14 días. ↩ ↩2 ↩3
-
Microsoft Learn, Missing runs or triggers history for a flow. Sobre que el historial de ejecuciones de un flujo se conserva, por defecto, solo durante 28 días. ↩ ↩2
-
Microsoft Learn, Troubleshoot Power Automate trigger issues and errors. Sobre que una fórmula escrita en la entrada del disparador (como utcNow()) se calcula y queda fijada en el momento de guardar el flujo, sin volver a calcularse en cada ejecución, y que un flujo con disparador Recurrence se ejecuta con la conexión de quien creó el flujo. ↩ ↩2
-
Microsoft Learn, Schedules for recurring workflow triggers in Azure Logic Apps. Sobre que, si no se selecciona zona horaria, la hora de ejecución se desvía una hora en cada cambio de horario de verano; que, si se selecciona la zona horaria, la programación se mantiene siguiendo los cambios estacionales; y que el disparador Recurrence, al reanudarse tras estar detenido, no procesa las programaciones perdidas y reanuda desde el siguiente ciclo. ↩ ↩2 ↩3
-
Microsoft Learn, Expression cookbook for cloud flows. Sobre que utcNow() siempre devuelve UTC, que el valor devuelto por dayOfWeek() va de 0 (domingo) a 6 (sábado), y que la comprobación «mayor que 5» deja fuera el domingo. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Convert a time zone. Sobre los argumentos de la fórmula convertTimeZone (marca de tiempo, origen, destino, formato) y la acción «Convertir zona horaria», que ofrece la misma funcionalidad. ↩ ↩2
-
Microsoft Learn, In-depth analysis into Get items and Get files SharePoint actions. Sobre la consulta de filtro OData de Get items (eq/ne/lt/gt, etc., e inserción de fórmulas), que el número de elementos obtenidos por defecto es 100 y puede cambiarse con Top Count, y sobre la configuración de paginación en listas con más de 5000 elementos. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Schema reference guide for trigger and action types in Azure Logic Apps. Sobre que la acción Terminate detiene la ejecución y devuelve el estado indicado (Succeeded/Cancelled/Failed), y que no puede colocarse dentro de bucles Foreach o Until. ↩ ↩2
-
Microsoft Learn, Share a cloud flow. Sobre lo que puede hacer un copropietario (editar el flujo, actualizar las credenciales de conexión, etc.) y sobre que la conexión está vinculada al usuario que la creó. ↩
Artículos relacionados
Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.
Cómo procesar automáticamente con Power Automate los PDF de pedidos y facturas recibidos por correo — diseño de guardado, clasificación, notificación y lectura
Diseño para automatizar con Power Automate el guardado, la clasificación y el aviso de PDF de pedidos y facturas por correo: trigger de O...
Crear un flujo de aprobación con Power Automate — Digitalizar solicitudes y autorizaciones en papel y correo
Guía práctica para digitalizar con Power Automate las solicitudes y aprobaciones en papel o Excel adjunto a correo: tipos de acción de ap...
Power Automate y PowerShell + Programador de tareas: cuándo usar cada uno ── conectar las herramientas de automatización sin mezclarlas, cada una en su lugar
Para TI de pymes con PowerShell y Power Automate a la vez: diferencias, tabla de decisión, integración vía SharePoint y aspectos de licen...
Crear un punto de recepción para solicitudes internas con Microsoft Forms — Cómo centralizar en un formulario las solicitudes por correo y de viva voz
Guía práctica para centralizar en Microsoft Forms las solicitudes internas de TI y administración: preguntas, alcance interno, adjuntos y...
Sustituir los libros de registro en Excel por listas de SharePoint — decir adiós a los libros que «se rompen» con uso compartido, historial e integración de flujos
Guía práctica para migrar libros de registro en Excel de carpetas compartidas a listas de SharePoint (Microsoft Lists), con la edición si...
Temas relacionados
Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.
Temas técnicos de Windows
Portal sobre desarrollo de Windows, investigación de fallos y aprovechamiento de activos existentes.
Preguntas frecuentes
Preguntas habituales en las consultas sobre el tema del artículo.
- ¿Cómo hago que un flujo programado de Power Automate se ejecute todas las mañanas a las 9:00, hora de Japón?
- En el campo de zona horaria del disparador Recurrence, seleccione «(UTC+09:00) Osaka, Sapporo, Tokio» e indique la hora de inicio. Si no se especifica una zona horaria, la hora de inicio se interpreta como UTC (Tiempo Universal Coordinado) con una «Z» al final, de modo que si configura «9:00» pensando en hora local, el flujo se ejecutará en realidad a las 18:00, hora de Japón. Además, utcNow() dentro de una fórmula siempre devuelve UTC, así que cuando necesite «la fecha de hoy» dentro del flujo debe convertirla primero a hora de Japón con algo como convertTimeZone(utcNow(), 'UTC', 'Tokyo Standard Time', 'yyyy-MM-dd').
- ¿Power Automate tiene alguna función para determinar los días festivos de Japón?
- No existe nada integrado. El disparador Recurrence permite ejecutar «solo en días laborables» mediante la selección de días de la semana, pero no tiene en cuenta los festivos, y tampoco hay ninguna función en el listado de fórmulas que devuelva si una fecha es festiva. En la práctica, la solución es mantener una maestra propia con las fechas de los festivos (por ejemplo, una lista de SharePoint) y, al inicio del flujo, buscar si «la fecha de hoy» está en esa maestra, terminando la ejecución si el día no es hábil. Como fuente primaria para mantener actualizada esa maestra puede usarse el CSV de festivos que publica la Oficina del Gabinete de Japón.
- ¿Se puede crear un flujo que se ejecute solo en el último día hábil de cada mes?
- Para una fecha fija como «el día 20 de cada mes», basta con configurar la fecha y hora de inicio en el día objetivo y la frecuencia en «mensual»: a partir de esa fecha de inicio se generan ejecuciones el mismo día y a la misma hora cada mes. En cambio, el disparador Recurrence no ofrece ninguna opción para indicar directamente «el último día del mes», y las opciones detalladas de día de la semana u hora solo están disponibles cuando la frecuencia es «diaria» o «semanal». Para un proceso con una fecha variable, como el fin de mes, la solución es ejecutar el flujo todos los días (o todos los días laborables) y, al inicio, usar una fórmula para determinar si «hoy es fin de mes» o «hoy es día hábil», terminando la ejecución los días que no cumplan la condición. La determinación de fin de mes puede escribirse con una fórmula del tipo «si el mes de hoy y el mes de mañana son distintos, hoy es fin de mes». La regla de «si el fin de mes cae en fin de semana o festivo, ejecutar el día hábil anterior» se expresa con la misma estructura, añadiendo la comprobación contra la maestra de festivos.
- Mi flujo programado se desactivó sin que nadie lo supiera. ¿Por qué ocurre esto?
- Power Automate tiene varias condiciones que desactivan un flujo automáticamente. Un flujo cuyo disparador o acciones fallan de forma continuada se desactiva a los 14 días, y lo mismo ocurre con un flujo sometido a limitación (throttling) continua. Además, un flujo que no se dispara ni una sola vez en 90 días puede desactivarse (esto no aplica si el propietario tiene una licencia premium o de capacidad, y se notifica al propietario y a los copropietarios 30 días antes de la desactivación). Como es difícil que alguien note que un flujo programado se ha detenido, es fundamental incorporar desde el principio las notificaciones de fallo y un registro de ejecuciones.
Perfil del autor
Página de presentación del autor del artículo.
Go Komura
Representante de KomuraSoft LLC
Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.