Excel compatibility

VBA support

Experimental

VBA support is experimental. Only pure worksheet UDFs run in production; workbooks that rely on macros, events, or worksheet mutation are refused rather than partially run. The supported subset and its behavior may change between releases, so treat a compile refusal — not a saved value — as the authoritative support decision.

xplo runs a deliberately narrow, production-safe slice of VBA: pure worksheet user-defined functions (UDFs). Covered Functions are compiled into every runtime artifact and recompute from live worksheet inputs, exactly like a built-in formula function.

What xplo runs

Support is decided for the whole VBA project, not one formula at a time. A macro-enabled .xlsm file is simply how the Function source reaches xplo — it is not permission to automate Excel.

CapabilityProduction workbooks
Run covered worksheet UDFs from cell formulasYes
Return scalars, worksheet errors, or arrays / spillsYes
Read cells and ranges passed in as Function argumentsYes
Run Sub procedures or button / form callbacksNo — workbook refused
Run Workbook_Open, Auto_Open, or worksheet eventsNo — workbook refused
Mutate cells, formulas, names, formatting, or app stateNo — workbook refused
Use files, the shell, COM, DLLs, or the networkNo — workbook refused

The whole-project acceptance rule

A workbook's VBA is accepted only when every one of these is true:

  • The embedded VBA source extracted completely and every module parses.
  • The project contains at least one Function.
  • Every procedure is an analyzer-proven pure Function.
  • Every Function lowers completely to the portable UDF runtime.
  • No procedure is a Sub, event handler, property procedure, workbook read, workbook mutation, or external / world effect.
  • The native Rust, WASM, and XVM artifacts all carry the same UDF programs.

If any part of the project falls outside this boundary, code generation fails with unsupported_vba and specific blocking reasons. xplo does not silently skip the unsupported procedure, and it never substitutes the values Excel last saved.

This rule is intentionally conservative. A workbook with one supported UDF and one unused Sub ExportReport() is still refused. Removing the Sub, or shipping a deployment copy whose VBA project contains only the pure Functions, makes the supported boundary explicit.

How to use supported VBA

Put pure Functions in a standard VBA module, save the workbook as .xlsm, and call them from ordinary worksheet formulas. Upload or build the .xlsm through the same workflow you use for .xlsx— there is no separate “enable macros” switch in xplo. The ingest pipeline extracts and analyzes the project, and the compiler embeds accepted Functions into every runtime artifact.

Option Explicit

Public Function WeightedAmount( _
    ByVal amount As Double, _
    Optional ByVal factor As Double = 1# _
) As Double
    WeightedAmount = amount * factor
End Function

Public Function NumericTotal(ByVal source As Range) As Double
    Dim cell As Range
    For Each cell In source.Cells
        If IsNumeric(cell.Value2) Then
            NumericTotal = NumericTotal + CDbl(cell.Value2)
        End If
    Next cell
End Function

These worksheet formulas are supported:

=WeightedAmount(A2, B2)
=WeightedAmount(A2)
=NumericTotal(C2:C20)
=Module1.NumericTotal(C2:C20)

For the smoothest path:

  • Use a standard module and ByVal parameters.
  • Pass every worksheet value or Range the Function reads as an explicit formula argument, so the dependency graph knows every cell it touches.
  • Keep the project free of Sub procedures, events, module state, and external capabilities.
  • Prefer small Functions and private pure helper Functions.
The formulas must already exist in the saved workbook. A setup macro that writes formulas during Workbook_Open or from a button will not run in production.

What is not supported

Anything that automates or mutates Excel puts the whole project outside the supported boundary:

  • An .xlsm file does not mean xplo runs its macros. Sub procedures, form / ActiveX and Ribbon callbacks, Workbook_Open, Auto_Open, and worksheet events all make the project unsupported.
  • The embedded project, not the filename, is authoritative. xplo checks for an actual xl/vbaProject.bin. Renaming an .xlsx to .xlsm, or dropping .bas files beside the workbook, does not add production VBA.
  • Files, the shell, COM, DLLs, and the network are never available to a production UDF.

The supported UDF subset

The portable runtime covers a focused subset. This describes the production runtime — not everything the parser or engineering tools understand.

Values, parameters, and results

  • Scalar Variant, Double, String, Boolean, Single, Currency, Date, Byte, Integer, Long, and LongLongvalues, with VBA coercion (including banker's rounding and four-decimal Currency) at typed boundaries.
  • ByVal parameters, optional parameters with literal defaults, omitted arguments, and ParamArray. A worksheet cell is never mutated by passing it ByRef.
  • Local fixed-size and dynamic arrays (including non-one-based bounds and Option Base), and one- and two-dimensional array results with mixed values, blanks, and worksheet errors.
  • Worksheet errors via CVErr, error propagation, Empty / Null behavior, and returning an explicit Range parameter with Set FunctionName = source.

Statements and control flow

  • Local declarations and assignments; If / ElseIf / Else (including single-line forms).
  • For loops with an omitted or positive-literal Step; For Each over local arrays, Range cells, and Range areas.
  • ReDim without Preserve, Exit Function, self-recursion with a depth guard, and calls to other covered pure Functions (mutual recursion is refused).
  • On Error GoTo label, On Error GoTo 0, the Error statement, and the error-number portion of Err.Raise.

Operators and built-ins

  • Arithmetic + - * / and Mod, concatenation &, comparisons = < <= >, and Or / Not with unary + / -. String comparison is VBA's default binary, case-sensitive ordering.
  • A focused built-in set: CVErr, CStr, CDbl, CCur, CSng, CLng, DateSerial, Year, Month, Day, Sqr, LBound, UBound, Len, LCase, ChrW, IsNumeric, IsMissing, IsObject, IsError, IsEmpty, TypeName, and VarType, plus the worksheet error constants.
  • Range operations rooted in an explicit Range parameter: .Value / .Value2, .Cells(row, column), .Rows.Count, .Columns.Count, .Cells.Count, .Areas.Count, iteration over .Cells and .Areas, .Worksheet.Name, .HasFormula, and Application.WorksheetFunction.Sum(...).