Le azioni e le operazioni sui dati

Dopo il trigger, tutto quello che il flow fa è una action: la pagina Actions di Power Automate le definisce come le operazioni che vuoi far compiere al flow dopo che l’evento del trigger si è verificato. Si aggiungono con il segno più (+) sotto il trigger o sotto un’azione esistente, e il pannello di configurazione che si apre è organizzato in quattro sezioni: Favorites, AI capabilities, Built-in tools e By connector. I costrutti di controllo di cui parla questa unità stanno fra i built-in, non fra i connettori: non cercare una reference del connettore di controllo, perché non esiste.

Prima ancora di ramificare, molte azioni servono solo a dare forma ai dati. La pagina Use data operations documenta Compose (un output unico a partire da più input, comodo per non riscrivere lo stesso valore), Join (array in una stringa con il separatore scelto), Select (cambia la forma degli oggetti di un array, ma avverte che non puoi cambiare il numero di oggetti), Filter array (riduce l’array a un sottoinsieme, e il testo su cui filtri è case-sensitive), Create CSV table e Create HTML table.

Accanto ci sono le variabili: Initialize variable, Set variable, Increment variable, Decrement variable, Append to string variable, Append to array variable. Due dettagli che l’esame ama: le variabili sono globali al flow e persistono fra le iterazioni dei cicli, e si possono dichiarare solo a livello globale, non dentro scope, condizioni o loop. Nelle impostazioni della singola azione trovi anche Retry policy, che la guidance consiglia di impostare esponenziale per i guasti transitori.

Condition e Switch: dove il flow si biforca

Il Condition confronta un valore con un altro e manda l’esecuzione su uno dei due rami. Attenzione ai nomi, perché cambiano con il designer: il tutorial Add a condition usa If yes e If no, mentre nella scheda del nuovo designer di Use expressions in conditions i rami si chiamano True e False. In una domanda d’esame che cita uno dei due, la sostanza non cambia: il ramo scelto dipende dal risultato booleano.

Per confronti multipli si passa a Edit in advanced mode e si scrive un’espressione. Le funzioni logiche documentate sono and, or, equals, less, lessOrEquals, greater, greaterOrEquals, empty, not, if, e ogni condizione avanzata inizia con il simbolo @:

@and(greater(item()?['Due'], item()?['Paid']), less(item()?['dueDate'], addDays(utcNow(),1)))

Quando i rami sono più di due, la scelta è lo Switch: la pagina Actions elenca condizioni, switch e scope come i modi per organizzare le decisioni, e la pagina dei limiti fissa a 25 il numero massimo di case di uno switch.

Apply to each, Do until e la concorrenza

Apply to each richiede un array in ingresso e ripete le azioni contenute per ogni elemento. Il punto che separa chi ha letto la doc da chi va a intuito è la concorrenza. Nella pagina Limits of automated, scheduled, and instant flows, la riga Apply to each concurrency dice che il default è 1 e che puoi portarlo a un valore fra 1 e 50 inclusi; la riga Apply to each array item fissa il numero massimo di elementi processabili a 5.000 per il profilo Low e 100.000 per gli altri. La stessa tabella descrive Split on items, cioè la possibilità, per i trigger che restituiscono un array, di usare la proprietà SplitOn per far partire una istanza di flow per ogni elemento invece di ciclare, con il limite che scende a 100 elementi quando la concorrenza del trigger è attiva.

Prima di alzare la parallelizzazione, leggi l’avviso della pagina sulle variabili: di default le iterazioni girano in sequenza, e se usi variabili dentro il ciclo devi restare sequenziale per avere risultati prevedibili. La guidance sugli anti-pattern aggiunge di evitare i For each annidati, perché le iterazioni si moltiplicano, e ricorda che il ciclo può processare fino a 50 record in parallelo.

Il Do until ripete finché una condizione non è soddisfatta. Qui c’è un buco di documentazione da conoscere per non perdere tempo: non esiste una pagina dedicata, il costrutto compare dentro altri articoli. I suoi limiti li trovi sempre nella pagina dei limiti, alla riga Until iterations: default 60, massimo 5.000. La stessa pagina suggerisce un pattern di polling asincrono o un ciclo Until per le operazioni lunghe che sforerebbero il timeout della richiesta sincrona.

Una confusione tipica da smontare: la Concurrency Control delle impostazioni del trigger governa quante esecuzioni del flow girano insieme (1-100, default 25 quando è attiva), mentre la concorrenza di Apply to each governa quante iterazioni girano insieme dentro una singola esecuzione. Sono due manopole diverse.

Scope, Run after e Terminate

Lo Scope è un contenitore che raggruppa azioni correlate: quando gira, tutto il blocco viene eseguito come un’unità e riporta un solo stato (Succeeded, Failed, Skipped e altri). Combinato con Run after — l’impostazione che stabilisce cosa succede se un’azione fallisce, va in timeout, viene saltata o riesce — permette il pattern try/catch: uno scope principale e uno scope di gestione errori configurato per partire solo se il primo fallisce. La doc raccomanda di tenere trigger e azioni di risposta fuori dagli scope e di non abusarne.

Due limiti strutturali da ricordare: 500 azioni per workflow e 8 livelli di annidamento, che la pagina Use scopes chiarisce comprendere scope, condizioni, case di switch e loop apply-to-each — oltre quella profondità il flow non si salva e non gira. Quando serve fermare tutto, si usa l’azione Terminate, che imposta uno stato e un messaggio; la guidance la propone sia per interrompere dopo un errore critico sia come salvaguardia contro i loop infiniti. Infine, il Flow checker (l’icona a stetoscopio sulla command bar) segnala errori e warning e si apre da solo al salvataggio quando ne trova.