Financial Spreadsheet Operations
description: Two capabilities in one skill — audit spreadsheets for formula accuracy and model integrity, and clean messy data for analysis. Covers formula-level checks (errors, hardcodes, inconsistencies), full financial model audits (BS balance, cash tie-out, logic sanity), and data cleanup (whitespace, casing, duplicates, type coercion, date normalization). Triggers on "audit this sheet", "check my formulas", "find formula errors", "QA this spreadsheet", "model check", "model won't balance", "clean this data", "normalize this data", "fix formatting", "dedupe", "this data is messy".
Environment
- Standalone .xlsx file: Use Python/openpyxl. Read cell values and formulas programmatically.
- If asked to generate a cleaned/audited copy: Write to a new file, never overwrite the original without explicit permission.
No paid MCP dependencies. All operations use openpyxl or pandas — nothing that requires a subscription or external API.
Part A: Spreadsheet Audit
Audit formulas and data for accuracy and mistakes. Scope determines depth.
Step 1: Determine Scope
If the user already gave a scope, use it. Otherwise ask:
What scope do you want me to audit?
- selection — just a specific range (e.g.
A1:F200)
- sheet — one sheet only
- model — the whole workbook, including financial-model integrity checks (BS balance, cash tie-out, roll-forwards, logic sanity)
The model scope is the deepest — use it for DCF, LBO, 3-statement, merger, comps, or any integrated financial model.
Step 2: Formula-Level Checks (ALL scopes)
| Check |
What to look for |
| Formula errors |
#REF!, #VALUE!, #N/A, #DIV/0!, #NAME? |
| Hardcodes inside formulas |
=A1*1.05 — the 1.05 should be a cell reference |
| Inconsistent formulas |
A formula that breaks the pattern of its neighbors in a row/column |
| Off-by-one ranges |
SUM/AVERAGE that misses the first or last row |
| Pasted-over formulas |
Cell that looks like a formula but is actually a hardcoded value |
| Circular references |
Intentional or accidental |
| Broken cross-sheet links |
References to cells that moved or were deleted |
| Unit/scale mismatches |
Thousands mixed with millions, % stored as whole numbers |
| Hidden rows/tabs |
Could contain overrides or stale calculations |
Step 3: Model-Integrity Checks (MODEL scope only)
If scope is model, identify the model type (DCF / LBO / 3-statement / merger / comps / custom) and run the appropriate integrity checks.
3a. Structural Review
| Check |
What to look for |
| Input/formula separation |
Are inputs clearly separated from calculations? |
| Color convention |
Blue=input, black=formula, green=link — or whatever the model uses, applied consistently? |
| Tab flow |
Logical order (Assumptions → IS → BS → CF → Valuation)? |
| Date headers |
Consistent across all tabs? |
| Units |
Consistent (thousands vs millions vs actuals)? |
3b. Balance Sheet
| Check |
Test |
| BS balances |
Total Assets = Total Liabilities + Equity (every period) |
| RE rollforward |
Prior RE + Net Income − Dividends = Current RE |
| Goodwill/intangibles |
Flow from acquisition assumptions (if M&A) |
If BS doesn't balance, quantify the gap per period and trace where it breaks — nothing else matters until this is fixed.
3c. Cash Flow Statement
| Check |
Test |
| Cash tie-out |
CF Ending Cash = BS Cash (every period) |
| CF sums |
CFO + CFI + CFF = Δ Cash |
| D&A match |
D&A on CF = D&A on IS |
| CapEx match |
CapEx on CF matches PP&E rollforward on BS |
| WC changes |
Signs match BS movements (ΔAR, ΔAP, ΔInventory) |
3d. Income Statement
| Check |
Test |
| Revenue build |
Ties to segment/product detail |
| Tax |
Tax expense = Pre-tax income × tax rate (allow for deferred tax adj) |
| Share count |
Ties to dilution schedule (options, converts, buybacks) |
3e. Circular References
- Interest → debt balance → cash → interest is a common intentional circ in LBO/3-stmt models
- If intentional: verify iteration toggle exists and works
- If unintentional: trace the loop and flag how to break it
3f. Logic & Reasonableness
| Check |
Flag if |
| Growth rates |
>100% revenue growth without explanation |
| Margins |
Outside industry norms |
| Terminal value dominance |
TV > ~75% of DCF EV (yellow flag) |
| Hockey-stick |
Projections ramp unrealistically in out-years |
| Compounding |
EBITDA compounds to absurd $ by Year 10 |
| Edge cases |
Model breaks at 0% or negative growth, negative EBITDA, leverage goes negative |
3g. Model-Type-Specific Bugs
DCF:
- Discount rate applied to wrong period (mid-year vs end-of-year)
- Terminal value not discounted back
- WACC uses book values instead of market values
- FCF includes interest expense (should be unlevered)
- Tax shield double-counted
LBO:
- Debt paydown doesn't match cash sweep mechanics
- PIK interest not accruing to principal
- Exit multiple applied to wrong EBITDA (LTM vs NTM)
- Fees/expenses not deducted from Day 1 equity
Merger:
- Accretion/dilution uses wrong share count (pre- vs post-deal)
- Synergies not phased in
- Purchase price allocation doesn't balance
- Transaction fees not in sources & uses
3-Statement:
- Working capital changes have wrong sign
- Depreciation doesn't match PP&E schedule
- Debt maturity schedule doesn't match principal payments
- Dividends exceed net income without explanation
Step 4: Audit Report
Output a findings table:
| # |
Sheet |
Cell/Range |
Severity |
Category |
Issue |
Suggested Fix |
Severity:
- Critical — wrong output (BS doesn't balance, formula broken, cash doesn't tie)
- Warning — risky (hardcodes, inconsistent formulas, edge-case failures)
- Info — style/best-practice (color coding, layout, naming)
For model scope, prepend a summary line:
Model type: [DCF/LBO/3-stmt/...] — Overall: [Clean / Minor Issues / Major Issues] — [N] critical, [N] warnings, [N] info
Don't change anything without asking — report first, fix on request.
Part B: Data Cleanup
Clean messy data in a sheet or specified range.
Step 1: Scope
- If a range is given (e.g.
A1:F200), use it
- Otherwise use the full used range of the active sheet
- Profile each column: detect its dominant type (text / number / date) and identify outliers
Step 2: Detect Issues
| Issue |
What to look for |
| Whitespace |
leading/trailing spaces, double spaces |
| Casing |
inconsistent casing in categorical columns (aus / AUS / Aus) |
| Number-as-text |
numeric values stored as text; stray $, ,, % in number cells |
| Dates |
mixed formats in the same column (3/8/26, 2026-03-08, March 8 2026) |
| Duplicates |
exact-duplicate rows and near-duplicates (case/whitespace differences) |
| Blanks |
empty cells in otherwise-populated columns |
| Mixed types |
a column that's 98% numbers but has 3 text entries |
| Encoding |
mojibake (é, ’), non-printing characters |
| Errors |
#REF!, #N/A, #VALUE!, #DIV/0! |
Step 3: Propose Fixes
Show a summary table before changing anything:
| Column |
Issue |
Count |
Proposed Fix |
Step 4: Apply
- Prefer formulas over hardcoded cleaned values — where the cleaned output can be expressed as a formula (e.g.
=TRIM(A2), =VALUE(SUBSTITUTE(B2,"$","")), =UPPER(C2), =DATEVALUE(D2)), write the formula in an adjacent helper column rather than computing the result in Python and overwriting the original. This keeps the transformation transparent and auditable.
- Only overwrite in place with computed values when the user explicitly asks for it, or when no sensible formula equivalent exists (e.g. encoding/mojibake repair)
- For destructive operations (removing duplicates, filling blanks, overwriting originals), confirm with the user first
- After each category of fix (whitespace → casing → number conversion → dates → dedup), show the user a sample of what changed and get confirmation before moving to the next category
- Report a before/after summary of what changed
AU-Specific Data Patterns
When working with Australian financial data, watch for:
| Pattern |
Example |
Note |
| ABN format |
51 824 753 556 |
11 digits, often stored inconsistently |
| GST amounts |
$1,100.00 inc GST |
Text in number columns |
| Date format |
DD/MM/YYYY |
Australia uses day-first — don't assume US MM/DD/YYYY |
| BSB/Account |
062-000 12345678 |
Banking identifiers in payment data |
| Super fund USI |
STA0100AU |
Unique Superannuation Identifier |
Notes
- BS balance first — if it doesn't balance, everything downstream is suspect
- Hardcoded overrides are the #1 source of silent bugs — search aggressively
- Sign convention errors (positive vs negative for cash outflows) are extremely common
- If the model uses VBA macros, note any macro-driven calculations that can't be audited from formulas alone
- Always create a backup before applying any data cleanup changes
1---2name: financial-ops3description: Financial Spreadsheet Operations4---5# Financial Spreadsheet Operations67description: Two capabilities in one skill — audit spreadsheets for formula accuracy and model integrity, and clean messy data for analysis. Covers formula-level checks (errors, hardcodes, inconsistencies), full financial model audits (BS balance, cash tie-out, logic sanity), and data cleanup (whitespace, casing, duplicates, type coercion, date normalization). Triggers on "audit this sheet", "check my formulas", "find formula errors", "QA this spreadsheet", "model check", "model won't balance", "clean this data", "normalize this data", "fix formatting", "dedupe", "this data is messy".89## Environment1011- **Standalone .xlsx file**: Use Python/openpyxl. Read cell values and formulas programmatically.12- **If asked to generate a cleaned/audited copy**: Write to a new file, never overwrite the original without explicit permission.1314No paid MCP dependencies. All operations use openpyxl or pandas — nothing that requires a subscription or external API.1516---1718## Part A: Spreadsheet Audit1920Audit formulas and data for accuracy and mistakes. Scope determines depth.2122### Step 1: Determine Scope2324If the user already gave a scope, use it. Otherwise ask:2526> What scope do you want me to audit?27> - **selection** — just a specific range (e.g. `A1:F200`)28> - **sheet** — one sheet only29> - **model** — the whole workbook, including financial-model integrity checks (BS balance, cash tie-out, roll-forwards, logic sanity)3031The **model** scope is the deepest — use it for DCF, LBO, 3-statement, merger, comps, or any integrated financial model.3233### Step 2: Formula-Level Checks (ALL scopes)3435| Check | What to look for |36|---|---|37| Formula errors | `#REF!`, `#VALUE!`, `#N/A`, `#DIV/0!`, `#NAME?` |38| Hardcodes inside formulas | `=A1*1.05` — the `1.05` should be a cell reference |39| Inconsistent formulas | A formula that breaks the pattern of its neighbors in a row/column |40| Off-by-one ranges | `SUM`/`AVERAGE` that misses the first or last row |41| Pasted-over formulas | Cell that looks like a formula but is actually a hardcoded value |42| Circular references | Intentional or accidental |43| Broken cross-sheet links | References to cells that moved or were deleted |44| Unit/scale mismatches | Thousands mixed with millions, % stored as whole numbers |45| Hidden rows/tabs | Could contain overrides or stale calculations |4647### Step 3: Model-Integrity Checks (MODEL scope only)4849If scope is **model**, identify the model type (DCF / LBO / 3-statement / merger / comps / custom) and run the appropriate integrity checks.5051#### 3a. Structural Review5253| Check | What to look for |54|---|---|55| Input/formula separation | Are inputs clearly separated from calculations? |56| Color convention | Blue=input, black=formula, green=link — or whatever the model uses, applied consistently? |57| Tab flow | Logical order (Assumptions → IS → BS → CF → Valuation)? |58| Date headers | Consistent across all tabs? |59| Units | Consistent (thousands vs millions vs actuals)? |6061#### 3b. Balance Sheet6263| Check | Test |64|---|---|65| BS balances | Total Assets = Total Liabilities + Equity (every period) |66| RE rollforward | Prior RE + Net Income − Dividends = Current RE |67| Goodwill/intangibles | Flow from acquisition assumptions (if M&A) |6869If BS doesn't balance, **quantify the gap per period and trace where it breaks** — nothing else matters until this is fixed.7071#### 3c. Cash Flow Statement7273| Check | Test |74|---|---|75| Cash tie-out | CF Ending Cash = BS Cash (every period) |76| CF sums | CFO + CFI + CFF = Δ Cash |77| D&A match | D&A on CF = D&A on IS |78| CapEx match | CapEx on CF matches PP&E rollforward on BS |79| WC changes | Signs match BS movements (ΔAR, ΔAP, ΔInventory) |8081#### 3d. Income Statement8283| Check | Test |84|---|---|85| Revenue build | Ties to segment/product detail |86| Tax | Tax expense = Pre-tax income × tax rate (allow for deferred tax adj) |87| Share count | Ties to dilution schedule (options, converts, buybacks) |8889#### 3e. Circular References9091- Interest → debt balance → cash → interest is a common intentional circ in LBO/3-stmt models92- If intentional: verify iteration toggle exists and works93- If unintentional: trace the loop and flag how to break it9495#### 3f. Logic & Reasonableness9697| Check | Flag if |98|---|---|99| Growth rates | >100% revenue growth without explanation |100| Margins | Outside industry norms |101| Terminal value dominance | TV > ~75% of DCF EV (yellow flag) |102| Hockey-stick | Projections ramp unrealistically in out-years |103| Compounding | EBITDA compounds to absurd $ by Year 10 |104| Edge cases | Model breaks at 0% or negative growth, negative EBITDA, leverage goes negative |105106#### 3g. Model-Type-Specific Bugs107108**DCF:**109- Discount rate applied to wrong period (mid-year vs end-of-year)110- Terminal value not discounted back111- WACC uses book values instead of market values112- FCF includes interest expense (should be unlevered)113- Tax shield double-counted114115**LBO:**116- Debt paydown doesn't match cash sweep mechanics117- PIK interest not accruing to principal118- Exit multiple applied to wrong EBITDA (LTM vs NTM)119- Fees/expenses not deducted from Day 1 equity120121**Merger:**122- Accretion/dilution uses wrong share count (pre- vs post-deal)123- Synergies not phased in124- Purchase price allocation doesn't balance125- Transaction fees not in sources & uses126127**3-Statement:**128- Working capital changes have wrong sign129- Depreciation doesn't match PP&E schedule130- Debt maturity schedule doesn't match principal payments131- Dividends exceed net income without explanation132133### Step 4: Audit Report134135Output a findings table:136137| # | Sheet | Cell/Range | Severity | Category | Issue | Suggested Fix |138|---|---|---|---|---|---|---|139140**Severity:**141- **Critical** — wrong output (BS doesn't balance, formula broken, cash doesn't tie)142- **Warning** — risky (hardcodes, inconsistent formulas, edge-case failures)143- **Info** — style/best-practice (color coding, layout, naming)144145For **model** scope, prepend a summary line:146147> Model type: [DCF/LBO/3-stmt/...] — Overall: [Clean / Minor Issues / Major Issues] — [N] critical, [N] warnings, [N] info148149**Don't change anything without asking** — report first, fix on request.150151---152153## Part B: Data Cleanup154155Clean messy data in a sheet or specified range.156157### Step 1: Scope158159- If a range is given (e.g. `A1:F200`), use it160- Otherwise use the full used range of the active sheet161- Profile each column: detect its dominant type (text / number / date) and identify outliers162163### Step 2: Detect Issues164165| Issue | What to look for |166|---|---|167| Whitespace | leading/trailing spaces, double spaces |168| Casing | inconsistent casing in categorical columns (`aus` / `AUS` / `Aus`) |169| Number-as-text | numeric values stored as text; stray `$`, `,`, `%` in number cells |170| Dates | mixed formats in the same column (`3/8/26`, `2026-03-08`, `March 8 2026`) |171| Duplicates | exact-duplicate rows and near-duplicates (case/whitespace differences) |172| Blanks | empty cells in otherwise-populated columns |173| Mixed types | a column that's 98% numbers but has 3 text entries |174| Encoding | mojibake (`é`, `’`), non-printing characters |175| Errors | `#REF!`, `#N/A`, `#VALUE!`, `#DIV/0!` |176177### Step 3: Propose Fixes178179Show a summary table before changing anything:180181| Column | Issue | Count | Proposed Fix |182|---|---|---|---|183184### Step 4: Apply185186- **Prefer formulas over hardcoded cleaned values** — where the cleaned output can be expressed as a formula (e.g. `=TRIM(A2)`, `=VALUE(SUBSTITUTE(B2,"$",""))`, `=UPPER(C2)`, `=DATEVALUE(D2)`), write the formula in an adjacent helper column rather than computing the result in Python and overwriting the original. This keeps the transformation transparent and auditable.187- Only overwrite in place with computed values when the user explicitly asks for it, or when no sensible formula equivalent exists (e.g. encoding/mojibake repair)188- For destructive operations (removing duplicates, filling blanks, overwriting originals), confirm with the user first189- After each category of fix (whitespace → casing → number conversion → dates → dedup), show the user a sample of what changed and get confirmation before moving to the next category190- Report a before/after summary of what changed191192---193194## AU-Specific Data Patterns195196When working with Australian financial data, watch for:197198| Pattern | Example | Note |199|---|---|---|200| ABN format | `51 824 753 556` | 11 digits, often stored inconsistently |201| GST amounts | `$1,100.00 inc GST` | Text in number columns |202| Date format | `DD/MM/YYYY` | Australia uses day-first — don't assume US MM/DD/YYYY |203| BSB/Account | `062-000 12345678` | Banking identifiers in payment data |204| Super fund USI | `STA0100AU` | Unique Superannuation Identifier |205206---207208## Notes209210- **BS balance first** — if it doesn't balance, everything downstream is suspect211- **Hardcoded overrides are the #1 source of silent bugs** — search aggressively212- **Sign convention errors** (positive vs negative for cash outflows) are extremely common213- If the model uses VBA macros, note any macro-driven calculations that can't be audited from formulas alone214- **Always create a backup** before applying any data cleanup changes