Quando due tabelle contengono dati compatibili ma non sono collegate da una relazione, molti report Power BI iniziano a restituire risultati incompleti o difficili da interpretare. In questi casi, TREATAS in DAX permette di trasferire dinamicamente i valori selezionati da una tabella a un’altra, anche se il modello non contiene una relazione fisica. Vediamo come funziona, quando usarla, quali alternative valutare e quali errori evitare.
La funzione che porta un filtro dove serve
- Scopo: applicare i valori di un’espressione tabellare a colonne di una tabella non correlata.
- Uso tipico: inserire TREATAS dentro CALCULATE per sincronizzare filtri e slicer.
- Regola essenziale: il numero e l’ordine delle colonne devono corrispondere.
- Limite importante: i valori presenti nella tabella sorgente ma assenti nella colonna destinazione vengono ignorati.
- Scelta progettuale: una relazione del modello resta preferibile quando il legame tra le tabelle è stabile.

Che cosa fa davvero TREATAS
TREATAS prende il risultato di un’espressione che restituisce una tabella e lo usa come filtro su una o più colonne esistenti. Il suo valore pratico è evidente quando le tabelle sono disconnesse, cioè non hanno una relazione attiva nel modello semantico.
Immaginiamo una tabella SelettoreCategoria con le categorie scelte dall’utente e una tabella DimProdotto che filtra le vendite. Anche senza una relazione tra le due, possiamo trasferire la selezione in questo modo:
Vendite filtrate :=
CALCULATE(
[Vendite totali],
TREATAS(
VALUES(SelettoreCategoria[Categoria]),
DimProdotto[Categoria]
)
)VALUES legge i valori attualmente presenti nel contesto di filtro, mentre TREATAS li applica a DimProdotto[Categoria]. Io considero questa funzione una sorta di ponte virtuale: non modifica il modello e non crea una relazione permanente, ma influenza il calcolo della misura.
Il risultato è una tabella di valori filtranti, non un numero. Per questo TREATAS viene usata soprattutto come argomento di CALCULATE, che modifica il contesto nel quale viene valutata una misura.
Sintassi e regole che determinano il risultato
La sintassi generale è semplice:
TREATAS(
table_expression,
ColonnaDestinazione1,
ColonnaDestinazione2
)Il primo argomento deve produrre una tabella. Può trattarsi, per esempio, di VALUES, FILTER, SELECTCOLUMNS, DATATABLE o di un’altra espressione DAX. Le colonne indicate dopo l’espressione devono essere colonne fisiche esistenti, non espressioni calcolate scritte direttamente nella funzione.
Con una sola colonna, la corrispondenza è intuitiva. Se invece si trasferiscono più colonne, è necessario rispettare due condizioni precise:
- il numero delle colonne dell’espressione sorgente deve coincidere con quello delle colonne destinazione;
- le colonne devono comparire nello stesso ordine.
Un esempio a due colonne può essere utile per filtrare contemporaneamente anno e mese:
Vendite periodo selezionato :=
CALCULATE(
[Vendite totali],
TREATAS(
SUMMARIZE(
SelettorePeriodo,
SelettorePeriodo[Anno],
SelettorePeriodo[MeseNumero]
),
Calendario[Anno],
Calendario[MeseNumero]
)
)Qui la prima colonna prodotta da SUMMARIZE viene associata all’anno e la seconda al numero del mese. Se l’ordine fosse invertito, il filtro sarebbe logicamente sbagliato anche se la formula fosse accettata.
Un altro dettaglio spesso trascurato riguarda i valori mancanti. Se l’espressione sorgente contiene una categoria che non esiste nella colonna di destinazione, quella categoria viene ignorata. Questo evita un errore di esecuzione, ma può nascondere problemi di qualità dati o differenze di codifica tra le tabelle.
Tre applicazioni pratiche in Power BI
Sincronizzare uno slicer disconnesso
Uno slicer basato su una tabella disconnessa è utile quando voglio separare la selezione dell’utente dalla dimensione principale del modello. Per esempio, posso creare una tabella di confronto con due gruppi di prodotto e usare TREATAS per applicare il gruppo scelto alle vendite.
Vendite gruppo selezionato :=
CALCULATE(
[Vendite totali],
TREATAS(
VALUES(GruppiAnalisi[Categoria]),
DimProdotto[Categoria]
)
)Questo approccio è comodo per scenari di what-if, confronti tra segmenti e selezioni speciali. La tabella del selettore non deve però contenere valori scritti in modo diverso, come “Accessori” in una tabella e “accessorio” nell’altra.
Confrontare due tabelle prodotto indipendenti
Microsoft Learn mostra un caso classico con due tabelle prodotto non correlate. Se l’utente filtra una categoria nella prima tabella, TREATAS può applicare gli stessi valori alla seconda, rendendo possibile un confronto coerente tra assortimenti o listini.
Vendite secondo catalogo :=
CALCULATE(
SUM(VenditeCatalogo2[Importo]),
TREATAS(
VALUES(DimProdotto1[Categoria]),
DimProdotto2[Categoria]
)
)La funzione non verifica che i prodotti siano identici riga per riga. Trasferisce soltanto i valori della colonna indicata. Per questo è importante scegliere una chiave realmente condivisa, come un codice prodotto standardizzato, invece di una descrizione commerciale che può cambiare tra sistemi.
Applicare un insieme di valori costruito nella misura
TREATAS può lavorare anche con un elenco creato direttamente nella formula. Questo è utile per prove, regole di business circoscritte o misure che devono considerare un gruppo fisso di valori.
Vendite colori prioritari :=
CALCULATE(
[Vendite totali],
TREATAS(
{"Rosso", "Verde", "Blu"},
DimProdotto[Colore]
)
)Se “Blu” non compare nella dimensione prodotto, il valore non produrrà righe. Il codice resta valido, ma il risultato dipenderà dai dati presenti nel modello. In produzione preferisco usare una tabella di configurazione quando l’elenco deve essere modificato da utenti o amministratori.
TREATAS, relazioni e funzioni alternative
La domanda più importante non è soltanto come scrivere la formula, ma se TREATAS sia davvero la scelta migliore. Se due tabelle rappresentano un legame stabile e frequente, una relazione nel modello è generalmente più leggibile, più facile da mantenere e più naturale per il motore tabulare.
| Soluzione | Quando usarla | Attenzione a |
|---|---|---|
| TREATAS | Filtri virtuali tra tabelle disconnesse | Tipi, ordine e cardinalità delle colonne |
| Relazione | Legami stabili tra dimensioni e fatti | Ambiguità e direzione del filtro |
| USERELATIONSHIP | Attivare una relazione già presente ma inattiva | La relazione deve esistere nel modello |
| FILTER | Applicare condizioni più articolate riga per riga | Può risultare più pesante su tabelle grandi |
| INTERSECT | Calcolare l’intersezione tra insiemi compatibili | La struttura delle colonne deve essere coerente |
USERELATIONSHIP è preferibile quando il problema riguarda, per esempio, una tabella calendario con relazione inattiva sulla data di consegna. In quel caso non sto simulando un collegamento tra colonne indipendenti, ma attivando temporaneamente un legame già modellato.
Vendite per data consegna :=
CALCULATE(
[Vendite totali],
USERELATIONSHIP(
Calendario[Data],
Vendite[DataConsegna]
)
)Io uso TREATAS soprattutto quando il filtro è intenzionalmente virtuale. Se invece la misura ricorre continuamente allo stesso trasferimento tra le stesse colonne, quel pattern può indicare che il modello dati andrebbe riprogettato.
Errori frequenti e limiti da conoscere
L’errore più comune consiste nel confondere TREATAS con una relazione. La funzione non collega davvero le tabelle, non aggiunge chiavi e non risolve automaticamente duplicati, valori vuoti o codici incompatibili.
Tipo di dato e valori non allineati
Una colonna numerica e una colonna testuale possono rappresentare lo stesso codice ma non comportarsi allo stesso modo nel filtro. Prima di usare la funzione, controllo sempre che i valori abbiano stesso formato e stesso significato, inclusi zeri iniziali, spazi e maiuscole quando rilevanti.
Filtri sovrascritti da CALCULATE
Come altri filtri passati a CALCULATE, TREATAS può sostituire un filtro già presente sulla stessa colonna. Se voglio aggiungere valori senza rimuovere quelli esistenti, valuto l’uso di KEEPFILTERS:
Vendite con filtro aggiuntivo :=
CALCULATE(
[Vendite totali],
KEEPFILTERS(
TREATAS(
VALUES(Selettore[Categoria]),
DimProdotto[Categoria]
)
)
)La differenza può cambiare molto il risultato di una matrice o di una scheda KPI. Quando una misura restituisce numeri inattesi, verifico prima il contesto filtro nel visual e poi controllo se la formula sta sostituendo o combinando i filtri.
Leggi anche: Tabular Editor in Power BI - guida a DAX, versioni e modelli
DirectQuery, colonne calcolate e RLS
Secondo la documentazione di Microsoft Learn, TREATAS non è supportata in modalità DirectQuery quando viene usata in colonne calcolate o nelle regole di sicurezza a livello di riga, note come RLS. Nelle misure il caso d’uso resta diverso, ma la compatibilità va verificata nell’architettura concreta del progetto.
Per modelli molto grandi, il problema non è automaticamente la funzione in sé. Pesano soprattutto la cardinalità delle colonne, la complessità dell’espressione tabellare e il numero di visual che ricalcolano la misura. Una misura semplice basata su VALUES è in genere più prevedibile di una costruzione con filtri annidati e tabelle intermedie molto ampie.
Un metodo pratico per decidere se usarla
Prima di scrivere la formula, seguo una verifica in quattro passaggi:
- Identifico la tabella che contiene la selezione o l’insieme di valori.
- Controllo che la tabella destinazione abbia una colonna con la stessa chiave logica.
- Verifico se una relazione stabile risolverebbe il problema in modo più chiaro.
- Testo la misura con valori presenti, assenti, duplicati e selezione vuota.
Per il debug, creo spesso una misura di controllo che conta i valori trasferiti:
Numero categorie trasferite :=
COUNTROWS(
TREATAS(
VALUES(SelettoreCategoria[Categoria]),
DimProdotto[Categoria]
)
)Se il conteggio non coincide con le aspettative, non continuo a modificare la misura principale alla cieca. Controllo prima il contenuto della tabella sorgente, le corrispondenze effettive e il contesto del visual. Questa piccola verifica fa emergere rapidamente la maggior parte degli errori.
La scelta giusta per un modello DAX più solido
TREATAS è una soluzione elegante quando devo trasferire un filtro senza creare una relazione fisica. Funziona particolarmente bene con slicer disconnessi, tabelle di confronto e scenari di analisi selettiva, purché le colonne condividano valori e significato.
Non la considero però un sostituto universale della modellazione dimensionale. Quando lo stesso collegamento serve in molte misure, una relazione ben progettata rende il report più comprensibile e riduce la logica nascosta nel codice DAX.
La regola pratica è semplice: usa TREATAS per un’esigenza virtuale e mirata, usa una relazione per un legame strutturale. Questa distinzione evita formule fragili e rende il modello Power BI più facile da spiegare, testare e mantenere nel tempo.
