That is Copilot. It is kind of mind boggling how clear and concise it is.
So somewhat related question I had is why you can use TempVars in a query and not a VBA variable. It is also related to above.
Access looks inconsistent here at first glance, but once you understand
which engine is doing the work, the behavior makes perfect sense.
Let’s break it down cleanly.
Why TempVars work in queries but VBA variables don’t
Access queries are evaluated by the
Expression Engine, not the VBA runtime.
That single fact explains everything.
The Expression Engine can only “see” things that are:
- Stored in Access’s global expression namespace
- Exposed through Access’s object model
- Designed to be expression‑safe
TempVars meet all three criteria.
VBA variables meet none of them.
1. TempVars are part of Access’s global expression namespace
TempVars live in a global collection that Access exposes to:
- Queries
- Macros
- Control sources
- Validation rules
- Event property expressions
The Expression Engine knows how to resolve:
TempVars!MyValue
because TempVars are explicitly registered with the engine.
This makes them “expression-visible.”
2. VBA variables are private to the VBA runtime
A VBA variable—whether declared in:
- a procedure
- a module
- a class
- a form/report module
exists
only inside the VBA runtime, not in the expression engine.
The Expression Engine has
no mechanism to:
- inspect the call stack
- read module-level variables
- read static variables
- read local variables
- read object variables
- read anything stored in the VBA runtime
So when a query tries to evaluate:
MyVbaVariable
the expression engine simply has no idea what that is.
3. TempVars were created specifically to bridge the gap
TempVars were introduced in Access 2007 for exactly this reason:
- Developers needed a way to pass values from VBA → queries/macros/forms
- Without relying on hidden controls or global functions
TempVars are:
- Global
- Persisted
- Expression-safe
- Thread-safe within Access’s single-threaded UI model
- Accessible from both VBA and the Expression Engine
They are the official “shared memory” between the two worlds.
4. Why Access doesn’t expose VBA variables to queries
There are deep architectural reasons:
a. Expression Engine must be deterministic
Queries may be:
- cached
- optimized
- executed outside the form context
- run by the ACE engine (JET successor) without the UI loaded
VBA variables are not stable enough for that.
b. VBA variables can disappear
They vanish when:
- a form closes
- a module resets
- an error occurs
- the project recompiles
- Access auto-compacts memory
The query engine cannot depend on such volatile state.
c. Security and sandboxing
Expression evaluation must be safe.
VBA variables could expose objects, file handles, or unsafe references.
Bottom Line
| Feature | TempVars | VBA Variables |
|---|
| Visible to Expression Engine | Yes | No |
| Visible to VBA | Yes | Yes |
| Persist across queries | Yes | No |
| Designed for cross-engine communication | Yes | No |
| Can be used in queries | Yes | No |
Access can evaluate TempVars in a query because TempVars are part of the expression engine’s global namespace.
Access cannot evaluate VBA variables because they exist only inside the VBA runtime.
If you want, I can show you the cleanest patterns for passing values from VBA to queries—TempVars, hidden controls, global functions, or parameterized DAO queries—and when each one is the best choice.