@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.
Files changed (193) hide show
  1. package/.claude-plugin/plugin.json +8 -0
  2. package/.mcp.json +25 -0
  3. package/AGENTS.md +244 -0
  4. package/CHANGELOG.md +265 -0
  5. package/LICENSE +21 -0
  6. package/README.md +211 -0
  7. package/bin/build-plugin.js +30 -0
  8. package/bin/cli.js +1064 -0
  9. package/bin/commands/add.js +533 -0
  10. package/bin/commands/add.test.js +77 -0
  11. package/bin/commands/build-desktop.js +166 -0
  12. package/bin/commands/changelog.js +443 -0
  13. package/bin/commands/diff.js +325 -0
  14. package/bin/commands/lint.js +419 -0
  15. package/bin/commands/lint.test.js +103 -0
  16. package/bin/commands/mcp-setup.js +246 -0
  17. package/bin/commands/pull.js +287 -0
  18. package/bin/commands/pull.test.js +36 -0
  19. package/bin/commands/push.js +231 -0
  20. package/bin/commands/push.test.js +14 -0
  21. package/bin/commands/search.js +344 -0
  22. package/bin/commands/search.test.js +115 -0
  23. package/bin/commands/setup.js +545 -0
  24. package/bin/commands/setup.test.js +46 -0
  25. package/bin/commands/sync-profile.js +405 -0
  26. package/bin/commands/sync-profile.test.js +14 -0
  27. package/bin/commands/sync-source.js +418 -0
  28. package/bin/commands/sync-source.test.js +14 -0
  29. package/bin/commands/watch.js +206 -0
  30. package/bin/lib/generators/claude-plugin.js +266 -0
  31. package/bin/lib/generators/claude-plugin.test.js +110 -0
  32. package/bin/lib/generators/index.js +116 -0
  33. package/bin/lib/generators/shared.js +282 -0
  34. package/bin/lib/licensing/index.js +35 -0
  35. package/bin/lib/licensing/storage.js +364 -0
  36. package/bin/lib/licensing/storage.test.js +55 -0
  37. package/bin/lib/licensing/validator.js +213 -0
  38. package/bin/lib/licensing/validator.test.js +137 -0
  39. package/bin/lib/microsoft-mcp.js +176 -0
  40. package/bin/lib/microsoft-mcp.test.js +106 -0
  41. package/bin/lib/skills.js +84 -0
  42. package/bin/mcp/powerbi-modeling-launcher.js +38 -0
  43. package/bin/postinstall.js +44 -0
  44. package/bin/utils/errors.js +159 -0
  45. package/bin/utils/git.js +298 -0
  46. package/bin/utils/logger.js +142 -0
  47. package/bin/utils/mcp-detect.js +274 -0
  48. package/bin/utils/mcp-detect.test.js +105 -0
  49. package/bin/utils/pbix.js +305 -0
  50. package/bin/utils/pbix.test.js +37 -0
  51. package/bin/utils/profiles.js +312 -0
  52. package/bin/utils/projects.js +168 -0
  53. package/bin/utils/readline.js +206 -0
  54. package/bin/utils/readline.test.js +47 -0
  55. package/bin/utils/tui.js +314 -0
  56. package/bin/utils/tui.test.js +127 -0
  57. package/commands/contributions.md +265 -0
  58. package/commands/data-model-design.md +468 -0
  59. package/commands/dax-doctor.md +248 -0
  60. package/commands/fabric-scripts.md +452 -0
  61. package/commands/migration-assistant.md +290 -0
  62. package/commands/model-documenter.md +242 -0
  63. package/commands/pbi-connect.md +239 -0
  64. package/commands/project-kickoff.md +905 -0
  65. package/commands/report-layout.md +296 -0
  66. package/commands/rls-design.md +533 -0
  67. package/commands/theme-tweaker.md +624 -0
  68. package/config.example.json +23 -0
  69. package/config.json +23 -0
  70. package/desktop-extension/manifest.json +37 -0
  71. package/desktop-extension/package.json +10 -0
  72. package/desktop-extension/server.js +95 -0
  73. package/docs/openrouter-free-models.md +92 -0
  74. package/library/examples/README.md +151 -0
  75. package/library/examples/finance-reporting/README.md +351 -0
  76. package/library/examples/finance-reporting/data-model.md +267 -0
  77. package/library/examples/finance-reporting/measures.dax +557 -0
  78. package/library/examples/hr-analytics/README.md +371 -0
  79. package/library/examples/hr-analytics/data-model.md +315 -0
  80. package/library/examples/hr-analytics/measures.dax +460 -0
  81. package/library/examples/marketing-analytics/README.md +37 -0
  82. package/library/examples/marketing-analytics/data-model.md +62 -0
  83. package/library/examples/marketing-analytics/measures.dax +110 -0
  84. package/library/examples/retail-analytics/README.md +439 -0
  85. package/library/examples/retail-analytics/data-model.md +288 -0
  86. package/library/examples/retail-analytics/measures.dax +481 -0
  87. package/library/examples/supply-chain/README.md +37 -0
  88. package/library/examples/supply-chain/data-model.md +69 -0
  89. package/library/examples/supply-chain/measures.dax +77 -0
  90. package/library/examples/udf-library/README.md +228 -0
  91. package/library/examples/udf-library/functions.dax +571 -0
  92. package/library/snippets/dax/README.md +292 -0
  93. package/library/snippets/dax/business-domains.md +576 -0
  94. package/library/snippets/dax/calculate-patterns.md +276 -0
  95. package/library/snippets/dax/calculation-groups.md +489 -0
  96. package/library/snippets/dax/error-handling.md +495 -0
  97. package/library/snippets/dax/iterators-and-aggregations.md +474 -0
  98. package/library/snippets/dax/kpis-and-metrics.md +293 -0
  99. package/library/snippets/dax/rankings-and-topn.md +235 -0
  100. package/library/snippets/dax/security-patterns.md +413 -0
  101. package/library/snippets/dax/text-and-formatting.md +316 -0
  102. package/library/snippets/dax/time-intelligence.md +196 -0
  103. package/library/snippets/dax/user-defined-functions.md +477 -0
  104. package/library/snippets/dax/virtual-tables.md +546 -0
  105. package/library/snippets/excel-formulas/README.md +84 -0
  106. package/library/snippets/excel-formulas/aggregations.md +330 -0
  107. package/library/snippets/excel-formulas/dates-and-times.md +361 -0
  108. package/library/snippets/excel-formulas/dynamic-arrays.md +314 -0
  109. package/library/snippets/excel-formulas/lookups.md +169 -0
  110. package/library/snippets/excel-formulas/text-functions.md +363 -0
  111. package/library/snippets/governance/naming-conventions.md +97 -0
  112. package/library/snippets/governance/review-checklists.md +107 -0
  113. package/library/snippets/power-query/README.md +389 -0
  114. package/library/snippets/power-query/api-integration.md +707 -0
  115. package/library/snippets/power-query/connections.md +434 -0
  116. package/library/snippets/power-query/data-cleaning.md +298 -0
  117. package/library/snippets/power-query/error-handling.md +526 -0
  118. package/library/snippets/power-query/parameters.md +350 -0
  119. package/library/snippets/power-query/performance.md +506 -0
  120. package/library/snippets/power-query/transformations.md +330 -0
  121. package/library/snippets/report-design/accessibility.md +78 -0
  122. package/library/snippets/report-design/chart-selection.md +54 -0
  123. package/library/snippets/report-design/layout-patterns.md +87 -0
  124. package/library/templates/data-models/README.md +93 -0
  125. package/library/templates/data-models/finance-model.md +627 -0
  126. package/library/templates/data-models/retail-star-schema.md +473 -0
  127. package/library/templates/excel/README.md +83 -0
  128. package/library/templates/excel/budget-tracker.md +432 -0
  129. package/library/templates/excel/data-entry-form.md +533 -0
  130. package/library/templates/power-bi/README.md +72 -0
  131. package/library/templates/power-bi/finance-report.md +449 -0
  132. package/library/templates/power-bi/kpi-scorecard.md +461 -0
  133. package/library/templates/power-bi/sales-dashboard.md +281 -0
  134. package/library/themes/excel/README.md +436 -0
  135. package/library/themes/power-bi/README.md +271 -0
  136. package/library/themes/power-bi/accessible.json +307 -0
  137. package/library/themes/power-bi/bi-superpowers-default.json +858 -0
  138. package/library/themes/power-bi/corporate-blue.json +291 -0
  139. package/library/themes/power-bi/dark-mode.json +291 -0
  140. package/library/themes/power-bi/minimal.json +292 -0
  141. package/library/themes/power-bi/print-friendly.json +309 -0
  142. package/package.json +93 -0
  143. package/skills/contributions/SKILL.md +267 -0
  144. package/skills/data-model-design/SKILL.md +470 -0
  145. package/skills/data-modeling/SKILL.md +254 -0
  146. package/skills/data-quality/SKILL.md +664 -0
  147. package/skills/dax/SKILL.md +708 -0
  148. package/skills/dax-doctor/SKILL.md +250 -0
  149. package/skills/dax-udf/SKILL.md +489 -0
  150. package/skills/deployment/SKILL.md +320 -0
  151. package/skills/excel-formulas/SKILL.md +463 -0
  152. package/skills/fabric-scripts/SKILL.md +454 -0
  153. package/skills/fast-standard/SKILL.md +509 -0
  154. package/skills/governance/SKILL.md +205 -0
  155. package/skills/migration-assistant/SKILL.md +292 -0
  156. package/skills/model-documenter/SKILL.md +244 -0
  157. package/skills/pbi-connect/SKILL.md +241 -0
  158. package/skills/power-query/SKILL.md +406 -0
  159. package/skills/project-kickoff/SKILL.md +907 -0
  160. package/skills/query-performance/SKILL.md +480 -0
  161. package/skills/report-design/SKILL.md +207 -0
  162. package/skills/report-layout/SKILL.md +298 -0
  163. package/skills/rls-design/SKILL.md +535 -0
  164. package/skills/semantic-model/SKILL.md +237 -0
  165. package/skills/testing-validation/SKILL.md +643 -0
  166. package/skills/theme-tweaker/SKILL.md +626 -0
  167. package/src/content/base.md +237 -0
  168. package/src/content/mcp-requirements.json +69 -0
  169. package/src/content/routing.md +203 -0
  170. package/src/content/skills/contributions.md +259 -0
  171. package/src/content/skills/data-model-design.md +462 -0
  172. package/src/content/skills/data-modeling.md +246 -0
  173. package/src/content/skills/data-quality.md +656 -0
  174. package/src/content/skills/dax-doctor.md +242 -0
  175. package/src/content/skills/dax-udf.md +481 -0
  176. package/src/content/skills/dax.md +700 -0
  177. package/src/content/skills/deployment.md +312 -0
  178. package/src/content/skills/excel-formulas.md +455 -0
  179. package/src/content/skills/fabric-scripts.md +446 -0
  180. package/src/content/skills/fast-standard.md +501 -0
  181. package/src/content/skills/governance.md +197 -0
  182. package/src/content/skills/migration-assistant.md +284 -0
  183. package/src/content/skills/model-documenter.md +236 -0
  184. package/src/content/skills/pbi-connect.md +233 -0
  185. package/src/content/skills/power-query.md +398 -0
  186. package/src/content/skills/project-kickoff.md +899 -0
  187. package/src/content/skills/query-performance.md +472 -0
  188. package/src/content/skills/report-design.md +199 -0
  189. package/src/content/skills/report-layout.md +290 -0
  190. package/src/content/skills/rls-design.md +527 -0
  191. package/src/content/skills/semantic-model.md +229 -0
  192. package/src/content/skills/testing-validation.md +635 -0
  193. 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)