Microsoft Power BI 和 DAX - 计算非 YTD 度量的上一年周数的百分比变化

Microsoft Power BI and DAX - compute percentage change across previous year week numbers for non YTD measures

我在 Power BI Matrix 视觉对象中有一个场景,其中有一个简单的度量,称为 SalesAmount。 它是基于 table 的单列的简单总和,称为 FactSales。

我的模型中有一个日期维度(日历)table,名为 Dates2。

我开发了一个矩阵报告如下。此报告使用 Dates2 table 中的周数。 我还开发了另一个名为 SalesAmount_SWLY 的度量来获取 SalesAmount 度量 去年的同一周。我的周数周期是周一到周日(不是默认的周日到周六周期)。

(以上2张图,第一张是实际报告,第二张只是给大家看看,上一年相应周的measure是如何存储的。)

请务必注意,SalesAmount 度量不是累积的(非 YTD),即对于一年中的第 10 周,我们不需要将第 1 周的销售额添加到第 10 周的销售额,但显示只有第 10 周的销售额。 但是年份总数是在给定年份的所有周内汇总的。

然后我制定了一个衡量标准,在平行的几周内产生百分比变化。例如,将 2020 年的第 1 周与 2019 年的第 1 周进行比较,以得出百分比变化。

2020 年第 1 周的百分比变化公式 = {(2020 年第 1 周的值)-(2019 年第 1 周的值)}/(2019 年第 1 周的值)

2020 年百分比变化的公式 = {(2020 年所有周的总和)-(2019 年所有周的总和)}/(2019 年所有周的总和)

这工作正常,但有一个问题。在 2021 年,我们只有 2 周的数据。 (假设到今天为止,我们在 2021 年只完成了 2 周,即使我们在 9 月)

就百分比变化而言,对于 2021 年的总计(右侧矩阵的最后一列),我们需要将 2021 年前 2 周的总计与2020年前两周的相应总数。

在上面的视觉效果中,我不想看到 -95.66%,而是 -18.75%。

逻辑:我们在 2021 年只完成了两周

2021 年合计值 = 13(即 6 + 7)

2020 年的总值 = 16(即 1 + 15,仅在 2020 年的前两周)

(目前取2020年的数值为300,不正确)

百分比变化 = (13-16)/16 = -18.75 %(报告中需要)

百分比变化 = (13-300)/300 = -95.66 %(当前显示在报告中,不正确)

几个月前我发布了一个类似的问题,关于不同年份的月份百分比变化:

有人可以使用 DAX 中的新度量帮助我解决跨周数的百分比变化问题吗?

逻辑:

  1. 我使用从周一到周日的 7 天周期来计算 Dates2 table 中的周数。 Dates2 table.
  2. 中的列名称为 WeekNumber

我使用以下公式计算去年同一周数的度量:

SalesAmount_SWLY = CALCULATE(

                             [SalesAmount], 

                              FILTER(

                                     ALL(Dates2),

                                     Dates2[Year] = SELECTEDVALUE(Dates2[Year]) - 1
                                     &&
                                     Dates2[WeekNumber] = SELECTEDVALUE(Dates2[WeekNumber])

                                   )

                             )
  1. 我计算不同年份各个周之间的百分比变化的方式很好,比如 2020 年的第 5 周和 2019 年的第 5 周。类似地,任何连续两年的相应周数.

  2. 我在计算最近一年(2021 年)和前一年(2020 年)之间的年度(大)百分比变化时遇到了挑战(这是因为,在 2021 年,我们还没有完成所有周)

  3. 我在 2021 年只有 'n' 周。2021 年所有 'n' 周的总计很好; n < 53(大多数情况下,直到全年结束)。

  4. 我转到上一年2020年。找到2020年第n周第7天的日期。让我把这个日期称为X。这个被视为上一年 (2020) 的结束日期。

  5. 2020 年的总计是从 1 月 1 日到 X 日计算的。该值用于计算从 2020 年到 2021 年的年度百分比变化。

对于连续年份的年度(总)百分比变化,我需要对这两年进行总计,只有当这两年都有 53 周的数据时。最近一年(比如 2021 年),我通常不会有所有的星期。在这种情况下,在 2021 年和 2020 年之间(仅),我只比较前 'n' 周的数据。对于所有其他情况,一切正常。

下面的逻辑需要在代码中考虑:

比如2016年,我有全部53周,但是2017年我只有前50周(Week-51 Week-52 Week-53没有数据),因为最后3周没有记录数据2017 年第几周。

当我在 2017 年和 2016 年之间进行百分比比较时,在这种情况下,我需要 2017 年矩阵的总计来使用这两年的所有周,而不是仅仅停留在 50 周2016.

本质上,我需要的主要逻辑是缩短前一年的周数,仅适用于当年,即 2021 年,并且当我们尚未完成当年的所有 53 周时。

Count Previous Year EOWEEK =
VAR EquivDateLastYear =
    DATEADD ( DATEADD ( MAX ( [FactTable[Date] ), -1, YEAR ), 1, DAY )
RETURN
    IF (
        HASONEVALUE ( Dates2[Month] ),
        IF (
            [Count] <> BLANK (),
            CALCULATE ( [Count], SAMEPERIODLASTYEAR ( Dates2[Date] ) )
        ),
        IF (
            HASONEVALUE ( Dates2[Year] ),
            CALCULATE (
                [Count],
                DATESBETWEEN (
                    Dates2[Date],
                    EDATE ( MIN ( Dates2[Date] ), -12 ),
                    EquivDateLastYear - WEEKDAY ( EquivDateLastYear, 2 ) + 5
                )
            )
        )
    )

这应该会为您提供上一年的 YTD 到等效周的星期五。如果您需要在一周中的不同日期结束日期,请操作“+5”部分。

SalesAmount_SWLY = 

                   VAR LastYear = YEAR(

                                        MAXX(
                                             ALL(FactSales),
                                             FactSales[Date]
                                            )

                                      )


                   VAR LastDateOfRecordedSales = MAXX(

                                                       FILTER(

                                                               ALL(FactSales),

                                                               YEAR(FactSales[Date]) = MAX(Dates2[Year])
                                                               &&
                                                               ISBLANK(FactSales[Sales]) = FALSE

                                                              ),

                                                        FactSales[Date]

                                                       )


                   VAR MaxWeekNumber = IF(
                                     
                                           MAX(Dates2[Year]) = LastYear,

                                           WEEKNUM(LastDateOfRecordedSales, 2),

                                           53

                                          )


                   VAR SWLY = CALCULATE(

                                          [SalesAmount], 

                                          FILTER(

                                                  ALL(Dates2),

                                                  Dates2[Year] = SELECTEDVALUE(Dates2[Year]) - 1
                                                  &&
                                                  Dates2[WeekNumber] = SELECTEDVALUE(Dates2[WeekNumber])

                                                )

                                       )


                   VAR SWLYtotal = CALCULATE(

                                               [SalesAmount], 

                                               FILTER(

                                                       ALL(Dates2),

                                                       Dates2[Year] = SELECTEDVALUE(Dates2[Year]) - 1
                                                       &&
                                                       Dates2[WeekNumber] <= MaxWeekNumber

                                                     )

                                            )


                   RETURN

                          IF(

                              (HASONEVALUE(Dates2[Year]) = TRUE && HASONEVALUE(Dates2[WeekNumber]) = TRUE),

                              SWLY,

                              IF(

                                 (HASONEVALUE(Dates2[Year]) = TRUE && HASONEVALUE(Dates2[WeekNumber]) = FALSE),

                                 SWLYtotal,

                                 BLANK()

                                )

                             )