A personal C# framework for Excel tooling — the modern replacement for the VBA PERSONAL.XLSB
macro collection. Everything is an Excel-DNA add-in (a single .xll you enable once), written
in C# on .NET Framework 4.8, so it loads reliably and the code lives in git as plain text.
Why net48? Late-bound (
dynamic) Office COM — the VBA-identicalws.Cells(r,c).Valuestyle — works cleanly only on .NET Framework. On modern .NET (8/10) dynamic COM indexers are broken. See docs/add-in-reference.md.
excel_tools/
├─ ExcelPowerTools.sln
├─ src/
│ ├─ ExcelPowerTools/ the add-in (COM, ribbon, UI, UDFs, dev commands)
│ │ ├─ AddIn.cs lifecycle + app-event wiring
│ │ ├─ RibbonController.cs the "Power Tools" ribbon tab
│ │ ├─ Commands/ one file per feature area (incl. DevCommands.cs)
│ │ ├─ Functions/ worksheet UDFs (=PT.*)
│ │ ├─ Interop/ COM helpers + FrameworkPaths (self-location)
│ │ ├─ UI/ WinForms dialogs
│ │ └─ Settings/ per-user settings (registry)
│ └─ ExcelPowerTools.Core/ pure, Excel-free logic (unit-test target)
├─ tests/ExcelPowerTools.Tests/ xUnit over Core
└─ docs/add-in-reference.md feature-by-feature reference + VBA mapping
dotnet build -c Release # builds + packs the .xll
dotnet test # runs the unit tests
The 64-bit add-in to install: src/ExcelPowerTools/bin/Release/net48/publish/ExcelPowerTools-AddIn64-packed.xll
(enable via Excel ▸ File ▸ Options ▸ Add-ins ▸ Manage: Excel Add-ins ▸ Go ▸ Browse).
The add-in has a Framework ribbon group so you can jump into the code the way Alt+F11 does in VBA:
- Open in VS → opens
ExcelPowerTools.slnin the newest installed Visual Studio (resolved viavswhere, so it ignores the.slnfile association, which may point at an older VS). - Repo folder / Build output → open those folders in Explorer.
- About → shows the loaded
.xllpath and the resolved repo/solution (handy diagnostics).
Typical cycle:
- In Excel, Framework ▸ Open in VS.
- Edit code. To debug, pick the "Excel (load add-in)" launch profile and press F5 — VS starts a
fresh Excel with the freshly built Debug
.xllloaded, breakpoints live. (The profile's Excel path and Debug.xllpath are insrc/ExcelPowerTools/Properties/launchSettings.json.) - For a normal rebuild, close the Excel that has the add-in loaded first — a running
.xllis file-locked, so the pack step can't overwrite it otherwise. After closing, giveEXCEL.EXEa few seconds to fully exit (it can linger ~15–30s and hold the lock) before rebuilding.
The framework grows by convention — no plumbing:
- A command (menu/ribbon action): add a method to a
Commands/*.csclass, tagged[ExcelCommand(Name = "PT_Something")](addShortCut = "^k"for a hotkey). Add a<button>toRibbonController.GetCustomUIand a one-lineOnSomethingcallback. - A worksheet function: add a
[ExcelFunction(Name = "PT.SOMETHING")]method inFunctions/. - Pure logic worth testing: put it in
ExcelPowerTools.Core, add a matching<Compile Link>line inExcelPowerTools.csproj(so it stays in the single-file.xll), and cover it intests/.