DAX-fout "Multiple columns cannot be converted" (2026)
DAX gebruikt een tabel met meerdere kolommen waar één scalar nodig is. Herstel FILTER, SUMMARIZE, SELECTCOLUMNS en tabelvariabelen gericht.
Conceptpagina. Deze pagina wordt nog gecontroleerd. Daarom staat hij op noindex en blijft hij buiten de sitemap tot de inhoud publicatieklaar is.
De fout “The expression refers to multiple columns. Multiple columns cannot be converted to a scalar value” betekent dat een DAX-expressie een tabel met meerdere kolommen doorgeeft op een plek waar één waarde nodig is. Bepaal of je een scalar, een filtertabel of een berekende tabel wilt en geef de tabel daarna aan een passende aggregatie, iterator of tabelpositie.
Wat gaat er precies mis?
DAX werkt met scalaire waarden en tabellen. Een scalar is één waarde, zoals tekst, een getal, een datum of TRUE en FALSE. Een tabel heeft rijen en één of meer kolommen en wordt meestal als tussentabel door een andere functie verwerkt.
Functies zoals FILTER, SUMMARIZE, SELECTCOLUMNS, TOPN en CALCULATETABLE retourneren een tabel. Dat is geldig wanneer je die uitkomst gebruikt:
- als invoer voor
COUNTROWS,SUMX,MAXXof een andere iterator; - als filterargument van
CALCULATE; - als resultaat van een berekende tabel;
- na
EVALUATEin een DAX-query.
De fout ontstaat wanneer dezelfde tabel bijvoorbeeld het eindresultaat van een measure, een berekende kolom, een vergelijking of een scalar functieargument wordt. De tabel hoeft daarvoor niet meerdere rijen te bevatten. Eén rij met twee kolommen blijft een tabel met meerdere kolommen en kan niet één waarde voorstellen.
Microsoft legt in het officiële DAX-overzicht uit dat tabelfuncties hun resultaat als invoer aan andere tabelfuncties geven en niet rechtstreeks als berekeningswaarde worden opgeslagen. De plaats in de formule bepaalt dus of een tabeluitkomst geldig is.
Verschil met de fout over meerdere waarden
Deze melding lijkt op “A table of multiple values was supplied where a single value was expected”, maar de eerste diagnose verschilt:
- Multiple columns cannot be converted: controleer de breedte van de tabel.
FILTER(Orders, ...)behoudt bijvoorbeeld alle kolommen vanOrders. - A table of multiple values was supplied: controleer hoeveel waarden of rijen een eenkolomstabel of lookup oplevert.
- A single value for column cannot be determined: controleer een losse kolomverwijzing in de huidige filtercontext met de single-value-decoder.
Een formule kan beide dimensies tegelijk verkeerd behandelen. SELECTCOLUMNS kan een tabel smaller maken, maar maakt haar nog niet automatisch scalair. Los daarom niet alleen de kolombreedte op. Bepaal ook hoeveel rijen geldig zijn en welke zakelijke uitkomst je nodig hebt.
Stap voor stap de multiple-columns-fout oplossen
1. Controleer welk object je aan het maken bent
Kijk eerst of je Nieuwe measure, Nieuwe kolom of Nieuwe tabel hebt gekozen. Dezelfde DAX-expressie kan als berekende tabel geldig zijn en als measure ongeldig.
Noteer vervolgens wat het object moet opleveren:
- een getal voor een kaart of grafiek;
- tekst voor een titel;
- één waarde per modelrij;
- een reeks rijen voor een nieuw modelobject;
- een tabel die alleen een andere berekening filtert.
Deze keuze bepaalt de reparatie. Alleen van objecttype wisselen omdat de formule dan wordt geaccepteerd is geen oplossing als het rapport een dynamische measure nodig heeft.
2. Zoek de tabelproducerende expressie
Scan de formule op functies met een tabel als retourwaarde. Veelvoorkomende kandidaten zijn:
FILTER;SUMMARIZEenSUMMARIZECOLUMNS;SELECTCOLUMNSenADDCOLUMNS;TOPN;VALUESmet een tabelnaam;ALLmet een tabelnaam;CALCULATETABLE;- een tabelconstructor met accolades.
Controleer bij twijfel de retourwaarde in de DAX-functiereferentie. Een variabele verandert het type niet:
VAR OpenOrders =
FILTER(
Orders,
Orders[Status] = "Open"
)
OpenOrders blijft hier een tabel met alle kolommen die FILTER uit Orders doorgeeft.
3. Bekijk de tabelvorm in DAX Query View
Kopieer alleen de tabeluitdrukking naar een tijdelijke query in DAX Query View. Zet er EVALUATE voor:
EVALUATE
TOPN(
5,
FILTER(
Orders,
Orders[Status] = "Open"
),
Orders[Orderdatum],
DESC
)
De resultaten tonen welke kolommen en rijen de expressie werkelijk teruggeeft. Dit is een diagnose, geen measure. EVALUATE hoort bij een DAX-query en niet in de formulebalk van een modelmeasure.
4. Kies wat er met de tabel moet gebeuren
Maak een expliciete keuze:
- rijen tellen:
COUNTROWS; - een numerieke expressie per rij optellen:
SUMX; - één veld uit een aantoonbaar gekozen rij lezen: bijvoorbeeld
MAXXover een deterministischeTOPN; - waarden als tekst samenvoegen:
CONCATENATEX; - de berekening filteren: tabel als filterargument van
CALCULATE; - rijen en kolommen bewaren: een berekende tabel maken.
Een willekeurige MAXX of MINX toevoegen omdat die één waarde oplevert kan de melding verbergen en tegelijk een onjuiste businessregel introduceren.
5. Repareer de grens tussen tabel en scalar
Laat de tabelproducerende expressie staan als zij de juiste rijen selecteert. Pas de buitenste laag aan zodat de ontvanger het juiste type krijgt. Daardoor blijven filterlogica en resultaatlogica gescheiden.
Geef tabelvariabelen herkenbare namen zoals OpenOrdersTabel en scalars namen zoals AantalOpenOrders. De naam is geen typecontrole, maar maakt een onjuiste RETURN veel sneller zichtbaar.
6. Test vorm, context en lege resultaten
Test de formule met:
- geen gevonden rijen;
- één gevonden rij;
- meerdere gevonden rijen;
- een detailrij in een visual;
- een subtotaal en eindtotaal;
- één en meerdere slicerselecties.
Controleer bij een gekozen record ook gelijke sorteerwaarden. TOPN(1, ...) kan door een gelijke waarde op de grens meerdere rijen teruggeven. Voeg daarom een unieke tweede sortering toe wanneer precies één rij vereist is.
Oplossing 1: FILTER tellen in plaats van retourneren
Deze measure probeert een volledige tabel terug te geven:
Open orders =
FILTER(
Orders,
Orders[Status] = "Open"
)
Wil je het aantal open orders tonen, tel dan de rijen:
Aantal open orders =
COALESCE(
COUNTROWS(
FILTER(
Orders,
Orders[Status] = "Open"
)
),
0
)
FILTER retourneert een tabel. COUNTROWS accepteert die tabel en retourneert één geheel getal, of BLANK() bij een lege tabel. COALESCE zet die lege uitkomst hier bewust om naar nul.
Gebruik COUNTROWS alleen als een aantal de bedoelde rapportwaarde is. Voor omzet, duur of een ander numeriek veld heb je een passende aggregatie of iterator nodig.
Oplossing 2: een tabelvariabele met een iterator reduceren
Deze formule selecteert de juiste orders, maar retourneert de tabelvariabele rechtstreeks:
Open orderomzet =
VAR OpenOrdersTabel =
FILTER(
Orders,
Orders[Status] = "Open"
)
RETURN
OpenOrdersTabel
Laat SUMX de omzet per gevonden rij optellen:
Open orderomzet =
VAR OpenOrdersTabel =
FILTER(
Orders,
Orders[Status] = "Open"
)
RETURN
SUMX(
OpenOrdersTabel,
Orders[Omzet]
)
De officiële documentatie voor SUMX beschrijft precies deze typegrens: het eerste argument is een tabel, terwijl de functie uiteindelijk één decimaal getal retourneert.
Voor een eenvoudige kolomvoorwaarde is een scalaire aggregatie binnen CALCULATE vaak compacter:
Open orderomzet =
CALCULATE(
SUM(Orders[Omzet]),
Orders[Status] = "Open"
)
Het eerste argument van CALCULATE levert hier één waarde op. De statusvoorwaarde wijzigt alleen de filtercontext.
Oplossing 3: CALCULATE en CALCULATETABLE niet verwisselen
Deze formule is een geldige tabeluitdrukking, maar niet het geldige eindresultaat van een measure:
Orders dit jaar =
CALCULATETABLE(
Orders,
'Datum'[Jaar] = YEAR(TODAY())
)
Wil je een dynamisch aantal in visuals, maak dan een measure met CALCULATE:
Aantal orders dit jaar =
CALCULATE(
COUNTROWS(Orders),
'Datum'[Jaar] = YEAR(TODAY())
)
Wil je de gefilterde rijen werkelijk als modeltabel bewaren, kies dan Nieuwe tabel en gebruik de eerste formule daar. Een berekende tabel wordt bij een modelverversing herberekend en reageert niet rechtstreeks op slicers.
Microsoft beschrijft het typeverschil bij CALCULATETABLE: deze functie verwacht en retourneert een tabel. CALCULATE evalueert een measure-achtige expressie in een gewijzigde filtercontext en levert de resulterende waarde op.
Oplossing 4: SUMMARIZE of SELECTCOLUMNS bewust consumeren
Deze measure retourneert een samenvatting met meerdere kolommen:
Categorieoverzicht =
SUMMARIZE(
Sales,
Sales[Categorie],
Sales[Regio]
)
Als je het aantal zichtbare combinaties nodig hebt, gebruik:
Aantal categorie-regio-combinaties =
COUNTROWS(
SUMMARIZE(
Sales,
Sales[Categorie],
Sales[Regio]
)
)
Als je het overzicht zelf nodig hebt voor relaties of velden in een visual, maak de eerste formule als berekende tabel. SUMMARIZE retourneert één rij per groep en blijft een tabel, ongeacht het aantal groepen.
Ook SELECTCOLUMNS blijft een tabelfunctie. In dit berekende-tabelvoorbeeld moet iedere benoemde expressie wel één waarde per productrij opleveren:
Productoverzicht =
SELECTCOLUMNS(
Product,
"Product", Product[Productnaam],
"Aantal orderregels", COUNTROWS(RELATEDTABLE(Sales))
)
De documentatie voor SELECTCOLUMNS maakt het onderscheid expliciet: de functie retourneert een tabel, terwijl iedere expressie voor een toegevoegde kolom per rij scalair moet zijn. Een FILTER(...) rechtstreeks als benoemde kolomexpressie gebruiken verwisselt die twee niveaus opnieuw.
Oplossing 5: TOPN eerst deterministisch maken en dan uitlezen
TOPN geeft ook met N = 1 een tabel terug. Deze measure kan daarom niet direct worden opgeslagen:
Topproduct =
TOPN(
1,
Product,
[Omzet],
DESC
)
Bouw eerst een ranglijst, voeg een unieke tweede sortering toe en lees daarna de productnaam uit de gekozen rij:
Topproduct =
VAR Ranglijst =
ADDCOLUMNS(
SUMMARIZE(
Product,
Product[ProductId],
Product[Productnaam]
),
"Omzetwaarde", [Omzet]
)
VAR EersteRij =
TOPN(
1,
Ranglijst,
[Omzetwaarde],
DESC,
Product[ProductId],
ASC
)
RETURN
MAXX(
EersteRij,
Product[Productnaam]
)
De tweede sortering zorgt dat twee producten met dezelfde omzet niet allebei op de grens blijven staan, mits ProductId uniek is. MAXX dient hier alleen om de productnaam uit de aantoonbaar ene rij te lezen. De officiële TOPN-documentatie bevestigt dat de functie een tabel retourneert en bij gelijke grenswaarden meer dan N rijen kan opleveren.
Oplossing 6: een tabelconstructor op een tabelpositie gebruiken
Accolades maken een tabel. Deze measure probeert één rij met twee kolommen als één rapportwaarde te gebruiken:
Geselecteerde combinatie =
{
(
SELECTEDVALUE(Product[Merk]),
SELECTEDVALUE(Product[Kleur])
)
}
Wil je een label, maak dan zelf één tekstscalar:
Geselecteerde combinatie =
VAR Merk = SELECTEDVALUE(Product[Merk])
VAR Kleur = SELECTEDVALUE(Product[Kleur])
RETURN
IF(
ISBLANK(Merk) || ISBLANK(Kleur),
BLANK(),
Merk & " - " & Kleur
)
Wil je juist vaste merk-kleurcombinaties als filter toepassen, dan is de tabelconstructor geldig binnen een functie die twee tabelkolommen verwacht:
Omzet gekozen combinaties =
CALCULATE(
[Omzet],
TREATAS(
{
("Contoso", "Rood"),
("Fabrikam", "Blauw")
},
Product[Merk],
Product[Kleur]
)
)
De officiële uitleg over de tabelconstructor vermeldt dat dit patroon een tabel met één of meer kolommen retourneert. Bij TREATAS moet het aantal doelkolommen overeenkomen met het aantal kolommen in de tabeluitdrukking en moet de volgorde gelijk zijn.
Let op bij DirectQuery
De multiple-columns-fout is een typemismatch en kan zowel in Import als DirectQuery optreden. De opslagmodus verandert een tabeluitkomst niet in een scalar.
Controleer daarnaast de beperkingen van iedere gebruikte functie. Microsoft vermeldt bijvoorbeeld bij FILTER, COUNTROWS, SELECTCOLUMNS, SUMMARIZE, TOPN en TREATAS dat deze functies in DirectQuery niet worden ondersteund wanneer je ze in berekende kolommen of RLS-regels gebruikt. Dat is geen algemeen verbod op dezelfde functies in measures.
Kies de berekeningslaag op basis van het gewenste gedrag. Een measure wordt op aanvraag in filtercontext berekend. Een berekende tabel wordt bij modelverversing opgebouwd en opgeslagen. Het actuele overzicht staat bij Calculation Options in Power BI Desktop.
Veelgemaakte fouten
- Nieuwe measure kiezen terwijl je een tabel wilt maken. Een geldige tabeluitdrukking past niet als eindresultaat van een measure.
- FILTER rechtstreeks na RETURN zetten.
FILTERretourneert de gevonden rijen met de kolommen van zijn invoertabel. - Aannemen dat SELECTCOLUMNS een scalar maakt. Minder kolommen betekent nog steeds niet automatisch één waarde.
- TOPN(1) als één waarde behandelen.
TOPNretourneert een tabel en kan bij gelijke grenswaarden meer rijen opleveren. - Overal COUNTROWS omheen zetten. Dat is alleen correct als een aantal werkelijk de gewenste uitkomst is.
- CALCULATETABLE voor een dynamische kaartwaarde gebruiken. Gebruik een scalaire expressie binnen
CALCULATE. - Een tabelvariabele een enkelvoudige naam geven en haar type vergeten. De variabelenaam verandert de retourwaarde niet.
- Alleen één toevallig resultaat testen. De kolombreedte blijft ook bij één rij bestaan en een bredere filtercontext kan extra rijen toevoegen.
Zo voorkom je deze fout
Benoem bij iedere variabele of zij een tabel of scalar bevat. Controleer bij een onbekende functie de officiële retourwaarde voordat je haar in een measure gebruikt. Bouw complexe berekeningen van binnen naar buiten en test tussentabellen afzonderlijk in DAX Query View.
Maak daarnaast vóór het schrijven van de formule een keuze tussen een dynamische rapportwaarde en een opgeslagen modeltabel. Zo voorkom je dat een correcte tabeluitdrukking in het verkeerde objecttype belandt.
Krijg je na deze reparatie een andere melding, ga dan naar het overzicht met DAX-foutmeldingen. Bij een parserfout helpt de decoder voor “The syntax for ... is incorrect”, en bij een afhankelijkheidslus de uitleg over circular dependencies. Alle Power BI-handleidingen staan op de Power BI-hub.
Veelgestelde vragen
- Wat betekent 'The expression refers to multiple columns. Multiple columns cannot be converted to a scalar value'?
- Een deel van de DAX-formule levert een tabel met meerdere kolommen op, terwijl de ontvangende plek één scalar verwacht. Bepaal eerst of je een getal, tekst, datum, booleaanse waarde, filtertabel of berekende tabel nodig hebt en pas daarna de buitenste functie aan.
- Wat is het verschil met 'A table of multiple values was supplied'?
- De multiple-columns-fout wijst op een tabel die te veel kolommen heeft voor een scalarpositie, zelfs als die tabel maar één rij bevat. De multiple-values-fout gaat meestal over een eenkolomstabel of lookup die meerdere waarden kan opleveren waar één waarde nodig is.
- Waarom kan ik FILTER niet rechtstreeks als measure gebruiken?
- FILTER retourneert een tabel met de kolommen van zijn invoertabel. Een measure moet per evaluatiecontext één waarde opleveren. Tel de rijen met COUNTROWS, aggregeer ze met een iterator of gebruik de tabel als filterargument van een scalaire berekening.
- Mag een berekende tabel wel meerdere kolommen retourneren?
- Ja. Een berekende tabel is juist een modelobject met rijen en kolommen. Maak de formule via Nieuwe tabel en houd er rekening mee dat het resultaat bij modelverversing wordt herberekend en niet rechtstreeks met slicers meebeweegt.
- Wanneer gebruik ik CALCULATE en wanneer CALCULATETABLE?
- Gebruik CALCULATE wanneer de eerste expressie één waarde moet opleveren, zoals een som, telling of measure. Gebruik CALCULATETABLE wanneer de eerste expressie een tabel is en de ontvanger ook werkelijk een tabel verwacht.
- Maakt SELECTCOLUMNS een tabel automatisch scalair?
- Nee. SELECTCOLUMNS kiest of berekent kolommen, maar retourneert nog steeds een tabel. Gebruik het resultaat als tabelinvoer, maak er een berekende tabel van of reduceer het bewust met bijvoorbeeld COUNTROWS, SUMX, MAXX of CONCATENATEX.
- Waarom geeft TOPN met N gelijk aan 1 nog steeds deze fout?
- TOPN retourneert altijd een tabel en kan bij een gelijke sorteerwaarde op de grens zelfs meer dan één rij teruggeven. Voeg een unieke tweede sortering toe en lees daarna de bedoelde kolom uit met een iterator, of gebruik de tabel als tabelinvoer.
Lees ook
Hulp nodig bij jouw situatie?
Kom je er niet uit? Stuur kort wat context, wat je wilt bereiken en waar je vastloopt. Vraag een offerte aan als je wilt dat ik het voor je oplos.
w.bouwmeester@bouwmeesterconsultancy.nl · +31 6 28963636