Expert guide

Using AI to Write Microsoft Access VBA

What to tell the AI about your database, safe code patterns, and what to check before you run it

Short answer: tell the AI it is Microsoft Access VBA, name the form, controls, tables and fields, and say whether tables are linked or on SQL Server. Ask for Option Explicit, DAO with CurrentDb.Execute dbFailOnError rather than SetWarnings, and an error handler in every procedure. Compile, test on copies of front end and back end, and step through with F8. For code that the whole team depends on, use Access VBA development.

Access databases often run critical processes with VBA written by someone who left years ago. AI can extend that code, explain it, and fix it, which is genuinely useful. It can also introduce bugs that only show up when three people use the database at once. The difference is in what you tell it and what you check.

What the AI Needs to Know

  • That it is Access, not Excel

    Otherwise you get Range and Worksheet objects that do not exist in Access.

  • The form and control names

    frmOrders with txtCustomerID, cboStatus, cmdSave, and the subform control name, not just the subform's form name.

  • Tables and key fields

    Which table the form is bound to and the primary key.

  • Where the data lives

    Local tables, linked Access back end on a network share, or linked SQL Server tables. Some techniques behave differently.

  • Who uses it

    One person, or several at once. Multi-user code needs record-locking awareness.

A Prompt Template That Works

Microsoft Access 365 VBA (DAO). Split database; tables linked from
\\server\data\Ops_BE.accdb. 5–8 concurrent users.
Form frmOrders, bound to tblOrders (PK OrderID).
Controls: cboCustomerID, txtOrderDate, cboStatus, cmdApprove.
Task: when cmdApprove is clicked:
  1. If cboStatus is not "Pending", show a message and stop.
  2. Set Status to "Approved", ApprovedBy to the Windows user name,
     ApprovedOn to Now().
  3. Insert a row in tblOrderLog (OrderID, Action, User, LoggedAt).
  4. Save the record and refresh the form.
Rules: Option Explicit, error handler, CurrentDb.Execute with
dbFailOnError, no DoCmd.SetWarnings. Comment each block.

What Good Access VBA Looks Like

Option Compare Database
Option Explicit

Private Sub cmdApprove_Click()
    On Error GoTo Fail
    Dim db As DAO.Database
    Dim userName As String

    If Nz(Me.cboStatus, "") <> "Pending" Then
        MsgBox "Only Pending orders can be approved.", vbExclamation
        Exit Sub
    End If

    ' Save any unsaved edits first so we update the current values
    If Me.Dirty Then Me.Dirty = False

    userName = Environ("USERNAME")
    Set db = CurrentDb

    db.Execute "UPDATE tblOrders SET Status = 'Approved', " & _
               "ApprovedBy = '" & Replace(userName, "'", "''") & "', " & _
               "ApprovedOn = Now() WHERE OrderID = " & Me.OrderID, dbFailOnError

    db.Execute "INSERT INTO tblOrderLog (OrderID, Action, [User], LoggedAt) " & _
               "VALUES (" & Me.OrderID & ", 'Approved', '" & _
               Replace(userName, "'", "''") & "', Now())", dbFailOnError

    Me.Requery
    MsgBox "Order " & Me.OrderID & " approved.", vbInformation

Done:
    Set db = Nothing
    Exit Sub
Fail:
    MsgBox "Could not approve order: " & Err.Description, vbCritical
    Resume Done
End Sub
  • Me.Dirty = False saves pending edits, avoiding a write conflict between the form and the UPDATE.

  • dbFailOnError raises an error instead of silently skipping locked or invalid rows.

  • Replace(..., "'", "''") prevents a user name with an apostrophe from breaking the SQL.

  • [User] is bracketed because User is a reserved word in Access SQL.

Recordset Loop Pattern AI Should Follow

Dim rs As DAO.Recordset
Set rs = CurrentDb.OpenRecordset( _
    "SELECT OrderID, Total FROM tblOrders WHERE Status = 'Open'", _
    dbOpenDynaset, dbSeeChanges)

Do While Not rs.EOF
    If rs!Total > 10000 Then
        rs.Edit
        rs!NeedsReview = True
        rs.Update
    End If
    rs.MoveNext
Loop
rs.Close: Set rs = Nothing

dbSeeChanges is required when the table is a linked SQL Server table with an identity column; without it you get error 3622. AI often omits it. If the change can be expressed as one UPDATE query, that is faster and simpler than a loop.

Review Checklist for AI-Written Access Code

  • Compile first

    Debug → Compile catches undeclared variables, wrong control names and missing references before anything runs.

  • Search for DoCmd.SetWarnings

    Replace with CurrentDb.Execute ... dbFailOnError.

  • Search for DELETE and DROP

    Confirm the WHERE clause, test it as a SELECT.

  • Check string-built SQL

    Text values need quotes and apostrophe escaping; dates need # and a safe format such as Format(d, "\#yyyy-mm-dd\#").

  • Check every procedure has an error handler

    Unhandled errors in Access Runtime close the application.

  • Check object cleanup

    Recordsets closed, objects set to Nothing, especially in loops.

Errors AI-Written Access VBA Causes Most

ErrorTypical causeFix
Compile error: Method or data member not foundControl name guessed wronglyUse the real control name from the form's property sheet
3061 Too few parametersField name misspelled in SQL, or a form reference inside SQL run by DAOFix the name; concatenate form values into the SQL
3075 Syntax error (missing operator)Unquoted text or an apostrophe in the dataQuote and escape text values
3218 Could not update; currently lockedAnother user or the form itself holds the recordSave the form first; see our record-locking guide
3622 You must use dbSeeChangesRecordset on a SQL Server linked tableAdd dbSeeChanges
Write Conflict dialogCode updated a record the form also has open with editsMe.Dirty = False before the update

Record locking deserves its own guide: Access error 3218 explained. If you are running Access on 64-bit Office and old code fails with Declare errors, see converting Access VBA to 64-bit.

Using AI to Understand Inherited Code

  • Paste a module and ask: what does each procedure do, which tables does it read and write, and what could it delete?

  • Ask for a list of every form, report and query the code references.

  • Ask it to add comments without changing behaviour, then diff the result to confirm.

  • Ask where the code would break if the back end moved to SQL Server.

A structured way to document a whole inherited database is in documenting a legacy Access database with AI. When the database runs a core part of the business, a review by an Access consultant before major changes costs far less than repairing corruption or lost data afterwards.

FAQ

AI and Access VBA FAQ

Writing, reviewing and understanding Access code

Yes. AI assistants write Access VBA for form events, DAO recordset loops, validation, exports and email automation. Results improve dramatically when you name the form, its controls and the tables involved, and state whether the database is split with linked tables or uses a SQL Server back end.

The language is the same; the object model is different. Access code works with forms, reports, controls and data through DAO or ADO recordsets, CurrentDb and DoCmd. Excel code works with workbooks, worksheets and ranges. AI tools frequently mix the two unless you specify Access.

It hides every Access confirmation and error message until it is switched back on. If the code fails between SetWarnings False and SetWarnings True, warnings stay off for the session and later action queries delete or change data without asking. Use CurrentDb.Execute with dbFailOnError instead, which runs silently but still raises errors.

Work on a copy of both the front end and the back end. Compile the project first (Debug → Compile) to catch undeclared variables and typos. Step through with F8 and breakpoints, and check the affected tables before and after running.

Yes, and this is one of the most valuable uses. Paste a module or event procedure and ask for a plain-English explanation, a list of tables it reads and writes, and anything it deletes. It is a fast way to document an inherited database before changing it.