Tableau Workbook Cleanup
Clean up Tableau workbooks (.twb/.twbx) by editing XML. Run validation, fix errors, repeat until clean.
Scratchpad
Use .cleanup/ directory. Track progress in .cleanup/status.json.
Scripts
| Script |
Purpose |
scripts/backup_workbook.py <input> |
Backup before editing |
scripts/extract_twbx.py <input.twbx> |
Unzip packaged workbook |
scripts/list_calculations.py <file.twb> |
List all calcs as JSON |
scripts/validate_cleanup.py <file.twb> |
Check all rules, output errors |
scripts/validate_xml.py <file.twb> |
Check XML validity |
scripts/repackage_twbx.py <dir> <output.twbx> |
Repackage to .twbx |
Safety Rules
- Backup first - Always run backup_workbook.py
- Never modify
name attributes - Only edit caption
- Escape XML:
& -> &, ' -> '
- Create
_cleaned copy - Don't overwrite original
What You CAN and CANNOT Edit
CAN EDIT (Safe)
| Element |
Attribute |
What to do |
<column> |
caption |
Change to Title Case, remove underscores, remove c_ prefix |
<calculation> |
formula |
ADD // comment at START (only if formula attribute already exists) |
<folders-common> |
(whole element) |
CREATE if missing, add folders |
<folder> |
name |
Use exact names from Folder Rules with HTML entity codes |
<folder-item> |
name, type |
Reference calculation names |
<layout> |
show-structure |
Set to 'true' |
CANNOT EDIT (Will Corrupt Workbook)
| Element |
What NOT to do |
Why |
<column> |
Change name attribute |
Breaks all references to this field |
<calculation class='categorical-bin'> |
Add formula attribute |
Bin/group calcs use XML structure, not formulas |
<calculation class='quantitative-bin'> |
Add formula attribute |
Same - bins don't have formulas |
Any <calculation> without formula |
Add formula attribute |
These are special calc types |
Formulas with |
Remove or change these |
These are valid XML-encoded newlines |
Formulas with & |
Change to &amp; |
Already properly encoded |
<column> |
Change datatype, role, type |
Breaks field behavior |
<datasource> |
Change name or structure |
Breaks data connections |
STOP Conditions
If you encounter these, STOP and report - do NOT try to fix:
- Validator says "newline not XML-encoded" but you see
in raw XML - Validator bug
- Validator says "unescaped &" but you see
& in raw XML - Validator bug
- Validator says "missing comment" on a calc with no
formula attribute - Can't add comment
- Any error on
categorical-bin or quantitative-bin calculations - Skip these
Example: What a Proper Edit Looks Like
BEFORE:
<column caption='c_total_sales' name='[Calculation_123]'>
<calculation formula='SUM([Sales])' />
</column>
AFTER:
<column caption='Total Sales' name='[Calculation_123]'>
<calculation formula='// Aggregates all sales for the selected period SUM([Sales])' />
</column>
NOTICE:
caption changed (safe)
formula has comment ADDED at start (safe)
name attribute UNCHANGED (critical!)
used for newline (correct XML encoding)
Reference Documents
Before starting, read these guides in the skill's resources/ folder:
resources/comment-guide.md - How to write meaningful comments (REQUIRED for M3)
resources/good-comments.md - 50+ real examples by category
resources/xml-folders-guide.md - How to create folders in XML
Workflow
- Backup workbook
- Extract if .twbx
- Run
validate_cleanup.py to see all errors
- Fix errors one category at a time
- Run validation again
- Repeat until 0 errors
- Repackage if .twbx
- Report changes
Caption Rules
- Title Case with spaces (no underscores)
- No
c_ prefix
- Preserve acronyms: ID, YTD, MTD, KPI, ROI, YOY, MOM, WOW, LOD
- No double parentheses
()()
Comment Rules
Add // comment explaining PURPOSE at start of formula:
formula='// Flags at-risk accounts for dashboard highlight [Score] < 50'
Use for newlines. Escape & as &.
Comment Quality Requirements (M3 Validation)
Comments MUST:
- Be 15+ characters of explanation
- Explain WHY (purpose), not just WHAT (formula description)
- NOT just restate the caption
Comments that FAIL M3:
// Calculated field - too generic
// Sum - too short (only 3 chars)
// Total Revenue (if caption is "Total Revenue") - restates caption
See resources/comment-guide.md for detailed guidance.
Batch Processing (Recommended)
Use scripts/batch_comments.py to process calculations 10 at a time:
python batch_comments.py workbook.twb init # Create batches
python batch_comments.py workbook.twb next # Show next 10 calcs
python batch_comments.py workbook.twb done 1 # Mark batch complete
python batch_comments.py workbook.twb status # Check progress
This ensures you READ each formula before commenting.
Folder Rules
Insert <folders-common> BEFORE <layout> with exactly 6 broad folders (use HTML entity codes):
<folders-common>
<folder name='📊 Metrics'>
<folder-item name='[Calculation_XXX]' type='field' />
</folder>
</folders-common>
6 Folders Only (use HTML entity codes to avoid encoding issues):
| Folder |
Entity Code |
Contains |
| Metrics |
📊 |
KPIs, totals, margins, revenue, percentages, averages, growth |
| Dates |
📅 |
Date calcs, periods, fiscal, YTD/MTD/QTD, year, month, quarter |
| Filters |
🚦 |
Booleans, flags, is_, has_, visibility, include/exclude, parameters |
| Display |
🎨 |
Labels, tooltips, formatting, colors, text, UI elements, rankings |
| Projections |
🔮 |
Forecasts, targets, goals, budgets, predictions, estimates |
| Security |
🔒 |
RLS, user-based filters, permissions, access control |
IMPORTANT: Use &#x entity format, NOT raw emoji characters (prevents encoding corruption).
Note: LOD calcs (FIXED/INCLUDE/EXCLUDE) go in the folder matching their PURPOSE, not technique.
Report
=== Tableau Cleanup Complete ===
Workbook: <name>
Errors fixed: X
Output: <path>_cleaned.twbx
1---2name: tableau-cleanup3description: Clean up Tableau workbooks by standardizing captions, adding comments, and organizing into folders.4---56# Tableau Workbook Cleanup78Clean up Tableau workbooks (.twb/.twbx) by editing XML. Run validation, fix errors, repeat until clean.910## Scratchpad1112Use `.cleanup/` directory. Track progress in `.cleanup/status.json`.1314## Scripts1516| Script | Purpose |17|--------|---------|18| `scripts/backup_workbook.py <input>` | Backup before editing |19| `scripts/extract_twbx.py <input.twbx>` | Unzip packaged workbook |20| `scripts/list_calculations.py <file.twb>` | List all calcs as JSON |21| `scripts/validate_cleanup.py <file.twb>` | **Check all rules, output errors** |22| `scripts/validate_xml.py <file.twb>` | Check XML validity |23| `scripts/repackage_twbx.py <dir> <output.twbx>` | Repackage to .twbx |2425## Safety Rules26271. **Backup first** - Always run backup_workbook.py282. **Never modify `name` attributes** - Only edit `caption`293. **Escape XML**: `&` -> `&`, `'` -> `'`304. **Create `_cleaned` copy** - Don't overwrite original3132## What You CAN and CANNOT Edit3334### CAN EDIT (Safe)3536| Element | Attribute | What to do |37|---------|-----------|------------|38| `<column>` | `caption` | Change to Title Case, remove underscores, remove c_ prefix |39| `<calculation>` | `formula` | ADD `// comment` at START (only if formula attribute already exists) |40| `<folders-common>` | (whole element) | CREATE if missing, add folders |41| `<folder>` | `name` | Use exact names from Folder Rules with HTML entity codes |42| `<folder-item>` | `name`, `type` | Reference calculation names |43| `<layout>` | `show-structure` | Set to `'true'` |4445### CANNOT EDIT (Will Corrupt Workbook)4647| Element | What NOT to do | Why |48|---------|----------------|-----|49| `<column>` | Change `name` attribute | Breaks all references to this field |50| `<calculation class='categorical-bin'>` | Add `formula` attribute | Bin/group calcs use XML structure, not formulas |51| `<calculation class='quantitative-bin'>` | Add `formula` attribute | Same - bins don't have formulas |52| Any `<calculation>` without `formula` | Add `formula` attribute | These are special calc types |53| Formulas with ` ` | Remove or change these | These are valid XML-encoded newlines |54| Formulas with `&` | Change to `&amp;` | Already properly encoded |55| `<column>` | Change `datatype`, `role`, `type` | Breaks field behavior |56| `<datasource>` | Change `name` or structure | Breaks data connections |5758### STOP Conditions5960If you encounter these, STOP and report - do NOT try to fix:611. Validator says "newline not XML-encoded" but you see ` ` in raw XML - Validator bug622. Validator says "unescaped &" but you see `&` in raw XML - Validator bug633. Validator says "missing comment" on a calc with no `formula` attribute - Can't add comment644. Any error on `categorical-bin` or `quantitative-bin` calculations - Skip these6566### Example: What a Proper Edit Looks Like6768**BEFORE:**69```xml70<column caption='c_total_sales' name='[Calculation_123]'>71 <calculation formula='SUM([Sales])' />72</column>73```7475**AFTER:**76```xml77<column caption='Total Sales' name='[Calculation_123]'>78 <calculation formula='// Aggregates all sales for the selected period SUM([Sales])' />79</column>80```8182**NOTICE:**83- `caption` changed (safe)84- `formula` has comment ADDED at start (safe)85- `name` attribute UNCHANGED (critical!)86- ` ` used for newline (correct XML encoding)8788## Reference Documents8990Before starting, read these guides in the skill's `resources/` folder:91- `resources/comment-guide.md` - How to write meaningful comments (REQUIRED for M3)92- `resources/good-comments.md` - 50+ real examples by category93- `resources/xml-folders-guide.md` - How to create folders in XML9495## Workflow96971. Backup workbook982. Extract if .twbx993. Run `validate_cleanup.py` to see all errors1004. Fix errors one category at a time1015. Run validation again1026. Repeat until 0 errors1037. Repackage if .twbx1048. Report changes105106## Caption Rules107108- Title Case with spaces (no underscores)109- No `c_` prefix110- Preserve acronyms: ID, YTD, MTD, KPI, ROI, YOY, MOM, WOW, LOD111- No double parentheses `()()`112113## Comment Rules114115Add `//` comment explaining PURPOSE at start of formula:116```xml117formula='// Flags at-risk accounts for dashboard highlight [Score] < 50'118```119120Use ` ` for newlines. Escape `&` as `&`.121122### Comment Quality Requirements (M3 Validation)123124Comments MUST:125- Be **15+ characters** of explanation126- Explain **WHY** (purpose), not just WHAT (formula description)127- NOT just restate the caption128129Comments that FAIL M3:130- `// Calculated field` - too generic131- `// Sum` - too short (only 3 chars)132- `// Total Revenue` (if caption is "Total Revenue") - restates caption133134See `resources/comment-guide.md` for detailed guidance.135136### Batch Processing (Recommended)137138Use `scripts/batch_comments.py` to process calculations 10 at a time:139140```bash141python batch_comments.py workbook.twb init # Create batches142python batch_comments.py workbook.twb next # Show next 10 calcs143python batch_comments.py workbook.twb done 1 # Mark batch complete144python batch_comments.py workbook.twb status # Check progress145```146147This ensures you READ each formula before commenting.148149## Folder Rules150151Insert `<folders-common>` BEFORE `<layout>` with exactly 6 broad folders (use HTML entity codes):152153```xml154<folders-common>155 <folder name='📊 Metrics'>156 <folder-item name='[Calculation_XXX]' type='field' />157 </folder>158</folders-common>159```160161**6 Folders Only** (use HTML entity codes to avoid encoding issues):162| Folder | Entity Code | Contains |163|--------|-------------|----------|164| Metrics | `📊` | KPIs, totals, margins, revenue, percentages, averages, growth |165| Dates | `📅` | Date calcs, periods, fiscal, YTD/MTD/QTD, year, month, quarter |166| Filters | `🚦` | Booleans, flags, is_, has_, visibility, include/exclude, parameters |167| Display | `🎨` | Labels, tooltips, formatting, colors, text, UI elements, rankings |168| Projections | `🔮` | Forecasts, targets, goals, budgets, predictions, estimates |169| Security | `🔒` | RLS, user-based filters, permissions, access control |170171**IMPORTANT:** Use `&#x` entity format, NOT raw emoji characters (prevents encoding corruption).172173**Note:** LOD calcs (FIXED/INCLUDE/EXCLUDE) go in the folder matching their PURPOSE, not technique.174175## Report176177```178=== Tableau Cleanup Complete ===179Workbook: <name>180Errors fixed: X181Output: <path>_cleaned.twbx182```