计算修改后的筛选器上下文中的表达式。
注意
还有 CALCULATETABLE 函数。 它执行的功能完全相同,只不过它修改 筛选器上下文 应用于返回 表对象的表达式。
语法
CALCULATE(<expression>[, <filter1> [, <filter2> [, …]]])
参数
| 术语 | 定义 | 
|---|---|
| expression | 要计算的表达式。 | 
| filter1, filter2,… | (可选)定义筛选器或筛选修饰符函数的布尔表达式或表表达式。 | 
用作第一个参数的表达式实质上与度量值相同。
筛选器可以是:
- 布尔筛选器表达式
- 表筛选器表达式
- 筛选器修改函数
当有多个筛选器时,可以使用 AND(&&)逻辑运算符来计算它们,这意味着所有条件都必须 TRUE,或者由 OR(||)逻辑运算符计算,这意味着任一条件都可以为 true。
布尔筛选器表达式
布尔表达式筛选器是计算结果为 TRUE 或 FALSE的表达式。 有几个规则必须遵守:
- 它们可以引用单个表中的列。
- 它们不能引用度量值。
- 它们不能使用嵌套 CALCULATE 函数。
从 2021 年 9 月版 Power BI Desktop 开始,以下各项也适用:
- 除非将表作为参数传递给聚合函数,否则它们不能使用扫描或返回表的函数。
- 它们 可以 包含返回标量值的聚合函数。 例如Total sales on the last selected date = CALCULATE ( SUM ( Sales[Sales Amount] ), 'Sales'[OrderDateKey] = MAX ( 'Sales'[OrderDateKey] ) )
表筛选器表达式
表表达式筛选器将表对象作为筛选器应用。 它可以是对模型表的引用,但更有可能是返回表对象的函数。 可以使用 FILTER 函数应用复杂筛选条件,包括布尔筛选器表达式无法定义的条件。
筛选器修饰符函数
筛选器修饰符函数允许你执行更多操作,而不仅仅是添加筛选器。 它们提供修改筛选器上下文时的其他控件。
| 功能 | 目的 | 
|---|---|
| REMOVEFILTERS | 从表的一个或多个列或从单个表的所有列中删除所有筛选器或筛选器。 | 
| ALL 1、ALLEXCEPT、ALLNOBLANKROW | 从一个或多个列中删除筛选器,或者从单个表的所有列中删除筛选器。 | 
| KEEPFILTERS | 添加筛选器而不删除相同列上的现有筛选器。 | 
| USERELATIONSHIP | 在相关列之间参与非活动关系,在这种情况下,活动关系将自动变为非活动状态。 | 
| CROSSFILTER | 修改筛选器方向(从两者到单个或从一个到两者)或禁用关系。 | 
1ALL 函数及其变体的行为既充当筛选器修饰符,又充当返回表对象的函数。 如果工具支持 REMOVEFILTERS 函数,最好使用它来删除筛选器。
返回值
表示表达式结果的值。
言论
- 提供筛选器表达式时,CALCULATE 函数将修改筛选器上下文以计算表达式。 对于每个筛选器表达式,当筛选器表达式未包装在 KEEPFILTERS 函数中时,有两个可能的标准结果: - 如果列(或表)不在筛选器上下文中,则将新筛选器添加到筛选器上下文中以计算表达式。
- 如果列(或表)已在筛选器上下文中,则新筛选器将覆盖现有筛选器以计算 CALCULATE 表达式。
 
- 不使用筛选器 - 使用的 - 函数可实现特定要求。 它将转换行上下文以筛选上下文。 在行上下文中需要计算汇总模型数据的表达式(而不是模型度量值)时,这是必需的。 此方案可以在计算列公式中或在计算迭代器函数中的表达式时发生。 请注意,在行上下文中使用模型度量值时,上下文转换是自动的。 
- 在计算列或行级别安全性 (RLS) 规则中使用时,不支持在 DirectQuery 模式下使用此函数。 
例子
以下 Sales 表度量值定义会产生收入结果,但仅适用于颜色为蓝色的产品。
本文中的示例可用于示例 Adventure Works DW 2020 Power BI Desktop 模型。 若要获取模型,请参阅 DAX 示例模型。
Blue Revenue =
CALCULATE(
    SUM(Sales[Sales Amount]),
    'Product'[Color] = "Blue"
)
| 类别 | 销售金额 | 蓝色收入 | 
|---|---|---|
| 辅料 | $1,272,057.89 | $165,406.62 | 
| 自行车 | $94,620,526.21 | $8,374,313.88 | 
| 服装 | $2,117,613.45 | $259,488.37 | 
| 组件 | $11,799,076.66 | $803,642.10 | 
| 总计 | $109,809,274.20 | $9,602,850.97 | 
CALCULATE 函数计算修改后的筛选器上下文中 Sales 表 Sales Amount 列的总和。 新筛选器将添加到 Product 表,颜色 列,或者筛选器覆盖已应用于该列的任何筛选器。
以下 Sales 表度量值定义生成所有销售渠道销售额的比率。
| 渠道 | 销售金额 | 总频道收入 % | 
|---|---|---|
| 互联网 | $29,358,677.22 | 26.74% | 
| 经销商 | $80,450,596.98 | 73.26% | 
| 总计 | $109,809,274.20 | 100.00% | 
Revenue % Total Channel =
DIVIDE(
    SUM(Sales[Sales Amount]),
    CALCULATE(
        SUM(Sales[Sales Amount]),
        REMOVEFILTERS('Sales Order'[Channel])
    )
)
DIVIDE 函数将 Sales 表的总和除以修改后的筛选器上下文中的同一表达式 Sales Amount 列值(在筛选器上下文中)。 它是使用 CALCULATE 函数(筛选器修饰符函数)修改筛选器上下文的 REMOVEFILTERS 函数。 它会从 销售订单 表 频道 列中删除筛选器。
以下 Customer 表计算列定义将客户分类为会员类。 这是一个非常简单的方案:当客户产生的收入小于 2500 美元时,它们被归类为 低;否则,它们 高。
Customer Segment =
IF(
    CALCULATE(SUM(Sales[Sales Amount]), ALLEXCEPT(Customer, Customer[CustomerKey])) < 2500,
    "Low",
    "High"
)
在此示例中,行上下文转换为筛选器上下文。 它被称为 上下文转换。 ALLEXCEPT 函数从除 CustomerKey 列之外的所有 Customer 表列中删除筛选器。
