Table of Contents

DAX脚本

DAX脚本可让你在一个文档中查看和编辑多个对象的 DAX 表达式及其基本属性。例如,当复杂的业务逻辑分散在多个度量值中时,这会很有用。

你可以为 TOM Explorer 中任何包含 DAX 表达式的对象生成 DAX 脚本。

要使用此功能,请在 TOM Explorer 中找到你希望汇总到同一文档中的对象。选中多个对象,然后右键选择 生成 DAX 脚本。系统会创建一个新文档,其中包含所有所选对象的 DAX 表达式和基本属性。你也可以分别选择某个表对象或模型对象,从而为表内的所有对象或整个模型内的所有对象生成 DAX脚本。

Dax 脚本

通过 DAX脚本编辑对象与通过 表达式编辑器 编辑略有不同。使用后者时,当你切换到其他对象时,改动会立即应用。但在 DAX脚本中,改动不会自动应用,只有在你手动使用 脚本 > 应用(F5)选项后才会生效。如果你已连接到某个 Analysis Services 实例,可以使用 脚本 > 应用并同步(SHIFT+F5)选项,同时应用改动并将更新后的模型元数据保存到 Analysis Services。

要撤销或重做 DAX 脚本所做的更改,请单击 TOM Explorer,然后按 Ctrl+Z 或 Ctrl+Y。在脚本编辑器中,这些快捷键用于撤销和重做键入内容。请参阅 文本编辑器中的撤销。

多个 DAX脚本

如果你更喜欢同时打开多个文档窗口,而不是只打开一个窗口,那么可以按需创建任意数量的 DAX脚本。这样一来,你就可以使用常见的 IDE 功能,将文档并排显示、分布在不同显示器上等。注意:当你在 TOM 中更改对象的表达式/属性时,DAX脚本窗口中的代码不会自动更新。换句话说,如果你有两个或多个 DAX 脚本都包含同一对象(s)的定义,那么最后应用 (F5) 的脚本始终会覆盖通过其他 DAX 脚本所做的更改,或在 属性视图 中直接做的更改。

使用 DAX脚本文件

DAX脚本可以保存为文本文件,文件扩展名为 .te3daxs。要将 DAX脚本保存为文件,只需使用 文件 > 保存(Ctrl+S)。要从文本文件打开 DAX脚本,请使用 文件 > 打开 > 文件...(Ctrl+O)。

Note

DAX脚本并不特定于某个模型。但由于 DAX 表达式可能会引用模型中定义的度量值、列和表,因此无法保证任何 DAX脚本都能应用到任何模型。 DAX脚本主要用于在特定 Data model 的上下文中,在单个文档里处理多个 DAX 对象。

DAX脚本编辑器

DAX脚本编辑器具备 Tabular Editor 3 中其他位置所使用的 DAX 编辑器的全部功能。例如自动完成、自动格式化、参数提示等。

此外,为了便于管理大型 DAX脚本,DAX脚本视图顶部会显示两个下拉列表。左侧的下拉列表可让你在脚本中定义的对象之间跳转;右侧的下拉列表可让你在当前对象的各个属性之间跳转。

Dax脚本导航

定义度量值

如果你想在脚本中包含某个被引用但尚未在脚本中定义的度量值定义,可以在度量值引用上右键单击,然后选择“定义度量值”或“定义度量值及其依赖项”选项。

定义度量值及依赖项

快捷键

要将脚本应用到模型,请使用以下快捷键:

  • F5:将整个脚本应用到本地模型元数据中
  • Shift+F5:将整个脚本应用到本地模型元数据中,然后将模型元数据保存回源
  • F8:将当前选中的脚本部分应用到本地模型元数据中
  • Shift+F8:将当前选中的脚本部分应用到本地模型元数据中,然后将模型元数据保存回源

支持的 DAX 对象

Tabular Editor 3 支持使用 DAX脚本编辑以下类型的对象:

  • 度量值(包括 KPI)
  • 计算列
  • 计算表格
  • 计算组(包括计算项)

DAX脚本语法

DAX脚本的语法如下:

<DAX script>:
MEASURE 'Table name'[Measure name] [= [<DAX expression>]]
    [<Measure properties>]

COLUMN 'Table name'[Column name] [= [<DAX expression>]]
    [<Column properties>]

TABLE 'Table name' [= [<DAX expression>]]
    [<Table properties>]

CALCULATIONGROUP 'Table name'[Column name]
    [<Calculation Group properties>]
    CALCULATIONITEM "Item 1" [= [<DAX expression>]]
        [<Calculation Item properties>]
    CALCULATIONITEM "Item 2" [= [<DAX expression>]]
        [<Calculation Item properties>]
    ...

<Measure properties>:
    DetailRows = [<DAX expression>]
    DisplayFolder = ["string"]
    FormatString = ["string" / <DAX expression>]
    Description = ["string"]
    Visible = TRUE/FALSE
    KpiStatusExpression = [<DAX expression>]
    KpiStatusDescription = ["string"]
    KpiStatusGraphic = ["string"]
    KpiTrendExpression = [<DAX expression>]
    KpiTrendDescription = ["string"]
    KpiTrendGraphic = ["string"]
    KpiTargetExpression = [<DAX expression>]
    KpiTargetDescription = ["string"]
    KpiTargetFormatString = ["string"]

<Column properties>:
    DisplayFolder = ["string"]
    FormatString = ["string"]
    Description = ["string"]
    Visible = TRUE / FALSE
    Datatype = BOOLEAN / DOUBLE / INTEGER / DATETIME / CURRENCY / STRING

<Table properties>:
    Description = ["string"]
    Visible = TRUE / FALSE
    DetailRows = [<DAX expression>]

<Calculation Group properties>:
    Description = ["string"]
    Visible = TRUE / FALSE
    Precedence = <integer value>

<Calculation Item properties>
    Description = ["string"]
    Ordinal = <integer value>
    FormatString = [<DAX expression>]
Tip

用过 TMDL 的人肯定注意到,DAX脚本语法和 TMDL 语法有一些相似之处。事实上,TMDL 的灵感正是来自 DAX脚本。不过,为了保持简单,DAX脚本有意只支持那些关联了一个或多个 DAX 表达式的对象。此外,DAX脚本语法的设计是为了兼容 DAX 查询的 DEFINE 部分(只要 DAX脚本不指定任何对象属性)。而 TMDL 用于定义整个模型元数据,并不局限于 DAX 对象。不过,TMDL 代码块无法直接用于 DAX 查询,因为 TMDL 中用于定义对象名称的语法在 DAX 中并不合法。

示例 1:度量值

例如,下面的脚本在 'Internet Sales' 表中定义了 [Internet Total Sales] 度量值。除了度量值的 DAX 表达式之外,该脚本还包含了度量值说明和格式字符串。

----------------------------------
-- Measure: [Internet Total Sales]
----------------------------------
MEASURE 'Internet Sales'[Internet Total Sales] = SUM('Internet Sales'[Sales Amount])
    Description = "Returns the sum of all Internet Sales"
    FormatString = "\$#,0.00;(\$#,0.00);\$#,0.00"

示例 2:带状态和目标 KPI 的度量值

下面的 DAX脚本定义了 [Internet Current Quarter Sales Performance] 度量值,其中包含一个带状态表达式和目标表达式的 KPI。该状态 KPI 使用“Shapes”图形。

--------------------------------------------------------
-- Measure: [Internet Current Quarter Sales Performance]
--------------------------------------------------------
MEASURE 'Internet Sales'[Internet Current Quarter Sales Performance] =
    IFERROR(
        [Internet Current Quarter Sales] / [Internet Previous Quarter Sales Proportion to QTD],
        BLANK()
    )
    , KpiStatusExpression =
        VAR x = [Internet Current Quarter Sales Performance]
        RETURN
            IF(
                ISBLANK( x ),
                BLANK(),
                IF(x < 1, -1, IF(x < 1.07, 0, 1))
            )
    , KpiStatusGraphic = "Shapes"
    , KpiTargetExpression = 1.1

示例 3:计算组

下面的 DAX 脚本定义了 'Time Intelligence' 计算组,其中包含 [Period] 列。该计算组包含 6 个计算项,用于执行各种时间计算。注意 "YoY %" 这一项使用了不同的格式字符串。

-----------------------------------------
-- Calculation Group: 'Time Intelligence'
-----------------------------------------
CALCULATIONGROUP 'Time Intelligence'[Period]
    Description = "Use this table to perform time calculations"

    CALCULATIONITEM "Current" = SELECTEDMEASURE()
        Ordinal = 0

    CALCULATIONITEM "MTD" = TOTALMTD(SELECTEDMEASURE(), 'Calendar'[Date])
        Ordinal = 1

    CALCULATIONITEM "YTD" = TOTALYTD(SELECTEDMEASURE(), 'Calendar'[Date])
        Ordinal = 2

    CALCULATIONITEM "PY" = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date]))
        Ordinal = 3

    CALCULATIONITEM "YoY" = 
        SELECTEDMEASURE()
         - CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date]))
        Ordinal = 4

    CALCULATIONITEM "YoY %" = 
        VAR lastYear = 
            CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Calendar'[Date]))
        RETURN
            DIVIDE(
                SELECTEDMEASURE() - lastYear,
                lastYear
            )
        FormatString = "Percent"
        Ordinal = 5

未指定或为空的表达式与属性

从 Tabular Editor 3.16.0 起,可以在 DAX脚本中指定空表达式和空属性值,或者完全省略对象表达式。

例如,以下脚本会创建一个度量值:DAX 表达式为空、格式字符串为空,并且不设置显示文件夹。如果该度量值已存在,它将被更新为:DAX 表达式为空、格式字符串为空,并且不设置显示文件夹。

MEASURE 'Internet Sales'[Internet Total Sales] =
    , Description = "TODO: Ask business how this should be implemented and formatted."
    , FormatString =
    , DisplayFolder =

注意:空表达式后面的属性之前,必须写 ,(逗号)。当前面的表达式不为空时,逗号是可选的。

如果你想保留度量值现有的 DAX 表达式,可以在对象名称后省略 = 符号:

MEASURE 'Internet Sales'[Internet Total Sales]
    DisplayFolder = "Totals"

上面的示例会将 [Internet Total Sales] 度量值的 DisplayFolder 设置为指定值,但会保留现有的 DAX 表达式。对象上的所有其他属性,例如 Description 和 FormatString,将保持不变。

这些新特性让你更容易编写只更新对象特定属性的脚本,而无需指定完整的对象定义。这样,脚本也更容易在不同模型之间复用。