@luquimbo/bi-superpowers 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +8 -0
- package/.mcp.json +25 -0
- package/AGENTS.md +244 -0
- package/CHANGELOG.md +265 -0
- package/LICENSE +21 -0
- package/README.md +211 -0
- package/bin/build-plugin.js +30 -0
- package/bin/cli.js +1064 -0
- package/bin/commands/add.js +533 -0
- package/bin/commands/add.test.js +77 -0
- package/bin/commands/build-desktop.js +166 -0
- package/bin/commands/changelog.js +443 -0
- package/bin/commands/diff.js +325 -0
- package/bin/commands/lint.js +419 -0
- package/bin/commands/lint.test.js +103 -0
- package/bin/commands/mcp-setup.js +246 -0
- package/bin/commands/pull.js +287 -0
- package/bin/commands/pull.test.js +36 -0
- package/bin/commands/push.js +231 -0
- package/bin/commands/push.test.js +14 -0
- package/bin/commands/search.js +344 -0
- package/bin/commands/search.test.js +115 -0
- package/bin/commands/setup.js +545 -0
- package/bin/commands/setup.test.js +46 -0
- package/bin/commands/sync-profile.js +405 -0
- package/bin/commands/sync-profile.test.js +14 -0
- package/bin/commands/sync-source.js +418 -0
- package/bin/commands/sync-source.test.js +14 -0
- package/bin/commands/watch.js +206 -0
- package/bin/lib/generators/claude-plugin.js +266 -0
- package/bin/lib/generators/claude-plugin.test.js +110 -0
- package/bin/lib/generators/index.js +116 -0
- package/bin/lib/generators/shared.js +282 -0
- package/bin/lib/licensing/index.js +35 -0
- package/bin/lib/licensing/storage.js +364 -0
- package/bin/lib/licensing/storage.test.js +55 -0
- package/bin/lib/licensing/validator.js +213 -0
- package/bin/lib/licensing/validator.test.js +137 -0
- package/bin/lib/microsoft-mcp.js +176 -0
- package/bin/lib/microsoft-mcp.test.js +106 -0
- package/bin/lib/skills.js +84 -0
- package/bin/mcp/powerbi-modeling-launcher.js +38 -0
- package/bin/postinstall.js +44 -0
- package/bin/utils/errors.js +159 -0
- package/bin/utils/git.js +298 -0
- package/bin/utils/logger.js +142 -0
- package/bin/utils/mcp-detect.js +274 -0
- package/bin/utils/mcp-detect.test.js +105 -0
- package/bin/utils/pbix.js +305 -0
- package/bin/utils/pbix.test.js +37 -0
- package/bin/utils/profiles.js +312 -0
- package/bin/utils/projects.js +168 -0
- package/bin/utils/readline.js +206 -0
- package/bin/utils/readline.test.js +47 -0
- package/bin/utils/tui.js +314 -0
- package/bin/utils/tui.test.js +127 -0
- package/commands/contributions.md +265 -0
- package/commands/data-model-design.md +468 -0
- package/commands/dax-doctor.md +248 -0
- package/commands/fabric-scripts.md +452 -0
- package/commands/migration-assistant.md +290 -0
- package/commands/model-documenter.md +242 -0
- package/commands/pbi-connect.md +239 -0
- package/commands/project-kickoff.md +905 -0
- package/commands/report-layout.md +296 -0
- package/commands/rls-design.md +533 -0
- package/commands/theme-tweaker.md +624 -0
- package/config.example.json +23 -0
- package/config.json +23 -0
- package/desktop-extension/manifest.json +37 -0
- package/desktop-extension/package.json +10 -0
- package/desktop-extension/server.js +95 -0
- package/docs/openrouter-free-models.md +92 -0
- package/library/examples/README.md +151 -0
- package/library/examples/finance-reporting/README.md +351 -0
- package/library/examples/finance-reporting/data-model.md +267 -0
- package/library/examples/finance-reporting/measures.dax +557 -0
- package/library/examples/hr-analytics/README.md +371 -0
- package/library/examples/hr-analytics/data-model.md +315 -0
- package/library/examples/hr-analytics/measures.dax +460 -0
- package/library/examples/marketing-analytics/README.md +37 -0
- package/library/examples/marketing-analytics/data-model.md +62 -0
- package/library/examples/marketing-analytics/measures.dax +110 -0
- package/library/examples/retail-analytics/README.md +439 -0
- package/library/examples/retail-analytics/data-model.md +288 -0
- package/library/examples/retail-analytics/measures.dax +481 -0
- package/library/examples/supply-chain/README.md +37 -0
- package/library/examples/supply-chain/data-model.md +69 -0
- package/library/examples/supply-chain/measures.dax +77 -0
- package/library/examples/udf-library/README.md +228 -0
- package/library/examples/udf-library/functions.dax +571 -0
- package/library/snippets/dax/README.md +292 -0
- package/library/snippets/dax/business-domains.md +576 -0
- package/library/snippets/dax/calculate-patterns.md +276 -0
- package/library/snippets/dax/calculation-groups.md +489 -0
- package/library/snippets/dax/error-handling.md +495 -0
- package/library/snippets/dax/iterators-and-aggregations.md +474 -0
- package/library/snippets/dax/kpis-and-metrics.md +293 -0
- package/library/snippets/dax/rankings-and-topn.md +235 -0
- package/library/snippets/dax/security-patterns.md +413 -0
- package/library/snippets/dax/text-and-formatting.md +316 -0
- package/library/snippets/dax/time-intelligence.md +196 -0
- package/library/snippets/dax/user-defined-functions.md +477 -0
- package/library/snippets/dax/virtual-tables.md +546 -0
- package/library/snippets/excel-formulas/README.md +84 -0
- package/library/snippets/excel-formulas/aggregations.md +330 -0
- package/library/snippets/excel-formulas/dates-and-times.md +361 -0
- package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
- package/library/snippets/excel-formulas/lookups.md +169 -0
- package/library/snippets/excel-formulas/text-functions.md +363 -0
- package/library/snippets/governance/naming-conventions.md +97 -0
- package/library/snippets/governance/review-checklists.md +107 -0
- package/library/snippets/power-query/README.md +389 -0
- package/library/snippets/power-query/api-integration.md +707 -0
- package/library/snippets/power-query/connections.md +434 -0
- package/library/snippets/power-query/data-cleaning.md +298 -0
- package/library/snippets/power-query/error-handling.md +526 -0
- package/library/snippets/power-query/parameters.md +350 -0
- package/library/snippets/power-query/performance.md +506 -0
- package/library/snippets/power-query/transformations.md +330 -0
- package/library/snippets/report-design/accessibility.md +78 -0
- package/library/snippets/report-design/chart-selection.md +54 -0
- package/library/snippets/report-design/layout-patterns.md +87 -0
- package/library/templates/data-models/README.md +93 -0
- package/library/templates/data-models/finance-model.md +627 -0
- package/library/templates/data-models/retail-star-schema.md +473 -0
- package/library/templates/excel/README.md +83 -0
- package/library/templates/excel/budget-tracker.md +432 -0
- package/library/templates/excel/data-entry-form.md +533 -0
- package/library/templates/power-bi/README.md +72 -0
- package/library/templates/power-bi/finance-report.md +449 -0
- package/library/templates/power-bi/kpi-scorecard.md +461 -0
- package/library/templates/power-bi/sales-dashboard.md +281 -0
- package/library/themes/excel/README.md +436 -0
- package/library/themes/power-bi/README.md +271 -0
- package/library/themes/power-bi/accessible.json +307 -0
- package/library/themes/power-bi/bi-superpowers-default.json +858 -0
- package/library/themes/power-bi/corporate-blue.json +291 -0
- package/library/themes/power-bi/dark-mode.json +291 -0
- package/library/themes/power-bi/minimal.json +292 -0
- package/library/themes/power-bi/print-friendly.json +309 -0
- package/package.json +93 -0
- package/skills/contributions/SKILL.md +267 -0
- package/skills/data-model-design/SKILL.md +470 -0
- package/skills/data-modeling/SKILL.md +254 -0
- package/skills/data-quality/SKILL.md +664 -0
- package/skills/dax/SKILL.md +708 -0
- package/skills/dax-doctor/SKILL.md +250 -0
- package/skills/dax-udf/SKILL.md +489 -0
- package/skills/deployment/SKILL.md +320 -0
- package/skills/excel-formulas/SKILL.md +463 -0
- package/skills/fabric-scripts/SKILL.md +454 -0
- package/skills/fast-standard/SKILL.md +509 -0
- package/skills/governance/SKILL.md +205 -0
- package/skills/migration-assistant/SKILL.md +292 -0
- package/skills/model-documenter/SKILL.md +244 -0
- package/skills/pbi-connect/SKILL.md +241 -0
- package/skills/power-query/SKILL.md +406 -0
- package/skills/project-kickoff/SKILL.md +907 -0
- package/skills/query-performance/SKILL.md +480 -0
- package/skills/report-design/SKILL.md +207 -0
- package/skills/report-layout/SKILL.md +298 -0
- package/skills/rls-design/SKILL.md +535 -0
- package/skills/semantic-model/SKILL.md +237 -0
- package/skills/testing-validation/SKILL.md +643 -0
- package/skills/theme-tweaker/SKILL.md +626 -0
- package/src/content/base.md +237 -0
- package/src/content/mcp-requirements.json +69 -0
- package/src/content/routing.md +203 -0
- package/src/content/skills/contributions.md +259 -0
- package/src/content/skills/data-model-design.md +462 -0
- package/src/content/skills/data-modeling.md +246 -0
- package/src/content/skills/data-quality.md +656 -0
- package/src/content/skills/dax-doctor.md +242 -0
- package/src/content/skills/dax-udf.md +481 -0
- package/src/content/skills/dax.md +700 -0
- package/src/content/skills/deployment.md +312 -0
- package/src/content/skills/excel-formulas.md +455 -0
- package/src/content/skills/fabric-scripts.md +446 -0
- package/src/content/skills/fast-standard.md +501 -0
- package/src/content/skills/governance.md +197 -0
- package/src/content/skills/migration-assistant.md +284 -0
- package/src/content/skills/model-documenter.md +236 -0
- package/src/content/skills/pbi-connect.md +233 -0
- package/src/content/skills/power-query.md +398 -0
- package/src/content/skills/project-kickoff.md +899 -0
- package/src/content/skills/query-performance.md +472 -0
- package/src/content/skills/report-design.md +199 -0
- package/src/content/skills/report-layout.md +290 -0
- package/src/content/skills/rls-design.md +527 -0
- package/src/content/skills/semantic-model.md +229 -0
- package/src/content/skills/testing-validation.md +635 -0
- package/src/content/skills/theme-tweaker.md +618 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
# Calculation Groups in DAX
|
|
2
|
+
|
|
3
|
+
Patterns for creating and using calculation groups for time intelligence, currency conversion, and measure formatting.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What Are Calculation Groups?
|
|
8
|
+
|
|
9
|
+
Calculation groups modify how measures are evaluated without changing the measures themselves. They're created in external tools (Tabular Editor, TMDL) and consist of:
|
|
10
|
+
|
|
11
|
+
- **Calculation Group**: Container table
|
|
12
|
+
- **Calculation Items**: Individual modifiers (e.g., YTD, PY, MTD)
|
|
13
|
+
- **SELECTEDMEASURE()**: Reference to the measure being modified
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Time Intelligence Calculation Group
|
|
18
|
+
|
|
19
|
+
### Basic Time Intelligence Items
|
|
20
|
+
|
|
21
|
+
```dax
|
|
22
|
+
// Calculation Group: Time Calculations
|
|
23
|
+
// Column: Time Calculation
|
|
24
|
+
|
|
25
|
+
// Item: Current
|
|
26
|
+
SELECTEDMEASURE()
|
|
27
|
+
|
|
28
|
+
// Item: YTD (Year-to-Date)
|
|
29
|
+
CALCULATE(
|
|
30
|
+
SELECTEDMEASURE(),
|
|
31
|
+
DATESYTD('Date'[Date])
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
// Item: PY (Prior Year)
|
|
35
|
+
CALCULATE(
|
|
36
|
+
SELECTEDMEASURE(),
|
|
37
|
+
SAMEPERIODLASTYEAR('Date'[Date])
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
// Item: YTD PY (Prior Year YTD)
|
|
41
|
+
CALCULATE(
|
|
42
|
+
SELECTEDMEASURE(),
|
|
43
|
+
DATESYTD(SAMEPERIODLASTYEAR('Date'[Date]))
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
// Item: QTD (Quarter-to-Date)
|
|
47
|
+
CALCULATE(
|
|
48
|
+
SELECTEDMEASURE(),
|
|
49
|
+
DATESQTD('Date'[Date])
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
// Item: MTD (Month-to-Date)
|
|
53
|
+
CALCULATE(
|
|
54
|
+
SELECTEDMEASURE(),
|
|
55
|
+
DATESMTD('Date'[Date])
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
// Item: Rolling 12 Months
|
|
59
|
+
CALCULATE(
|
|
60
|
+
SELECTEDMEASURE(),
|
|
61
|
+
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -12, MONTH)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
// Item: Rolling 3 Months
|
|
65
|
+
CALCULATE(
|
|
66
|
+
SELECTEDMEASURE(),
|
|
67
|
+
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -3, MONTH)
|
|
68
|
+
)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### YoY Variance Items
|
|
72
|
+
|
|
73
|
+
```dax
|
|
74
|
+
// Item: YoY Abs (Year-over-Year Absolute)
|
|
75
|
+
VAR _Current = SELECTEDMEASURE()
|
|
76
|
+
VAR _PY = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Date'[Date]))
|
|
77
|
+
RETURN
|
|
78
|
+
_Current - _PY
|
|
79
|
+
|
|
80
|
+
// Item: YoY % (Year-over-Year Percentage)
|
|
81
|
+
VAR _Current = SELECTEDMEASURE()
|
|
82
|
+
VAR _PY = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Date'[Date]))
|
|
83
|
+
RETURN
|
|
84
|
+
DIVIDE(_Current - _PY, ABS(_PY))
|
|
85
|
+
|
|
86
|
+
// Item: YTD YoY % (YTD Year-over-Year Percentage)
|
|
87
|
+
VAR _CurrentYTD = CALCULATE(SELECTEDMEASURE(), DATESYTD('Date'[Date]))
|
|
88
|
+
VAR _PYYTD = CALCULATE(SELECTEDMEASURE(), DATESYTD(SAMEPERIODLASTYEAR('Date'[Date])))
|
|
89
|
+
RETURN
|
|
90
|
+
DIVIDE(_CurrentYTD - _PYYTD, ABS(_PYYTD))
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Fiscal Year Time Intelligence
|
|
94
|
+
|
|
95
|
+
```dax
|
|
96
|
+
// Item: FYTD (Fiscal Year-to-Date)
|
|
97
|
+
// Assumes July 1 fiscal year start
|
|
98
|
+
CALCULATE(
|
|
99
|
+
SELECTEDMEASURE(),
|
|
100
|
+
DATESYTD('Date'[Date], "6-30") // Fiscal year end
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
// Item: FY PY (Fiscal Prior Year)
|
|
104
|
+
CALCULATE(
|
|
105
|
+
SELECTEDMEASURE(),
|
|
106
|
+
DATEADD('Date'[Date], -1, YEAR)
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Currency Conversion Calculation Group
|
|
113
|
+
|
|
114
|
+
### Multi-Currency Items
|
|
115
|
+
|
|
116
|
+
```dax
|
|
117
|
+
// Calculation Group: Currency
|
|
118
|
+
// Column: Currency Display
|
|
119
|
+
|
|
120
|
+
// Item: Local Currency
|
|
121
|
+
SELECTEDMEASURE()
|
|
122
|
+
|
|
123
|
+
// Item: USD
|
|
124
|
+
VAR _Result = SELECTEDMEASURE()
|
|
125
|
+
VAR _AvgRate = AVERAGE(DimCurrency[ToUSD_Rate])
|
|
126
|
+
RETURN
|
|
127
|
+
_Result * _AvgRate
|
|
128
|
+
|
|
129
|
+
// Item: EUR
|
|
130
|
+
VAR _Result = SELECTEDMEASURE()
|
|
131
|
+
VAR _AvgRate = AVERAGE(DimCurrency[ToEUR_Rate])
|
|
132
|
+
RETURN
|
|
133
|
+
_Result * _AvgRate
|
|
134
|
+
|
|
135
|
+
// Item: GBP
|
|
136
|
+
VAR _Result = SELECTEDMEASURE()
|
|
137
|
+
VAR _AvgRate = AVERAGE(DimCurrency[ToGBP_Rate])
|
|
138
|
+
RETURN
|
|
139
|
+
_Result * _AvgRate
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### With Historical Rates
|
|
143
|
+
|
|
144
|
+
```dax
|
|
145
|
+
// Item: USD (Historical Rate)
|
|
146
|
+
SUMX(
|
|
147
|
+
VALUES('Date'[Date]),
|
|
148
|
+
VAR _DailyAmount = CALCULATE(SELECTEDMEASURE())
|
|
149
|
+
VAR _DailyRate =
|
|
150
|
+
CALCULATE(
|
|
151
|
+
VALUES(DimExchangeRate[ToUSD]),
|
|
152
|
+
DimExchangeRate[Date] = EARLIER('Date'[Date])
|
|
153
|
+
)
|
|
154
|
+
RETURN
|
|
155
|
+
_DailyAmount * _DailyRate
|
|
156
|
+
)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Budget vs Actual Calculation Group
|
|
162
|
+
|
|
163
|
+
### Scenario Comparison Items
|
|
164
|
+
|
|
165
|
+
```dax
|
|
166
|
+
// Calculation Group: Scenario Analysis
|
|
167
|
+
// Column: Scenario
|
|
168
|
+
|
|
169
|
+
// Item: Actual
|
|
170
|
+
CALCULATE(
|
|
171
|
+
SELECTEDMEASURE(),
|
|
172
|
+
DimScenario[ScenarioName] = "Actual"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
// Item: Budget
|
|
176
|
+
CALCULATE(
|
|
177
|
+
SELECTEDMEASURE(),
|
|
178
|
+
DimScenario[ScenarioName] = "Budget"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
// Item: Forecast
|
|
182
|
+
CALCULATE(
|
|
183
|
+
SELECTEDMEASURE(),
|
|
184
|
+
DimScenario[ScenarioName] = "Forecast"
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
// Item: Variance (Actual - Budget)
|
|
188
|
+
VAR _Actual = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Actual")
|
|
189
|
+
VAR _Budget = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Budget")
|
|
190
|
+
RETURN
|
|
191
|
+
_Actual - _Budget
|
|
192
|
+
|
|
193
|
+
// Item: Variance %
|
|
194
|
+
VAR _Actual = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Actual")
|
|
195
|
+
VAR _Budget = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Budget")
|
|
196
|
+
RETURN
|
|
197
|
+
DIVIDE(_Actual - _Budget, ABS(_Budget))
|
|
198
|
+
|
|
199
|
+
// Item: Attainment %
|
|
200
|
+
VAR _Actual = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Actual")
|
|
201
|
+
VAR _Budget = CALCULATE(SELECTEDMEASURE(), DimScenario[ScenarioName] = "Budget")
|
|
202
|
+
RETURN
|
|
203
|
+
DIVIDE(_Actual, _Budget)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Format String Calculation Group
|
|
209
|
+
|
|
210
|
+
### Dynamic Formatting Items
|
|
211
|
+
|
|
212
|
+
```dax
|
|
213
|
+
// Calculation Group: Display Format
|
|
214
|
+
// Column: Format
|
|
215
|
+
|
|
216
|
+
// Item: Number
|
|
217
|
+
SELECTEDMEASURE()
|
|
218
|
+
// Format String: #,##0
|
|
219
|
+
|
|
220
|
+
// Item: Currency
|
|
221
|
+
SELECTEDMEASURE()
|
|
222
|
+
// Format String: $#,##0
|
|
223
|
+
|
|
224
|
+
// Item: Percent
|
|
225
|
+
SELECTEDMEASURE()
|
|
226
|
+
// Format String: 0.0%
|
|
227
|
+
|
|
228
|
+
// Item: Thousands (K)
|
|
229
|
+
DIVIDE(SELECTEDMEASURE(), 1000)
|
|
230
|
+
// Format String: #,##0 K
|
|
231
|
+
|
|
232
|
+
// Item: Millions (M)
|
|
233
|
+
DIVIDE(SELECTEDMEASURE(), 1000000)
|
|
234
|
+
// Format String: #,##0.0 M
|
|
235
|
+
|
|
236
|
+
// Item: Billions (B)
|
|
237
|
+
DIVIDE(SELECTEDMEASURE(), 1000000000)
|
|
238
|
+
// Format String: #,##0.00 B
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Conditional Formatting
|
|
242
|
+
|
|
243
|
+
```dax
|
|
244
|
+
// Item: Auto Scale
|
|
245
|
+
VAR _Value = SELECTEDMEASURE()
|
|
246
|
+
RETURN
|
|
247
|
+
SWITCH(
|
|
248
|
+
TRUE(),
|
|
249
|
+
ABS(_Value) >= 1000000000, DIVIDE(_Value, 1000000000),
|
|
250
|
+
ABS(_Value) >= 1000000, DIVIDE(_Value, 1000000),
|
|
251
|
+
ABS(_Value) >= 1000, DIVIDE(_Value, 1000),
|
|
252
|
+
_Value
|
|
253
|
+
)
|
|
254
|
+
// Dynamic format string (requires Tabular Editor 3):
|
|
255
|
+
// "Auto" -- or implement via FORMAT in the item
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Advanced Patterns
|
|
261
|
+
|
|
262
|
+
### Moving Averages
|
|
263
|
+
|
|
264
|
+
```dax
|
|
265
|
+
// Calculation Group: Moving Averages
|
|
266
|
+
// Column: Moving Average
|
|
267
|
+
|
|
268
|
+
// Item: Current
|
|
269
|
+
SELECTEDMEASURE()
|
|
270
|
+
|
|
271
|
+
// Item: 3-Month Moving Average
|
|
272
|
+
AVERAGEX(
|
|
273
|
+
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -3, MONTH),
|
|
274
|
+
CALCULATE(SELECTEDMEASURE())
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
// Item: 6-Month Moving Average
|
|
278
|
+
AVERAGEX(
|
|
279
|
+
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -6, MONTH),
|
|
280
|
+
CALCULATE(SELECTEDMEASURE())
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
// Item: 12-Month Moving Average
|
|
284
|
+
AVERAGEX(
|
|
285
|
+
DATESINPERIOD('Date'[Date], MAX('Date'[Date]), -12, MONTH),
|
|
286
|
+
CALCULATE(SELECTEDMEASURE())
|
|
287
|
+
)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### Period-over-Period
|
|
291
|
+
|
|
292
|
+
```dax
|
|
293
|
+
// Item: MoM (Month-over-Month)
|
|
294
|
+
VAR _Current = SELECTEDMEASURE()
|
|
295
|
+
VAR _PM = CALCULATE(SELECTEDMEASURE(), DATEADD('Date'[Date], -1, MONTH))
|
|
296
|
+
RETURN
|
|
297
|
+
_Current - _PM
|
|
298
|
+
|
|
299
|
+
// Item: MoM %
|
|
300
|
+
VAR _Current = SELECTEDMEASURE()
|
|
301
|
+
VAR _PM = CALCULATE(SELECTEDMEASURE(), DATEADD('Date'[Date], -1, MONTH))
|
|
302
|
+
RETURN
|
|
303
|
+
DIVIDE(_Current - _PM, ABS(_PM))
|
|
304
|
+
|
|
305
|
+
// Item: QoQ (Quarter-over-Quarter)
|
|
306
|
+
VAR _Current = SELECTEDMEASURE()
|
|
307
|
+
VAR _PQ = CALCULATE(SELECTEDMEASURE(), DATEADD('Date'[Date], -1, QUARTER))
|
|
308
|
+
RETURN
|
|
309
|
+
_Current - _PQ
|
|
310
|
+
|
|
311
|
+
// Item: QoQ %
|
|
312
|
+
VAR _Current = SELECTEDMEASURE()
|
|
313
|
+
VAR _PQ = CALCULATE(SELECTEDMEASURE(), DATEADD('Date'[Date], -1, QUARTER))
|
|
314
|
+
RETURN
|
|
315
|
+
DIVIDE(_Current - _PQ, ABS(_PQ))
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Growth Rates
|
|
319
|
+
|
|
320
|
+
```dax
|
|
321
|
+
// Item: CAGR (Compound Annual Growth Rate)
|
|
322
|
+
VAR _StartValue =
|
|
323
|
+
CALCULATE(
|
|
324
|
+
SELECTEDMEASURE(),
|
|
325
|
+
FIRSTDATE('Date'[Date])
|
|
326
|
+
)
|
|
327
|
+
VAR _EndValue =
|
|
328
|
+
CALCULATE(
|
|
329
|
+
SELECTEDMEASURE(),
|
|
330
|
+
LASTDATE('Date'[Date])
|
|
331
|
+
)
|
|
332
|
+
VAR _Years =
|
|
333
|
+
DATEDIFF(
|
|
334
|
+
MIN('Date'[Date]),
|
|
335
|
+
MAX('Date'[Date]),
|
|
336
|
+
YEAR
|
|
337
|
+
)
|
|
338
|
+
RETURN
|
|
339
|
+
IF(
|
|
340
|
+
_Years > 0 && _StartValue > 0,
|
|
341
|
+
POWER(DIVIDE(_EndValue, _StartValue), DIVIDE(1, _Years)) - 1,
|
|
342
|
+
BLANK()
|
|
343
|
+
)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## Multiple Calculation Groups
|
|
349
|
+
|
|
350
|
+
### Combining Time + Currency
|
|
351
|
+
|
|
352
|
+
When you have multiple calculation groups, they compose:
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
Revenue with "YTD" + "USD" =
|
|
356
|
+
Revenue calculated YTD, then converted to USD
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Order matters in Tabular Editor:**
|
|
360
|
+
- Set precedence for each calculation group
|
|
361
|
+
- Higher precedence applies outer (last)
|
|
362
|
+
|
|
363
|
+
```dax
|
|
364
|
+
// If Time has precedence 10, Currency has precedence 20:
|
|
365
|
+
// Currency(Time(SELECTEDMEASURE()))
|
|
366
|
+
|
|
367
|
+
// The currency conversion wraps the time calculation
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Precedence Example
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
Calculation Group: Time Intelligence (Precedence: 10)
|
|
374
|
+
Calculation Group: Currency (Precedence: 20)
|
|
375
|
+
Calculation Group: Format (Precedence: 30)
|
|
376
|
+
|
|
377
|
+
Result: Format(Currency(Time(Measure)))
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## Using in Reports
|
|
383
|
+
|
|
384
|
+
### Slicer on Calculation Group
|
|
385
|
+
|
|
386
|
+
1. Add calculation group column to slicer
|
|
387
|
+
2. User selects "YTD" or "PY"
|
|
388
|
+
3. All measures automatically adjust
|
|
389
|
+
|
|
390
|
+
### Matrix with Calculation Items
|
|
391
|
+
|
|
392
|
+
| Product | Current | YTD | PY | YoY % |
|
|
393
|
+
|---------|---------|-----|----|----- |
|
|
394
|
+
| Widget A | 100K | 800K | 90K | 11% |
|
|
395
|
+
| Widget B | 75K | 600K | 80K | -6% |
|
|
396
|
+
|
|
397
|
+
### Combining with Regular Measures
|
|
398
|
+
|
|
399
|
+
```dax
|
|
400
|
+
// Measure that uses calculation group result
|
|
401
|
+
Revenue with Time Calc =
|
|
402
|
+
VAR _TimeCalc = SELECTEDVALUE('Time Calculations'[Time Calculation], "Current")
|
|
403
|
+
RETURN
|
|
404
|
+
SWITCH(
|
|
405
|
+
_TimeCalc,
|
|
406
|
+
"Current", [Revenue],
|
|
407
|
+
"YTD", [Revenue YTD], // Explicit measure
|
|
408
|
+
[Revenue] // Fallback
|
|
409
|
+
)
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Best Practices
|
|
415
|
+
|
|
416
|
+
### 1. Name Items Clearly
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
✓ "YTD (Year-to-Date)"
|
|
420
|
+
✓ "PY (Prior Year)"
|
|
421
|
+
✓ "YoY % (Year-over-Year %)"
|
|
422
|
+
|
|
423
|
+
✗ "Calc1"
|
|
424
|
+
✗ "Time1"
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### 2. Include "Current" Item
|
|
428
|
+
|
|
429
|
+
```dax
|
|
430
|
+
// Always have a baseline item
|
|
431
|
+
// Item: Current
|
|
432
|
+
SELECTEDMEASURE()
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### 3. Handle Blanks
|
|
436
|
+
|
|
437
|
+
```dax
|
|
438
|
+
// Item: YoY % (with blank handling)
|
|
439
|
+
VAR _Current = SELECTEDMEASURE()
|
|
440
|
+
VAR _PY = CALCULATE(SELECTEDMEASURE(), SAMEPERIODLASTYEAR('Date'[Date]))
|
|
441
|
+
RETURN
|
|
442
|
+
IF(
|
|
443
|
+
ISBLANK(_PY) || _PY = 0,
|
|
444
|
+
BLANK(),
|
|
445
|
+
DIVIDE(_Current - _PY, ABS(_PY))
|
|
446
|
+
)
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### 4. Set Format Strings
|
|
450
|
+
|
|
451
|
+
Each calculation item can have its own format string:
|
|
452
|
+
|
|
453
|
+
| Item | Format String |
|
|
454
|
+
|------|---------------|
|
|
455
|
+
| Current | #,##0 |
|
|
456
|
+
| YoY % | 0.0% |
|
|
457
|
+
| YoY Abs | +#,##0;-#,##0;0 |
|
|
458
|
+
|
|
459
|
+
### 5. Test with Multiple Measures
|
|
460
|
+
|
|
461
|
+
Calculation groups apply to ALL measures. Test with:
|
|
462
|
+
- Sum measures (Revenue, Quantity)
|
|
463
|
+
- Average measures (Avg Price)
|
|
464
|
+
- Count measures (Customer Count)
|
|
465
|
+
- Ratio measures (Margin %)
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## Limitations
|
|
470
|
+
|
|
471
|
+
| Limitation | Workaround |
|
|
472
|
+
|------------|------------|
|
|
473
|
+
| Cannot use with semi-additive measures (Avg, Distinct Count) without care | Create explicit measures for these |
|
|
474
|
+
| Format strings limited in Power BI Desktop | Use Tabular Editor 3 |
|
|
475
|
+
| No nested calculation groups | Set precedence carefully |
|
|
476
|
+
| Can't reference another calc item | Use explicit measures |
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## Setup Checklist
|
|
481
|
+
|
|
482
|
+
- [ ] Identify repetitive time intelligence patterns
|
|
483
|
+
- [ ] Create calculation group in Tabular Editor
|
|
484
|
+
- [ ] Add calculation items with clear names
|
|
485
|
+
- [ ] Set format strings for each item
|
|
486
|
+
- [ ] Set precedence if multiple groups
|
|
487
|
+
- [ ] Test with various measure types
|
|
488
|
+
- [ ] Add slicer to report
|
|
489
|
+
- [ ] Document for users
|