skills/xlsx/SKILL.md
Use when the task involves creating, editing, analyzing, or recalculating .xlsx, .xlsm, .csv, or .tsv files -- especially financial models, structured data exports, or formula-driven spreadsheets. NEVER for purely in-memory data analysis where no file output is needed.
npx skillsauth add sharkitect-solutions/sharkitect-claude-toolkit xlsxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| File | Purpose |
|------|---------|
| SKILL.md | Rules, standards, and workflow for all Excel operations |
| recalc.py | LibreOffice-based formula recalculation and error detection |
| LICENSE.txt | Complete license terms |
| Rule | Why It Exists | What Goes Wrong Without It | |------|--------------|---------------------------| | Use Excel formulas, never Python-calculated hardcodes | Spreadsheets must recalculate when inputs change | Model breaks on first scenario change; outputs become stale immediately | | Run recalc.py after every openpyxl write | openpyxl stores formulas as strings; values are not evaluated | File opens with stale cached values or #VALUE! errors; recipient sees wrong numbers | | Blue/black/green/red text color coding | IB standard lets any analyst instantly identify input vs. formula vs. link | Auditing is slow; formula cells get accidentally overwritten by users | | Zeros display as "-" not "0" | Financial convention; zero clutter harms readability of sparse models | Models look amateur; key non-zero cells are hard to find visually | | Assumptions in dedicated cells, never inline | Enables scenario analysis and sensitivity tables | Changing one assumption requires hunting through 50 formula strings | | Years formatted as text strings | Prevents Excel from treating column headers as numbers and summing them | Year headers appear as "2,024" or get auto-converted in unexpected ways | | Document all hardcoded values with source comments | Audit trail and reproducibility requirement | Nobody can validate the model or update it when data refreshes |
data_only=True and then save it -- this permanently destroys all formulas and replaces them with static values.Stop and verify if any of these are true before saving:
sheet['B10'] = total)Sheet1!A1, not A1 alone)data_only=True for reading and then saved -- formulas are now gone| Situation | Tool | Reason |
|-----------|------|--------|
| Data analysis, aggregation, statistics | pandas | Vectorized operations, fast, easy filtering |
| Formula writing, cell formatting, complex layouts | openpyxl | Full access to Excel object model |
| Recalculating formulas after openpyxl writes | recalc.py | openpyxl does not evaluate formulas |
| Reading calculated values from an existing file | openpyxl data_only=True | Returns cached values without re-evaluating |
Use pandas for reading and analyzing. Use openpyxl for writing anything that requires formulas or formatting. Never mix responsibilities: do not use pandas to write a financial model.
Every file must be delivered with zero formula errors. Run recalc.py and fix every error before delivery. The acceptable error count is 0.
When modifying an existing file: study its format, style, and conventions first. Match them exactly. Existing template conventions override all guidelines below. Never impose standardization on a file that already has patterns.
Apply these colors unless the existing file uses different conventions or the user specifies otherwise.
| Color | RGB | Meaning | |-------|-----|---------| | Blue text | 0, 0, 255 | Hardcoded inputs -- numbers users change for scenarios | | Black text | 0, 0, 0 | All formulas and calculations | | Green text | 0, 128, 0 | Cross-sheet links (same workbook, different sheet) | | Red text | 255, 0, 0 | External links to other files | | Yellow background | 255, 255, 0 | Key assumptions requiring attention or cells pending update |
In openpyxl, set font color via Font(color="0000FF") using hex. Blue = "0000FF", Black = "000000", Green = "008000", Red = "FF0000".
| Data Type | Format String | Notes |
|-----------|--------------|-------|
| Currency | $#,##0;($#,##0);- | Units in header: "Revenue ($mm)" |
| Percentage | 0.0% | One decimal default |
| Multiples | 0.0x | EV/EBITDA, P/E, etc. |
| Years | Text string | Write as "2024" not 2024 |
| Zeros | - via format | Include in all numeric formats |
| Negatives | Parentheses (123) | Never use minus sign in financial output |
The format string $#,##0;($#,##0);- handles all three cases: positive (currency), negative (parentheses), zero (dash).
Place every assumption -- growth rates, margins, discount rates, multiples, tax rates -- in a dedicated cell on an assumptions sheet or assumptions section. Reference it by cell address in every formula that uses it.
Wrong:
sheet['C5'] = '=B5*1.05' # Growth rate hardcoded in formula
Correct:
sheet['B2'] = 0.05 # Growth rate assumption cell (blue font)
sheet['C5'] = '=B5*(1+$B$2)' # Formula references assumption
This is the single biggest structural difference between a professional model and a static table.
Any cell containing a hardcoded value sourced from external data requires a comment:
Format: Source: [System/Document], [Date], [Specific Reference], [URL if applicable]
Examples:
Source: Company 10-K, FY2024, Page 45, Revenue Note, https://sec.gov/...Source: Bloomberg Terminal, 2025-08-15, AAPL US EquitySource: FactSet, 2025-08-20, Consensus Estimates ScreenThis is the most commonly violated rule. openpyxl writes whatever value you assign to a cell. If you compute a total in Python and assign the number, that number is frozen forever. Write formula strings instead.
Wrong pattern:
total = df['Sales'].sum()
sheet['B10'] = total # Frozen. Will not update if Sales changes.
Correct pattern:
sheet['B10'] = '=SUM(B2:B9)' # Recalculates automatically.
This applies to every calculation: sums, averages, growth rates, ratios, differences, percentages. If Excel has a function for it, use it.
openpyxl writes formula strings but does not evaluate them. The file contains correct formula text but stale or empty calculated values. recalc.py uses LibreOffice to open the file, recalculate all sheets, scan for errors, and return a JSON report.
Run after every openpyxl save that introduced formulas:
python recalc.py output.xlsx
python recalc.py output.xlsx 60 # Optional timeout in seconds
Interpreting the output:
{
"status": "success",
"total_errors": 0,
"total_formulas": 42,
"error_summary": {}
}
If status is "errors_found", error_summary lists error types with counts and cell addresses. Fix every error, save again, re-run recalc.py. Repeat until total_errors is 0.
Common errors and causes:
| Error | Typical Cause |
|-------|--------------|
| #REF! | Cell reference points to a deleted row/column or out-of-bounds range |
| #DIV/0! | Formula divides by a cell that contains zero or is empty |
| #VALUE! | Wrong data type in formula (e.g., text where number expected) |
| #NAME? | Misspelled function name or undefined named range |
recalc.py automatically configures the LibreOffice macro on first run. LibreOffice must be installed.
Run this before calling recalc.py to catch the most common mistakes early:
Sheet1!A1data_only=True reads cached calculated values (last saved by Excel or recalc.py)data_only=True permanently destroys formulas. Read-only means read-only.read_only=True for reading, write_only=True for fresh writes=dtype={'id': str}usecols=['A', 'C']parse_dates=['date_column'] handles date conversion automaticallyWrite minimal Python code for Excel operations. No unnecessary comments, no verbose variable names, no redundant print statements. The code runs; it does not narrate itself.
For Excel file content: add comments to cells with complex formulas or important assumptions. Document all hardcoded values with source references. Include section headers for model navigation.
development
When the user wants help with paid advertising campaigns on Google Ads, Meta (Facebook/Instagram), LinkedIn, Twitter/X, or other ad platforms. Also use when the user mentions 'PPC,' 'paid media,' 'ad copy,' 'ad creative,' 'ROAS,' 'CPA,' 'ad campaign,' 'retargeting,' or 'audience targeting.' This skill covers campaign strategy, ad creation, audience targeting, and optimization.
testing
--- name: using-sharkitect-methodology description: Use when starting any conversation in a Sharkitect workspace OR before any task involving NEW pricing, positioning, proposal, strategy, plan-execution, or schema-design work — mandates invocation of Sharkitect-specific methodology skills (pricing-strategy, marketing-strategy-pmm, smb-cfo, hq-revenue-ops, executing-plans, brainstorming) under the same anti-rationalization discipline as using-superpowers. Documentation has failed 4 times across H
testing
Use when user says 'end session', 'wrap up', 'stop for the day', 'done for today', 'close out', 'save session', 'wrapping up', or invokes /end-session. Runs the full 9-step end-of-session protocol: resource audit, MEMORY.md update, lessons capture, plan status, pending items, workspace checklist, .tmp/ audit, git commit+push, Supabase brain sync, session brief, summary. Final step schedules a detached self-kill of the current session ONLY (3s delay) so the window closes cleanly. Other claude.exe processes (active workspaces) are NOT touched -- orphan cleanup is handled separately by Claude-Orphan-Cleanup-Hourly with proper age safeguards. Do NOT use for: mid-session quick saves (use session-checkpoint), skill syncing (use sync-skills.py), brain memory queries (use supabase-sync.py pull), document freshness reviews (use document-lifecycle), resource gap detection (use resource-auditor).
testing
Remove signs of AI-generated writing from text. Use when editing or reviewing text to make it sound more natural and human-written. Based on Wikipedia's comprehensive "Signs of AI writing" guide. Detects and fixes patterns including: inflated symbolism, promotional language, superficial -ing analyses, vague attributions, em dash overuse, rule of three, AI vocabulary words, passive voice, negative parallelisms, and filler phrases.