Expert guide
Document a Legacy Access Database with AI
Turn a database nobody understands into a map you can maintain, migrate or retire
Call us at +1 (385) 386-3860
Short answer: export every query's SQL and every form, report, macro and module as text with a short VBA routine, then have AI explain each object in plain English: purpose, tables read, tables changed, and dependencies. Combine that with a relationship diagram, linked table paths and interviews with users, and you have documentation that makes the database safe to change. If the goal is a migration, an Access consultant can turn the result into a scoped plan.
It is a common situation: the person who built the company's Access database left, retired or moved on. The database still runs invoicing, scheduling or inventory. It has 140 queries named Query1 to Query140, forms with buttons that do mysterious things, and a nightly macro nobody is sure about. Nobody wants to touch it, and nobody can replace it, because nobody knows exactly what it does.
AI has made documenting these systems dramatically faster. It reads SQL and VBA quickly and explains it clearly. What it cannot do on its own is decide what matters. This process combines both.
Step 0: Work on Copies
Copy the front end and the back end to a separate folder. Turn off any startup form or AutoExec macro on the copy by holding Shift while opening it. Everything below happens on the copy.
Step 1: Build an Inventory
Paste this into a new module and run it. It lists every object with its type and last-modified date into a new table.
Public Sub BuildInventory()
Dim db As DAO.Database, doc As DAO.Document, ctr As DAO.Container
Dim td As DAO.TableDef
Set db = CurrentDb
On Error Resume Next
db.Execute "DROP TABLE zInventory"
On Error GoTo 0
db.Execute "CREATE TABLE zInventory (ObjType TEXT(20), ObjName TEXT(255), " & _
"LinkedTo TEXT(255), Modified DATETIME)"
For Each td In db.TableDefs
If Left$(td.Name, 4) <> "MSys" And Left$(td.Name, 1) <> "~" Then
db.Execute "INSERT INTO zInventory VALUES ('Table','" & td.Name & "','" & _
Replace(td.Connect, "'", "''") & "',#" & _
Format(td.LastUpdated, "yyyy-mm-dd hh:nn:ss") & "#)"
End If
Next td
For Each ctr In db.Containers
Select Case ctr.Name
Case "Forms", "Reports", "Scripts", "Modules"
For Each doc In ctr.Documents
db.Execute "INSERT INTO zInventory VALUES ('" & ctr.Name & "','" & _
doc.Name & "','',#" & _
Format(doc.LastUpdated, "yyyy-mm-dd hh:nn:ss") & "#)"
Next doc
End Select
Next ctr
Dim qd As DAO.QueryDef
For Each qd In db.QueryDefs
If Left$(qd.Name, 1) <> "~" Then
db.Execute "INSERT INTO zInventory VALUES ('Query','" & qd.Name & "','',#" & _
Format(qd.LastUpdated, "yyyy-mm-dd hh:nn:ss") & "#)"
End If
Next qd
End Sub"Scripts" is the container for macros. The LinkedTo column shows the connection string for linked tables, which tells you where the real data lives: an Access back end, SQL Server, Excel files or something stranger.
Step 2: Export Everything as Text
Public Sub ExportAllAsText(ByVal folder As String)
Dim db As DAO.Database, qd As DAO.QueryDef, f As Integer
Dim obj As AccessObject
Set db = CurrentDb
If Right$(folder, 1) <> "\" Then folder = folder & "\"
MkDir folder & "queries": MkDir folder & "forms"
MkDir folder & "reports": MkDir folder & "modules": MkDir folder & "macros"
For Each qd In db.QueryDefs
If Left$(qd.Name, 1) <> "~" Then
f = FreeFile
Open folder & "queries\" & qd.Name & ".sql" For Output As #f
Print #f, qd.SQL
Close #f
End If
Next qd
For Each obj In CurrentProject.AllForms
Application.SaveAsText acForm, obj.Name, folder & "forms\" & obj.Name & ".txt"
Next obj
For Each obj In CurrentProject.AllReports
Application.SaveAsText acReport, obj.Name, folder & "reports\" & obj.Name & ".txt"
Next obj
For Each obj In CurrentProject.AllModules
Application.SaveAsText acModule, obj.Name, folder & "modules\" & obj.Name & ".bas"
Next obj
For Each obj In CurrentProject.AllMacros
Application.SaveAsText acMacro, obj.Name, folder & "macros\" & obj.Name & ".txt"
Next obj
End SubRun ExportAllAsText "C:\AccessDocs\" and you have a folder you can search with any text editor. Search for a table name and you instantly see every query, form and module that uses it. Commit the folder to version control and you have a baseline for every future change.
Step 3: Let AI Explain Each Object
Form text exports are long; for forms, extract just the RecordSource and the code-behind module. Then use prompts like these:
For each Access query below, return a table with: name | purpose in one sentence | tables read | tables changed (if action query) | parameters or form references | risks (deletes, make-table, hard-coded dates). Use plain business language. [paste 10–20 query SQL texts with their names]
Explain this Access VBA module for a non-programmer: 1. What each procedure does and when it runs (event, button, startup). 2. Every table it reads or writes. 3. Any file paths, servers, emails or external systems it touches. 4. Anything that deletes or overwrites data. 5. Likely problems if the back end moved to SQL Server. [paste module]
Step 4: Find What Is Actually Used
Old databases contain a lot of dead weight. AI cannot tell you what is used; evidence can.
Last-modified dates
Objects untouched for many years are candidates, but not proof: a stable report may simply work.
References
Search the exported text for each query name. A query referenced by no form, report, macro or module, and not run by users directly, is probably dead.
Usage logging
Add a one-line call in each form's Open event and each report's Open event to log name, user and time. A month of logs tells you what people use.
Interviews
Ask each user to show you their weekly routine. People use objects in ways nobody planned.
Step 5: Write It Up
| Section | What to include |
|---|---|
| Overview | Business processes the database supports, users, where it runs |
| Data map | Tables grouped by area, relationships diagram, linked table locations |
| Processes | For each process: forms used, queries run, reports produced, tables changed |
| Automation | Macros, scheduled tasks, startup code, external connections |
| Risks | Hard-coded paths, missing backups, size near 2 GB, 32-bit dependencies, single points of knowledge |
| Retirement list | Objects with no evidence of use, to archive after confirmation |
What Usually Turns Up
Queries with hard-coded years that someone edits every January.
Back end on a mapped drive letter that only works on some PCs.
VBA using 32-bit Declare statements that will break on 64-bit Office.
No referential integrity, and orphan records in child tables.
Passwords for SQL Server or email in plain text in a module.
An Excel file that is imported nightly and is the real source of truth.
The 64-bit issue is covered in converting Access VBA to 64-bit. Once documented, the decision becomes clearer: keep and stabilise, extend, or migrate and upgrade. Writing new code against the documented database is safer with the approach in using AI for Access VBA.
FAQ
Documenting legacy Access databases FAQ
Inventories, exports and AI explanations