A macro broken by an Office update: telling Mark of the Web from a MISSING reference from a Declare without PtrSafe, why lowering macro security is not a fix.
Key takeaways
- "Microsoft has blocked macros from running because the source of the file is untrusted" is not a code error. It is a Zone.Identifier mark Windows attached to the file.
- Removing that mark is a per-file action: right-click > Properties > Unblock, or `Unblock-File` in PowerShell.
- A broken reference is labelled explicitly in Tools > References with a `MISSING:` prefix, and it throws a compile error on a line that has nothing to do with the problem.
- From Office 2019 and Microsoft 365, the default install is 64-bit. Every `Declare` statement then requires the `PtrSafe` keyword.
- Lowering macro security treats one symptom and leaves everything else open. It is not a diagnostic step.
In most cases the file is not damaged. Three separate mechanisms explain nearly every occurrence: macro blocking on files that came from outside the machine (Mark of the Web), a reference that broke in Tools > References, and a Declare statement that a 64-bit Office build refuses to compile. Each has a different fix.
What actually changed - on the machine, not in the file
An Office update almost never changes the code stored inside the workbook. It changes three things around it: the versions of the object libraries registered on the machine, the compilation architecture (32-bit or 64-bit), and the default behaviour towards files that arrive from the internet or from a network share.
So the first diagnostic question is not "what is in the code" but "where does this file live and where did it come from". A file that ran for years out of a local folder and was suddenly emailed to a colleague will behave differently without a single line changing.
Which message did you get, exactly?
The message is the diagnosis. These four cover most cases:
| What appears on screen | Mechanism | Where to look | The correct fix |
|---|---|---|---|
| "Microsoft has blocked macros from running because the source of the file is untrusted" | Mark of the Web on the file | File properties in Explorer | Unblock the file, or make the folder a Trusted Location |
| "Compile error: Can't find project or library" | A reference that cannot be resolved | Alt+F11 > Tools > References | Clear the MISSING: entry and point at the version present |
An error stating a Declare statement lacks PtrSafe | Compiling under 64-bit Office | Every Declare line in the project | Add PtrSafe and widen the data types |
Code halts on an innocent line such as Left(...) or Date | A broken reference breaking name resolution | The same References dialog | Identical to row two |
That last row wastes the most time. When a reference is missing, VBA can no longer resolve the names of built-in functions, so it flags an error on a line that looks entirely ordinary. Anyone who starts editing that line is fixing something that was never broken.
Why does removing Mark of the Web work when lowering macro security does not?
Because they are two different mechanisms. Mark of the Web is a marker the operating system attaches to a file that was downloaded through a browser, received as an attachment, or opened from a location outside the trusted zone - and it travels with the file. Removing it deals with one file and leaves the protection active for everything else.
Lowering the setting in the Trust Center, by contrast, disables the check for every file that machine opens from then on - including the next one that arrives by email and that you did not write. It also does not reliably work: a file sitting on a network share that is not in the Local intranet zone or in the trusted sites list is blocked regardless.
The three correct routes, in order of scope:
- A single file: right-click > Properties > tick Unblock on the General tab. If that checkbox is absent, the PowerShell
Unblock-Filecmdlet removes the same marker. - A folder you control: add it as a Trusted Location via File > Options > Trust Center > Trust Center Settings.
- A recurring source, such as an internal server: add the location to Windows trusted sites so files from it never acquire the marker in the first place.
The reference that went MISSING
In Alt+F11 > Tools > References, an unresolved entry is prefixed MISSING:. That happens when the DLL is registered on the machine but the file itself was removed, moved, or replaced by another version - for example after a jump from one Outlook version to a newer one.
One behaviour matters before you touch anything: a workbook saved on a machine with the newer version pins the reference to that version, and then breaks on the machine still running the older one. That is why the fault appears for some users and not others, and why it returns after being "fixed".
- Untick the
MISSING:entry and click OK. - Run Debug > Compile to see what is still unresolved.
- If the code genuinely needs the library, tick the version present on the machine and compile again.
- For code that runs across users on different versions, switching to late binding - declaring as
Objectand usingCreateObject- takes the reference out of the equation entirely.
32-bit to 64-bit: the statements that stop compiling
Office 2010 through 2016 installed as 32-bit by default. From Office 2019 and Microsoft 365, the default is 64-bit. The difference only affects code that calls the Windows API directly through a Declare statement.
In older code, pointers and handles were declared as Long, a 4-byte type. In a 64-bit environment those are 8-byte values, and they get truncated. Microsoft added three tools: the PtrSafe keyword, which asserts a statement targets 64-bit; the LongPtr alias, which resolves to Long on 32-bit and LongLong on 64-bit; and the LongLong type itself.
A legacy declaration that reads:
Declare Function GetActiveWindow Lib "user32" () As Long
becomes:
Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
Note the trap that catches half-finished fixes: adding PtrSafe alone satisfies the compiler but does not repair a return value still typed Long. The code runs and returns a truncated value. If the file must work in both environments, wrap the declarations in #If VBA7 Then and #If Win64 Then.
A diagnosis order that does not destroy evidence
- Copy the file aside. Everything from here happens on the copy.
- Record the exact message wording, the Office version, and the architecture (File > Account > About).
- Establish the file's origin: download, attachment, network share, or local folder.
- If the message is the macro block, deal with the marker, not with the security level.
- If the macro does run but fails, open Alt+F11 and run Debug > Compile before reading any code.
- Open the References dialog and look for
MISSING:. - Only if no reference is missing, search every module for
Declareand check forPtrSafe.
What to verify before calling it fixed
- The file was tested by a second user, not only by whoever fixed it.
- It was tested from the location it is actually opened from day to day, not from the desktop.
- Any security level changed temporarily has been restored.
- References were checked on the machine running the oldest Office version still in use.
A macro file that has become business infrastructure and breaks itself on every update is a familiar signal. The same question arises when one spreadsheet carries an entire process - see when a spreadsheet has outgrown itself, handing over a single-owner spreadsheet, and a method for consolidating forty Excel files.
Sources
Frequently asked questions
Can I unblock every file in a folder at once?
Yes. The PowerShell `Unblock-File` cmdlet accepts a path and strips the Zone.Identifier from every file passed to it. It still only affects files that already exist: a new download into that folder acquires the marker again, unless the folder has been declared a Trusted Location.
Why does the error point at a line that worked for years?
When a reference fails to resolve, VBA loses the ability to resolve the names of built-in functions, and the error lands on the first line that uses one. The line is fine. The missing reference is the fault, and it shows in Tools > References with the MISSING prefix.
How do I tell whether Office is 32-bit or 64-bit?
File > Account > About, in any Office application. The first line states the version and the architecture. That single fact determines whether Declare statements in the code must carry the PtrSafe keyword, which is why it is the first detail to record before touching any code at all.
Does digitally signing the project solve this?
Partly. Signing with a certificate configured as a trusted publisher allows the macro to run without unblocking each file separately, and it is the right approach for an organisation distributing files internally. It does nothing for a missing reference and nothing for Declare statements that were never adapted to 64-bit.
Keep reading
Related service
Access & Excel Rescue
Stabilise the file the business runs on, then fix it or move it to the web.
About the author
Yehonatan Saadia
Freelance automation, web & MVP developer
I'm Yehonatan Saadia, a senior developer who builds business automation, custom websites, and MVPs for small and mid-sized companies across the US, Europe, and Israel. These guides come from real client work, not theory.
Work with meHave a project like this?
Tell me what you're trying to automate or build. I reply within 24 business hours with a few targeted questions, then we walk through it on a free 30-minute call, with no commitment. You come away with a scope, a timeline and a fixed price - or a straight answer that it isn't worth building.
