Your Access database has been running your business for years. Maybe decades. It tracks inventory, manages customer records, runs payroll reports, or logs service calls. And then you upgraded to Windows 11 — or moved to a new machine with 64-bit Office — and suddenly it doesn't work anymore.
This is the guide you need. We'll cover everything: the difference between .mdb and .accdb, what actually breaks during migration, how to preserve your VBA code, what to do about ActiveX controls, how Jet SQL differs from ACE SQL, and how to verify that nothing was lost after the move.
Other tools — including some that claim to migrate Access databases — only move your data. Your VBA code, your forms, your ActiveX controls, your Jet SQL procedures: most tools silently drop all of it. This guide explains what a real migration covers.
Both .mdb and .accdb are Microsoft Access database formats, but they use completely different underlying database engines.
| Feature | .mdb (Legacy) | .accdb (Modern) |
|---|---|---|
| Database engine | Jet 4.0 | ACE (Access Connectivity Engine) |
| Introduced | Access 97 | Access 2007 |
| Max database size | 2GB total | 2GB per database file (same as .mdb) |
| Max table size | 2GB | 2GB (same, but more flexible) |
| Encryption | Weak (RC4-based) | Strong (AES-256) |
| Multi-value fields | Not supported | Supported |
| Attachment fields | Not supported | Supported |
| 64-bit Windows 11 | Broken (Jet not available) | Fully supported |
| Office 365 compatibility | Limited / broken | Full |
| Jet OLEDB provider | Required (deprecated) | Not needed (uses ACE OLEDB) |
The core issue is the database engine. Jet 4.0 is a 32-bit engine that Microsoft stopped developing after Access 2003. It was never ported to 64-bit. Windows 11 64-bit doesn't include the 32-bit Jet provider by default, and even when installed, Jet has known security vulnerabilities that Microsoft will not patch.
ACE (Access Connectivity Engine) is Jet's replacement. It's 64-bit native, actively maintained, and included with all modern Office installations.
The Jet OLEDB 4.0 provider is not present on clean Windows 11 64-bit installations. This means any application that tries to open an .mdb file using the standard OLEDB connection string will fail. This affects not just Access itself — it affects Excel workbooks that query Access, .NET applications using OleDbConnection, and any VBA code that uses DAO or ADO to connect to .mdb files.
Jet 4.0 has several publicly documented security vulnerabilities (CVE-2018-8423, CVE-2019-1024, and others). Microsoft has explicitly stated these will not be patched because Jet is end-of-life. If your .mdb database is accessible from a network or web application, running Jet 4.0 is a security risk.
The RC4-based encryption in .mdb is easily broken by free tools. If you're encrypting sensitive data in an .mdb database and believe it's protected — it isn't. AES-256 encryption in .accdb is legitimate.
Most enterprise IT departments have already removed or blocked the Jet OLEDB 4.0 redistributable as part of security hardening. If your business has users on managed Windows 11 machines, they likely can't open .mdb files even if they want to.
LegacyLeaps scans your .mdb file and produces a report of every VBA issue, broken reference, and compatibility problem — before you convert anything.
Run Free ScanBefore you touch anything, document everything. A migration without a pre-migration inventory is how databases get partially migrated and then used in production half-working for months.
SELECT Name, Type FROM MSysObjects WHERE Type IN (1, 4, 5, 6) ORDER BY Type, Name — this lists tables (1), queries (5), forms (2), and reports (3).
Copy the .mdb file to a separate drive or cloud storage. Do not proceed without a verified backup. This sounds obvious but is the most commonly skipped step — and the source of most irreversible migrations.
Before converting, compact and repair the .mdb in its original version of Access (or the nearest available). This catches any pre-existing corruption. A database with corruption before migration will have worse corruption after it. Tools > Database Utilities > Compact and Repair Database.
Open the compacted .mdb in Access 2016, 2019, 2021, or 365. Go to File > Save As > Access Database (.accdb). Give the new file a distinct name — don't overwrite the .mdb.
Access will convert the data, queries, forms, reports, macros, and VBA modules. It will not automatically fix compatibility issues — it will just copy them into the new container. The compatibility work happens in the steps below.
This is where most migrations fail if done manually. See the VBA section below for complete details. At minimum: add PtrSafe to all Declare statements, replace Long with LongPtr for pointers, and resolve broken references.
Open every form and check for errors. ActiveX controls that reference 32-bit-only libraries will not load on 64-bit Office. See the ActiveX section for replacement strategies.
Open the Linked Table Manager (External Data > Linked Table Manager) and refresh all connections. Update any paths that pointed to the old .mdb files.
Run every query in the database. Pay attention to queries that use: IN with subqueries, TRANSFORM/PIVOT, TOP with ties, and date arithmetic using # delimiters. Some Jet SQL behaviors changed slightly in ACE.
See the Data Integrity Verification section. Don't skip this. Record counts must match exactly.
This is the section that distinguishes a real migration from a "data dump." Most migration tools — including SysTools — extract your tables and queries but silently ignore your VBA code modules. Your forms lose their event handlers. Your reports lose their custom formatting logic. Your automation stops working.
When you use Access's Save As to convert from .mdb to .accdb, the following transfers without intervention:
64-bit Office VBA requires the PtrSafe keyword on every Declare statement. Without it, any Declare in your code will cause a compile error in 64-bit Access.
' Before (fails on 64-bit Office)
Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
' After (works on 32-bit and 64-bit Office)
Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Parameters that represent window handles, memory addresses, or pointers should use LongPtr instead of Long. LongPtr is 32-bit on 32-bit Office and 64-bit on 64-bit Office, so it's the right type for any pointer or handle value.
If your VBA code opens connections to other databases using ADO, the connection string must be updated to reference ACE OLEDB instead of Jet OLEDB:
' Old (Jet — fails on 64-bit Windows 11)
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & dbPath
' New (ACE — works on current systems)
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.16.0;Data Source=" & dbPath
Tools > References in the VBA editor. Anything marked MISSING needs to be removed and re-added (if still needed) or removed entirely (if the library is obsolete). Common culprits:
LegacyLeaps scans your entire .mdb database, identifies every VBA compatibility issue, and applies all fixes automatically during migration. No code editing required.
See Done-For-You MigrationMost Jet SQL works identically in ACE. But there are edge cases that can silently return different results or throw errors after migration.
Jet SQL uses # delimiters for date literals: WHERE OrderDate = #01/15/2020#. ACE SQL accepts the same syntax, but regional date format interpretation can vary. If your database was created in a UK locale and is now running in a US locale (or vice versa), date queries may return wrong results.
Best practice: Use ISO 8601 format in date literals: #2020-01-15#. This is unambiguous in both Jet and ACE.
Jet SQL supported an older outer join syntax using *= and =* from the early SQL days. This does not work in ACE. Replace with standard ANSI LEFT JOIN, RIGHT JOIN, and FULL OUTER JOIN.
' Old Jet syntax (broken in ACE)
SELECT * FROM Customers, Orders WHERE Customers.ID *= Orders.CustomerID
' Standard ANSI (works in ACE)
SELECT * FROM Customers LEFT JOIN Orders ON Customers.ID = Orders.CustomerID
Jet SQL's DISTINCTROW keyword (which removes duplicates based on entire rows from the source table) has different behavior in ACE in edge cases. Review any queries using DISTINCTROW carefully.
In Jet, SELECT TOP 10 would return up to 10 records but might return more if there were ties on the ordering column. ACE behavior is similar but there are known edge cases. Verify TOP queries return expected record counts.
These Access-specific functions work in both Jet and ACE, but IIf() always evaluates both branches in Jet (even the one not selected), which can cause errors. ACE behavior is similar. Avoid IIf() with side-effect expressions.
Pass-through queries use the syntax of the back-end database, not Jet/ACE. If your .mdb had pass-through queries to SQL Server, they will continue to work after migration to .accdb — assuming the ODBC connection string is valid.
This is the issue most migration guides — and most migration tools — skip entirely. ActiveX controls are COM components embedded in Access forms and reports. They add functionality like calendars, progress bars, rich text editors, and custom grid controls.
The problem: many ActiveX controls are 32-bit only. A 32-bit ActiveX control cannot load in 64-bit Access. The form opens, but the control is a grey box with an error, and any code referencing it throws a runtime error.
Open each form in Design View. Any control with a small icon in the corner is likely an ActiveX control. Check the Properties sheet — the Control Source property will be blank and the control class will show something like Forms.{GUID}.0 or a descriptive name like MSComctlLib.ProgressBar.
| Legacy ActiveX Control | 64-bit Status | Replacement |
|---|---|---|
| Microsoft Calendar Control (mscal.ocx) | 32-bit only — broken | Use a text box with Date Picker or free Date Picker from Microsoft |
| MSComctlLib (ListView, TreeView, ProgressBar) | 32-bit only — broken | MSCOMCTL.OCX has a 64-bit version — re-register it, or use VBA-drawn alternatives |
| Microsoft Masked Edit Control | 32-bit only — broken | Use native Access input masks on text boxes |
| Microsoft Rich Textbox Control | 32-bit only — broken | Use a bound text box with Memo/Long Text field type |
| Microsoft WebBrowser Control | 64-bit version exists | May work after re-registration — test carefully |
| Tabstrip Control (MSComctlLib) | 32-bit only — broken | Use native Access Tab Control |
For controls that have 64-bit versions available, you can try re-registering the .ocx file. Open Command Prompt as Administrator and run: regsvr32 "C:\Windows\SysWOW64\MSCOMCTL.OCX". This may restore some controls but will not help for controls with no 64-bit version at all.
If your database has dozens of forms with ActiveX controls, manual replacement becomes a large project. Each control replacement requires testing the form, rewriting any VBA that referenced the old control's properties and methods, and verifying the replacement behaves identically.
This is exactly the kind of migration complexity that LegacyLeaps's done-for-you service handles — we document every ActiveX control, identify the replacement strategy, and implement it as part of the migration.
Linked tables are one of the most common sources of post-migration headaches. The table data doesn't live inside the .mdb — it lives elsewhere, and the .mdb just contains a connection string and schema definition.
After your main database converts to .accdb, any linked .mdb files also need to be converted (or the links updated to use the Jet OLEDB provider with the redistributable). The simplest approach: convert all linked .mdb databases first, then update the links in the main database to point to the new .accdb files.
Use the Linked Table Manager (External Data > Linked Table Manager) to view and update all links at once. You can also update links programmatically:
' VBA to update all linked table connection strings
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Set db = CurrentDb()
For Each tdf In db.TableDefs
If Left(tdf.Connect, 10) = ";DATABASE=" Then
' Update the path to the new .accdb location
tdf.Connect = ";DATABASE=C:\NewPath\Database.accdb"
tdf.RefreshLink
End If
Next tdf
ODBC-linked tables (SQL Server, MySQL, Oracle) generally survive migration without changes — the ODBC connection string doesn't care whether the front-end is .mdb or .accdb. However, verify that the ODBC driver is still registered on the new machine and that connection strings are still valid.
SharePoint-linked tables are stored differently in .accdb vs .mdb. After migration, you may need to unlink and re-link SharePoint tables. Access's External Data > SharePoint List wizard handles this.
Links to .xls spreadsheets use the Jet OLEDB provider — same as .mdb files. On 64-bit Windows 11, these links will fail too. Convert linked Excel files to .xlsx first, then update the links to use the ACE OLEDB provider with the Excel connection string format.
The most important step — and the one most commonly skipped. Do not declare a migration complete until you've verified that every record, every relationship, and every computation produces the same result in the new database.
Run this in both the old and new database. Counts must match exactly:
-- Run in both .mdb and .accdb and compare output
SELECT 'Customers' AS TableName, COUNT(*) AS RecordCount FROM Customers
UNION ALL
SELECT 'Orders', COUNT(*) FROM Orders
UNION ALL
SELECT 'Products', COUNT(*) FROM Products
-- (add all tables)
ORDER BY TableName
Open the Relationships window (Database Tools > Relationships) in both databases and compare. Referential integrity settings, cascade delete/update settings, and join types must all match.
Run every query in both the old and new database on the same date/time and compare outputs. For large result sets, export to CSV and diff the files. Pay special attention to aggregate queries, date-range queries, and queries with complex joins.
Open every form in Normal view (not Design view). Click every button, fill every input, trigger every event. Check that all subforms load, all calculated fields display correctly, and all record navigation works. Run every report and visually verify the output against a known-good printout from the old version.
Run every VBA procedure that's accessible via button click, form event, or standalone module. Check the Immediate Window (Ctrl+G in VBA editor) for runtime errors during execution.
After migration and validation, run Compact and Repair on the new .accdb (Database Tools > Compact and Repair Database). This rebuilds indexes, reclaims space, and catches any internal inconsistencies introduced by the migration.
Converting to .accdb is the right move for most small business Access databases. But if your database has grown beyond what Access was designed for, migration to SQL Server (with Access as a front-end, or a full application rewrite) may be the better long-term investment.
This is the lowest-risk migration path: keep your Access forms, reports, and VBA code exactly as-is, but move the data tables to SQL Server. The Access database becomes a thin client connected to SQL Server via ODBC linked tables.
This preserves all your Access-specific UI work while gaining SQL Server's reliability, scalability, and backup capabilities. It's the approach recommended for databases with more than 5 concurrent users or files over 500MB.
A full migration (rewriting the Access front-end as a web application or thick client against SQL Server) makes sense when the Access UI itself is the bottleneck — outdated forms, poor performance, or a need to add web or mobile access. This is a larger project and typically requires developer engagement.
For most businesses, the right answer is .accdb first, SQL Server later if needed. Converting to .accdb solves the immediate compatibility problem. If you grow into SQL Server territory, you migrate from a stable .accdb rather than a broken .mdb.
Use this checklist before calling a migration complete.
Coming Soon
AI-powered code generation from .accdb files. Your data never leaves your machine.
LegacyLeaps handles the full migration: VBA fixes, ActiveX replacement, Jet SQL updates, linked table refresh, and data integrity verification. 100% money-back guarantee — if LegacyLeaps doesn't preserve your VBA code, forms, and data, we'll refund every penny.
Get a Free ConsultationPractical fixes for legacy Excel and Access problems. No spam.