@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,330 @@
|
|
|
1
|
+
# Aggregation Functions
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Excel patterns for conditional aggregation using SUMIFS, COUNTIFS, AVERAGEIFS, and related functions.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## SUMIFS - Conditional Sum
|
|
9
|
+
|
|
10
|
+
### Basic Single Condition
|
|
11
|
+
```excel
|
|
12
|
+
=SUMIFS(sum_range, criteria_range, criteria)
|
|
13
|
+
|
|
14
|
+
// Sum sales for North region
|
|
15
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Region], "North")
|
|
16
|
+
|
|
17
|
+
// Sum where value > 1000
|
|
18
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Amount], ">1000")
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Multiple Conditions (AND logic)
|
|
22
|
+
```excel
|
|
23
|
+
// Sum sales for North region in 2024
|
|
24
|
+
=SUMIFS(
|
|
25
|
+
tbl_Sales[Amount],
|
|
26
|
+
tbl_Sales[Region], "North",
|
|
27
|
+
tbl_Sales[Year], 2024
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
// Sum sales for North region, Product A, Q1
|
|
31
|
+
=SUMIFS(
|
|
32
|
+
tbl_Sales[Amount],
|
|
33
|
+
tbl_Sales[Region], "North",
|
|
34
|
+
tbl_Sales[Product], "Product A",
|
|
35
|
+
tbl_Sales[Quarter], 1
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### With Operators
|
|
40
|
+
```excel
|
|
41
|
+
// Sum sales greater than 1000
|
|
42
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Amount], ">1000")
|
|
43
|
+
|
|
44
|
+
// Sum sales between dates
|
|
45
|
+
=SUMIFS(
|
|
46
|
+
tbl_Sales[Amount],
|
|
47
|
+
tbl_Sales[Date], ">="&DATE(2024,1,1),
|
|
48
|
+
tbl_Sales[Date], "<="&DATE(2024,12,31)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
// Sum sales not equal to zero
|
|
52
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Amount], "<>0")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### With Cell References
|
|
56
|
+
```excel
|
|
57
|
+
// Dynamic criteria from cells
|
|
58
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Region], A1)
|
|
59
|
+
|
|
60
|
+
// With operator from cell
|
|
61
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Amount], ">"&B1)
|
|
62
|
+
|
|
63
|
+
// Between two cell values
|
|
64
|
+
=SUMIFS(
|
|
65
|
+
tbl_Sales[Amount],
|
|
66
|
+
tbl_Sales[Date], ">="&StartDate,
|
|
67
|
+
tbl_Sales[Date], "<="&EndDate
|
|
68
|
+
)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Wildcards
|
|
72
|
+
```excel
|
|
73
|
+
// Contains "phone"
|
|
74
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Product], "*phone*")
|
|
75
|
+
|
|
76
|
+
// Starts with "A"
|
|
77
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Product], "A*")
|
|
78
|
+
|
|
79
|
+
// Single character wildcard
|
|
80
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Code], "A?B")
|
|
81
|
+
|
|
82
|
+
// Literal asterisk (escape with ~)
|
|
83
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Code], "~*Special")
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## COUNTIFS - Conditional Count
|
|
89
|
+
|
|
90
|
+
### Basic Patterns
|
|
91
|
+
```excel
|
|
92
|
+
// Count rows for North region
|
|
93
|
+
=COUNTIFS(tbl_Sales[Region], "North")
|
|
94
|
+
|
|
95
|
+
// Count with multiple conditions
|
|
96
|
+
=COUNTIFS(
|
|
97
|
+
tbl_Sales[Region], "North",
|
|
98
|
+
tbl_Sales[Status], "Complete"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
// Count non-blank cells
|
|
102
|
+
=COUNTIFS(tbl_Sales[Amount], "<>")
|
|
103
|
+
|
|
104
|
+
// Count blank cells
|
|
105
|
+
=COUNTIFS(tbl_Sales[Amount], "")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Count Unique with SUMPRODUCT
|
|
109
|
+
```excel
|
|
110
|
+
// Count unique values (pre-365)
|
|
111
|
+
=SUMPRODUCT(1/COUNTIFS(tbl_Sales[CustomerID], tbl_Sales[CustomerID]))
|
|
112
|
+
|
|
113
|
+
// Count unique with condition
|
|
114
|
+
=SUMPRODUCT(
|
|
115
|
+
(tbl_Sales[Region]="North")/
|
|
116
|
+
COUNTIFS(tbl_Sales[CustomerID], tbl_Sales[CustomerID], tbl_Sales[Region], "North")
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Count Unique with UNIQUE (365)
|
|
121
|
+
```excel
|
|
122
|
+
=ROWS(UNIQUE(tbl_Sales[CustomerID]))
|
|
123
|
+
|
|
124
|
+
// With condition
|
|
125
|
+
=ROWS(UNIQUE(FILTER(tbl_Sales[CustomerID], tbl_Sales[Region]="North")))
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## AVERAGEIFS - Conditional Average
|
|
131
|
+
|
|
132
|
+
### Basic Patterns
|
|
133
|
+
```excel
|
|
134
|
+
// Average for North region
|
|
135
|
+
=AVERAGEIFS(tbl_Sales[Amount], tbl_Sales[Region], "North")
|
|
136
|
+
|
|
137
|
+
// Average with multiple conditions
|
|
138
|
+
=AVERAGEIFS(
|
|
139
|
+
tbl_Sales[Amount],
|
|
140
|
+
tbl_Sales[Region], "North",
|
|
141
|
+
tbl_Sales[Year], 2024
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
// Average excluding zeros
|
|
145
|
+
=AVERAGEIFS(tbl_Sales[Amount], tbl_Sales[Amount], "<>0")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Weighted Average
|
|
149
|
+
```excel
|
|
150
|
+
// Weighted average (price weighted by quantity)
|
|
151
|
+
=SUMPRODUCT(tbl_Sales[Price], tbl_Sales[Quantity]) / SUM(tbl_Sales[Quantity])
|
|
152
|
+
|
|
153
|
+
// Weighted average with condition
|
|
154
|
+
=SUMPRODUCT(
|
|
155
|
+
(tbl_Sales[Region]="North") * tbl_Sales[Price] * tbl_Sales[Quantity]
|
|
156
|
+
) / SUMIFS(tbl_Sales[Quantity], tbl_Sales[Region], "North")
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## MAXIFS / MINIFS - Conditional Max/Min
|
|
162
|
+
|
|
163
|
+
### Basic Patterns
|
|
164
|
+
```excel
|
|
165
|
+
// Max sale for North region
|
|
166
|
+
=MAXIFS(tbl_Sales[Amount], tbl_Sales[Region], "North")
|
|
167
|
+
|
|
168
|
+
// Min price for active products
|
|
169
|
+
=MINIFS(tbl_Products[Price], tbl_Products[Status], "Active")
|
|
170
|
+
|
|
171
|
+
// Max with multiple conditions
|
|
172
|
+
=MAXIFS(
|
|
173
|
+
tbl_Sales[Amount],
|
|
174
|
+
tbl_Sales[Region], "North",
|
|
175
|
+
tbl_Sales[Year], 2024
|
|
176
|
+
)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Nth Largest/Smallest with Conditions
|
|
180
|
+
```excel
|
|
181
|
+
// 2nd largest sale in North (using LARGE + IF as array)
|
|
182
|
+
=LARGE(IF(tbl_Sales[Region]="North", tbl_Sales[Amount]), 2)
|
|
183
|
+
|
|
184
|
+
// With FILTER (365)
|
|
185
|
+
=LARGE(FILTER(tbl_Sales[Amount], tbl_Sales[Region]="North"), 2)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## SUMPRODUCT - Flexible Aggregation
|
|
191
|
+
|
|
192
|
+
### As Conditional Sum
|
|
193
|
+
```excel
|
|
194
|
+
// Equivalent to SUMIFS
|
|
195
|
+
=SUMPRODUCT((tbl_Sales[Region]="North") * tbl_Sales[Amount])
|
|
196
|
+
|
|
197
|
+
// Multiple conditions
|
|
198
|
+
=SUMPRODUCT(
|
|
199
|
+
(tbl_Sales[Region]="North") *
|
|
200
|
+
(tbl_Sales[Year]=2024) *
|
|
201
|
+
tbl_Sales[Amount]
|
|
202
|
+
)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### OR Conditions (not possible with SUMIFS)
|
|
206
|
+
```excel
|
|
207
|
+
// Sum where Region is North OR South
|
|
208
|
+
=SUMPRODUCT(
|
|
209
|
+
((tbl_Sales[Region]="North") + (tbl_Sales[Region]="South")) *
|
|
210
|
+
tbl_Sales[Amount]
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Array Comparisons
|
|
215
|
+
```excel
|
|
216
|
+
// Sum where product is in a list
|
|
217
|
+
=SUMPRODUCT(
|
|
218
|
+
SUMIFS(tbl_Sales[Amount], tbl_Sales[Product], {"A","B","C"})
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
// Or using SUMPRODUCT with ISNUMBER/MATCH
|
|
222
|
+
=SUMPRODUCT(
|
|
223
|
+
ISNUMBER(MATCH(tbl_Sales[Product], {"A","B","C"}, 0)) *
|
|
224
|
+
tbl_Sales[Amount]
|
|
225
|
+
)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Running Totals and Cumulative
|
|
231
|
+
|
|
232
|
+
### Running Total (Table Column)
|
|
233
|
+
```excel
|
|
234
|
+
// In a table column (structured reference for current row)
|
|
235
|
+
=SUMIFS(
|
|
236
|
+
tbl_Sales[Amount],
|
|
237
|
+
tbl_Sales[Date], "<="&[@Date]
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
// Running total by group
|
|
241
|
+
=SUMIFS(
|
|
242
|
+
tbl_Sales[Amount],
|
|
243
|
+
tbl_Sales[Region], [@Region],
|
|
244
|
+
tbl_Sales[Date], "<="&[@Date]
|
|
245
|
+
)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Running Count
|
|
249
|
+
```excel
|
|
250
|
+
=COUNTIFS(tbl_Sales[Date], "<="&[@Date])
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Running Average
|
|
254
|
+
```excel
|
|
255
|
+
=AVERAGEIFS(
|
|
256
|
+
tbl_Sales[Amount],
|
|
257
|
+
tbl_Sales[Date], "<="&[@Date]
|
|
258
|
+
)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Cross-Table Aggregation
|
|
264
|
+
|
|
265
|
+
### SUMIFS Across Tables
|
|
266
|
+
```excel
|
|
267
|
+
// Sum from Orders where CustomerID matches Customers table
|
|
268
|
+
=SUMIFS(
|
|
269
|
+
tbl_Orders[Amount],
|
|
270
|
+
tbl_Orders[CustomerID], tbl_Customers[@CustomerID]
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
// With additional condition
|
|
274
|
+
=SUMIFS(
|
|
275
|
+
tbl_Orders[Amount],
|
|
276
|
+
tbl_Orders[CustomerID], tbl_Customers[@CustomerID],
|
|
277
|
+
tbl_Orders[Status], "Complete"
|
|
278
|
+
)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Handling Errors and Edge Cases
|
|
284
|
+
|
|
285
|
+
### Empty Results
|
|
286
|
+
```excel
|
|
287
|
+
// Return 0 instead of error when no matches
|
|
288
|
+
=IFERROR(AVERAGEIFS(tbl_Sales[Amount], tbl_Sales[Region], "Unknown"), 0)
|
|
289
|
+
|
|
290
|
+
// Or check count first
|
|
291
|
+
=IF(COUNTIFS(tbl_Sales[Region], "Unknown")=0, 0,
|
|
292
|
+
AVERAGEIFS(tbl_Sales[Amount], tbl_Sales[Region], "Unknown"))
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Text as Numbers
|
|
296
|
+
```excel
|
|
297
|
+
// Force text to number comparison
|
|
298
|
+
=SUMPRODUCT((tbl_Sales[TextAmount]+0) * (tbl_Sales[Region]="North"))
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Performance Tips
|
|
304
|
+
|
|
305
|
+
1. **Use Table References** - Faster than entire column (A:A)
|
|
306
|
+
2. **Order Conditions** - Put most restrictive condition first
|
|
307
|
+
3. **Avoid Volatile Functions** - TODAY() in criteria recalculates constantly
|
|
308
|
+
4. **Pre-calculate Dates** - Use cell reference instead of DATE() in formula
|
|
309
|
+
5. **Consider SUMPRODUCT** - Sometimes faster for complex conditions
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Quick Reference
|
|
314
|
+
|
|
315
|
+
| Function | Purpose | Returns |
|
|
316
|
+
|----------|---------|---------|
|
|
317
|
+
| SUMIFS | Conditional sum | Number |
|
|
318
|
+
| COUNTIFS | Conditional count | Integer |
|
|
319
|
+
| AVERAGEIFS | Conditional average | Number |
|
|
320
|
+
| MAXIFS | Conditional maximum | Number |
|
|
321
|
+
| MINIFS | Conditional minimum | Number |
|
|
322
|
+
| SUMPRODUCT | Array multiplication sum | Number |
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Related Resources
|
|
327
|
+
|
|
328
|
+
- [Dynamic Arrays](./dynamic-arrays.md)
|
|
329
|
+
- [Lookups](./lookups.md)
|
|
330
|
+
- [Excel Formulas Skill](../../skills/excel-formulas/SKILL.md)
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
# Dates and Times
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Excel patterns for date calculations, time operations, and working with date ranges.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Date Construction
|
|
9
|
+
|
|
10
|
+
### Create Dates
|
|
11
|
+
```excel
|
|
12
|
+
// From components
|
|
13
|
+
=DATE(2024, 1, 15) // January 15, 2024
|
|
14
|
+
|
|
15
|
+
// From cell values
|
|
16
|
+
=DATE(A1, B1, C1) // Year, Month, Day in cells
|
|
17
|
+
|
|
18
|
+
// Today's date
|
|
19
|
+
=TODAY() // Updates daily
|
|
20
|
+
|
|
21
|
+
// Current date and time
|
|
22
|
+
=NOW() // Updates on recalculation
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Extract Components
|
|
26
|
+
```excel
|
|
27
|
+
=YEAR(A1) // 2024
|
|
28
|
+
=MONTH(A1) // 1-12
|
|
29
|
+
=DAY(A1) // 1-31
|
|
30
|
+
=WEEKDAY(A1) // 1-7 (Sunday=1 by default)
|
|
31
|
+
=WEEKDAY(A1, 2) // 1-7 (Monday=1)
|
|
32
|
+
=WEEKNUM(A1) // Week number (US)
|
|
33
|
+
=ISOWEEKNUM(A1) // ISO week number
|
|
34
|
+
=HOUR(A1) // 0-23
|
|
35
|
+
=MINUTE(A1) // 0-59
|
|
36
|
+
=SECOND(A1) // 0-59
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Date Arithmetic
|
|
42
|
+
|
|
43
|
+
### Add/Subtract Days
|
|
44
|
+
```excel
|
|
45
|
+
// Add days
|
|
46
|
+
=A1 + 7 // Add 7 days
|
|
47
|
+
=A1 - 30 // Subtract 30 days
|
|
48
|
+
|
|
49
|
+
// Days between dates
|
|
50
|
+
=B1 - A1 // Simple difference
|
|
51
|
+
=DAYS(B1, A1) // Same result, clearer
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Add/Subtract Months
|
|
55
|
+
```excel
|
|
56
|
+
// Add months
|
|
57
|
+
=EDATE(A1, 3) // Add 3 months
|
|
58
|
+
=EDATE(A1, -6) // Subtract 6 months
|
|
59
|
+
|
|
60
|
+
// Months between dates
|
|
61
|
+
=DATEDIF(A1, B1, "M") // Complete months between
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Add/Subtract Years
|
|
65
|
+
```excel
|
|
66
|
+
// Add years
|
|
67
|
+
=EDATE(A1, 12) // Add 1 year (12 months)
|
|
68
|
+
=DATE(YEAR(A1)+1, MONTH(A1), DAY(A1)) // Same date next year
|
|
69
|
+
|
|
70
|
+
// Years between dates
|
|
71
|
+
=DATEDIF(A1, B1, "Y") // Complete years between
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Working Days
|
|
77
|
+
|
|
78
|
+
### NETWORKDAYS
|
|
79
|
+
```excel
|
|
80
|
+
// Working days between dates (excludes weekends)
|
|
81
|
+
=NETWORKDAYS(StartDate, EndDate)
|
|
82
|
+
|
|
83
|
+
// With holidays
|
|
84
|
+
=NETWORKDAYS(StartDate, EndDate, HolidayRange)
|
|
85
|
+
|
|
86
|
+
// Example with holiday list
|
|
87
|
+
=NETWORKDAYS(A1, B1, $D$1:$D$10)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### NETWORKDAYS.INTL - Custom Weekends
|
|
91
|
+
```excel
|
|
92
|
+
// Weekend string: 1=non-working, 0=working (Mon-Sun)
|
|
93
|
+
=NETWORKDAYS.INTL(A1, B1, "0000011") // Sat-Sun weekend (default)
|
|
94
|
+
=NETWORKDAYS.INTL(A1, B1, "0000001") // Sunday only weekend
|
|
95
|
+
=NETWORKDAYS.INTL(A1, B1, "1000001") // Mon+Sun weekend
|
|
96
|
+
=NETWORKDAYS.INTL(A1, B1, "0000000") // No weekend (7-day week)
|
|
97
|
+
|
|
98
|
+
// Weekend number codes
|
|
99
|
+
=NETWORKDAYS.INTL(A1, B1, 1) // Sat-Sun (default)
|
|
100
|
+
=NETWORKDAYS.INTL(A1, B1, 2) // Sun-Mon
|
|
101
|
+
=NETWORKDAYS.INTL(A1, B1, 11) // Sunday only
|
|
102
|
+
=NETWORKDAYS.INTL(A1, B1, 17) // No weekend
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### WORKDAY - Add Working Days
|
|
106
|
+
```excel
|
|
107
|
+
// Add working days
|
|
108
|
+
=WORKDAY(StartDate, 10) // Add 10 working days
|
|
109
|
+
=WORKDAY(StartDate, -5) // Subtract 5 working days
|
|
110
|
+
=WORKDAY(StartDate, 10, HolidayRange) // Excluding holidays
|
|
111
|
+
|
|
112
|
+
// Custom weekend
|
|
113
|
+
=WORKDAY.INTL(StartDate, 10, "0000011", HolidayRange)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Month/Year Boundaries
|
|
119
|
+
|
|
120
|
+
### Start of Period
|
|
121
|
+
```excel
|
|
122
|
+
// First day of current month
|
|
123
|
+
=EOMONTH(A1, -1) + 1
|
|
124
|
+
|
|
125
|
+
// First day of current year
|
|
126
|
+
=DATE(YEAR(A1), 1, 1)
|
|
127
|
+
|
|
128
|
+
// First day of current quarter
|
|
129
|
+
=DATE(YEAR(A1), CEILING(MONTH(A1), 3) - 2, 1)
|
|
130
|
+
|
|
131
|
+
// First day of current week (Monday)
|
|
132
|
+
=A1 - WEEKDAY(A1, 2) + 1
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### End of Period
|
|
136
|
+
```excel
|
|
137
|
+
// Last day of current month
|
|
138
|
+
=EOMONTH(A1, 0)
|
|
139
|
+
|
|
140
|
+
// Last day of previous month
|
|
141
|
+
=EOMONTH(A1, -1)
|
|
142
|
+
|
|
143
|
+
// Last day of current year
|
|
144
|
+
=DATE(YEAR(A1), 12, 31)
|
|
145
|
+
|
|
146
|
+
// Last day of current quarter
|
|
147
|
+
=EOMONTH(DATE(YEAR(A1), CEILING(MONTH(A1), 3), 1), 0)
|
|
148
|
+
|
|
149
|
+
// Last day of current week (Sunday)
|
|
150
|
+
=A1 - WEEKDAY(A1, 2) + 7
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Quarter Calculations
|
|
156
|
+
|
|
157
|
+
### Get Quarter
|
|
158
|
+
```excel
|
|
159
|
+
// Quarter number (1-4)
|
|
160
|
+
=CEILING(MONTH(A1) / 3, 1)
|
|
161
|
+
|
|
162
|
+
// Or using ROUNDUP
|
|
163
|
+
=ROUNDUP(MONTH(A1) / 3, 0)
|
|
164
|
+
|
|
165
|
+
// Quarter text
|
|
166
|
+
="Q" & CEILING(MONTH(A1) / 3, 1)
|
|
167
|
+
|
|
168
|
+
// Quarter and Year
|
|
169
|
+
="Q" & CEILING(MONTH(A1) / 3, 1) & " " & YEAR(A1)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Fiscal Quarter (Starting April)
|
|
173
|
+
```excel
|
|
174
|
+
// Fiscal quarter (April = Q1)
|
|
175
|
+
=MOD(CEILING(MONTH(A1) / 3, 1) + 2, 4) + 1
|
|
176
|
+
|
|
177
|
+
// Fiscal year (April start)
|
|
178
|
+
=YEAR(A1) + IF(MONTH(A1) >= 4, 0, -1)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Age Calculations
|
|
184
|
+
|
|
185
|
+
### DATEDIF Function
|
|
186
|
+
```excel
|
|
187
|
+
// Years between dates
|
|
188
|
+
=DATEDIF(BirthDate, TODAY(), "Y")
|
|
189
|
+
|
|
190
|
+
// Months between dates
|
|
191
|
+
=DATEDIF(StartDate, EndDate, "M")
|
|
192
|
+
|
|
193
|
+
// Days between dates
|
|
194
|
+
=DATEDIF(StartDate, EndDate, "D")
|
|
195
|
+
|
|
196
|
+
// Full age (years, months, days)
|
|
197
|
+
=DATEDIF(A1, TODAY(), "Y") & " years, " &
|
|
198
|
+
DATEDIF(A1, TODAY(), "YM") & " months, " &
|
|
199
|
+
DATEDIF(A1, TODAY(), "MD") & " days"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Age in Decimal Years
|
|
203
|
+
```excel
|
|
204
|
+
=YEARFRAC(BirthDate, TODAY())
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Tenure Calculations
|
|
208
|
+
```excel
|
|
209
|
+
// Employment tenure in years
|
|
210
|
+
=DATEDIF(HireDate, TODAY(), "Y")
|
|
211
|
+
|
|
212
|
+
// Tenure category
|
|
213
|
+
=IFS(
|
|
214
|
+
DATEDIF(HireDate, TODAY(), "Y") < 1, "< 1 Year",
|
|
215
|
+
DATEDIF(HireDate, TODAY(), "Y") < 3, "1-3 Years",
|
|
216
|
+
DATEDIF(HireDate, TODAY(), "Y") < 5, "3-5 Years",
|
|
217
|
+
TRUE, "5+ Years"
|
|
218
|
+
)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Time Calculations
|
|
224
|
+
|
|
225
|
+
### Time Arithmetic
|
|
226
|
+
```excel
|
|
227
|
+
// Duration in hours
|
|
228
|
+
=(EndTime - StartTime) * 24
|
|
229
|
+
|
|
230
|
+
// Duration in minutes
|
|
231
|
+
=(EndTime - StartTime) * 1440
|
|
232
|
+
|
|
233
|
+
// Add hours to time
|
|
234
|
+
=StartTime + TIME(2, 30, 0) // Add 2 hours 30 minutes
|
|
235
|
+
|
|
236
|
+
// Subtract times
|
|
237
|
+
=EndTime - StartTime // Returns time duration
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Crossing Midnight
|
|
241
|
+
```excel
|
|
242
|
+
// Handle times crossing midnight
|
|
243
|
+
=IF(EndTime < StartTime,
|
|
244
|
+
(1 - StartTime + EndTime) * 24,
|
|
245
|
+
(EndTime - StartTime) * 24
|
|
246
|
+
)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Round Time
|
|
250
|
+
```excel
|
|
251
|
+
// Round to nearest 15 minutes
|
|
252
|
+
=MROUND(A1, "0:15")
|
|
253
|
+
|
|
254
|
+
// Round down to 15 minutes
|
|
255
|
+
=FLOOR(A1, "0:15")
|
|
256
|
+
|
|
257
|
+
// Round up to 15 minutes
|
|
258
|
+
=CEILING(A1, "0:15")
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Date Formatting (TEXT Function)
|
|
264
|
+
|
|
265
|
+
### Common Formats
|
|
266
|
+
```excel
|
|
267
|
+
=TEXT(A1, "MM/DD/YYYY") // 01/15/2024
|
|
268
|
+
=TEXT(A1, "DD-MMM-YYYY") // 15-Jan-2024
|
|
269
|
+
=TEXT(A1, "MMMM D, YYYY") // January 15, 2024
|
|
270
|
+
=TEXT(A1, "YYYY-MM-DD") // 2024-01-15 (ISO)
|
|
271
|
+
=TEXT(A1, "DDDD") // Monday
|
|
272
|
+
=TEXT(A1, "DDD") // Mon
|
|
273
|
+
=TEXT(A1, "MMMM") // January
|
|
274
|
+
=TEXT(A1, "MMM") // Jan
|
|
275
|
+
=TEXT(A1, "Q") // 1 (quarter)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Time Formats
|
|
279
|
+
```excel
|
|
280
|
+
=TEXT(A1, "HH:MM:SS") // 14:30:00 (24-hour)
|
|
281
|
+
=TEXT(A1, "H:MM AM/PM") // 2:30 PM
|
|
282
|
+
=TEXT(A1, "HH:MM") // 14:30
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Date Validation
|
|
288
|
+
|
|
289
|
+
### Is Valid Date
|
|
290
|
+
```excel
|
|
291
|
+
=ISNUMBER(A1) // Check if cell contains date
|
|
292
|
+
|
|
293
|
+
// Check if text is valid date
|
|
294
|
+
=ISNUMBER(DATEVALUE(A1))
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Is Weekday/Weekend
|
|
298
|
+
```excel
|
|
299
|
+
// Is weekday (Mon-Fri)
|
|
300
|
+
=WEEKDAY(A1, 2) <= 5
|
|
301
|
+
|
|
302
|
+
// Is weekend (Sat-Sun)
|
|
303
|
+
=WEEKDAY(A1, 2) > 5
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Is Within Range
|
|
307
|
+
```excel
|
|
308
|
+
=AND(A1 >= StartDate, A1 <= EndDate)
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Dynamic Date Sequences
|
|
314
|
+
|
|
315
|
+
### Generate Date Range (365)
|
|
316
|
+
```excel
|
|
317
|
+
// Dates from start to end
|
|
318
|
+
=SEQUENCE(EndDate - StartDate + 1, 1, StartDate, 1)
|
|
319
|
+
|
|
320
|
+
// First day of each month for a year
|
|
321
|
+
=EDATE(DATE(2024, 1, 1), SEQUENCE(12, 1, 0, 1))
|
|
322
|
+
|
|
323
|
+
// Last day of each month for a year
|
|
324
|
+
=EOMONTH(DATE(2024, 1, 1), SEQUENCE(12, 1, 0, 1))
|
|
325
|
+
|
|
326
|
+
// Weekly dates
|
|
327
|
+
=SEQUENCE(52, 1, DATE(2024, 1, 1), 7)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## Performance Tips
|
|
333
|
+
|
|
334
|
+
1. **Avoid TODAY() in large arrays** - Causes constant recalculation
|
|
335
|
+
2. **Pre-calculate reference dates** - Store TODAY() in a cell and reference it
|
|
336
|
+
3. **Use numbers for date math** - Dates are numbers; simple arithmetic is fast
|
|
337
|
+
4. **Cache DATEDIF results** - Can be slow in large datasets
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Quick Reference
|
|
342
|
+
|
|
343
|
+
| Function | Purpose |
|
|
344
|
+
|----------|---------|
|
|
345
|
+
| DATE | Create date from Y, M, D |
|
|
346
|
+
| EDATE | Add/subtract months |
|
|
347
|
+
| EOMONTH | End of month |
|
|
348
|
+
| WORKDAY | Add working days |
|
|
349
|
+
| NETWORKDAYS | Count working days |
|
|
350
|
+
| DATEDIF | Difference in Y/M/D |
|
|
351
|
+
| YEARFRAC | Decimal years |
|
|
352
|
+
| WEEKDAY | Day of week (1-7) |
|
|
353
|
+
| ISOWEEKNUM | ISO week number |
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
## Related Resources
|
|
358
|
+
|
|
359
|
+
- [Aggregations](./aggregations.md)
|
|
360
|
+
- [Dynamic Arrays](./dynamic-arrays.md)
|
|
361
|
+
- [Excel Formulas Skill](../../skills/excel-formulas/SKILL.md)
|