@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,363 @@
|
|
|
1
|
+
# Text Functions
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Excel patterns for text manipulation, extraction, parsing, and formatting.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Text Extraction
|
|
9
|
+
|
|
10
|
+
### LEFT, RIGHT, MID
|
|
11
|
+
```excel
|
|
12
|
+
// First N characters
|
|
13
|
+
=LEFT(A1, 5) // First 5 characters
|
|
14
|
+
|
|
15
|
+
// Last N characters
|
|
16
|
+
=RIGHT(A1, 3) // Last 3 characters
|
|
17
|
+
|
|
18
|
+
// Characters from middle
|
|
19
|
+
=MID(A1, 3, 4) // 4 characters starting at position 3
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Extract with FIND/SEARCH
|
|
23
|
+
```excel
|
|
24
|
+
// Text before delimiter
|
|
25
|
+
=LEFT(A1, FIND("-", A1) - 1)
|
|
26
|
+
|
|
27
|
+
// Text after delimiter
|
|
28
|
+
=MID(A1, FIND("-", A1) + 1, 100)
|
|
29
|
+
|
|
30
|
+
// Between two delimiters
|
|
31
|
+
=MID(A1, FIND("[", A1) + 1, FIND("]", A1) - FIND("[", A1) - 1)
|
|
32
|
+
|
|
33
|
+
// Second word (after first space)
|
|
34
|
+
=MID(A1, FIND(" ", A1) + 1, FIND(" ", A1, FIND(" ", A1) + 1) - FIND(" ", A1) - 1)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### FIND vs SEARCH
|
|
38
|
+
```excel
|
|
39
|
+
// FIND is case-sensitive
|
|
40
|
+
=FIND("A", "Apple") // Returns 1
|
|
41
|
+
=FIND("a", "Apple") // Returns #VALUE! (not found)
|
|
42
|
+
|
|
43
|
+
// SEARCH is case-insensitive and supports wildcards
|
|
44
|
+
=SEARCH("a", "Apple") // Returns 1
|
|
45
|
+
=SEARCH("a*e", "Apple") // Returns 1 (wildcard)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## TEXTSPLIT (Excel 365)
|
|
51
|
+
|
|
52
|
+
### Basic Splitting
|
|
53
|
+
```excel
|
|
54
|
+
// Split by delimiter (horizontal)
|
|
55
|
+
=TEXTSPLIT("A,B,C", ",") // {A, B, C}
|
|
56
|
+
|
|
57
|
+
// Split by delimiter (vertical)
|
|
58
|
+
=TEXTSPLIT("A,B,C", , ",") // Column: A, B, C
|
|
59
|
+
|
|
60
|
+
// Split by multiple delimiters
|
|
61
|
+
=TEXTSPLIT(A1, {",", ";", " "}) // Any of these delimiters
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Two-Dimensional Split
|
|
65
|
+
```excel
|
|
66
|
+
// Split rows and columns
|
|
67
|
+
=TEXTSPLIT("A,B;C,D", ",", ";")
|
|
68
|
+
// Result:
|
|
69
|
+
// | A | B |
|
|
70
|
+
// | C | D |
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Handling Empty Values
|
|
74
|
+
```excel
|
|
75
|
+
// Ignore consecutive delimiters
|
|
76
|
+
=TEXTSPLIT("A,,B,C", ",", , TRUE) // {A, B, C}
|
|
77
|
+
|
|
78
|
+
// Keep empty values (default)
|
|
79
|
+
=TEXTSPLIT("A,,B,C", ",") // {A, "", B, C}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Extract Nth Element
|
|
83
|
+
```excel
|
|
84
|
+
// Get 2nd element from comma-separated
|
|
85
|
+
=INDEX(TEXTSPLIT(A1, ","), 2)
|
|
86
|
+
|
|
87
|
+
// Get last element
|
|
88
|
+
=INDEX(TEXTSPLIT(A1, ","), COUNTA(TEXTSPLIT(A1, ",")))
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## TEXTJOIN
|
|
94
|
+
|
|
95
|
+
### Basic Joining
|
|
96
|
+
```excel
|
|
97
|
+
// Join with delimiter
|
|
98
|
+
=TEXTJOIN(", ", TRUE, A1:A5) // "A, B, C, D, E"
|
|
99
|
+
|
|
100
|
+
// TRUE = ignore empty cells
|
|
101
|
+
=TEXTJOIN(", ", FALSE, A1:A5) // Includes empty values
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Join Array Results
|
|
105
|
+
```excel
|
|
106
|
+
// Join unique values
|
|
107
|
+
=TEXTJOIN(", ", TRUE, UNIQUE(A1:A10))
|
|
108
|
+
|
|
109
|
+
// Join filtered values
|
|
110
|
+
=TEXTJOIN(", ", TRUE, FILTER(A1:A10, B1:B10="Active"))
|
|
111
|
+
|
|
112
|
+
// Join with condition
|
|
113
|
+
=TEXTJOIN(", ", TRUE, IF(B1:B10="Active", A1:A10, ""))
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## CONCAT / CONCATENATE
|
|
119
|
+
|
|
120
|
+
### CONCAT (Modern)
|
|
121
|
+
```excel
|
|
122
|
+
// Concatenate range
|
|
123
|
+
=CONCAT(A1:A5) // "ABCDE" (no delimiter)
|
|
124
|
+
|
|
125
|
+
// With text
|
|
126
|
+
=CONCAT("Hello ", A1, "!") // "Hello John!"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### & Operator
|
|
130
|
+
```excel
|
|
131
|
+
// Simple concatenation
|
|
132
|
+
=A1 & " " & B1 // "John Smith"
|
|
133
|
+
|
|
134
|
+
// With formatting
|
|
135
|
+
="Total: " & TEXT(A1, "$#,##0") // "Total: $1,234"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Text Cleaning
|
|
141
|
+
|
|
142
|
+
### TRIM, CLEAN
|
|
143
|
+
```excel
|
|
144
|
+
// Remove extra spaces
|
|
145
|
+
=TRIM(A1) // " hello world " → "hello world"
|
|
146
|
+
|
|
147
|
+
// Remove non-printable characters
|
|
148
|
+
=CLEAN(A1) // Removes CHAR(0) to CHAR(31)
|
|
149
|
+
|
|
150
|
+
// Combined cleaning
|
|
151
|
+
=TRIM(CLEAN(A1))
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Remove Specific Characters
|
|
155
|
+
```excel
|
|
156
|
+
// Remove dashes
|
|
157
|
+
=SUBSTITUTE(A1, "-", "")
|
|
158
|
+
|
|
159
|
+
// Remove multiple characters
|
|
160
|
+
=SUBSTITUTE(SUBSTITUTE(A1, "-", ""), " ", "")
|
|
161
|
+
|
|
162
|
+
// Remove all non-numeric
|
|
163
|
+
=TEXTJOIN("", TRUE, IF(ISNUMBER(MID(A1, SEQUENCE(LEN(A1)), 1)+0),
|
|
164
|
+
MID(A1, SEQUENCE(LEN(A1)), 1), ""))
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### SUBSTITUTE
|
|
168
|
+
```excel
|
|
169
|
+
// Replace text
|
|
170
|
+
=SUBSTITUTE(A1, "old", "new")
|
|
171
|
+
|
|
172
|
+
// Replace specific instance (3rd parameter)
|
|
173
|
+
=SUBSTITUTE(A1, "-", "/", 1) // Replace only first dash
|
|
174
|
+
|
|
175
|
+
// Replace multiple
|
|
176
|
+
=SUBSTITUTE(SUBSTITUTE(A1, "a", "x"), "b", "y")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## Case Conversion
|
|
182
|
+
|
|
183
|
+
### Basic Functions
|
|
184
|
+
```excel
|
|
185
|
+
=UPPER(A1) // HELLO WORLD
|
|
186
|
+
=LOWER(A1) // hello world
|
|
187
|
+
=PROPER(A1) // Hello World
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Custom Case
|
|
191
|
+
```excel
|
|
192
|
+
// Sentence case (first letter only)
|
|
193
|
+
=UPPER(LEFT(A1, 1)) & LOWER(MID(A1, 2, 100))
|
|
194
|
+
|
|
195
|
+
// All caps except articles (manual approach)
|
|
196
|
+
=SUBSTITUTE(SUBSTITUTE(PROPER(A1), " Of ", " of "), " The ", " the ")
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Text Validation
|
|
202
|
+
|
|
203
|
+
### Check Content
|
|
204
|
+
```excel
|
|
205
|
+
// Contains specific text
|
|
206
|
+
=ISNUMBER(SEARCH("keyword", A1)) // TRUE/FALSE
|
|
207
|
+
|
|
208
|
+
// Starts with
|
|
209
|
+
=LEFT(A1, 3) = "ABC"
|
|
210
|
+
|
|
211
|
+
// Ends with
|
|
212
|
+
=RIGHT(A1, 4) = ".com"
|
|
213
|
+
|
|
214
|
+
// Is numeric text
|
|
215
|
+
=ISNUMBER(A1 * 1) // Can be multiplied
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Length Validation
|
|
219
|
+
```excel
|
|
220
|
+
=LEN(A1) // Character count
|
|
221
|
+
|
|
222
|
+
// Check length
|
|
223
|
+
=LEN(A1) = 10 // Exactly 10 characters
|
|
224
|
+
=LEN(A1) >= 5 // At least 5 characters
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Pattern Matching
|
|
228
|
+
```excel
|
|
229
|
+
// Email validation (basic)
|
|
230
|
+
=AND(
|
|
231
|
+
ISNUMBER(SEARCH("@", A1)),
|
|
232
|
+
ISNUMBER(SEARCH(".", A1, SEARCH("@", A1))),
|
|
233
|
+
LEN(A1) - LEN(SUBSTITUTE(A1, "@", "")) = 1
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
// Phone format (XXX-XXX-XXXX)
|
|
237
|
+
=AND(
|
|
238
|
+
LEN(A1) = 12,
|
|
239
|
+
MID(A1, 4, 1) = "-",
|
|
240
|
+
MID(A1, 8, 1) = "-"
|
|
241
|
+
)
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Padding and Formatting
|
|
247
|
+
|
|
248
|
+
### Add Leading Zeros
|
|
249
|
+
```excel
|
|
250
|
+
=TEXT(A1, "00000") // 123 → "00123"
|
|
251
|
+
|
|
252
|
+
// Dynamic padding
|
|
253
|
+
=REPT("0", 5 - LEN(A1)) & A1 // Pad to 5 characters
|
|
254
|
+
|
|
255
|
+
// Using RIGHT
|
|
256
|
+
=RIGHT("00000" & A1, 5) // Pad to 5 characters
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### REPT - Repeat Characters
|
|
260
|
+
```excel
|
|
261
|
+
=REPT("*", 5) // "*****"
|
|
262
|
+
|
|
263
|
+
// Simple bar chart
|
|
264
|
+
=REPT("█", A1/10) // Visual bar based on value
|
|
265
|
+
|
|
266
|
+
// Padding right
|
|
267
|
+
=A1 & REPT(" ", 20 - LEN(A1)) // Right-pad to 20 chars
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Advanced Patterns
|
|
273
|
+
|
|
274
|
+
### Extract Email Domain
|
|
275
|
+
```excel
|
|
276
|
+
=MID(A1, SEARCH("@", A1) + 1, 100)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Extract First/Last Name
|
|
280
|
+
```excel
|
|
281
|
+
// First name (before space)
|
|
282
|
+
=LEFT(A1, SEARCH(" ", A1) - 1)
|
|
283
|
+
|
|
284
|
+
// Last name (after last space)
|
|
285
|
+
=RIGHT(A1, LEN(A1) - SEARCH("~", SUBSTITUTE(A1, " ", "~", LEN(A1) - LEN(SUBSTITUTE(A1, " ", "")))))
|
|
286
|
+
|
|
287
|
+
// Or with TEXTSPLIT (365)
|
|
288
|
+
=INDEX(TEXTSPLIT(A1, " "), 1) // First name
|
|
289
|
+
=INDEX(TEXTSPLIT(A1, " "), -1) // Last name (negative index)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Parse Name with Suffix
|
|
293
|
+
```excel
|
|
294
|
+
// "Smith, John Jr." → Last, First, Suffix
|
|
295
|
+
=LET(
|
|
296
|
+
full, A1,
|
|
297
|
+
parts, TEXTSPLIT(full, ", "),
|
|
298
|
+
last, INDEX(parts, 1),
|
|
299
|
+
firstParts, TEXTSPLIT(INDEX(parts, 2), " "),
|
|
300
|
+
first, INDEX(firstParts, 1),
|
|
301
|
+
suffix, IF(COLUMNS(firstParts) > 1, INDEX(firstParts, 2), ""),
|
|
302
|
+
HSTACK(last, first, suffix)
|
|
303
|
+
)
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Remove HTML Tags
|
|
307
|
+
```excel
|
|
308
|
+
// Basic tag removal (won't handle all cases)
|
|
309
|
+
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,
|
|
310
|
+
"<"&MID(A1, SEARCH("<", A1)+1, SEARCH(">", A1)-SEARCH("<", A1)-1)&">", ""),
|
|
311
|
+
"</"&MID(A1, SEARCH("</", A1)+2, SEARCH(">", A1, SEARCH("</", A1))-SEARCH("</", A1)-2)&">", ""),
|
|
312
|
+
" ", " ")
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## Character Functions
|
|
318
|
+
|
|
319
|
+
### CHAR / UNICODE
|
|
320
|
+
```excel
|
|
321
|
+
=CHAR(65) // "A"
|
|
322
|
+
=CHAR(10) // Line break
|
|
323
|
+
=CHAR(9) // Tab
|
|
324
|
+
|
|
325
|
+
=UNICODE("A") // 65
|
|
326
|
+
=UNICODE("€") // 8364
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Line Breaks in Text
|
|
330
|
+
```excel
|
|
331
|
+
// Insert line break
|
|
332
|
+
=A1 & CHAR(10) & B1
|
|
333
|
+
|
|
334
|
+
// Remove line breaks
|
|
335
|
+
=SUBSTITUTE(A1, CHAR(10), " ")
|
|
336
|
+
=SUBSTITUTE(SUBSTITUTE(A1, CHAR(10), " "), CHAR(13), " ")
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Quick Reference
|
|
342
|
+
|
|
343
|
+
| Function | Purpose |
|
|
344
|
+
|----------|---------|
|
|
345
|
+
| LEFT/RIGHT/MID | Extract characters |
|
|
346
|
+
| TEXTSPLIT | Split by delimiter (365) |
|
|
347
|
+
| TEXTJOIN | Join with delimiter |
|
|
348
|
+
| FIND/SEARCH | Find position |
|
|
349
|
+
| SUBSTITUTE | Replace text |
|
|
350
|
+
| TRIM/CLEAN | Remove spaces/non-printable |
|
|
351
|
+
| UPPER/LOWER/PROPER | Change case |
|
|
352
|
+
| LEN | Character count |
|
|
353
|
+
| REPT | Repeat text |
|
|
354
|
+
| TEXT | Format as text |
|
|
355
|
+
| CHAR/UNICODE | Character codes |
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Related Resources
|
|
360
|
+
|
|
361
|
+
- [Dynamic Arrays](./dynamic-arrays.md)
|
|
362
|
+
- [Lookups](./lookups.md)
|
|
363
|
+
- [Excel Formulas Skill](../../skills/excel-formulas/SKILL.md)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Naming Conventions for BI Projects
|
|
2
|
+
|
|
3
|
+
Consistent naming across models, reports, and workspaces.
|
|
4
|
+
|
|
5
|
+
## Tables
|
|
6
|
+
|
|
7
|
+
| Type | Convention | Example |
|
|
8
|
+
|------|-----------|---------|
|
|
9
|
+
| Dimension | Singular, PascalCase | `Customer`, `Product`, `Date` |
|
|
10
|
+
| Fact | Singular with Fact prefix (optional) | `Sales`, `FactSales` |
|
|
11
|
+
| Bridge | Bridge prefix | `BridgeCustomerProduct` |
|
|
12
|
+
| Security | Dim prefix + Security | `DimUserSecurity` |
|
|
13
|
+
| Calculated | Calc prefix | `CalcDateTable` |
|
|
14
|
+
| Staging (hidden) | _ prefix | `_StagingRawData` |
|
|
15
|
+
|
|
16
|
+
## Columns
|
|
17
|
+
|
|
18
|
+
| Type | Convention | Example |
|
|
19
|
+
|------|-----------|---------|
|
|
20
|
+
| Key (PK/FK) | TableNameKey | `CustomerKey`, `ProductKey` |
|
|
21
|
+
| Name/Label | Descriptive PascalCase | `CustomerName`, `ProductCategory` |
|
|
22
|
+
| Date | Suffix with Date | `OrderDate`, `ShipDate` |
|
|
23
|
+
| Flag/Boolean | Is/Has prefix | `IsActive`, `HasDiscount` |
|
|
24
|
+
| Amount | Descriptive | `UnitPrice`, `Quantity` |
|
|
25
|
+
| Code | Suffix with Code/ID | `RegionCode`, `EmployeeID` |
|
|
26
|
+
|
|
27
|
+
## Measures
|
|
28
|
+
|
|
29
|
+
| Type | Convention | Example |
|
|
30
|
+
|------|-----------|---------|
|
|
31
|
+
| Base aggregate | Action verb | `TotalSales`, `CountOrders` |
|
|
32
|
+
| Ratio/Percentage | Descriptive with % | `MarginPct`, `GrowthPct` |
|
|
33
|
+
| Time intelligence | Suffix with period | `SalesYTD`, `SalesPY`, `SalesMAT` |
|
|
34
|
+
| Variance | Suffix Var or Diff | `SalesVsPlanVar`, `SalesYoYDiff` |
|
|
35
|
+
| Ranking | Rank prefix | `RankByRevenue` |
|
|
36
|
+
| Debug/Temp | _ prefix (hidden) | `_DebugCurrentUser` |
|
|
37
|
+
|
|
38
|
+
### Measure Display Folders
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
Measures/
|
|
42
|
+
├── Sales/
|
|
43
|
+
│ ├── TotalSales
|
|
44
|
+
│ ├── SalesYTD
|
|
45
|
+
│ └── SalesVsPlanVar
|
|
46
|
+
├── Costs/
|
|
47
|
+
│ ├── TotalCost
|
|
48
|
+
│ └── CostPerUnit
|
|
49
|
+
├── Profitability/
|
|
50
|
+
│ ├── GrossMargin
|
|
51
|
+
│ └── MarginPct
|
|
52
|
+
└── _Debug/ ← Hidden folder
|
|
53
|
+
├── _DebugUser
|
|
54
|
+
└── _DebugFilter
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Variables (DAX)
|
|
58
|
+
|
|
59
|
+
```dax
|
|
60
|
+
// Prefix with underscore — signals local scope
|
|
61
|
+
VAR _CurrentSales = [TotalSales]
|
|
62
|
+
VAR _PriorSales = CALCULATE([TotalSales], SAMEPERIODLASTYEAR('Date'[Date]))
|
|
63
|
+
VAR _Result = DIVIDE(_CurrentSales - _PriorSales, _PriorSales)
|
|
64
|
+
RETURN _Result
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Power Query Steps
|
|
68
|
+
|
|
69
|
+
| Convention | Example |
|
|
70
|
+
|-----------|---------|
|
|
71
|
+
| PascalCase, descriptive | `RemovedDuplicates` |
|
|
72
|
+
| Start with verb | `FilteredActiveRows` |
|
|
73
|
+
| Group related steps | `Merged_CustomerLookup` |
|
|
74
|
+
| Custom functions | `fn_` prefix | `fn_CleanText` |
|
|
75
|
+
|
|
76
|
+
## Workspaces
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
CompanyName - DEV ← Development
|
|
80
|
+
CompanyName - TEST ← Testing/UAT
|
|
81
|
+
CompanyName - PROD ← Production
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## File Naming (PBIP)
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
project-name/
|
|
88
|
+
├── project-name.pbip
|
|
89
|
+
├── project-name.Dataset/
|
|
90
|
+
│ ├── definition/
|
|
91
|
+
│ │ ├── tables/*.tmdl
|
|
92
|
+
│ │ └── relationships.tmdl
|
|
93
|
+
│ └── model.bim
|
|
94
|
+
└── project-name.Report/
|
|
95
|
+
└── definition/
|
|
96
|
+
└── pages/
|
|
97
|
+
```
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# BI Review Checklists
|
|
2
|
+
|
|
3
|
+
Structured review processes for models, reports, and deployments.
|
|
4
|
+
|
|
5
|
+
## Pre-Deployment Checklist
|
|
6
|
+
|
|
7
|
+
### Data Model
|
|
8
|
+
- [ ] All tables follow naming conventions
|
|
9
|
+
- [ ] No unused tables or columns (hidden or removed)
|
|
10
|
+
- [ ] All relationships are correct direction and cardinality
|
|
11
|
+
- [ ] Date table is marked as date table
|
|
12
|
+
- [ ] No circular dependencies
|
|
13
|
+
- [ ] Descriptions on all visible tables and measures
|
|
14
|
+
- [ ] Display folders organized logically
|
|
15
|
+
|
|
16
|
+
### Measures
|
|
17
|
+
- [ ] All measures use `DIVIDE()` instead of `/`
|
|
18
|
+
- [ ] `VAR/RETURN` pattern for complex measures
|
|
19
|
+
- [ ] No implicit measures (all explicit)
|
|
20
|
+
- [ ] Time intelligence uses proper date table
|
|
21
|
+
- [ ] Format strings set correctly (currency, %, #)
|
|
22
|
+
- [ ] Debug measures removed or hidden
|
|
23
|
+
|
|
24
|
+
### Security
|
|
25
|
+
- [ ] RLS roles defined and tested
|
|
26
|
+
- [ ] Security table populated
|
|
27
|
+
- [ ] Admin override role exists
|
|
28
|
+
- [ ] Tested with "View as" for each role
|
|
29
|
+
- [ ] No bi-directional relationships on security tables
|
|
30
|
+
|
|
31
|
+
### Performance
|
|
32
|
+
- [ ] DAX Studio scan shows no slow measures (>3s)
|
|
33
|
+
- [ ] No calculated columns that should be measures
|
|
34
|
+
- [ ] Query folding enabled where possible
|
|
35
|
+
- [ ] Aggregation tables for large datasets
|
|
36
|
+
- [ ] Cardinality checked on all columns
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Code Review Checklist (DAX)
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
For each measure, verify:
|
|
44
|
+
1. ☐ Name follows convention (PascalCase, descriptive)
|
|
45
|
+
2. ☐ Uses VAR/RETURN for multi-step logic
|
|
46
|
+
3. ☐ DIVIDE() for all division operations
|
|
47
|
+
4. ☐ No FILTER(table, ...) where CALCULATETABLE works
|
|
48
|
+
5. ☐ Context transition is intentional (not accidental)
|
|
49
|
+
6. ☐ Error handling for edge cases (blank, zero)
|
|
50
|
+
7. ☐ Format string specified
|
|
51
|
+
8. ☐ Description/documentation included
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Code Review Checklist (Power Query)
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
For each query, verify:
|
|
60
|
+
1. ☐ Steps have meaningful names
|
|
61
|
+
2. ☐ Query folding not broken unnecessarily
|
|
62
|
+
3. ☐ Error handling with try/otherwise
|
|
63
|
+
4. ☐ Column types explicitly set
|
|
64
|
+
5. ☐ No hardcoded values (use parameters)
|
|
65
|
+
6. ☐ Staging queries set to not load
|
|
66
|
+
7. ☐ Source connection is parameterized
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Report Review Checklist
|
|
72
|
+
|
|
73
|
+
### Visual Design
|
|
74
|
+
- [ ] Consistent color palette (theme applied)
|
|
75
|
+
- [ ] All visuals aligned to grid
|
|
76
|
+
- [ ] Font sizes meet minimum (10pt body, 14pt title)
|
|
77
|
+
- [ ] Alt text on every visual
|
|
78
|
+
- [ ] No overlapping visuals
|
|
79
|
+
- [ ] Consistent spacing between elements
|
|
80
|
+
|
|
81
|
+
### Functionality
|
|
82
|
+
- [ ] All slicers work correctly
|
|
83
|
+
- [ ] Cross-filtering behaves as expected
|
|
84
|
+
- [ ] Drill-through pages have back buttons
|
|
85
|
+
- [ ] Bookmarks/buttons navigate correctly
|
|
86
|
+
- [ ] Tooltips provide useful context
|
|
87
|
+
- [ ] Mobile layout configured (if required)
|
|
88
|
+
|
|
89
|
+
### Data Accuracy
|
|
90
|
+
- [ ] Totals match source system
|
|
91
|
+
- [ ] Filters don't hide relevant data
|
|
92
|
+
- [ ] Date ranges are correct
|
|
93
|
+
- [ ] Currency/number formatting consistent
|
|
94
|
+
- [ ] Edge cases handled (no data, single value)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Post-Deployment Checklist
|
|
99
|
+
|
|
100
|
+
- [ ] Report loads in < 10 seconds
|
|
101
|
+
- [ ] Scheduled refresh configured and tested
|
|
102
|
+
- [ ] Users added to correct RLS roles
|
|
103
|
+
- [ ] Workspace permissions set correctly
|
|
104
|
+
- [ ] Sensitivity labels applied (if required)
|
|
105
|
+
- [ ] Row-level security validated in Service
|
|
106
|
+
- [ ] Stakeholder sign-off obtained
|
|
107
|
+
- [ ] Documentation updated
|