【问题标题】:Looping a working DAX function for a calculated column为计算列循环工作 DAX 函数
【发布时间】:2019-09-04 15:39:21
【问题描述】:

我有一个函数将查看“项目提交上限”列中的空字段,并查找具有相同 ID 和下一个较早日期的值,并为“项目提交上限 NoNulls”列提供该值。 DAX 不会递归地执行此操作,因此如果连续有 2 个空值,我会得到一个空白。在另一种语言中,一个简单的 while 循环 (while value is null do: XYZ) 可以解决这个问题,但 DAX 不支持 For/While 循环?

如何让 DAX 函数正常工作以应用填充的值并继续运行直到不再有空值?

(可选)我如何强制它运行 X 次(可能是 10 次)?这不是一个很好的解决方案,但可以完成工作

下面的示例表被过滤为仅显示一个 2 个 ID,不同 ID 的记录在此处显示的记录之间,因此我无法执行类似 excel 的功能“从下面的行中取值”

这是将填充先前值的DAX函数(如上图所示):

ProjectCommitCap_NoNulls =
IF (
    ISBLANK ( 'Project Story Data'[Projected Commitments Cap] ),
    LOOKUPVALUE (
        'Project Story Data'[Projected Commitments Cap],
        'Project Story Data'[ID], 'Project Story Data'[ID],
        'Project Story Data'[Date of Data], CALCULATE (
            MAX ( 'Project Story Data'[Date of Data] ),
            FILTER (
                'Project Story Data',
                'Project Story Data'[ID] = EARLIER ( 'Project Story Data'[ID] )
                    && 'Project Story Data'[Date of Data]
                        < EARLIER ( 'Project Story Data'[Date of Data] )
            )
        )
    ),
    'Project Story Data'[Projected Commitments Cap]
)

我需要看起来像这样(NoNulls 中的所有值都要填写):

【问题讨论】:

  • 如果您可以利用 Power Query/M 而不是 DAX,它有一个“填充”转换,可以完全满足您的需求。这样做会简单得多。
  • 嘿,greggyb,不幸的是,想要的值几乎永远不会直接高于或低于需要填写的行
  • 不是先按[ID]和[Date of Data]排序吗? M 中的表可以有明确的排序,这与表格引擎中的不同。

标签: loops powerbi dax


【解决方案1】:
'Project Story Data'[ProjectCommitCap_NoNulls] =
IF (
    ISBLANK ( 'Project Story Data'[Projected Commitments Cap] ),
    VAR CurrentRowDate = 'Project Story Data'[Date of Data] // Table expression to find the most recent prior row for same [ID] that
    // has non-null [Project Commitment Cap]
    VAR PriorNonNullRow =
        CALCULATETABLE (
            // TOPN returns one row, here sorted by the [Date of Data]
            TOPN (
                1,
                'Project Story Data',
                'Project Story Data'[Date of Data], DESC
            ),
            // ALLEXCEPT clears all context, except for [ID], so the TOPN will
            // evaluate 'Project Story Data' for all rows with the same [ID]
            ALLEXCEPT (
                'Project Story Data',
                'Project Story Data'[ID]
            ),
            // Restrict it to only the [Date of Data] values less than current row
            'Project Story Data'[Date of Data] < CurrentRowDate,
            // And restrict it to just rows with non-null values
            NOT ( ISBLANK ( 'Project Story Data'[Projected Commitments Cap] ) )
        )
    RETURN
        // Using the table above as our filter context, find the MAX (or MIN, or VALUES -
        // it doesn't matter - just need to coerce the field to a scalar) of 
        // [Projected Commitments Cap]
        CALCULATE (
            MAX ( 'Project Story Data'[Projected Commitments Cap] ),
            PriorNonNullRow
        ),
    // This is arg3 of IF
    'Project Story Data'[Projected Commitments Cap]
)

使用这种方法应该对存储引擎更友好,因此比LOOKUPVALUE 更具有缓存能力。

【讨论】:

  • 谢谢greggyb!完美运行。由于它的强度较低,我将使用这种方法!
【解决方案2】:

DAX 根本不执行循环,但我认为您可以修改公式以查找最后一个非空白日期,而不仅仅是前一个日期。

ProjectCommitCap_NoNulls =
IF (
    ISBLANK ( 'Project Story Data'[Projected Commitments Cap] ),
    LOOKUPVALUE (
        'Project Story Data'[Projected Commitments Cap],
        'Project Story Data'[ID], 'Project Story Data'[ID],
        'Project Story Data'[Date of Data], CALCULATE (
            MAX ( 'Project Story Data'[Date of Data] ),
            FILTER (
                'Project Story Data',
                'Project Story Data'[ID] = EARLIER ( 'Project Story Data'[ID] )
                    && NOT ( ISBLANK ( 'Project Story Data'[Projected Commitments Cap] ) )
                    && 'Project Story Data'[Date of Data]
                        < EARLIER ( 'Project Story Data'[Date of Data] )
            )
        )
    ),
    'Project Story Data'[Projected Commitments Cap]
)


正如@greggyb 指出的那样,在查询编辑器中使用“Fill Down”转换是一种更简单的解决方案。

继续使用 DAX,您可能会发现此问答也很有用: Return top value ordered by another column

【讨论】:

  • 谢谢亚历克西斯!我不知道为什么我没有考虑添加另一个 && 而不是 ISBlank
猜你喜欢
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多