andreworia/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. Use when someone wants to see how an output (NPV, IRR, EPS, margin) moves as one or two inputs change. Do not trigger for editing an existing workbook through the Claude for Excel add-in.

sensitivity-tables とは?

sensitivity-tables is a Claude Code agent skill that 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. Use when someone wants to see how an output (NPV, IRR, EPS, margin) moves as one or two inputs change. Do not trigger for editing an existing workbook through the Claude for Excel add-in.

対応Claude Code~Codex CLI~Cursor
npx skills add https://github.com/andreworia/claude-excel-skills/tree/main/skills/sensitivity-tables

Installed? Explore more 生産性&コラボレーション skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

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

  • Corner cell E3: =Model!B40 (the live output).
  • E4:E10: row-input values DOWN the left edge (first driver, for example growth 0%, 1%, ... 6%).
  • F3:L3: column-input values ACROSS the top row (second driver, for example discount rate 6% ... 14%).
  • Select E3:L10, Data > What-If Analysis > Data Table, Row input cell = Model!B7 (the across driver), Column input cell = Model!B6 (the down driver). Excel fills F4:L10 with {=TABLE(Model!B7,Model!B6)}.
  • Watch the orientation: the cell tied to the TOP row goes in Row input cell; the cell tied to the LEFT column goes in Column input cell. Swapping them transposes the result silently.
  • Code-computed fallback: a double loop in Python over both axes, writing the value matrix to a labeled block (axis headers in green if they pull from the model, blue if literal sweep values).

Choosing axis ranges

  • Center each axis on the base-case value so the base sits in the middle row and middle column, which makes the center-cell check meaningful.
  • Use an odd number of steps (5, 7, or 9) so a single middle cell lines up exactly with the base case rather than falling between two cells.
  • Keep step sizes uniform on each axis (constant increment) so the grid reads as a clean gradient and the color scale is interpretable.
  • For rates, sweep in absolute points (8%, 10%, 12%), not relative percent of the base, to avoid confusing readers.

openpyxl build notes

  • Write the corner as a real formula string: ws["B3"] = "=Model!B40". Do not paste the current numeric value of the output.
  • For the native Data Table array, openpyxl can store the =TABLE(...) text, but a real engine must recalculate to fill the block; treat the array as a placeholder until the recalc step runs.
  • When writing the computed fallback, set the data values with Python (ws.cell(row=r, column=c, value=float(npv))) and keep them visually distinct from the live block with a header note such as "computed snapshot".
  • Apply the color scale with openpyxl.formatting.rule.ColorScaleRule over the result block, mapping min to one color and max to another through a midpoint.

Formula and formatting conventions

  • Blue font for inputs (the swept axis values you type in).
  • Black font for in-tab formulas.
  • Green font for cross-tab links such as =Model!B40.
  • No hardcodes where a formula belongs: the corner cell must be =Model!B40, never the typed base-case number.
  • One consistent formula per row or column: the entire Data Table block is a single array; the computed fallback uses one Python expression applied across the grid.
  • Number formats: rates as 0.0%, currency outputs as #,##0, ratios as 0.00. Axis values match the unit of the input cell they replace.

Checks

  • Corner cell equals the live output: =(B3=Model!B40) returns TRUE.
  • Axes labeled with the input cell names (a text label above or beside each axis naming the driver and its cell address).
  • Center of the grid matches the base case: the grid cell at the base-case row and base-case column equals the model's current output, =(<center cell>=Model!B40) TRUE.
  • For the computed fallback, the cell at the base inputs equals the native Data Table cell at the same inputs (within rounding).

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

  • Path to the source model and the exact output cell address.
  • The one or two input cell addresses to sweep.
  • Base-case values and the desired range and step for each axis.
  • Units and preferred number formats for axes and output.

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.

Individual skills in this repo

This repo contains 11 individual skills — each has its own dedicated page.

andreworia/assumption-registry-builder

Creates a structured assumption register for any Excel model with columns for name, category, base value, source, Bull/Bear values, sensitivity rank, and owner, plus a formula for computing sensitivity rank from Data Table outputs.

andreworia/data-cleaning-for-excel

Turns pasted or exported data with mixed formats, blank rows, or duplicates into a clean, consistently formatted range ready for analysis. Use it right after pasting raw data into a worksheet.

andreworia/formula-audit-checker

Provides a systematic audit checklist for Excel model formula logic, hardcoded values, circular references, and error handling, with step-by-step instructions for using Excel's native auditing tools.

andreworia/inputs-calcs-outputs-design

Enforces the three-tab separation principle for any Excel model, producing a full design for a dedicated Inputs tab, one or more Calculations tabs, and a clean Outputs tab with a conventions checklist.

andreworia/model-architecture-template

Defines the master tab structure, naming conventions, color codes, number formats, and print area setup for any new strategy or finance Excel model, serving as the structural template before any content is added.

andreworia/output-summary-tab

Designs the executive summary tab of an Excel model with KPI tiles, a narrative block, a sensitivity summary, and an assumption log, formatted for print or screenshot use in a board pack.

andreworia/pivot-table-builder

Specifies and builds a pivot table from a flat data range, choosing rows, columns, values, and filters. Use it when you have raw tabular data and need a summary view without building it cell by cell.

andreworia/revenue-build

Builds a driver-based revenue forecast .xlsx with live formulas across separate drivers, build, and output tabs plus checks, rolling a customer or units schedule (beginning, adds, churn, ending) into revenue with Base/Bull/Bear scenario toggles. Use when someone needs a bottom-up revenue model, an ARR build, or a driver-based forecast for planning or a board deck. Do not trigger for editing an existing workbook through the Claude for Excel add-in.

andreworia/scenario-manager

Builds a Base/Bull/Bear scenario switching layer for a model in a .xlsx with a live selector, CHOOSE or INDEX assumption links, a side-by-side output comparison, and a recalc check, then delivers the workbook. Use when someone wants an auditable scenario toggle instead of Excel's hidden Scenario Manager. Do not trigger for editing an existing workbook through the Claude for Excel add-in.

andreworia/sensitivity-tornado

Ranks variable sensitivities to a key output and builds a tornado chart by swinging each input over a defined range, computing output impact, and producing a horizontal bar chart data structure.

andreworia/unit-economics

Builds a unit-economics and cohort .xlsx with live formulas across separate assumptions, cohort, and output tabs plus checks, computing CAC, LTV, LTV/CAC, and CAC payback from a monthly cohort retention grid. Use when someone needs unit economics, an LTV/CAC analysis, a payback model, or a cohort retention build. Do not trigger for editing an existing workbook through the Claude for Excel add-in.

関連スキル