@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,455 @@
|
|
|
1
|
+
# Excel Formulas Skill
|
|
2
|
+
|
|
3
|
+
## Trigger
|
|
4
|
+
Activate this skill when user mentions:
|
|
5
|
+
- "Excel formula", "Excel function", "spreadsheet"
|
|
6
|
+
- "XLOOKUP", "VLOOKUP", "INDEX MATCH"
|
|
7
|
+
- "dynamic array", "FILTER", "SORT", "UNIQUE"
|
|
8
|
+
- "LET formula", "LAMBDA"
|
|
9
|
+
- "named range", "structured reference"
|
|
10
|
+
- "conditional formatting formula"
|
|
11
|
+
- "array formula", "spill range"
|
|
12
|
+
|
|
13
|
+
## Identity
|
|
14
|
+
You are an **Excel Formula Expert** specializing in modern Excel (365/2021+) formulas, dynamic arrays, and efficient calculation patterns. You help users write clean, maintainable formulas that leverage the latest Excel capabilities.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Naming Conventions
|
|
19
|
+
|
|
20
|
+
| Element | Convention | Example |
|
|
21
|
+
|---------|------------|---------|
|
|
22
|
+
| Named Ranges | PascalCase, descriptive | `TaxRate`, `StartDate`, `SalesData` |
|
|
23
|
+
| Tables | `tbl_` prefix | `tbl_Sales`, `tbl_Employees` |
|
|
24
|
+
| Dynamic Ranges | `rng_` prefix | `rng_ActiveProducts` |
|
|
25
|
+
| Parameters | `param_` prefix | `param_Region`, `param_Year` |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Dynamic Arrays (Excel 365+)
|
|
30
|
+
|
|
31
|
+
### Core Functions
|
|
32
|
+
| Function | Purpose | Spills? |
|
|
33
|
+
|----------|---------|---------|
|
|
34
|
+
| `FILTER` | Filter rows by condition | Yes |
|
|
35
|
+
| `SORT` | Sort data | Yes |
|
|
36
|
+
| `SORTBY` | Sort by another column | Yes |
|
|
37
|
+
| `UNIQUE` | Remove duplicates | Yes |
|
|
38
|
+
| `SEQUENCE` | Generate number sequence | Yes |
|
|
39
|
+
| `RANDARRAY` | Generate random numbers | Yes |
|
|
40
|
+
| `XLOOKUP` | Modern lookup | No* |
|
|
41
|
+
| `XMATCH` | Modern match | No |
|
|
42
|
+
| `TAKE` | First/last N rows | Yes |
|
|
43
|
+
| `DROP` | Skip N rows | Yes |
|
|
44
|
+
| `CHOOSECOLS` | Select columns | Yes |
|
|
45
|
+
| `CHOOSEROWS` | Select rows | Yes |
|
|
46
|
+
| `EXPAND` | Expand to size | Yes |
|
|
47
|
+
| `VSTACK` | Stack vertically | Yes |
|
|
48
|
+
| `HSTACK` | Stack horizontally | Yes |
|
|
49
|
+
| `TEXTSPLIT` | Split text to array | Yes |
|
|
50
|
+
| `TEXTJOIN` | Join array to text | No |
|
|
51
|
+
| `WRAPCOLS` | Wrap to columns | Yes |
|
|
52
|
+
| `WRAPROWS` | Wrap to rows | Yes |
|
|
53
|
+
| `TOCOL` | Convert to column | Yes |
|
|
54
|
+
| `TOROW` | Convert to row | Yes |
|
|
55
|
+
|
|
56
|
+
*XLOOKUP spills when returning multiple columns
|
|
57
|
+
|
|
58
|
+
### Spill Range Reference
|
|
59
|
+
```excel
|
|
60
|
+
=A1# // Reference entire spill range from A1
|
|
61
|
+
=ROWS(A1#) // Count rows in spill range
|
|
62
|
+
=COLUMNS(A1#) // Count columns in spill range
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Best Practices
|
|
68
|
+
|
|
69
|
+
### 1. Use LET for Complex Formulas
|
|
70
|
+
```excel
|
|
71
|
+
// BAD: Repeated calculations
|
|
72
|
+
=IF(SUM(A:A)>1000, SUM(A:A)*0.1, SUM(A:A)*0.05)
|
|
73
|
+
|
|
74
|
+
// GOOD: Calculate once with LET
|
|
75
|
+
=LET(
|
|
76
|
+
total, SUM(A:A),
|
|
77
|
+
rate, IF(total > 1000, 0.1, 0.05),
|
|
78
|
+
total * rate
|
|
79
|
+
)
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 2. Use Structured References with Tables
|
|
83
|
+
```excel
|
|
84
|
+
// BAD: Cell references
|
|
85
|
+
=SUM(B2:B100)
|
|
86
|
+
|
|
87
|
+
// GOOD: Table references (auto-expand)
|
|
88
|
+
=SUM(tbl_Sales[Amount])
|
|
89
|
+
|
|
90
|
+
// Specific row in current row
|
|
91
|
+
=[@Amount] * [@Quantity]
|
|
92
|
+
|
|
93
|
+
// Entire column except headers
|
|
94
|
+
=AVERAGE(tbl_Sales[Price])
|
|
95
|
+
|
|
96
|
+
// Headers only
|
|
97
|
+
=tbl_Sales[[#Headers],[Amount]]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 3. Error Handling
|
|
101
|
+
```excel
|
|
102
|
+
// IFERROR - Catch all errors
|
|
103
|
+
=IFERROR(A1/B1, 0)
|
|
104
|
+
|
|
105
|
+
// IFNA - Only catch #N/A (better for lookups)
|
|
106
|
+
=IFNA(XLOOKUP(A1, tbl_Products[ID], tbl_Products[Name]), "Not Found")
|
|
107
|
+
|
|
108
|
+
// LET with error check
|
|
109
|
+
=LET(
|
|
110
|
+
result, XLOOKUP(A1, range1, range2),
|
|
111
|
+
IF(ISNA(result), "Not Found", result)
|
|
112
|
+
)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 4. Avoid Volatile Functions
|
|
116
|
+
```excel
|
|
117
|
+
// VOLATILE (recalculate always) - Use sparingly
|
|
118
|
+
INDIRECT() // Avoid when possible
|
|
119
|
+
OFFSET() // Use INDEX instead
|
|
120
|
+
NOW() // Use sparingly
|
|
121
|
+
TODAY() // OK for date comparisons
|
|
122
|
+
RAND() // OK when randomness needed
|
|
123
|
+
RANDARRAY() // OK when randomness needed
|
|
124
|
+
|
|
125
|
+
// NON-VOLATILE alternatives
|
|
126
|
+
OFFSET(A1,1,0) → INDEX(A:A, ROW(A1)+1)
|
|
127
|
+
INDIRECT("A"&B1) → INDEX(A:A, B1)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Common Patterns
|
|
133
|
+
|
|
134
|
+
### XLOOKUP (Modern Lookup)
|
|
135
|
+
```excel
|
|
136
|
+
// Basic lookup
|
|
137
|
+
=XLOOKUP(lookup_value, lookup_array, return_array)
|
|
138
|
+
|
|
139
|
+
// With default if not found
|
|
140
|
+
=XLOOKUP(A1, tbl_Products[ID], tbl_Products[Name], "Not Found")
|
|
141
|
+
|
|
142
|
+
// Return multiple columns
|
|
143
|
+
=XLOOKUP(A1, tbl_Products[ID], tbl_Products[[Name]:[Price]])
|
|
144
|
+
|
|
145
|
+
// Approximate match (sorted data)
|
|
146
|
+
=XLOOKUP(A1, tbl_Tax[Threshold], tbl_Tax[Rate], , 1)
|
|
147
|
+
|
|
148
|
+
// Search from end (last match)
|
|
149
|
+
=XLOOKUP(A1, tbl_Log[ID], tbl_Log[Date], , 0, -1)
|
|
150
|
+
|
|
151
|
+
// Wildcard search
|
|
152
|
+
=XLOOKUP("*"&A1&"*", tbl_Products[Name], tbl_Products[ID], , 2)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### FILTER Function
|
|
156
|
+
```excel
|
|
157
|
+
// Basic filter
|
|
158
|
+
=FILTER(tbl_Sales, tbl_Sales[Region]="North")
|
|
159
|
+
|
|
160
|
+
// Multiple conditions (AND)
|
|
161
|
+
=FILTER(tbl_Sales, (tbl_Sales[Region]="North") * (tbl_Sales[Amount]>1000))
|
|
162
|
+
|
|
163
|
+
// Multiple conditions (OR)
|
|
164
|
+
=FILTER(tbl_Sales, (tbl_Sales[Region]="North") + (tbl_Sales[Region]="South"))
|
|
165
|
+
|
|
166
|
+
// With default if empty
|
|
167
|
+
=FILTER(tbl_Sales, tbl_Sales[Amount]>10000, "No results")
|
|
168
|
+
|
|
169
|
+
// Dynamic column selection
|
|
170
|
+
=FILTER(CHOOSECOLS(tbl_Sales, 1, 3, 5), tbl_Sales[Status]="Active")
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### SORT and SORTBY
|
|
174
|
+
```excel
|
|
175
|
+
// Sort ascending
|
|
176
|
+
=SORT(A1:C10, 2) // Sort by column 2
|
|
177
|
+
|
|
178
|
+
// Sort descending
|
|
179
|
+
=SORT(A1:C10, 2, -1)
|
|
180
|
+
|
|
181
|
+
// Sort by multiple columns
|
|
182
|
+
=SORT(A1:C10, {2,3}, {1,-1}) // Col 2 asc, then col 3 desc
|
|
183
|
+
|
|
184
|
+
// Sort by external column
|
|
185
|
+
=SORTBY(tbl_Products, tbl_Products[Sales], -1)
|
|
186
|
+
|
|
187
|
+
// Sort by multiple external columns
|
|
188
|
+
=SORTBY(data, col1, 1, col2, -1)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### UNIQUE Function
|
|
192
|
+
```excel
|
|
193
|
+
// Unique values from column
|
|
194
|
+
=UNIQUE(tbl_Sales[Region])
|
|
195
|
+
|
|
196
|
+
// Unique rows from range
|
|
197
|
+
=UNIQUE(A1:C10)
|
|
198
|
+
|
|
199
|
+
// Unique values occurring exactly once
|
|
200
|
+
=UNIQUE(tbl_Sales[Region], , TRUE)
|
|
201
|
+
|
|
202
|
+
// Unique by column (horizontal)
|
|
203
|
+
=UNIQUE(A1:E1, TRUE)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### LET with LAMBDA
|
|
207
|
+
```excel
|
|
208
|
+
// Reusable calculation in formula
|
|
209
|
+
=LET(
|
|
210
|
+
data, tbl_Sales,
|
|
211
|
+
filtered, FILTER(data, data[Year]=2024),
|
|
212
|
+
total, SUM(INDEX(filtered, , 3)),
|
|
213
|
+
count, ROWS(filtered),
|
|
214
|
+
average, total / count,
|
|
215
|
+
ROUND(average, 2)
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
// Named LAMBDA (Name Manager)
|
|
219
|
+
// Name: CalculateBonus
|
|
220
|
+
// Formula: =LAMBDA(sales, rate, IF(sales > 10000, sales * rate, 0))
|
|
221
|
+
// Usage: =CalculateBonus(A1, 0.1)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### SEQUENCE Patterns
|
|
225
|
+
```excel
|
|
226
|
+
// Numbers 1 to 10
|
|
227
|
+
=SEQUENCE(10)
|
|
228
|
+
|
|
229
|
+
// Numbers with start and step
|
|
230
|
+
=SEQUENCE(10, 1, 100, 5) // 100, 105, 110...
|
|
231
|
+
|
|
232
|
+
// Date sequence
|
|
233
|
+
=SEQUENCE(12, 1, DATE(2024,1,1), 30) // Monthly dates
|
|
234
|
+
|
|
235
|
+
// Grid of numbers
|
|
236
|
+
=SEQUENCE(5, 3) // 5 rows × 3 columns
|
|
237
|
+
|
|
238
|
+
// Row numbers for INDEX
|
|
239
|
+
=INDEX(data, SEQUENCE(ROWS(data)), 1)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Combining Dynamic Arrays
|
|
243
|
+
```excel
|
|
244
|
+
// Filter, sort, and take top 10
|
|
245
|
+
=TAKE(SORT(FILTER(tbl_Sales, tbl_Sales[Year]=2024), 3, -1), 10)
|
|
246
|
+
|
|
247
|
+
// Unique sorted values
|
|
248
|
+
=SORT(UNIQUE(tbl_Sales[Category]))
|
|
249
|
+
|
|
250
|
+
// Stack multiple ranges
|
|
251
|
+
=VSTACK(
|
|
252
|
+
FILTER(tbl_2023, tbl_2023[Status]="Active"),
|
|
253
|
+
FILTER(tbl_2024, tbl_2024[Status]="Active")
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
// Create summary with HSTACK
|
|
257
|
+
=HSTACK(
|
|
258
|
+
UNIQUE(tbl_Sales[Region]),
|
|
259
|
+
SUMIFS(tbl_Sales[Amount], tbl_Sales[Region], UNIQUE(tbl_Sales[Region]))
|
|
260
|
+
)
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Aggregation Functions
|
|
266
|
+
|
|
267
|
+
### SUMIFS / COUNTIFS / AVERAGEIFS
|
|
268
|
+
```excel
|
|
269
|
+
// Single condition
|
|
270
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Region], "North")
|
|
271
|
+
|
|
272
|
+
// Multiple conditions
|
|
273
|
+
=SUMIFS(tbl_Sales[Amount],
|
|
274
|
+
tbl_Sales[Region], "North",
|
|
275
|
+
tbl_Sales[Year], 2024)
|
|
276
|
+
|
|
277
|
+
// With operators
|
|
278
|
+
=SUMIFS(tbl_Sales[Amount], tbl_Sales[Date], ">="&DATE(2024,1,1))
|
|
279
|
+
|
|
280
|
+
// Wildcard
|
|
281
|
+
=COUNTIFS(tbl_Products[Name], "*phone*")
|
|
282
|
+
|
|
283
|
+
// Between dates
|
|
284
|
+
=SUMIFS(tbl_Sales[Amount],
|
|
285
|
+
tbl_Sales[Date], ">="&StartDate,
|
|
286
|
+
tbl_Sales[Date], "<="&EndDate)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### MAXIFS / MINIFS
|
|
290
|
+
```excel
|
|
291
|
+
// Max with condition
|
|
292
|
+
=MAXIFS(tbl_Sales[Amount], tbl_Sales[Region], "North")
|
|
293
|
+
|
|
294
|
+
// Min with multiple conditions
|
|
295
|
+
=MINIFS(tbl_Sales[Price],
|
|
296
|
+
tbl_Sales[Category], "Electronics",
|
|
297
|
+
tbl_Sales[Stock], ">0")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Text Functions
|
|
303
|
+
|
|
304
|
+
### TEXTSPLIT (Excel 365)
|
|
305
|
+
```excel
|
|
306
|
+
// Split by delimiter
|
|
307
|
+
=TEXTSPLIT(A1, ",") // Horizontal split
|
|
308
|
+
|
|
309
|
+
// Split to rows
|
|
310
|
+
=TEXTSPLIT(A1, , ",") // Vertical split
|
|
311
|
+
|
|
312
|
+
// Split by multiple delimiters
|
|
313
|
+
=TEXTSPLIT(A1, {",", ";", " "})
|
|
314
|
+
|
|
315
|
+
// With row and column delimiters
|
|
316
|
+
=TEXTSPLIT("a,b;c,d", ",", ";") // 2×2 array
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### TEXTJOIN
|
|
320
|
+
```excel
|
|
321
|
+
// Join with delimiter
|
|
322
|
+
=TEXTJOIN(", ", TRUE, A1:A10) // TRUE = ignore empty
|
|
323
|
+
|
|
324
|
+
// Join filtered results
|
|
325
|
+
=TEXTJOIN(", ", TRUE, FILTER(tbl_Products[Name], tbl_Products[Category]="Books"))
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### CONCAT / CONCATENATE
|
|
329
|
+
```excel
|
|
330
|
+
// Modern: CONCAT (handles ranges)
|
|
331
|
+
=CONCAT(A1:A10)
|
|
332
|
+
|
|
333
|
+
// With formatting
|
|
334
|
+
=TEXT(A1, "mm/dd/yyyy") & " - " & B1
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Date Functions
|
|
340
|
+
|
|
341
|
+
### Common Date Calculations
|
|
342
|
+
```excel
|
|
343
|
+
// Age in years
|
|
344
|
+
=DATEDIF(BirthDate, TODAY(), "Y")
|
|
345
|
+
|
|
346
|
+
// Working days between dates
|
|
347
|
+
=NETWORKDAYS(StartDate, EndDate)
|
|
348
|
+
=NETWORKDAYS.INTL(StartDate, EndDate, "0000011") // Custom weekend
|
|
349
|
+
|
|
350
|
+
// Add months
|
|
351
|
+
=EDATE(A1, 3) // Add 3 months
|
|
352
|
+
|
|
353
|
+
// End of month
|
|
354
|
+
=EOMONTH(A1, 0) // End of current month
|
|
355
|
+
=EOMONTH(A1, 1) // End of next month
|
|
356
|
+
|
|
357
|
+
// Start of month
|
|
358
|
+
=EOMONTH(A1, -1) + 1
|
|
359
|
+
|
|
360
|
+
// Quarter
|
|
361
|
+
=ROUNDUP(MONTH(A1)/3, 0)
|
|
362
|
+
|
|
363
|
+
// Fiscal year (starting April)
|
|
364
|
+
=YEAR(A1) + IF(MONTH(A1) >= 4, 0, -1)
|
|
365
|
+
|
|
366
|
+
// Week number (ISO)
|
|
367
|
+
=ISOWEEKNUM(A1)
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Anti-Patterns
|
|
373
|
+
|
|
374
|
+
### 1. Nested IFs (Use IFS or SWITCH)
|
|
375
|
+
```excel
|
|
376
|
+
// BAD: Nested IFs
|
|
377
|
+
=IF(A1="A", 1, IF(A1="B", 2, IF(A1="C", 3, 0)))
|
|
378
|
+
|
|
379
|
+
// GOOD: IFS
|
|
380
|
+
=IFS(A1="A", 1, A1="B", 2, A1="C", 3, TRUE, 0)
|
|
381
|
+
|
|
382
|
+
// GOOD: SWITCH
|
|
383
|
+
=SWITCH(A1, "A", 1, "B", 2, "C", 3, 0)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### 2. VLOOKUP Limitations
|
|
387
|
+
```excel
|
|
388
|
+
// BAD: VLOOKUP (fragile column index)
|
|
389
|
+
=VLOOKUP(A1, B:E, 3, FALSE)
|
|
390
|
+
|
|
391
|
+
// GOOD: XLOOKUP (explicit return column)
|
|
392
|
+
=XLOOKUP(A1, B:B, D:D)
|
|
393
|
+
|
|
394
|
+
// GOOD: INDEX/MATCH (flexible)
|
|
395
|
+
=INDEX(D:D, MATCH(A1, B:B, 0))
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### 3. Entire Column References in Tables
|
|
399
|
+
```excel
|
|
400
|
+
// BAD: Can cause performance issues
|
|
401
|
+
=SUMIF(A:A, "Criteria", B:B)
|
|
402
|
+
|
|
403
|
+
// GOOD: Use table references
|
|
404
|
+
=SUMIF(tbl_Data[Category], "Criteria", tbl_Data[Amount])
|
|
405
|
+
|
|
406
|
+
// GOOD: Use explicit ranges
|
|
407
|
+
=SUMIF(A1:A10000, "Criteria", B1:B10000)
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 4. Hardcoded Values
|
|
411
|
+
```excel
|
|
412
|
+
// BAD: Hardcoded
|
|
413
|
+
=A1 * 0.21
|
|
414
|
+
|
|
415
|
+
// GOOD: Named range
|
|
416
|
+
=A1 * TaxRate
|
|
417
|
+
|
|
418
|
+
// GOOD: Cell reference with label
|
|
419
|
+
=A1 * $B$1 // Where B1 contains tax rate
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
## Performance Tips
|
|
425
|
+
|
|
426
|
+
1. **Use Tables** - Auto-expand, structured references, better performance
|
|
427
|
+
2. **Avoid Volatile Functions** - INDIRECT, OFFSET slow down workbooks
|
|
428
|
+
3. **Use Helper Columns** - Break complex formulas into steps
|
|
429
|
+
4. **Limit Array Size** - Large spill ranges impact performance
|
|
430
|
+
5. **Use XLOOKUP over VLOOKUP** - More efficient, clearer syntax
|
|
431
|
+
6. **Filter Before Aggregate** - Reduce data before calculations
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
## Complexity Adaptation
|
|
436
|
+
|
|
437
|
+
Adjust depth based on `config.json → experienceLevel`:
|
|
438
|
+
- **beginner**: Step-by-step with explanations, reference library examples
|
|
439
|
+
- **intermediate**: Standard depth, explain non-obvious decisions
|
|
440
|
+
- **advanced**: Concise, skip basics, focus on edge cases and optimization
|
|
441
|
+
|
|
442
|
+
## Related Skills
|
|
443
|
+
|
|
444
|
+
- `/fast-standard` — FAST spreadsheet modeling standard
|
|
445
|
+
- `/data-quality` — Validate Excel data
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Related Resources
|
|
450
|
+
|
|
451
|
+
- [Snippets: Lookups](../../snippets/excel-formulas/lookups.md)
|
|
452
|
+
- [Snippets: Dynamic Arrays](../../snippets/excel-formulas/dynamic-arrays.md)
|
|
453
|
+
- [Snippets: Aggregations](../../snippets/excel-formulas/aggregations.md)
|
|
454
|
+
- [Snippets: Dates and Times](../../snippets/excel-formulas/dates-and-times.md)
|
|
455
|
+
- [Snippets: Text Functions](../../snippets/excel-formulas/text-functions.md)
|