Das ultimative Power BI Cheatsheet als Advanced Developer
Power BI Golden Rules — 34 Regeln, die den Unterschied zwischen Prototyp und Produktion ausmachen.
Das ausführliche Companion-Dokument zum „Power BI Golden Rules"-Cheatsheet. 34 Regeln, vier Domänen, null Kaffeepausen. Für alle, die Power BI über den Prototypen-Status hinaus produktiv entwickeln.
Warum dieser Guide?
Jeder, der Power BI über den Prototypen-Status hinaus entwickelt hat, kennt die Realität: Ein Modell, das im Desktop butterweich läuft, stolpert im Service über 10 Millionen Zeilen. Ein Bericht, den das Management „eigentlich ganz schick" findet, wird trotzdem nicht genutzt, weil niemand den Key Insight findet. Eine Measure, die der Werkstudent gebaut hat, killt nach sechs Monaten die Performance, weil sie bei jedem Filterwechsel die ganze Fact-Table scannt.
Die Ursache ist fast nie „Power BI ist zu langsam". Die Ursache sind handwerkliche Entscheidungen, die früh im Entwicklungsprozess getroffen — oder eben nicht getroffen — wurden.
Die folgenden 34 Regeln sind das Destillat aus hunderten Developer-Stunden in produktiven Power-BI-Projekten. Sortiert nach den vier Domänen, in denen fortgeschrittene Entwickler die meiste Zeit verbringen: DAX & Performance, Data Modeling, Power Query und Visualisierung. Jede Regel hat einen kurzen „Warum" — und wo es sinnvoll ist, ein konkretes Code-Snippet, das du direkt in dein Projekt übernehmen kannst.
Dieser Guide richtet sich nicht an Einsteiger. Wenn du weißt, was CALCULATE
macht, schon mal ein Star Schema gebaut hast und M-Code nicht aussieht wie eine fremde
Sprache, bist du richtig. Ziel: dass du nach der Lektüre mindestens drei Dinge an deinem
aktuellen Modell anders machst.
Daten sind nur dann wertvoll, wenn sie Entscheidungen besser machen — und Power-BI-Modelle nur dann wartbar, wenn sie handwerklich sauber gebaut sind.01 · Domäne
DAX & Performance — 9 Regeln
Hier entscheidet sich, ob ein Report in 200 Millisekunden oder in 20 Sekunden rendert. DAX ist unbarmherzig: die Engine verzeiht viele Designfehler — aber Performance bekommst du nur, wenn du weißt, was unter der Haube passiert.
01SUMMARIZECOLUMNS statt SUMMARIZE
SUMMARIZE mit CALCULATE
darin ist ein Klassiker aus der DAX-Steinzeit — und sollte genau dort bleiben.
SUMMARIZECOLUMNS ist die von Microsoft bevorzugte
Funktion für Gruppierungen mit Aggregaten: die Storage Engine generiert einen
wesentlich effizienteren Plan, mit weniger Materialisierungen, weniger Callbacks in
die Formula Engine und drastisch kürzerer Laufzeit bei großen Datasets.
-- AVOID SUMMARIZE( Sales, 'Date'[Year], "Revenue", CALCULATE(SUM(Sales[Amount])) ) -- DO SUMMARIZECOLUMNS( 'Date'[Year], "Revenue", SUM(Sales[Amount]) )
Die einzigen legitimen Einsatzgebiete für SUMMARIZE
sind reine Spalten-Projektionen ohne Aggregation — und selbst da gibt es meist
elegantere Alternativen.
02VAR für Wiederverwendung
Variablen sind nicht nur syntaktischer Zucker. Jede VAR
wird genau einmal evaluiert — unabhängig davon, wie oft sie im
RETURN-Teil referenziert wird. Wer denselben
Ausdruck zweimal hinschreibt, bezahlt zweimal die volle Evaluation, inklusive aller
Filter-Kontextwechsel und Storage-Engine-Queries.
-- AVOID Revenue YoY % = DIVIDE( SUM(Sales[Amount]) - CALCULATE(SUM(Sales[Amount]), SAMEPERIODLASTYEAR('Date'[Date])), CALCULATE(SUM(Sales[Amount]), SAMEPERIODLASTYEAR('Date'[Date])) ) -- DO Revenue YoY % = VAR CurrentRevenue = SUM(Sales[Amount]) VAR PriorRevenue = CALCULATE(SUM(Sales[Amount]), SAMEPERIODLASTYEAR('Date'[Date])) RETURN DIVIDE(CurrentRevenue - PriorRevenue, PriorRevenue)
Zusätzlicher Benefit: Variablen frieren den Filter-Kontext zum Zeitpunkt ihrer Definition ein. Komplexe Measures werden nicht nur schneller, sondern auch semantisch eindeutig — du vermeidest Context-Transition-Überraschungen, die sich sonst hartnäckig in Produktion einschleichen.
03Früh filtern, spät aggregieren
Die VertiPaq-Engine liebt kleine Zwischenergebnisse. Jede Operation, die die Zeilenzahl
reduziert, bevor aggregiert wird, spart Speicher, Callbacks und Zeit. Das gilt für
CALCULATE-Filter wie für iterierende Funktionen
(SUMX, FILTER).
-- AVOID: erst alle Zeilen iterieren, dann filtern SUMX( FILTER(Sales, Sales[Region] = "DACH"), Sales[Amount] * Sales[FXRate] ) -- DO: Filter als CALCULATE-Modifier, SUMX nur noch auf Subset CALCULATE( SUMX(Sales, Sales[Amount] * Sales[FXRate]), Sales[Region] = "DACH" )
Merksatz: Filter gehören so nah wie möglich an die Datenquelle — im Semantikmodell idealerweise auf die Dimensionstabelle, im Power Query so früh wie möglich in der Pipeline.
04SWITCH statt IF-Ketten
Verschachtelte IF-Anweisungen sind Wartungshölle und
kosten Kompilierzeit. SWITCH(TRUE(), …) ist nicht nur
lesbarer, sondern kompiliert zu einem schlankeren Abfrageplan. Bei fünf oder mehr
Bedingungen merkst du den Unterschied spürbar — bei zehn wird er dramatisch.
-- AVOID Band = IF(Sales[Amount] < 100, "XS", IF(Sales[Amount] < 500, "S", IF(Sales[Amount] < 2000, "M", IF(Sales[Amount] < 10000, "L", "XL")))) -- DO Band = SWITCH(TRUE(), Sales[Amount] < 100, "XS", Sales[Amount] < 500, "S", Sales[Amount] < 2000, "M", Sales[Amount] < 10000, "L", "XL" )
Bonus: Wer eine neue Bedingung einfügen muss, macht das in einer Zeile — nicht in einer Klammer-Orgie.
05DISTINCTCOUNT kostet
DISTINCTCOUNT ist eine der teuersten DAX-Funktionen
überhaupt, weil sie einen Hash über alle eindeutigen Werte bauen muss. Wenn du
garantieren kannst, dass eine Spalte bereits eindeutig ist — etwa ein Primärschlüssel
der Dimensionstabelle — ist COUNTROWS oder
COUNT bis zu einer Größenordnung schneller.
-- AVOID Active Customers = DISTINCTCOUNT(Sales[CustomerKey]) -- DO (wenn du über die Dimension zählst und Filterkontext greift) Active Customers = COUNTROWS(Customer)
In großen Modellen mit hoher Kardinalität ist diese Regel oft der Unterschied zwischen 3 Sekunden und 30 Sekunden Report-Ladezeit.
06ALL(T[Col]) statt ALL(Table)
ALL(Table) entfernt jeden Filter auf der gesamten
Tabelle — inklusive solcher, die du eigentlich behalten wolltest. Das führt zu
subtilen Bugs in Time-Intelligence-Measures oder Prozent-vom-Gesamt-Berechnungen,
weil plötzlich auch Slicer auf anderen Spalten ignoriert werden.
-- AVOID: killt auch den Region- oder Year-Filter Pct of Total = DIVIDE([Revenue], CALCULATE([Revenue], ALL(Sales))) -- DO: entfernt nur den Produkt-Filter, alle anderen Slicer bleiben wirksam Pct of Product Total = DIVIDE([Revenue], CALCULATE([Revenue], ALL(Product[ProductName])))
Faustregel: Schreibe immer so präzise wie möglich hin, welche Filter du entfernen willst. Alles andere ist Abrüstung mit dem Vorschlaghammer.
07DIVIDE() statt /-Operator
Der /-Operator wirft bei Division durch Null einen
Fehler — was im Report als graue Zelle oder komplett abstürzendes Visual endet.
DIVIDE() gibt standardmäßig BLANK()
zurück und ist zusätzlich minimal schneller, weil der Fehlerbehandlungs-Overhead in
der Engine intern optimiert ist.
-- AVOID Margin % = (Sales[Revenue] - Sales[Cost]) / Sales[Revenue] -- DO Margin % = DIVIDE(Sales[Revenue] - Sales[Cost], Sales[Revenue]) -- DO (mit explizitem Alternativwert) Margin % = DIVIDE(Sales[Revenue] - Sales[Cost], Sales[Revenue], 0)
Gerade in Dashboards mit dynamischen Slicern ist das Gold wert: ein leerer Filter darf dein Visual nicht in den Abgrund reißen.
08REMOVEFILTERS() statt ALL()
Seit DAX 2019 gibt es REMOVEFILTERS() — die
semantisch eindeutige Variante von ALL(), wenn es
als CALCULATE-Modifier eingesetzt wird. Funktional
identisch, aber der Intent ist beim Code-Review sofort klar: „Hier entferne ich Filter,
ich iteriere nicht über eine Tabelle."
-- Technisch identisch, aber REMOVEFILTERS ist selbsterklärend
Pct of Total =
DIVIDE(
[Revenue],
CALCULATE([Revenue], REMOVEFILTERS(Product[Category]))
)
Codebasen, die konsequent zwischen ALL
(Tabellenfunktion für Iteratoren) und REMOVEFILTERS
(CALCULATE-Modifier) trennen, sind messbar schneller zu warten. Ein stilistischer
Unterschied — aber einer, der sich in jedem Handover bezahlt macht.
09ISBLANK() statt = BLANK()
BLANK() ist in DAX kein Wert im klassischen Sinn —
es verhält sich je nach Kontext wie 0, wie leerer String oder wie „nichts". Ein
IF(Sales[Amount] = BLANK(), …) produziert deshalb
subtile Fehler, weil 0 = BLANK() in DAX
TRUE ergibt. ISBLANK()
prüft explizit auf die BLANK-Semantik und ist die einzig korrekte Variante.
-- AVOID: matcht auch auf 0 oder leeren String IF([Revenue] = BLANK(), "keine Daten", FORMAT([Revenue], "#,0")) -- DO IF(ISBLANK([Revenue]), "keine Daten", FORMAT([Revenue], "#,0"))
Einmal gelernt, nie wieder vergessen — und die Regel, die bei jedem Junior-Code-Review als erstes auffällt.
02 · DomäneData Modeling — 9 Regeln
Das Datenmodell ist das Fundament. Jeder Fehler hier multipliziert sich durch jede Measure und jedes Visual, das darauf aufbaut. Keine Abkürzungen — die folgenden neun Regeln sind nicht verhandelbar.
01Star Schema — immer
Kein Snowflake, keine „aber-in-unserem-Fall", keine Diskussion. Die VertiPaq-Engine ist für Star Schemas optimiert: eine Fact-Table in der Mitte, Dimensionstabellen drumherum, 1:n-Beziehungen von Dim zu Fact. Jede Normalisierung darüber hinaus kostet Performance, verkompliziert DAX und erschwert Wartung.
Wenn du Snowflake-artige Strukturen in deiner Quelle hast (Kategorie → Unterkategorie → Produkt), denormalisiere sie in Power Query zu einer einzigen Produkt-Dimension. Die paar MB mehr an Speicher sind im Vergleich zur Performance und Lesbarkeit völlig vernachlässigbar.
02Eigene Date-Tabelle
Die „Auto Date/Time"-Funktion legt für jede Datumsspalte eine versteckte Date-Tabelle an — inklusive aller Hierarchien. In einem Modell mit 15 Datumsspalten sind das 15 zusätzliche Tabellen, die du weder siehst noch verwalten kannst. Sie blähen das Modell auf, erschweren Time Intelligence und führen zu inkonsistenten Fiscal-Year-Logiken.
Stattdessen: eine dedizierte Date-Tabelle, als
Date-Table markiert (Mark as Date Table), mit
kontinuierlichen Datumswerten vom Anfang bis zum Ende deines Analysezeitraums und
allen benötigten Kalenderhierarchien.
// Minimal-Template für eine Date-Tabelle in Power Query
let
StartDate = #date(2020, 1, 1),
EndDate = Date.From(DateTime.LocalNow()),
DayCount = Duration.Days(EndDate - StartDate) + 1,
Dates = List.Dates(StartDate, DayCount, #duration(1,0,0,0)),
Table = Table.FromList(Dates, Splitter.SplitByNothing(), {"Date"}),
Typed = Table.TransformColumnTypes(Table, {{"Date", type date}}),
Enriched = Table.AddColumn(Typed, "Year", each Date.Year([Date]), Int64.Type)
in
Enriched
Auto Date/Time in den Optionen ausschalten — projektweit, einmal, nie wieder.
03Bidi-Filter vermeiden
Bidirektionale Beziehungen sehen verlockend aus, wenn eine Measure nicht das gewünschte Ergebnis liefert. Sie sind aber einer der häufigsten Performance-Killer und eine der häufigsten Quellen für mehrdeutige Abfragepfade. In komplexen Modellen mit mehreren Fact-Tables produzieren sie Endlosschleifen oder falsche Aggregationen, die sich nicht reproduzieren lassen.
Der saubere Weg: unidirektionale Beziehungen als Standard, und bei konkretem Bedarf
CROSSFILTER() auf Measure-Ebene einsetzen — lokal
und kontrolliert.
Customers With Sales =
CALCULATE(
DISTINCTCOUNT(Customer[CustomerKey]),
CROSSFILTER(Sales[CustomerKey], Customer[CustomerKey], BOTH)
)
So bleibt der Bidi-Effekt auf diese eine Measure beschränkt und kontaminiert nicht das ganze Modell.
04Measures dediziert ablegen
Measures in Fact-Tables zu werfen ist bequem — aber sobald das Modell wächst, wird die Suche nach „wo war nochmal die Umsatz-Measure" zur Archäologie. Eine dedizierte Measure-Tabelle (leere Tabelle, keine physischen Spalten, nur Measures als Inhalt) gibt dir einen zentralen, durchsuchbaren Anlaufpunkt.
So baust du eine Measure-Tabelle: In Power Query eine leere Tabelle anlegen
(= #table({"Dummy"}, {}) oder via Enter Data), die
einzige Spalte im Modell verstecken, alle Measures per Home-Table-Property dorthin
verschieben. Das Icon wechselt automatisch auf das Measure-Tabellen-Symbol.
In größeren Modellen empfiehlt sich zusätzlich eine Gruppierung via Display Folders:
Finance\Revenue, Finance\Costs,
Sales\Pipeline — skaliert deutlich besser als eine
lange flache Liste.
05Integer-Keys statt Text
VertiPaq speichert jede Spalte in einem Dictionary. Integer-Spalten sind drastisch kleiner und schneller zu joinen als Textspalten — in der Praxis 3–5× schneller bei Beziehungs-Lookups und mit deutlich geringerem RAM-Footprint. Bei Schlüsseln, die im Report nie sichtbar sind, ist Text reine Verschwendung.
Umsetzung: Wenn deine Quelle nur Textschlüssel liefert
(ProductCode = "SKU-AX-2291"), erzeuge in Power Query
einen synthetischen Integer-Key via Table.AddIndexColumn
oder einem deterministischen Hash. Der Text-Key bleibt als Attribut in der Dimension,
die Beziehung läuft über Integer.
Gleiches gilt für zusammengesetzte Schlüssel: niemals als konkatenierten String über die Beziehung joinen — immer einen separaten Surrogate Key bauen.
06M:N vermeiden
Many-to-many-Beziehungen sind seit Power BI 2018 zwar nativ unterstützt — sollten aber trotzdem vermieden werden. Sie sind intern auf bidirektionale Bridge-Tables abgebildet, die komplexe Abfragepläne erzeugen und nicht-triviale Filter-Kontextprobleme auslösen.
Der robuste Weg: explizite Bridge-Table mit zwei 1:n-Beziehungen von der Bridge zu den beiden Dimensionen. Kostet eine zusätzliche Tabelle, macht das Verhalten aber deterministisch, DAX-freundlich und auditable.
Beispiel Customer ↔ SalesRep: nicht direkt M:N modellieren, sondern eine Bridge-Table
CustomerSalesRep[CustomerKey, SalesRepKey] einziehen.
07Spalten entfernen — nicht nur ausblenden
Versteckte Spalten sind nicht weg. Sie belegen weiterhin Speicher, werden komprimiert, geladen, sortiert — einfach nur nicht angezeigt. In Modellen mit 50+ Spalten pro Tabelle, von denen 80 % nicht benötigt werden, ist das der größte einzelne Hebel für RAM-Einsparung.
Konsequenz: Im Power Query mit Table.SelectColumns
oder Remove Other Columns gezielt herausnehmen, was wirklich im Modell
gebraucht wird. Das macht nicht nur das Modell schlanker, sondern verkürzt auch die
Refresh-Zeit.
Table.SelectColumns(Source, {"CustomerKey", "CustomerName", "Region", "SegmentKey"})
08Datentypen bewusst wählen
Die VertiPaq-Kompression ist auf niedrige Kardinalität und kleine Datentypen
optimiert. Ein Fixed Decimal Number (4 Byte intern)
oder ein Int32 spart bei großen Fact-Tables schnell
Hunderte MB. Gleiches gilt für Datum vs. Datum/Uhrzeit: wenn die Uhrzeit keine Rolle
spielt, ist ein reiner Date-Typ drastisch besser komprimierbar als ein DateTime.
09Inaktive Beziehungen für multiple Date Roles
Orders haben meistens mehrere relevante Daten: OrderDate,
ShipDate, DeliveryDate.
Drei aktive Beziehungen zur Date-Table sind nicht erlaubt — nur eine darf aktiv
sein. Die anderen werden inaktiv definiert und per
USERELATIONSHIP() in der Measure aktiviert.
Revenue by Ship Date =
CALCULATE(
[Revenue],
USERELATIONSHIP('Date'[Date], Sales[ShipDate])
)
Damit bleibt das Modell sauber, deterministisch — und du hast die volle Zeitdimensions-Funktionalität pro Datumsrolle. Der Fehler wäre, drei separate Date-Tabellen anzulegen; das ist nur dann legitim, wenn der Nutzer wirklich drei Datumsachsen nebeneinander filtern muss.
03 · DomänePower Query — 8 Regeln
Power Query ist die meistunterschätzte Schicht in Power BI. Hier fällt die Entscheidung, ob ein Refresh 30 Sekunden oder 30 Minuten dauert — und ob dein Modell morgens um 6 Uhr durchläuft oder die Ops-Kollegen anruft.
01Query Folding maximieren
Query Folding bedeutet, dass Power Query die Transformationen in die native Sprache der Quelle (SQL, CDM) übersetzt und dort ausführt — statt alle Rohdaten zu laden und in-memory zu verarbeiten. Bei Datenbank-Quellen ist das der Unterschied zwischen „Server macht's in 2 Sekunden" und „Gateway lädt 5 GB und macht's in 4 Minuten".
Jeder Schritt in deiner Query sollte folden. Ab dem ersten Schritt, der nicht foldet (erkennbar per Rechtsklick → View Native Query ausgegraut), ist der Rest der Pipeline ebenfalls in-memory. Deshalb: teure Operationen (Filter, Merges, Gruppierungen) früh, Folding-kritische Schritte ans Ende — oder in ein View bzw. eine Stored Procedure auslagern.
02Spalten früh entfernen
Je weniger Spalten du transportierst, desto schneller ist jeder nachfolgende Schritt.
Remove Other Columns (mit expliziter Whitelist) ist
robuster als Remove Columns (Blacklist), weil neue
Spalten in der Quelle nicht automatisch ins Modell rutschen.
// AVOID: bricht, wenn "SecretColumn" nicht mehr existiert Table.RemoveColumns(Source, {"SecretColumn", "LegacyFlag"}) // DO: stabil gegen Schema-Änderungen, explizit dokumentiert Table.SelectColumns(Source, {"OrderKey", "CustomerKey", "Amount", "Date"})
Faustregel: Spalten filtern vor Merges, Filtern, Groupings — in dieser Reihenfolge.
03Datentypen explizit setzen — kein Auto-Detect
Die automatische Typ-Erkennung rät basierend auf den ersten 1.000 Zeilen. Das geht lange gut — bis eine Zeile kommt, in der der String „—" statt einer Zahl steht und der Refresh bricht. Oder bis ein deutsches Datumsformat falsch interpretiert wird und alle Daten um drei Monate verschoben sind.
Table.TransformColumnTypes(Source, {
{"OrderDate", type date},
{"Amount", Currency.Type},
{"Quantity", Int64.Type},
{"CustomerName", type text}
})
Und: „Promoted Headers" plus „Changed Type" am Query-Anfang — auto-generiert beim Excel/CSV-Import — gehören kritisch reviewt und meist an eine spätere Position verschoben.
04Filtern vor Mergen
Ein Merge materialisiert potenziell beide Inputs komplett. Wenn du 10 Millionen Zeilen mit einer Lookup-Table joinst, obwohl du nachher nur 50.000 Zeilen brauchst, ist das reine Ressourcenverschwendung — im Gateway, auf dem Refresh-Server, und in deiner Wartezeit.
// AVOID Merged = Table.NestedJoin(Sales, {"CustomerKey"}, Customer, {"CustomerKey"}, "Cust"), Filtered = Table.SelectRows(Merged, each [Region] = "DACH") // DO FilteredSales = Table.SelectRows(Sales, each [Region] = "DACH"), Merged = Table.NestedJoin(FilteredSales, {"CustomerKey"}, Customer, {"CustomerKey"}, "Cust")
Als Bonus foldet die zweite Variante deutlich häufiger sauber in die Quelle.
05Table.Buffer() bei mehrfach referenzierten Tabellen
Power Query ist lazy und re-evaluiert Queries, wenn sie mehrfach referenziert werden.
Wenn du also eine teure Quell-Abfrage in drei verschiedenen Downstream-Queries nutzt,
läuft sie standardmäßig dreimal. Table.Buffer()
erzwingt, dass die Tabelle einmal in den Speicher gezogen und dann aus dem Speicher
bedient wird.
let
Raw = Sql.Database("server", "db"){[Name="ExpensiveView"]}[Data],
Buffered = Table.Buffer(Raw)
in
Buffered
06try … otherwise für Fehlerbehandlung
Ein einzelner Fehler-Wert in einer Spalte kann in Power Query den gesamten Refresh
stoppen. Mit try … otherwise fängst du lokal ab und
lieferst einen kontrollierten Default.
Table.AddColumn(Source, "Ratio",
each try [Numerator] / [Denominator] otherwise null,
type number
)
Besonders wichtig bei Custom Columns, die aus Textfeldern parsen — Datumsstrings aus Fremdsystemen, Währungsformate mit Sonderzeichen, Boolean-Mapping aus „Y/N/1/0/yes".
07Parameter für Umgebungen
Jedes ernsthafte Projekt hat mindestens Dev, Staging und Prod. Server-Adressen, Datenbanknamen oder API-Keys hardcoded in Queries sind eine Zeitbombe: beim Deployment wird die falsche Quelle gezogen, der Bericht zeigt alte Daten, und niemand merkt es bis zum nächsten Management-Meeting.
// Parameter "ServerName" und "DatabaseName"
Sql.Database(ServerName, DatabaseName)
Ergänzt sich perfekt mit Dataflows oder Shared Datasets: Parameter einmal zentral, alle Berichte profitieren.
08Staging Queries (Enable Load = off)
Nicht jede Query muss im Modell landen. Zwischen-Queries, die nur zur Transformation dienen und deren Ergebnis nur intern referenziert wird (Lookup-Tabellen für spätere Merges, Parameter-Mappings), sollten auf Enable Load = off gestellt werden.
Vorteile: das Modell bleibt schlank, der Refresh ist schneller, und die Semantik im Dataset ist klarer. Konvention: Staging-Queries in einen eigenen Ordner und/oder mit Prefix kennzeichnen — bei 50+ Queries im Projekt unbezahlbar.
04 · DomäneVisualisierung — 8 Regeln
Ein perfektes Datenmodell mit einer schlechten Darstellung ist ein Bericht, den niemand nutzt. Hier gelten andere Regeln als im Backend: es geht um Wahrnehmung, kognitive Last und Entscheidbarkeit in Sekunden.
01Die 5-Sekunden-Regel
Öffne eine Reportseite. Zähle bis fünf. Wenn du bis dahin den Key Insight nicht erfassen kannst — die eine Zahl, die eine Richtung, den einen kritischen Ausreißer — ist die Seite überfrachtet. Nutzer scannen, sie lesen nicht. Jede Information, die nicht zum Kerninsight beiträgt, konkurriert mit ihm um Aufmerksamkeit.
Praktisch: vor jeder Seite eine klare Hypothese formulieren — „Der Leser muss in 5 Sekunden sehen, ob wir auf Plan sind." — und alles streichen, was nicht zu dieser einen Aussage beiträgt. Details wandern in Tooltips, Drill-Throughs oder Folgeseiten.
02Max 5–7 Visuals pro Seite
Mehr als sieben Visuals auf einer Seite sind kognitive Überforderung, kein Dashboard. Gleichzeitig bremsen viele Visuals das Rendering — jedes Visual ist eine eigene DAX-Query. In komplexen Modellen ist das der Unterschied zwischen 1 Sekunde und 8 Sekunden Seitenwechselzeit.
Wenn du mehr Informationen unterbringen musst: Tabs auf einer Seite, Bookmarks, Drill-Through oder eine zweite Seite im Report. „Alles auf eine Seite quetschen" ist der Charakteristik-Killer Nummer eins.
03Interactions steuern
Standardmäßig cross-filtert jedes Visual jedes andere auf derselben Seite. Das ist oft das Gegenteil von dem, was man will — ein Klick auf das Umsatz-KPI sollte vielleicht nicht das detaillierte Kunden-Ranking reset-filtern.
Im Format-Menü unter Edit Interactions kannst du pro Visual steuern, welche anderen Visuals auf Klicks reagieren: Filter, Highlight oder None. Auf gut designten Seiten ist das kein Detail, sondern ein Kernbestandteil der UX-Definition.
Ein Dashboard ohne explizit kuratierte Interactions ist kein Dashboard — es ist eine Sammlung unabsichtlich verbundener Kacheln.
04Kreisdiagramme — max 5 Segmente, oder gar nicht
Kreisdiagramme sind das wohl am häufigsten missbrauchte Visual überhaupt. Das menschliche Auge kann Winkel schlechter vergleichen als Längen — ein Balkendiagramm ist fast immer die bessere Wahl. Falls ein Pie Chart wirklich sinnvoll ist (Anteil an einem Ganzen, wenige klar unterscheidbare Segmente), dann mit maximal 5 Segmenten.
Alternativen: gestapeltes Balkendiagramm, 100%-gestapeltes Balkendiagramm, Treemap (für hierarchische Anteile) oder schlicht eine Tabelle mit Prozentwerten. In 90 % der Fälle klarer als ein Pie Chart.
05Drill-Through statt überfüllte Seiten
Drill-Through ist eines der unterschätztesten Power-BI-Features. Statt alle Dimensionen auf einer Seite zu zeigen, baust du eine Übersicht und eine oder mehrere Detail-Seiten, zu denen per Rechtsklick auf ein Visual gesprungen wird — gefiltert auf den Kontext des geklickten Elements.
Vorteile: die Übersichtsseite bleibt aufgeräumt, die Detail-Seite lädt nur bei Bedarf und nur für den relevanten Filter-Kontext, die Navigation wird für den Nutzer intuitiv. Fünf Minuten Setup, massiver UX-Gewinn.
06Farbe nur für Bedeutung, nie für Dekoration
Jede Farbe in einem Report sollte eine semantische Funktion haben: Warnung, Kategorie-Unterscheidung, Hervorhebung des Key Insights. „Weil es schöner aussieht" ist keine. Pre-attentive Wahrnehmung lenkt das Auge automatisch auf farbliche Ausreißer — wenn dort keine bedeutende Information sitzt, ist das verschwendete Aufmerksamkeit.
Praktisch: ein gedämpftes Farbschema als Baseline, eine Akzentfarbe für den Key Insight pro Seite, ein Warnsystem (Ampelfarben) für Abweichungen. Corporate-Design-Farben gehören in den Header und in Kategorieachsen — nicht in jede Balkenfläche.
07Tooltips für Kontext, nicht für Kerninfo
Tooltips sind großartig — für zusätzlichen Kontext. Trends, Vorjahresvergleiche, Erklärungen zu Datenquellen. Was sie nicht sein dürfen: der einzige Ort, an dem die Kerninformation sichtbar wird. Mobile-Nutzer, Bildschirm-Reader, Screenshots — alle sehen Tooltips nicht.
Power BI unterstützt zudem Report Page Tooltips — komplette Mini-Seiten als Tooltip. Sehr mächtig für Detail-Kontext, aber das Prinzip bleibt: Kerninfo im Visual, Anreicherung im Tooltip.
08Alt-Text für alle Visuals — Accessibility ist Pflicht
Barrierefreiheit ist in vielen Ländern rechtlich vorgeschrieben (BITV 2.0, EU-Richtlinie 2016/2102, ADA in den USA). Screen Reader benötigen Alt-Text für jedes Visual. In Power BI findest du das Feld unter Format Pane → General → Alt Text.
Pro Visual ein Satz, der beschreibt, was zu sehen ist und welcher Insight gezeigt wird: „Balkendiagramm: Umsatz je Region im aktuellen Quartal. Region DACH führt mit 4,2 Mio. € vor Benelux mit 2,8 Mio. €." Nicht nur barrierefrei, sondern zwingt dich auch, die Kernaussage jedes Visuals explizit zu formulieren — ein hervorragender Review-Check.
FazitWas machst du mit diesen 34 Regeln?
Ein gutes Power-BI-Modell ist kein Zufall. Es ist das Ergebnis von Dutzenden kleiner, disziplinierter Entscheidungen, die jede für sich unscheinbar wirken — und in Summe den Unterschied zwischen „läuft halt" und „Enterprise-tauglich" ausmachen.
Die 34 Regeln in diesem Guide sind keine Theorie. Sie sind das, was in produktiven Projekten wirklich zählt — was den Unterschied macht zwischen einem Bericht, der das Management-Meeting überlebt, und einem, der nach drei Monaten durch den nächsten Prototyp ersetzt wird.
Der beste Weg, diesen Guide einzusetzen: öffne dein aktuelles Power-BI-Projekt. Geh die vier Domänen durch. Markiere für jede Regel, ob du sie umsetzt, teilweise umsetzt oder bewusst dagegen entschieden hast. Die Stellen, an denen du nur schulterzuckend weitergehst, sind deine nächsten drei technischen Schulden — und die ersten drei Punkte auf deinem Refactoring-Backlog.
Die Takeaways in einem Absatz
- DAX:
SUMMARIZECOLUMNS,VAR,DIVIDE,SWITCH— früh filtern, spät aggregieren. - Modeling: Star Schema, eigene Date-Tabelle, Integer-Keys, keine Bidi-Filter, keine M:N.
- Power Query: Query Folding schützen, Spalten früh entfernen, Typen explizit setzen, vor dem Merge filtern.
- Visualisierung: 5-Sekunden-Regel, max 5–7 Visuals, Farbe nur für Bedeutung, Alt-Text ist Pflicht.
- Gemeinsamer Nenner: Handwerk vor Hype. Jede dieser Regeln spart im nächsten Sprint Stunden.
Das Cheat-Sheet als PDF
Pin das „Power BI Golden Rules"-Cheat-Sheet ans Board deines Teams. Kostenloser Download als druckfertiges PDF — DIN A3, markenkonform, ohne Anmeldung.
Dieser Guide ist das ausführliche Companion-Dokument zum „Power BI Golden Rules"-Cheat-Sheet. Du hast Feedback, eine Ergänzung oder einen eigenen Favoriten unter deinen Regeln? Schreib mir auf LinkedIn oder direkt an sw@weilerconsult.de — ich lese jede Nachricht. Weiler Consult GmbH · Business Intelligence & Power BI.
