如何让视觉对象行访问指定列所有行,修复ALLSELECTED筛选关联问题?
我有一个Power BI视觉对象,用到了Timesheets表和Users表的列,两表通过[_userID]建立Users到Timesheets的一对多单向关系。视觉对象的每行由Timesheets[Adhoc Payment Number]唯一标识,同时包含其他多列,且该视觉对象受两表列的筛选控制。
需求是将Timesheets[Worked (ms)]列(毫秒单位)转换为hh:mm:ss.fff格式的文本,且要根据该列的最大值自动补0,保证所有字符串长度一致:
- 若最长时长为10小时,不足10小时的显示两位小时(如
09:30:00.000) - 若最大值≥100小时,则显示三位小时数
当前示例中,该列最大值为85635743毫秒(约23小时)。
为实现需求,我尝试用度量值获取视觉对象中Timesheets[Worked (ms)]的最大值,计划用ALLSELECTED移除行上下文但保留视觉对象的筛选条件。但应用度量值后出现两个问题:
Timesheets[Adhoc Payment Number]不再唯一Timesheets[Worked (ms)]的最大值变为移除Users筛选后的结果,说明Users表的筛选失效了
当前使用的度量值代码:
Worked = VAR msPerHour = 1000 * 60 * 60 VAR msPerMin = 1000 * 60 VAR msPerSec = 1000 VAR maxMS = MAXX( ALLSELECTED( 'Timesheets'), Timesheets[Worked (ms)] ) -- max value in column VAR maxHours = INT( maxMS / msPerHour ) VAR hourDigits = LEN( FORMAT( maxHours, "0" ) ) VAR thisMS = SUM( 'Timesheets'[Worked (ms)] ) -- current row value VAR isNegative = thisMS < 0 VAR absMS = ABS( thisMS ) VAR hh = INT( absMS / msPerHour ) VAR mm = INT( MOD( absMS, msPerHour ) / msPerMin ) VAR ss = INT( MOD( absMS, msPerMin ) / msPerSec ) VAR fff = MOD( absMS, msPerSec ) RETURN maxMS /* IF( isNegative, "-", "") & FORMAT( hh, REPT( "0", hourDigits ) ) & ":" & FORMAT( mm, "00") & ":" & FORMAT( ss, "00") & "." & FORMAT( fff, "000") */
MAXX(ALLSELECTED('Timesheets'), Timesheets[Worked (ms)])的写法存在问题:ALLSELECTED('Timesheets')仅保留了直接作用于Timesheets表的筛选,忽略了通过Users表与Timesheets表关系传递过来的筛选条件。同时,SUM('Timesheets'[Worked (ms)])在被篡改的筛选上下文下,导致Adhoc Payment Number的唯一性被破坏。
要保留所有筛选上下文(包括Users表通过关系传递的筛选),同时移除当前行的行上下文计算最大值,需要用CALCULATE结合无参数的ALLSELECTED(),确保保留所有外部筛选的同时清除当前行的行上下文。另外,由于Adhoc Payment Number唯一标识每行,直接用MAX获取当前行的Worked (ms)值更准确,避免不必要的聚合。
Worked = VAR msPerHour = 1000 * 60 * 60 VAR msPerMin = 1000 * 60 VAR msPerSec = 1000 -- 保留所有筛选上下文(包括Users的筛选),计算视觉对象范围内的最大值 VAR maxMS = CALCULATE( MAX( 'Timesheets'[Worked (ms)] ), ALLSELECTED() ) VAR maxHours = INT( maxMS / msPerHour ) VAR hourDigits = LEN( FORMAT( maxHours, "0" ) ) -- 因Adhoc Payment Number唯一,直接取当前行的Worked (ms)值 VAR thisMS = MAX( 'Timesheets'[Worked (ms)] ) VAR isNegative = thisMS < 0 VAR absMS = ABS( thisMS ) VAR hh = INT( absMS / msPerHour ) VAR mm = INT( MOD( absMS, msPerHour ) / msPerMin ) VAR ss = INT( MOD( absMS, msPerMin ) / msPerSec ) VAR fff = MOD( absMS, msPerSec ) RETURN IF( isNegative, "-", "") & FORMAT( hh, REPT( "0", hourDigits ) ) & ":" & FORMAT( mm, "00") & ":" & FORMAT( ss, "00") & "." & FORMAT( fff, "000")
- 无参数的
ALLSELECTED()会保留所有外部筛选条件(包括来自Users表的筛选),同时移除当前行的行上下文,确保计算的最大值是视觉对象筛选后的正确值。 - 用
MAX(Timesheets[Worked (ms)])代替SUM,因为Adhoc Payment Number唯一标识每行,每个行上下文对应唯一的Worked (ms)值,直接取最大值更准确,也避免了SUM可能带来的意外聚合。
内容的提问来源于stack exchange,提问作者jonnybolton16

