在 Power BI 中显示一个大型的表,并不擅长,因为 Power BI 更倾向于制作高度聚合的可视化图表,但如果就是希望做到可以显示大篇幅的分页表格怎么办呢?本文就是来给出答案的。
先看效果吧:
这是一个拥有上千笔订单的表格,用户只想看其中的一部分,并通过分页实现。这里要实现的动态效果包括三点:
另外,以该案例为例,表格的显示应该依据具体的一个列排序
,当出现重复值的时候,依然可以平滑处理。在本案例中,是按照订单日期排序的,但会出现订单日期一样的订单,它们的排名是不同的,被有效错开了。
当然,最最重要的是:该解决方案必须具有通用性。
很显然,以上全部已经实现。
该控件的实现方法非常巧妙。大致思路如下:
根据这个实现思路就可以逐步来构建这个通用方法了。
可以用以下 DAX 构建分页控件如下:
PageControl =
// 请设置三个参数
VAR vOptionNumber = 10 // 有多少种每页行数的选择
VAR vUnit = 5 // 行数变化的单位基数
VAR vTotalPageNumber = 100 // 页面数
// 以下代码无需修改
RETURN
GENERATEALL(
ADDCOLUMNS(
SELECTCOLUMNS( GENERATESERIES( 1 , vOptionNumber ) , "OptionNumber" , [Value] ) ,
"RowsPerPage" , [OptionNumber] * vUnit ,
"RowsPerPageName" , [OptionNumber] * vUnit & " 行/页"
) ,
VAR vIDList =
SELECTCOLUMNS(
GENERATESERIES( 1 , vTotalPageNumber * [RowsPerPage] , 1 ) , "Row" , [Value]
)
VAR vPageList =
ADDCOLUMNS(
vIDList ,
"PageNumber" , INT( ( [Row] - 1 ) / [RowsPerPage]) + 1 ,
"PageName" , "第 " & INT( ( [Row] - 1 ) / [RowsPerPage] ) + 1 & " 页"
)
RETURN vPageList
)
这是一个模板,用户仅仅只需要改变参数设置,就可以自动完成。
用度量值做筛选在很多场景中,其实是一个重要的技巧,这里正好用到这个技巧,如下:
关键是如何构建这个度量值,用 DAX 实现如下:
PageControl.IsInPage =
VAR vRowMin = MIN( PageControl[Row] )
VAR vRowMax = MAX( PageControl[Row] )
VAR vCurrentValue =
SELECTCOLUMNS( SUMMARIZE( 'Order' , 'Order'[OrderDate] , 'Order'[OrderID] ) ,
"@Value" , FORMAT( [OrderDate] , "yyMMdd" ) & [OrderID]
)
RETURN SWITCH( TRUE() ,
vCurrentValue >
MAXX(
TOPN(
vRowMax ,
SELECTCOLUMNS(
ALL( 'Order'[OrderDate] , 'Order'[OrderID] ) ,
"@Value" , FORMAT( [OrderDate] , "yyMMdd" ) & [OrderID]
) , [@Value] , ASC ) ,
[@Value]
) , "No" ,
vCurrentValue <
MAXX(
TOPN(
vRowMin ,
SELECTCOLUMNS(
ALL( 'Order'[OrderDate] , 'Order'[OrderID] ) ,
"@Value" , FORMAT( [OrderDate] , "yyMMdd" ) & [OrderID]
) , [@Value] , ASC ) ,
[@Value]
) , "No" ,
"Yes"
)
没有错,根据业务逻辑中的按照订单日期进行排序,在排序相同时这里巧妙地借用订单号来进一步比较,就可以确保排序的唯一性了。
对当前的表格显示行号也是非常重要的,用 DAX 实现度量值如下:
PageControl.RowNumber =
VAR vRowNumberStartInPage = MIN( PageControl[Row] )
VAR vCurrentValue =
SELECTCOLUMNS( SUMMARIZE( 'Order' , 'Order'[OrderDate] , 'Order'[OrderID] ) ,
"@Value" , FORMAT( [OrderDate] , "yyMMdd" ) & [OrderID]
)
VAR vTableView =
CALCULATETABLE(
ADDCOLUMNS(
SUMMARIZE( 'Order' , 'Order'[OrderDate] , 'Order'[OrderID] ) ,
"@Value" , FORMAT( [OrderDate] , "yyMMdd" ) & [OrderID]
)
,
ALLSELECTED( )
)
RETURN vRowNumberStartInPage + RANKX( vTableView , [@Value] , vCurrentValue , ASC ) - 1
没有错,这里用到了我们全网首发的 Power BI DAX 视图层计算技巧,并借助页面信息,将计算仅仅控制在一个页面的范围,进一步降低运算量级,提升性能。
通过掌握《BI 真经》, 也就掌握了 DAX 思考问题的真谛,用《BI 真经》打好的坚实基础的确可以超越 Power BI 本身的限制,尽量将可塑性很强的 DAX 发挥到极限。本案例方法非常巧妙,但还有两个点要进一步思考:
这两个问题就留给读者进一步探索了。您大可复制粘贴上述 DAX 表达式来实现强大的通用分页控件。如果您还没有坚实的 DAX 基础,赶快系统化学习起来吧。
在订阅了BI佐罗讲授的《BI真经》之《BI进行时》课程区,除了可以下载本文案例,还可以观看视频讲解。
↙