这是两个非常有用的函数,可以帮助你更好地理解筛选上下文的传递。此外,对它们的学习还可以引入一个 DAX 中十分有趣的概念,即如何从 DAX 内部检测正在被计算的单元格。
认识 ISFILTERED 函数
这两个函数的用途是检测列的所有值在当前筛选上下文中是否可见,理解了直接筛选(Direct-Filter)和交叉筛选(Cross-Filter)的区别,你就理解了这两个函数的作用。
ISFILTERED
ISFILTERED ( <TableNameOrColumnName> )
返回 TRUE 或 FALSE,取决于作为参数的列是否被直接筛选,也就是说,参数列已经被放在行、列、切片器或筛选器上,并且正在对当前计值区域¹进行筛选。
当使用表作为参数时,只要表中的任意一列被直接筛选,ISFILTERED 返回 TRUE。
¹计值区域:图表的值区域,比如透视表、表格和矩阵的单元格等。
ISCROSSFILTERED
ISCROSSFILTERED ( <TableNameOrColumnName> )
返回 TRUE 或 FALSE,取决于列是否具有经过传递的筛选或直接筛选。由此可见,对交叉筛选的判定不区分筛选条件来自自身还是其他列,你可以认为直接筛选是一种特殊的交叉筛选。
函数示例
-- 以下查询返回 FALSE EVALUATE { CALCULATE ( ISFILTERED ( Sales ), 'Product'[Color] = "Red" ) } EVALUATE { CALCULATE ( ISFILTERED ( Sales[Quantity] ), 'Product'[Color] = "Red" ) } EVALUATE { CALCULATE ( ISFILTERED ( Sales[Quantity] ), Sales[Unit Price] > 10 ) } -- 以下查询返回 TRUE EVALUATE { CALCULATE ( ISFILTERED ( Sales ), Sales[Unit Price] > 10 ) } EVALUATE { CALCULATE ( ISFILTERED ( Sales[Unit Price] ), Sales[Unit Price] > 10 ) }
实战案例
在本节中,我们感兴趣的是如何使用函数来理解筛选上下文的传递。因此,我们将创建虚构的表达式,将其作为学习 DAX 的工具,如果你用这个定义创建一个新度量值:
[CategoryFilter] := ISFILTERED ( 'Product Category'[Category])
这个简单的度量值返回应用于产品类别的 ISFILTERED 函数的结果。之后你可以创建第二个度量值,用产品颜色进行相同的测试:
[ColorFilter] := ISFILTERED ( Product[ColorName] )
如果将这两个度量值添加到透视表中,将类别放在切片器,并将颜色放在行上,结果如图所示。
有趣的是,类别未被筛选,因为即使我们添加了切片器,我们也没有对它进行选择。另一方面,颜色总是在行上进行筛选,因为每一行都有特定的颜色,而总计不包括在内,因为总计行对应的是全部筛选上下文,不包含任何产品选择。
如果现在从类别切片器中选择一些值,结果会发生变化。因为现在类别中总是有一个筛选器,如下图。事实上,即使在透视表的汇总行上,切片器引入的筛选上下文也是有效的。
ISFILTERED 对于检测那些直接应用于某列的筛选器非常有用。但在另外一些情况下,一列不显示所有值,不是因为你正在筛选该列,而是因为你在其他列上设置了筛选器。例如,如果你筛选颜色,并计算产品品牌的数量,那么你将只得到该特定颜色产品的品牌数。当一个列因为另一列上的筛选器被筛选时,我们说该列是被交叉筛选的,ISCROSSFILTERED 函数被用来检测这种情况。
如果你在数据模型中加入这两个新的度量值,检查颜色和类别的交叉筛选情况:
[CrossCategory] := ISCROSSFILTERED( 'ProductCategory'[Category] ) [CrossColor] := ISCROSSFILTERED ( Product[Color] )
你会看到这样的结果
你可以看到颜色是被交叉筛选的,但类别不是。对于这个现象,一个有趣的问题是“为什么类别没有被筛选?”当你筛选颜色时,你可能希望只看到特定颜色的产品类别。要回答这个问题,你需要记住类别不是产品表的列。相反,它是产品类别表的一部分,关系的方向无法实现你想要的传递方式。如果你更改数据模型,将产品表和产品类别表之间的关系设置为双向筛选,那么结果将有所不同。
在本节中,你已经看到了一些 ISFILTERED 和 ISCROSSFILTERED 的示例,使用这些示例主要出于教学演示目的,是为了更好地帮助你理解筛选上下文如何通过关系进行传递。随着 DAX 水平的提高,通过编写高级 DAX 代码,你将了解为什么这两个函数如此有用。
没看懂这句话,切片器里的类别不是被选了吗?都是蓝色了。为啥要说没选呢?
请问是不是某列被直接筛选,则也是被交叉筛选???
老师,附件图,isfiltered的字段被直接筛选了的话,返回true,hasonefilter 参数为行业的下一个级别,为什么行业行返回false呢?而业子类级别返回true呢?行业和行业子类都被筛选了,都有一个筛选器呢,应该都是true?
你好老师,为什么crosscolor总是Ture?当对category不作筛选时,只有color的直接筛选器,那么corssfilter应该返回False吧
Isfiltered : “ ……并且正在对当前单元格进行筛选。”
这样描述不妥,容易产生迷惑,究竟是参数的列被筛选,还是当前单元格被筛选。当前单元格,并不是先于交叉筛选发生前构建出来的,是诸列筛选后的交叉结果。呈现出来的,等待去用度量值去度量。因此,描述为对当前单元格进行筛选的理解是:先构建一个空白单元格,然后在这个单元格里发生一系列筛选,这种理解是前后颠倒的。当然,当前单元格也没有被筛选。
可以这么讲:当前单元格包含了某列即isfiltered 参数列或表的直接筛选,或者描述为:当前单元格背后是某列即isfiltered 参数列或表的直接筛选正在发生作用。
老师,categoryfilter度量值,虽然isfitered的是product category 的category 列,透视行标签为产品颜色,根据扩展表原理,产品表扩展表包含产品类别表所有列,所以类别表里的类别列可以被颜色筛选呀,度量结果不是返回真吗?谢谢