FinanceFinancial Modelling

Sensitivity Tables

Builds one- and two-variable sensitivity (Data Table) analysis on a model output in a .xlsx with live formulas and a recalc check, then delivers the workbook.

AAndrew Oria·Finance·MIT

Library skill — the default version is maintained in GitHub; edits you make live in your own clone.

Use this skillDownload .zip
How does this work?
  • ChatGPT opens a new chat with the skill loaded. If it's too long for a link, it's copied to your clipboard — just paste.
  • Claude works the same way. To install it permanently, download the .zip and upload it under Claude → Settings → Capabilities → Skills (Pro/Team/Enterprise).
  • Copy prompt copies the skill so you can paste it into any assistant, including Grok.

Sensitivity Tables (One- and Two-Variable)

When to use

Use when a strategy or finance model has a single key output and you want to show how that output responds as one or two drivers vary across a range. Typical drivers are price, volume, discount rate, growth, churn, or cost per unit. This skill BUILDS a downloadable .xlsx from scratch in the Claude app (openpyxl plus numpy), with live formulas and a recalc-and-verify pass. It is not the Claude for Excel add-in.

What it builds

A single Sensitivity tab that attaches to an existing model. It references the model's input cells and output cell, lays out one-variable and two-variable grids, and color-scales the result block. If the source model lives on another sheet, the grid links to it with cross-sheet references so it stays live.

Build workflow

  1. Identify the output cell (for example Model!B40 holding NPV) and the one or two input cells that drive it (for example Model!B6 discount rate, Model!B7 growth).
  2. Confirm the output is a live formula chain back to those inputs. If the output is hardcoded, stop and wire the model first; a Data Table over a constant returns the constant.
  3. Choose input ranges around the base case (for example base discount rate 10 percent, sweep 6 to 14 percent in steps of 2).
  4. Build the native Excel Data Table structure: corner formula, input axes, and the {=TABLE(r,c)} array (see spec).
  5. ALSO build the code-computed grid as a robust fallback: re-evaluate the model in Python across every input combination and write the resulting values as a labeled matrix.
  6. Apply a 3-color scale to the result block and label both axes with the input cell names.
  7. Add the Checks block.
  8. Recalculate the workbook in a real engine (headless LibreOffice).
  9. Verify zero formula errors (#REF!, #DIV/0!, #VALUE!, #NAME?), confirm the checks pass, then deliver the .xlsx.

Tab-by-tab spec

Sensitivity tab, one-variable block

Pick a layout direction. For inputs running DOWN a column: - B3: the output formula, referencing the live output: =Model!B40. This is the corner cell. - A4:A10: the input values you sweep (blue inputs), for example 6%, 8%, 10%, 12%, 14%. - B4:B10: the Data Table results column. - Select A3:B10, then Data > What-If Analysis > Data Table, leaving Row input cell blank and setting Column input cell to Model!B6. Excel writes {=TABLE(,Model!B6)} into B4:B10. - openpyxl can write the array formula string =TABLE(,Model!B6) into the block and the =Model!B40 corner, but the values only populate after recalculation in a real engine.

Code-computed fallback for the same block (recommended when generating via code), written to a labeled matrix below, say starting A14: - A14: label "Discount rate". B14: "NPV (computed)". - For each input value in A15:A21, Python sets Model!B6 to that value, recomputes the model logic in numpy, and writes the resulting NPV as a plain value in column B. - Keep both: the native Data Table proves it is live; the computed matrix guarantees populated numbers even before the user opens Excel.

Sensitivity tab, two-variable block

Choosing axis ranges

openpyxl build notes

Formula and formatting conventions

Checks

Recalculate and verify

Save with openpyxl, then recalc headless (for example libreoffice --headless --convert-to xlsx) so =TABLE(...) and cross-sheet links populate. Reload and scan every cell for #REF!, #DIV/0!, #VALUE!, #NAME?. Confirm the three checks return TRUE. If any error or FALSE appears, fix the reference or range and loop until clean, then deliver.

Inputs to gather

Example

Hypothetical model: Model!B40 = project NPV, driven by Model!B6 discount rate (base 10%) and Model!B7 revenue growth (base 3%). One-variable block sweeps discount rate 6% to 14% by 2%, giving NPV of (for example) 1,210 / 980 / 760 / 560 / 380 in hypothetical units. Two-variable block crosses growth 0% to 6% against discount rate 6% to 14%; the center cell at 3% growth and 10% discount equals Model!B40 of 760, confirming the base case sits in the middle of the grid.