Ravindra BagaleCourses & study guides मराठी Track your progress

13. DAX: Data Analysis Expressions

13.25 IFERROR, Blank versus Zero, and Circular Dependency

Blank vs zero and DIVIDE in DAX with example — in 30 seconds

What: Blank means "no value". Zero is a real number. DIVIDE returns blank, not an error, when the bottom number is blank or zero.

Why: Kolhapur has only cancelled orders. A plain / sign shows NaN, and IFERROR would hide real problems.

Tiny example: Kolhapur: ₹0 sales, no delivered orders. [Total Sales] / [Delivered Orders] = NaN. DIVIDE gives blank.

First look at the data (before → after):

Blank vs zero and DIVIDE in DAX with example: before and after tables, fictional Blinkit Maharashtra data

Same before / after tables as text

Before — Matrix by city

City Total Orders Total Sales Delivered Orders
Pune 3 ₹600 2
Kolhapur 2 (both cancelled) ₹0 (blank)

Formula / click path

AOV (slash)  = [Total Sales] / [Delivered Orders]
AOV (DIVIDE) = DIVIDE([Total Sales], [Delivered Orders])
AOV (0)      = DIVIDE([Total Sales], [Delivered Orders], 0)

After — What each measure shows

Measure Pune Kolhapur Use when
AOV (slash) ₹300 NaN Never use / for measures
AOV (DIVIDE) ₹300 (blank) Default: the row stays quiet
AOV (0) ₹300 0 Only when 0 means something to the manager

Do it step by step:

  1. Build a matrix. Rows = DarkStore[City]. Values = Total Orders, Total Sales, Delivered Orders.
  2. Create AOV (slash) with the / sign. Kolhapur shows NaN.
  3. Create AOV (DIVIDE). Kolhapur goes blank. Pune stays ₹300.
  4. Create AOV (0) with the third argument only if the manager wants to see 0.
  5. Delete AOV (slash). Do not hide it inside IFERROR.

Do not copy Excel's IFERROR habit here. In DAX, do not hide errors; blank and zero are different.

IFERROR(value, fallback) catches any error and returns the fallback. That includes a real bug in the measure, not only divide-by-zero. The engine may also evaluate the expression in a heavier way. ISERROR returns TRUE or FALSE and has the same habit of hiding the problem. ERROR("message") raises an error on purpose, which you almost never want in a report measure.

Prefer, in this order: DIVIDE for division, IF / SWITCH for business rules, COALESCE for the first non-blank. Section 13.7 already chose DIVIDE over / because / can return infinity or an error when the denominator is zero or blank.

Margin or Blank = DIVIDE([Gross Profit], [Total Sales])
Margin or Zero = DIVIDE([Gross Profit], [Total Sales], 0)
First City = COALESCE(SELECTEDVALUE(DarkStore[City]), "All cities")

Blank versus zero. BLANK() means "no value". A visual often hides a blank and still shows a zero. In DAX comparisons, BLANK() = 0 is TRUE. So IF([Total Sales] = 0, "None", "Some") also flags a city with no rows. Use ISBLANK([Total Sales]) when you mean empty, and = 0 only after you know the measure returns a real zero.

Adding + 0 to force zeros makes a matrix print a row for every city and product combination. Section 13.19 warned about this. Do it only on a small lookup, never on a fact grain.

Circular dependency (एकमेकांवर अवलंबून असणारे स्तंभ) means A needs B and B needs A, so refresh cannot start. It also happens when a calculated column refers to a measure that refers to that column. The error names the column. Fixes: move the logic to a measure (measures can use other measures), or compute the column in Power Query where the steps are ordered, or split one column into a column that does not call back.

Worked example. [Gross Margin %] for a new city with no delivered sales is blank if you use DIVIDE with two arguments. The card looks empty, which is honest. DIVIDE(..., 0) shows 0%, which reads as "we sold and made nothing", a different story. IFERROR([Total Sales] / [Delivered Orders], 0) hides a misspelled column name as well as the zero case, so you ship a wrong zero. Kolhapur with no rows should stay blank. Mumbai with sales ₹0 on a cancelled-only day can be a real zero if that is the rule you agreed.

Ravindra Bagale's Tip

Many students wrap the whole measure in IFERROR and go home. The visual looks calm and the bug is invisible. Use DIVIDE, use ISBLANK, and when you hit a circular dependency, move the calculated column into a measure. Pay attention!

Loading DAX practice tasks...

  1. Price per seat (Easy): Measure: Price per Seat = [MRR] ÷ SUM of Seats.
  2. Tickets per seat by plan (Easy): Shown per Plan. Measure: Tickets per Seat = SUM of Tickets ÷ SUM of Seats.
  3. Churned MRR as zero (Easy): Shown per Country. Measure: Churned MRR = [MRR] for Status "Churned", showing 0 instead of blank.
  4. COALESCE for zero (Medium): Shown per Industry. Measure: Churned MRR = churned [MRR], or 0 if blank. Use COALESCE.
  5. Number from the ID (Medium): Calculated column on Subscriptions: Sub Number = the number in the last 2 characters of SubID, or 0 on error.
  6. Text flag for churn (Medium): Shown per Country. Measure: Churn Flag = "No churn" if churned [MRR] is blank, else "Has churn".
  7. Hide zero-ticket rows (Medium): Shown per SubID. Measure: Busy MRR = blank when SUM of Tickets is 0, else [MRR].
  8. Churn share or zero (Hard): Shown per Country. Measure: Churn Share = churned rows ÷ all rows, 0 when no churn.
  9. Enterprise MRR per company (Hard): Shown per Company. Measure: Ent MRR = [MRR] for Plan "Enterprise", plus 0.
  10. Tickets per active sub (Hard): Shown per Industry. Measure: Active Tickets = Tickets of Active subs ÷ number of Active subs, 0 if none.

Ravi Sir's Cards for this lesson

मराठी cards