Files
gridcraft/docs/macros.md
T
prxnvt 77150be455 Engine: col("Header") is refused on a range without a header row
col("...") always matched against the first row of the range, whatever
its header flag. On an input declared without a header row,
Input.col("Amount") silently picked the first column whose first data
cell read "Amount". After .data, the natural Input.data.col("Amount")
failed, because the first row was then a data row. The header row is
now carried through data, and col("...") is refused with a message when
there is none (an input without a header, a Name: base, or after any
other method).
2026-10-22 02:26:32 -04:00

4.6 KiB
Raw Blame History

Macros

Last updated: 2026-10-21 · Change: minor (macro tokens)

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, the tokens its steps use and how macros are saved in a workbook. The engine has no command that runs macros in this version.

A macro

{
  "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. A run binds each input to the range it is given, its default, or (for the first input) the selection, and refuses with messages that name the cells: "Input column 2 (Amount) must hold numbers; C4 holds text."
  • Limits: 1,000 macros a workbook, 10,000 steps a macro, and Repeat and If nested 4 deep.

Tokens

References in step parameters can be tokens, worked out when the step runs:

Token Means
Input, or another input's name the range the input is bound to
Output the output rule's anchor
Row, Column the current row or column of the Repeat around the step
Name:Total a defined name, or a table's data

Methods narrow or move a range and chain: col(2) or col("Amount"), row(1), cols(2..3), rows(2..), cell(r,c) (relative to the top-left cell; cell(0,1) is the cell above), offset(r,c), resize(h,w), data (without the header row), below(n) and right(n). col("Amount") looks the name up in an input's header row, directly or after data; on a range without a header row it is refused.

Write a token as the whole value of a reference parameter (cell, range, target, keys ending in Cell or Range…), as {"$ref": "Input.col(2)"} anywhere, or as {{Input.col(2)}} inside any string, such as a formula. Plain A1 references stay absolute; a Name: anchor follows inserted rows. A reference with a sheet name is never a token, so Output!A1 is a cell on a sheet called Output, even when a token or input has that name.

Storage

Macros are saved in the workbook: as a field in GridCraft's JSON format, and in xlsx as hidden defined names (_gc_macro_<n>_<k>, 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.