Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions advanced-formula-environment/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,17 @@ This happens when AFE tries to save a formula with certain errors in, such as a
- Check that none of the formulas have errors (red underlines).
- If the formulas use structured references, check that they match the tables and table columns in the workbook.
- If the error persists, feel free to create an issue on the tracker with the formulas.

#### Why does a formula work in the grid but fail in the AFE debugger?
The formula debugger is a **separate, partial evaluator** inside Advanced Formula Environment. It is not the same as Excel’s calculation engine or the classic **Evaluate Formula** dialog.

Excel may return a correct result in the cell while the debugger reports that a feature is not implemented. Common cases include:

- **REGEX functions** (`REGEXEXTRACT`, `REGEXTEST`, `REGEXREPLACE`, `REGEXEXTRACTALL`) — tracked in [Excel-Labs#45](https://github.com/microsoft/Excel-Labs/issues/45).
- **Other unimplemented functions** — the debugger may show a message such as *The formula uses features which the debugger does not yet implement* with a `Details:` function name (see [Excel-Labs#41](https://github.com/microsoft/Excel-Labs/issues/41)).
- **Dynamic / spilled arrays** — the debugger may refuse formulas that use spilled-array features even when the grid result is a single value (see [advanced-formula-environment#83](https://github.com/microsoft/advanced-formula-environment/issues/83)).

**Workaround while debugging:** use Excel’s **Formulas → Evaluate Formula**, or break the calculation into helper cells / intermediate named steps that avoid unsupported debugger features. Grid results remain authoritative when they differ from the debugger.

#### Do module function names allow dots?
Prefer **underscores** in named formula identifiers authored in modules (for example `JSON_GET`), not dotted names such as `JSON.GET`. Dotted identifiers are easy to confuse with module qualification and can break module syntax. Path *arguments* (for example `"meta.captured_at"`) may still contain dots.
78 changes: 78 additions & 0 deletions advanced-formula-environment/examples/JSON_GET.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
### Description
Lightweight JSON text helpers for Excel 365, built with `LAMBDA` + `REGEXEXTRACT`. Useful for reading flat property values and simple nested objects from JSON pasted into a range.

**Note:** These formulas calculate in the Excel grid when REGEX functions are available. The AFE **debugger** does not yet implement REGEX functions ([Excel-Labs#45](https://github.com/microsoft/Excel-Labs/issues/45)); use Evaluate Formula or helper cells to step them. Function names use underscores (`JSON_GET`), not dots (`JSON.GET`).

`JSON_OBJECT_AT` only supports **flat** objects (`\{[^}]*\}`). Nested braces inside an object will not match.

### Code
```
// JSON_TEXT — join a multi-cell paste into one string
JSON_TEXT=LAMBDA(json_range,
LET(
joined, TEXTJOIN("", TRUE, json_range),
IF(joined = "", NA(), TRIM(joined))
)
);

// JSON_PROP — read a scalar property from an object fragment
JSON_PROP=LAMBDA(object_text, prop_name,
LET(
pat, """" & prop_name & """\s*:\s*(""[^""\\]*(?:\\.[^""\\]*)*""|true|false|null|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)",
raw, IFERROR(REGEXEXTRACT(object_text, pat, 1), NA()),
IF(ISNA(raw),
NA(),
IF(LEFT(raw, 1) = """",
MID(raw, 2, LEN(raw) - 2),
IF(raw = "true",
TRUE,
IF(raw = "false",
FALSE,
IF(raw = "null", NA(), VALUE(raw))
)
)
)
)
)
);

// JSON_OBJECT_AT — extract a flat object by key (no nested braces)
JSON_OBJECT_AT=LAMBDA(json_text, key_name,
LET(
pat, """" & key_name & """\s*:\s*(\{[^}]*\})",
IFERROR(REGEXEXTRACT(json_text, pat, 1), NA())
)
);

// JSON_GET — dotted path into flat nested objects, e.g. "meta.captured_at"
JSON_GET=LAMBDA(json_range_or_text, path,
LET(
text, IF(ISREF(json_range_or_text),
JSON_TEXT(json_range_or_text),
json_range_or_text
),
parts, TEXTSPLIT(path, "."),
depth, COLUMNS(parts),
IF(depth = 1,
JSON_PROP(text, INDEX(parts, 1)),
LET(
obj, REDUCE(
text,
DROP(parts, , depth - 1),
LAMBDA(acc, key, JSON_OBJECT_AT(acc, key))
),
JSON_PROP(obj, INDEX(parts, depth))
)
)
)
);
```

### Sheet usage
```
=JSON_GET(A1, "meta.captured_at")
=JSON_PROP(A2, "elapsed_ms")
```

### Gist link
_(Paste into an AFE module, or publish your own gist and replace this line.)_