Tool-belt series · Microsoft 365 Copilot · Excel
A skill is a folder with a SKILL.md in it that teaches Copilot in Excel how your variance analysis, DCF, or month-end refresh is supposed to be done — so the tenth run looks like the first. Short page on purpose: what a skill is made of, how to write one that actually fires, how to share it, and three you can copy today.
Part A is what a skill actually is and where it lives. Part B is how to write one that fires when it should and does what you meant. Part C is sharing and keeping it trustworthy. Then three copy-paste examples. Check items off as you go — progress and collapsed sections save in this browser on this device.
Assumes a paid Microsoft 365 Copilot licence and Copilot in Excel with skills enabled. Custom skills are new and moving fast — the underlying SKILL.md format is the open Agent Skills spec, so what you learn here carries to Copilot Cowork and Claude alike.
The test is repeatability. If you will do it once, prompt it. If you will do it every month and you care that it looks the same every month, that is a skill — Copilot loads it, follows your steps, and applies your structure and formatting instead of improvising a fresh answer each time.
| Use | When | Lives |
|---|---|---|
| Prompt | One-off question, exploratory analysis, "what's driving this?" | Nowhere — the chat |
| Agent mode | Outcome-based ask; Copilot plans steps, writes formulas, builds the output in the workbook | The session |
| Skill | A process you own that must land identically every time, for you or the team | SKILL.md in OneDrive |
Every skill is a directory whose name matches the name in its frontmatter, containing at minimum a SKILL.md. Extra material goes in conventional subfolders that Copilot only opens when it needs them — that is the whole point of the layout.
skills/
└── variance-analysis/
├── SKILL.md # required: frontmatter + instructions
├── references/ # optional: detail loaded on demand
│ └── account-map.md
├── scripts/ # optional: Office.js run to completion
│ └── build-bridge.js
└── assets/ # optional: templates, lookup tables
└── variance-template.xlsx
The frontmatter is fenced by --- and only two fields are required. name is lowercase letters, numbers and hyphens, max 64 characters, no leading/trailing or doubled hyphens, and must match the folder name. For Excel, tag it so it is recognised as workbook-facing:
skills/variance-analysis/SKILL.md
---
name: variance-analysis
description: Builds a monthly actual-vs-budget variance bridge with commentary
thresholds. Use when the user asks for variance analysis, budget vs actual,
a bridge, or explains-the-gap reporting on a P&L extract.
metadata:
version: "1.0.0"
tags: excel
---
# Variance analysis
...instructions...
Custom skills live in a skills folder in your own OneDrive. Copilot creates it for you: Copilot pane → Settings → Manage skills → Custom skills → Create OneDrive folder. Drop skill folders in there, hit Refresh, and they appear under Add work content → All Skills.
Invoke either way: pick it from the All Skills list, or @skill-name inline in your prompt — e.g. @variance-analysis on the Actuals sheet for June. Microsoft ships its own too, like @brandkit and @theme-design for workbook styling, plus a pre-built finance library worth reading before you write your own.
@mentions it directly still gets it. "Disabled" is not "off".Skills load progressively. Only name and description sit in context all the time (~100 tokens); the body is read after Copilot decides to use the skill. So the description is not a summary — it is the routing logic. Say what it does and when to use it, in the user's words, with the keywords they'd actually type. Up to 1024 characters; use a couple of hundred of them.
# weak — never fires
description: Helps with variance.
# strong — does what and when, with trigger words
description: Builds a monthly actual-vs-budget variance bridge with
commentary above a materiality threshold. Use when the user asks for variance
analysis, budget vs actual, plan vs actual, a bridge, or "explain the gap"
on a P&L or cost-centre extract.
There are no format rules for the body, but Excel skills converge on the same shape. Write numbered, unambiguous steps — the reader is following instructions, not being inspired. Then two sections that are specific to Excel: Workbook output (because the deliverable is a sheet, not a chat reply) and Common pitfalls to avoid (because the failure modes are predictable and worth naming).
## Steps
1. Locate the actuals and budget columns on the active sheet by header,
not by position. If either is missing, ask — do not guess.
2. Compute variance = actual − budget, and variance % = variance / budget.
3. Flag any line where |variance| > 5% and |variance| > 50,000.
## Workbook output
- Create a sheet named "Variance Bridge"; never overwrite an existing one.
- Columns: Account | Actual | Budget | Var | Var % | Commentary.
- Currency as #,##0;(#,##0); negatives red; % to one decimal.
- Leave Commentary blank for the preparer — do not write commentary.
## Common pitfalls to avoid
- Do not search unrelated sheets for data.
- Do not invent missing months or accounts.
- Do not hard-code values a formula should produce.
- Do not claim the workbook was updated if it wasn't.
Two reference files earn their keep in almost every Excel skill. The first is a data guardrail: how the workbook should be cleaned or normalised before the skill writes anything, using the exact sheet and column names your scenario expects — scenario-specific, not generic Excel advice. The second covers in-Excel vs outside-Excel execution: what to do if someone invokes the skill from Copilot chat where there is no workbook to touch (answer: explain the steps, never claim a sheet was created).
If the skill needs to do something the model can't reliably do by hand, add an Office.js script under scripts/ and say in the body exactly when to run it — and when not to. Each script must run to completion unattended, and must not call Office.onReady or define Office.initialize; Copilot creates the runtime and loads Office.js for you.
// scripts/build-bridge.js — no Office.onReady, no Office.initialize
await Excel.run(async (context) => {
const sheet = context.workbook.worksheets.add("Variance Bridge");
// ...write headers, formulas, formats...
await context.sync();
});
There is no admin console that drops a SKILL.md into everyone's folder. Each person has their own skills folder, so distribution is: publish the canonical copy somewhere the team can see it, and each teammate copies the folder into their own OneDrive and hits Refresh. Sharing the file from OneDrive or Teams, or sharing the skill to specific people in your organisation from its detail page, are both just ways of handing over that copy.
Which means the real problem is drift: five copies, three of them stale. Solve it the way you'd solve it for code — one source of truth, a version number in metadata, and a note in the body saying where the canonical copy lives.
A shared skill is a shared procedure: when it's wrong, it's wrong for everybody, quietly. Two Copilot features do the heavy lifting. Plan makes Copilot draft its proposed actions first so you can approve, edit, or answer questions before anything in the workbook moves. Show Changes lists what it did alongside human edits, so a Copilot-made change is never anonymous.
skills/variance-analysis/SKILL.md
---
name: variance-analysis
description: Builds a monthly actual-vs-budget variance bridge with a
materiality flag and a blank commentary column. Use when the user asks for
variance analysis, budget vs actual, plan vs actual, a bridge, or to explain
the gap on a P&L or cost-centre extract. Not for forecast rebuilds.
metadata:
version: "1.2.0"
tags: excel
---
# Variance analysis
## Steps
1. Find Account, Actual and Budget columns by header on the active sheet.
If any is missing, ask for the exact header — do not guess or search
other sheets.
2. Confirm the period with the user before computing anything.
3. Variance = Actual − Budget. Variance % = Variance / Budget
(blank, not #DIV/0!, when Budget is zero).
4. Flag rows where |Variance| > 50,000 AND |Variance %| > 5%.
## Workbook output
- New sheet "Variance Bridge <period>". Never overwrite an existing sheet.
- Account | Actual | Budget | Variance | Var % | Flag | Commentary
- #,##0;[Red](#,##0) for currency; 0.0% for percentages; freeze the header row.
- Leave Commentary empty — the preparer writes it, not Copilot.
## Common pitfalls to avoid
- Do not write commentary or explanations into the sheet.
- Do not invent accounts or periods that aren't in the source.
- Do not reorder or re-map accounts; keep source order.
skills/data-hygiene-check/SKILL.md
---
name: data-hygiene-check
description: Audits an extract for the problems that break downstream
models — text-formatted numbers, trailing spaces, merged cells, duplicate
keys, inconsistent dates — and reports them without changing anything. Use
before analysing a new export, or when totals look wrong.
metadata:
version: "1.0.0"
tags: excel
---
# Data hygiene check
## Steps
1. Work only on the active sheet unless told otherwise.
2. Check, in order: numbers stored as text; leading/trailing whitespace;
merged cells; blank rows inside the table; duplicate values in the
key column; mixed date formats; inconsistent account codes.
3. Count occurrences and capture up to 5 example cell references each.
## Workbook output
- New sheet "Hygiene Report": Issue | Count | Example cells | Suggested fix.
- Sort by Count descending. Do not modify the source sheet — report only.
## Common pitfalls to avoid
- Do not fix anything. This skill reports; the user decides.
- Do not flag intentional blanks in a subtotal block as errors.
- If the sheet has no recognisable table, say so and stop.
skills/house-format/SKILL.md
---
name: house-format
description: Applies our reporting format to a finished table — number
formats, header style, column widths, print setup. Use when the user asks to
format, tidy, or make a sheet presentable, or mentions house style.
metadata:
version: "1.1.0"
tags: excel
---
# House format
## Workbook output
- Header row: bold, white on #217346, frozen, autofilter on.
- Currency #,##0;[Red](#,##0) · percentages 0.0% · dates dd-mmm-yy.
- Inputs blue font, formulas black, links green. Never change a value.
- Column widths autofit, capped at 40. Gridlines off. Fit to one page wide.
## Common pitfalls to avoid
- Do not alter values, formulas, or column order — formatting only.
- Do not apply this to a raw data extract; it is for finished output.