Why formulas won't get you there
Sheets has TRANSPOSE, FLATTEN, and a handful of array tricks, but none of them can emit a three-column (key, category, value) tuple for every cell in a range without knowing the exact column count at formula-write time. The moment your source table gains a column — a new month, a new region — the formula silently stops covering it. That's the bug that shows up in exports three weeks later.
Apps Script sidesteps this entirely. It reads the header row once, then loops over every data row and emits one output row per value column. The header count drives the loop, so new columns get picked up automatically the next time you run it.