Expert guide
Classify Emails and Tickets in Microsoft Access with AI
From a shared inbox nobody owns to a prioritised queue linked to your customers and orders
Call us at +1 (385) 386-3860
Short answer: capture new emails from a shared Outlook folder into an Access tblTickets table with VBA, send each subject and body to an AI model that returns category, priority, customer or order reference and a short summary, then match the reference to your customer table and show the result on a queue form. Keep a confidence field and a review view for uncertain tickets. We build this as part of AI workflow automation.
Shared inboxes such as info@, support@ and orders@ are where work goes to wait. Nobody knows who has replied, urgent messages sit behind newsletters, and the only report is "the inbox feels full". If your customers, orders or jobs already live in Access, the inbox can feed the database directly, with AI doing the first read of every message.
The Ticket Table
| Field | Type | Source |
|---|---|---|
| TicketID | AutoNumber | Generated |
| EntryID | Short Text (255) | Outlook's unique message ID, prevents duplicates |
| ReceivedOn, FromAddress, Subject, Body | Date/Time, Text, Text, Long Text | Outlook |
| Category, Priority | Short Text | AI, editable by staff |
| Reference | Short Text | AI-extracted order, invoice or job number |
| CustomerID | Number | Matched from FromAddress or Reference |
| Summary | Short Text (255) | AI |
| Confidence | Short Text | AI: high, medium, low |
| AssignedTo, Status, ClosedOn | Text, Text, Date/Time | Workflow |
Step 1: Capture Emails From Outlook
Public Sub ImportSupportEmails()
Dim ol As Object, ns As Object, fld As Object, itm As Object
Dim db As DAO.Database, rs As DAO.Recordset
Set ol = CreateObject("Outlook.Application")
Set ns = ol.GetNamespace("MAPI")
' Shared mailbox folder: adjust names to your mailbox
Set fld = ns.Folders("support@yourcompany.com").Folders("Inbox")
Set db = CurrentDb
Set rs = db.OpenRecordset("tblTickets", dbOpenDynaset)
For Each itm In fld.Items
If itm.Class = 43 Then ' 43 = olMail
If DCount("*", "tblTickets", "EntryID='" & itm.EntryID & "'") = 0 Then
rs.AddNew
rs!EntryID = itm.EntryID
rs!ReceivedOn = itm.ReceivedTime
rs!FromAddress = itm.SenderEmailAddress
rs!Subject = Left$(itm.Subject, 255)
rs!Body = Left$(itm.Body, 30000)
rs!Status = "New"
rs.Update
End If
End If
Next itm
rs.Close
End SubFor busy mailboxes, restrict to recent items with fld.Items.Restrict("[ReceivedTime] >= '" & Format(Date - 2, "ddddd h:nn AMPM") & "'") instead of scanning the whole folder every time.
Step 2: The Classification Prompt
Classify this customer email for a building-supplies distributor.
Return exactly one line:
category | priority | reference | summary | confidence
category: Order status, New order, Billing, Returns, Complaint,
Technical question, Supplier, Spam, Other
priority: High if delivery is today or overdue, a site is waiting,
a safety issue, or a legal or cancellation threat.
Medium for anything needing action this week. Low otherwise.
reference: any order (SO-#####), invoice (INV-#####) or PO number; else blank
summary: max 15 words, what the customer needs
confidence: high, medium or low
Subject: {subject}
Body: {first 3,000 characters of body}Call it with the AskAI function from connecting MS Access to the OpenAI API, split the pipe-separated result with Split(), and write each part to its field. Truncating the body avoids paying to classify long email threads and signatures.
Step 3: Match to Customers and Orders
-- By sender address
UPDATE tblTickets AS t INNER JOIN tblContacts AS c
ON t.FromAddress = c.Email
SET t.CustomerID = c.CustomerID
WHERE t.CustomerID Is Null;
-- By extracted order reference
UPDATE tblTickets AS t INNER JOIN tblOrders AS o
ON t.Reference = o.OrderNo
SET t.CustomerID = o.CustomerID
WHERE t.CustomerID Is Null;Once tickets link to customers, the queue form can show the customer's open orders, last invoice and account manager next to the email. That context is what makes the queue faster than the inbox.
Step 4: Rules That Override AI
Key accounts: raise priority one level when the customer's tier is Key.
Repeat contact: raise priority when the same sender has an open ticket older than 48 hours.
Spam with high confidence: auto-close, but keep the record.
Low confidence: route to a Review view regardless of category.
These rules live in queries, not in the prompt, so they are consistent and easy to change.
Step 5: The Queue Form
Continuous form sorted by Priority then ReceivedOn, filtered by Status <> Closed.
Colour by priority using conditional formatting.
Buttons: Assign to me, Reply in Outlook (opens a reply to the original via EntryID), Close.
A Category combo box so staff can correct AI; log corrections in a separate field to measure accuracy.
Measuring Whether It Works
| Measure | How to calculate | What good looks like |
|---|---|---|
| Category accuracy | Share of tickets where staff did not change the category | Steady improvement as definitions are refined |
| Time to first response | First reply time minus ReceivedOn, by priority | High priority handled the same day |
| Backlog | Open tickets by age bucket | Few tickets older than a week |
| Volume by category | Count per week | Shows where root-cause fixes would cut volume |
Category volume is often the most valuable output. If a third of emails are "Where is my order?", an automatic dispatch notification removes them entirely. Pair this with customer feedback theme analysis for a complete picture.
Scaling Up
Running Outlook automation from one desktop is fine for a small team. For larger volumes, a scheduled service reads the mailbox through Microsoft Graph and writes to the back end or SQL Server, so nothing depends on one PC being on. If tickets are part of a broader customer system, our Access CRM is a good base, and Access VBA development covers the integration work.
FAQ
AI ticket classification in Access FAQ
Capture, categories, priority and accuracy