Forum Discussion
Extra Blank Row in Power BI Table Visual After Adding Measures
I have a multiple tables (Project Milestone, Summary Data, Efforts but there is no relationship with Milestone Tables of both these tables) with 9 rows (M1–M9), each with Milestone, Milestone Name, and Accomplished columns.
I added two measures:
ProgressValue = MAX('Project Milestone'[Accomplished])
RemainingValue = 100 - [ProgressValue]
Once these measures are added to a table visual alongside Milestone and Milestone Name, the visual shows 10 rows instead of 9 - an extra row at the top with no Milestone/Milestone Name value, ProgressValue blank, and RemainingValue showing 100.
I confirmed:
- No blank/null values anywhere in the source data (checked in Power Query and in the Excel source).
- COUNTROWS('Project Milestone') as a card visual returns 9 - confirming only 9 real rows exist in the model.
So the extra row only appears in the table visual, and only after the measures are added - removing the measures makes the table show exactly 9 rows again.
Questions:
- Is this a known Power BI behavior where the table visual generates an extra row for reconciliation/aggregation purposes when measures are present?
- Is there a setting (visual-level or measure-level) to prevent this extra row from rendering, rather than just suppressing its displayed value with an ISBLANK check?
2 Replies
- Shai_Karmani
Super User
This is expected table visual behavior rather than a bug. A table or matrix visual only drops a row when every measure in it returns BLANK in that filter context, so if any single measure is non-blank the row stays visible.
Your RemainingValue is doing exactly that. 100 - [ProgressValue] evaluates to 100 when ProgressValue is BLANK, because DAX treats BLANK as 0 inside arithmetic. ProgressValue stays BLANK as expected, but RemainingValue produces 100, which forces the extra row to render.
There is no visual level toggle to override this, since the rule is "any measure non-blank keeps the row". The cleanest fix is to short circuit RemainingValue so it also returns BLANK when the source is blank:
RemainingValue = VAR _p = [ProgressValue] RETURN IF ( ISBLANK ( _p ), BLANK (), 100 - _p )If you want to avoid an explicit ISBLANK, you can gate the result on the dimension column instead, which acts as a measure level filter:
RemainingValue = IF ( HASONEVALUE ( 'Project Milestone'[Milestone] ), 100 - [ProgressValue] )Either version returns BLANK where there is no Milestone in context, and the visual then correctly drops the row.
If this helped, a thumbs up and marking it as the accepted solution would be appreciated.
Thanks,
Shai Karmani - AnshulGrover77Regular Visitor
I agree with this explanation from the comment before me. The extra row is caused by RemainingValue returning 100 when ProgressValue is blank, so the table keeps the row because at least one measure is non-blank.
I would use the same approach here and make RemainingValue return blank when there is no milestone in context:
RemainingValue = IF ( HASONEVALUE ( 'Project Milestone'[Milestone] ), 100 - [ProgressValue] )
Or, if you want to base it directly on the measure:
RemainingValue = VAR _Progress = [ProgressValue] RETURN IF ( ISBLANK ( _Progress ), BLANK (), 100 - _Progress )
The second option is probably safer if the logic in ProgressValue changes later. Either way, the important part is that RemainingValue must also return BLANK() when there is no milestone. That lets the table visual drop the unwanted row naturally.