A stateful UI framework for Excel worksheets. Build interactive, async-aware applications out of worksheet shapes and form controls the way you would with a component framework on the web. No UserForms, no ActiveX, no add-ins, no VBIDE access.
ReDim sits on top of ROneCOne, which supplies delegates, typed events, structured exceptions, and cooperative tasks. ReDim adds what ROneCOne's one-file invariant cannot carry: the host loop (ROneCOne ADR 0007 anticipated exactly this), a retained component model with diffed rendering, a state store with bindings, and an async engine that keeps Excel responsive while work runs.
Dim ui As ReDimUI
Set ui = ReDimUI.Mount(Sheet1, "Dashboard")
ui.Button("run").At("B2:C3").Text("Run Report").Primary.OnClickAsync "Demo.BuildReport"
ui.ProgressBar("prg").At("B5:F5").BindValue "progress"
ui.Label("status").At("B7:F7").BindText "statusMsg", "Status: {0}"
ui.RenderClicking Run disables the button, swaps its caption to busy text, runs Demo.BuildReport through
the pump, and restores the button when the work completes or fails. While a chunked job runs,
ui.SetState "progress", 40 moves the bar and "statusMsg" updates the label, all while the
user keeps working in the workbook.
- Components over shapes. Button, Label, Card, ProgressBar, Spinner, Toggle, TickBox, RadioGroup, Stepper, SlideBar (press-drag), SelectBox, ComboBox (editable, filtering live as you type), TransferList (dual listbox with move buttons), CheckList (checkbox list with a tri-state select-all header), DatePicker (month calendar), Table (sortable, paged, filtered as you type, copied and exported), Tabs (with panels of controls), Expander, MenuButton, Sparkline, Skeleton (loading placeholder), Badge, Image (embedded picture fills), TextInput with captions, hints, validation, and password masking, Toast, and a shapes-based modal overlay with Confirm, plus 71 Windows icons for buttons and labels - every control drawn from shapes and fully themed, with light, dark, and high-contrast presets and a theme that follows Windows dark mode and accent color, no native form controls anywhere, no cells required (text fields float free of the grid via a keyboard focus layer, or anchor to a cell if you want one), and no dependencies beyond a stock Excel 365 install.
- Keyboard and pointer. Every control takes keyboard focus, with Tab order, arrow keys,
access keys, and a default button, and a command palette (Ctrl+Shift+P) finds and runs
anything the app can do. Float fields edit like Windows text boxes: selection,
word moves, the clipboard, and undo. Opt-in hover and press looks, tooltips,
hold-to-repeat, and drag gestures come from the pump watching the pointer. Every
control carries alternative text for screen readers, a high-contrast theme passes WCAG
AA, and motion follows the Windows animation setting.
ValidateAllchecks a whole form before a save, andSetUITexttranslates every word ReDim draws or announces. - Stateful. Each app owns a key-value store.
BindText,BindValue,BindVisible, andBindEnabledre-render only what changed.OnStateChangedregisters workbook procedures as state listeners, run when a key changes.WritesToties a control to a key both ways: the control writes it, and follows it when code writes it. The store is deliberately in-memory and session-scoped: persistence belongs to the host application, which can walk the store withStateKeys, save it wherever fits (ROneCOne's JSON serializer is on board), and reseed on build withSetStateDefault, which never clobbers a value already in play. - Composable layout. Anchor to ranges with
At, to points withAtRect, or to other components withBelowandRightOf, or let aStackflow controls down or across, closing the gap when one hides and making room for anExpanderas it opens. Render prunes shapes orphaned by renamed components, so iterating on app code never litters the sheet. - Windows. Sheets as forms:
AsWindowregisters a window,Navigateshows one at a time (others go very-hidden),NavigateBackwalks the stack,OnShowandOnHidefire like form lifecycle events, a button becomes a nav link withNavigatesTo, andNavBarrenders window tabs with the active one highlighted. Background windows keep pumping.ProtectSurfaceturns an app sheet into a true application surface. - Genuinely async. A SetTimer pump ticks whenever Excel idles and steps ROneCOne tasks
without anyone blocking on
Await. Fire-and-forget ops disable their controls, spin a spinner, and fire done, fail, or cancel handlers. HTTP, database, shell, and delay tasks overlap for real; CPU-bound VBA runs as chunked jobs inside a per-tick millisecond budget, or paced jobs for game loops and animations. Cancellation rides ROneCOne CancellationTokenSource. - Crash-railed. The timer callback is a single guarded call that never lets an error escape, kills itself after repeated faults, stops when idle, records its timer id in a workbook name so orphans from VBA state loss are killed before re-arming, and tears down on workbook close.
- Idempotent. Re-running setup code adopts existing shapes instead of duplicating them, so an unhandled error that resets VBA state never leaves a broken sheet.
- Import
ROneCOne.clsfrom the latest release into your macro-enabled workbook. Each ReDim release attaches the ROneCOne version it was tested against. A workbook that already has ROneCOne 1.9.1 or later can keep its copy. - Import
ReDimUI.clsfrom the same release. - Import
ReDimHost.basfrom the same release.
Three imports, no references, no registration. Windows x64 Microsoft 365 Excel, the same target as ROneCOne.
Take all three files from the release rather than downloading them from a repository's src/.
The repositories store them with LF line endings, and the VBE imports an LF-only class file as
a standard module with its header pasted in as code. The release copies carry the CRLF endings
the VBE expects. They are built in CI from the tagged commit, with signed provenance:
gh attestation verify ReDimUI.cls --repo WilliamSmithEdward/ReDim checks a download.
Releases do not carry the demo workbooks. Build them from the VBA in demo/vba/ with
python tools/build_workbooks.py, which writes them into demo/. It injects the sources with
pyOpenVBA, so it needs Python and no Office; it reads ROneCOne.cls from a ROneCOne checkout
next to this one, or from the path in REDIM_RONECONE_PATH. Releases up to 1.1.1 attach the
workbooks they were built with. Open one with macros enabled and it builds itself (each ships
an Auto_Open); the entry macro rebuilds on demand.
| Workbook | Shows | Entry macro |
|---|---|---|
ReDim_Mission_Control.xlsm |
Three cancellable feeds with live progress, toasts, KPI cards, dark mode, confirm modal | BuildMissionControl |
ReDim_Widget_Gallery.xlsm |
Every component wired to a live state inspector, with the 1.0 controls in a tabbed section: form fields, a date picker, a sortable table, a skeleton | BuildWidgetGallery |
ReDim_Snake.xlsm |
A real game loop: paced pump job, arrow-key steering, score state, game-over modal | BuildSnake |
ReDim_Navigator.xlsm |
Sheets as forms: Navigate, back stack, lifecycle hooks | BuildNavigator |
ReDim_ReDex.xlsm |
The full-framework showcase: a living Pokedex on PokeAPI - async HTTP + JSON, sprite images, tweened stat bars, team building, custom theme with night mode | BuildPokeDex |
ReDim_Expense_Tracker.xlsm |
A small bookkeeping app from the 1.0 controls: a stacked form checked by ValidateAll, a table that filters as you type and deletes with an Undo toast, a sparkline and badge over six months, a budget meter, an Actions menu, and the command palette |
BuildExpenseTracker |
ReDim_Whats_New.xlsm |
A tour of 1.0.3 and 1.1.0 with a log of what each action did: two-way WritesTo, Tag and TagValue, filterable lists with disabled items, lists that scroll, Required picks, AutoGrow and placement that follows, themes from the With builders in any font, the pointer tint, focus rings, an op's task result, jobs sharing a step, the error sink, and a table that a search box, a status pick, and a region check list filter at once through state keys |
BuildWhatsNew |
Report a vulnerability privately from the repository's Security tab; SECURITY.md
has the details. It also sets out what ReDim's VBA does with Windows, keys, and the clipboard,
what the embedded ROneCOne runtime can do, and why macro scanners flag it. From 1.1.0, each
release attaches vX.Y.Z-security-report.md: olevba, mraptor, YARA-X, and ClamAV scan results
with reviewed reasons, plus SHA-256 hashes for every file the release carries.
VBA sources are plain files; workbooks are built artifacts.
pip install -r requirements-dev.txt
python tools/check.py # pyvbaanalysis static gate, zero findings in ReDim's sources
python tools/stamp_release.py # after a version bump: header in every release source
python tools/build_workbooks.py
python tools/security_scan.py --strict --clamav src/ReDimUI.cls src/ReDimHost.bas demo/*.xlsm
# reviewed findings; requires ClamAV and current signatures
python -m pytest tests/python # live Excel suite via pyvbaharness
python tools/bench.py --save before # timings in live Excel; later runs add --compare beforeThe live suite covers mount and adoption, dispatch and guards, bindings, batching, theming, the async op lifecycle, jobs, cancellation, every widget, a real armed-timer end-to-end run, a VBA compile gate for every shipped workbook, smoke runs of all seven demos, and an identifier-casing guard that exports the runtime, the demos, and sample host code through the VBE and requires every name back as written.
It drives a real Excel instance, so it cannot run on hosted CI. Continuous integration runs two static gates instead: pinned pyvbaanalysis over the same sources plus the ROneCOne runtime (CI), and the olevba, mraptor, YARA-X, and ClamAV scan over the runtime and demo workbooks it builds (Security). The live suite is a local step before release.
MIT. Every source ReDim ships, the two runtime files and each demo module, opens with the license text and the ReDim version and date it belongs to, so a copied module still says what it is and under what terms.