# Macros > **Last updated:** 2026-10-24 · **Change:** major (created: the macro format and storage) GridCraft macros are typed, declarative lists of commands, not VBA. Every step runs a GridCraft command (the same ids the ribbon, CLI and MCP use) or one of three bounded control steps. A macro declares the inputs it works on. This page describes the macro format and how macros are saved in a workbook. Step parameters can hold tokens such as `Input` and `Output`; the engine does not resolve or run them in this version. ## A macro ```json { "name": "Totals", "description": "Adds a total next to the amounts", "inputs": [{"name": "Input", "header": true, "cols": [2, 2], "colTypes": ["text", "number"]}], "output": {"anchor": "Input.right(2).cell(1,2)", "onConflict": "ask"}, "steps": [ {"type": "command", "id": "cell.set", "params": {"cell": "Output", "input": "Total"}}, {"type": "command", "id": "cell.set", "params": {"cell": "Output.offset(1,0)", "input": "=SUM({{Input.data.col(2)}})"}}, {"type": "repeat", "over": "Input.data", "of": "rows", "max": 1000, "body": [ {"type": "if", "cell": "Row.cell(1,2)", "op": "gt", "value": 100, "then": [{"type": "command", "id": "home.bold", "params": {"range": "Row"}}]} ]}, {"type": "stop", "message": "Done."} ], "permissions": [] } ``` - **Steps**: `command` (`id`, `params`), `repeat` (each row or column of `over`, at most `max` times), `if` (`cell` compared with `value` by `eq`, `ne`, `gt`, `ge`, `lt`, `le`, `empty`, `notEmpty` or `contains`; `then` and `else` lists) and `stop` (`message`; `rollback: true` undoes the run). Every step can carry `enabled`, `breakpoint` and `note`. The short form `{"command": "cell.set", "params": {…}}` is accepted for a command step. - **Inputs**: `kind` (`cell` or `range`), `rows` and `cols` as `[min, max]` (0 for no maximum; rows exclude the header), `header`, `colTypes` (`number`, `text`, `date`, `bool`, `any`), `nonEmpty` and `defaultRef`. These declare what a range must look like for the macro to work on it. An input's name is letters, digits and `_`, starting with a letter, and is neither a token of its own (`Output`, `Row`, `Column`, `Name`) nor something that reads as a cell reference (`Q1`), so a step written with plain A1 text keeps meaning the cell. This version stores and checks the declaration; it does not bind inputs or run macros. - **Limits**: 1,000 macros a workbook, 10,000 steps a macro, and Repeat and If nested 4 deep. ## Storage Macros are saved in the workbook: as a field in GridCraft's JSON format, and in xlsx as hidden defined names (`_gc_macro__`, the macro's JSON split into string literals within Excel's limits), which other spreadsheet applications keep but do not run. Each macro carries its format version, `v` (1 in this version; a missing `v` reads as 1). When a file is opened, a macro that is damaged, over the limits or in a newer format (a `v` above 1) is left out with one warning, and the rest of the workbook and its other macros open. A newer macro is never read in part, so a save can't write it back with its newer fields missing; a macro that was left out is not in the saved file. ## Automate scripts and VBA Automate scripts (`automate.recordActions`, `newScript`, `allScripts`, `runScript`, `deleteScript`) are an older, separate feature. They keep their commands, parameters, storage (`_sc_scripts`) and results, and View › Macros (`view.macros`) still lists them. Macros neither read nor change them; a workbook can hold a script and a macro with the same name. A VBA project in an `.xlsm` or `.xltm` file is preserved on save and never run. GridCraft macros are stored apart from it.