Yes. Access VBA can send email either through DoCmd.SendObject, which uses the computer’s configured MAPI email client, or by automating classic Outlook for more control over message fields and attachments. For a message you want to review before it goes out, use Outlook’s .Display method or set EditMessage:=True with SendObject; use automatic sending only after testing recipients and content.
Choose a sending method
The right method depends on what is installed and how much control the database needs. Access does not provide a general-purpose, built-in SMTP command that can send through any mail provider with a username and password. Its convenient built-in route is MAPI: it hands a message to a compatible mail program configured on the computer.
- Use
DoCmd.SendObjectfor a straightforward message, or to send an Access report, table, or query in a supported format. It is usually the shortest option. - Automate classic Outlook when VBA needs to set message properties, add files, address multiple recipients, or choose whether to display or send the message.
- Use an email service or API when a process must send reliably without a person signed in to a desktop email client, or when the provider requires modern authentication.
These methods are not interchangeable. A database can prepare a message, but delivery still depends on the mail client or service, its account configuration, network access, and any organizational sending rules.
Send a message with Access SendObject
DoCmd.SendObject is an Access application method. With acSendNoObject, it creates a message without exporting an Access object. The following example opens a draft for review rather than sending immediately:
Public Sub DraftAccessEmail()
Dim emailTo As String
' Replace this example address with a validated value from your form.
emailTo = "recipient@example.com"
' Save a copy of the database before running or changing VBA.
DoCmd.SendObject ObjectType:=acSendNoObject, _
To:=emailTo, _
Subject:="Access follow-up", _
MessageText:="Please review the information in the database.", _
EditMessage:=True
End Sub
The computer needs a compatible default MAPI mail client and an account that can send. Depending on that client and its configuration, the message may open for editing or be handed off to the mail program. EditMessage:=True asks Access to display the message for editing; it is useful for a person-in-the-loop workflow. To send without displaying the draft, set it to False, but test that behavior in the actual environment first.
To attach an Access object, choose its object type and name and specify an output format supported by the object. For example, a report can be exported as PDF and attached. Check the Access version’s DoCmd.SendObject documentation for supported formats: not every object type supports every format, and a misspelled object name causes an error.
Automate classic Outlook for more control
Outlook automation is useful when the message needs a file attachment or when code must set properties such as recipients, subject, and body. This late-bound example does not require selecting an Outlook reference in the VBA editor. It uses classic Outlook for Windows, which must be installed and configured with a mail profile.
Public Sub DraftOutlookEmail()
Dim outlookApp As Object
Dim mailItem As Object
Dim emailTo As String
On Error GoTo CleanUp
' Save a copy of the database before running or changing VBA.
emailTo = "recipient@example.com"
Set outlookApp = CreateObject("Outlook.Application")
Set mailItem = outlookApp.CreateItem(0) ' 0 means a mail item.
With mailItem
.To = emailTo
.Subject = "Access follow-up"
.Body = "Please review the information in the database."
' Add an attachment with .Attachments.Add using a full file path.
.Display ' Replace with .Send only after carefully testing.
End With
CleanUp:
Set mailItem = Nothing
Set outlookApp = Nothing
End Sub
The example deliberately displays a draft. After verifying the recipient and message, a developer can replace .Display with .Send for a workflow that should submit the message automatically. That change removes the last convenient chance for a person to inspect it, so production code should validate inputs and handle errors. A failure to create Outlook, for example, may mean it is not installed, its profile is unavailable, or the environment blocks automation.
Late binding uses generic Object variables and avoids a compile-time dependency on a particular Outlook object library. Early binding instead selects the relevant Microsoft Outlook Object Library under the VBA editor’s Tools > References menu and uses Outlook-specific types and constants. It provides editor assistance, but a reference can cause problems if another computer has a different library version or lacks Outlook.
Attach a report or other file
For Outlook automation, add a file with the message’s Attachments.Add method. The argument must be a valid full path, and the file must exist when the code runs. A database can build the path from a known folder and a record value, but it should not assume that every user has the same folder structure.
For example, after creating a PDF report, a procedure could add it with .Attachments.Add pdfPath, where pdfPath is a declared string containing the complete path. Check that the file exists before adding it, and consider the attachment size and sensitivity. For an Access report, DoCmd.OutputTo can export the report to a file; then Outlook automation can attach that file. This separates report generation from email delivery, making it easier to check that the PDF was created before building the message.
With SendObject, Access can export an object and attach the exported result as part of its operation. This can be convenient for a report sent in PDF form, but it gives less flexibility than controlling a message object directly. Whichever route you choose, make the file name meaningful and avoid sending a temporary or incomplete export.
Use database values and send to multiple people
A common pattern is to read an address from a form control or a record, then use it as the message’s To value. Validate that the value is present and appears to be an address before sending. A simple check can catch a blank field, but robust address validation is more complicated; the mail service ultimately determines whether an address can receive mail.
For a list of recipients, Outlook’s To, CC, and BCC properties accept address strings. Separate addresses with semicolons. For a mailing where recipients should not see one another’s addresses, use BCC or send an individual message to each recipient. Sending one message with a long visible recipient list can expose personal information and invite accidental reply-all messages.
Do not assume a loop over an Access table will always send successfully. A production routine should decide what happens if one address is invalid, a record is missing an attachment, or Outlook fails halfway through. Logging the record identifier, attempted time, and outcome helps an administrator investigate. Avoid storing credentials in a table or VBA module; anyone with access to the database file may be able to inspect its contents.
Classic Outlook, new Outlook, and other clients
Outlook VBA automation through CreateObject("Outlook.Application") is intended for classic Outlook on Windows. Microsoft’s new Outlook for Windows does not support the same COM automation interface. A database that relies on Outlook Object Model automation therefore needs classic Outlook available; installing new Outlook alone is not a drop-in replacement for this code.
SendObject follows a different route: it hands the message to the configured MAPI client. It is not a promise that every mail application will behave identically, and a client may need to be installed, configured, or selected as the default. If messages do not open or send, check the Windows default email application and the mail client’s profile before changing VBA.
Mac and web versions of Office do not provide the same Windows COM automation approach shown above. Access itself is a Windows desktop application, and this Outlook automation example is not a cross-platform Access solution. If users work on different platforms, an email service with an authenticated API may be a more suitable shared backend than relying on each person’s desktop client.
Common errors and how to troubleshoot them
When email fails, identify which stage failed: Access creating the message, the mail client accepting it, or the provider delivering it. A message visible in the Outbox has not necessarily reached the recipient. Spam filtering, invalid addresses, mailbox limits, and provider policies can all affect final delivery.
- “ActiveX component can’t create object” or a similar automation error: Confirm classic Outlook is installed and that the user can open it and sign in. Check that the code is running in a desktop session with a usable profile.
- No draft appears from
SendObject: Check the configured default email application and whether it supports MAPI. Try a small test message and verify the mail client can send manually. - Attachment not found: Inspect the complete path, confirm the export finished, and verify the Access user has permission to read the file.
- Message remains unsent: Check Outlook’s Outbox, connection status, account settings, and organizational policies. VBA cannot override a provider’s limits or authentication requirements.
- Warnings or blocked sending: Outlook security settings and organization-managed policies can restrict programmatic sending. Do not try to bypass those controls; ask the administrator about an approved method.
Use a test mailbox and non-sensitive sample data while developing. A procedure that runs without a VBA error only proves that the code reached a certain point; it does not prove that the intended recipient received or read the message.
Safety, privacy, and reliable automation
Email is difficult to retract. Before using .Send or EditMessage:=False, confirm the recipient, subject, body, and attachment are correct. A useful safeguard is to show a confirmation prompt or write a draft first. If records contain personal or confidential information, restrict who can run the procedure and who can access exported files.
Macros may be blocked by Trust Center settings, file-origin protections, or an organization’s policy. Use approved trusted locations or signed VBA where appropriate, and do not tell users to disable security controls broadly. Keep a backup before running or changing a macro: VBA actions are not undone with Ctrl+Z. For repeatable jobs, record failures and make the process safe to rerun so a retry does not accidentally send duplicates.
Desktop Outlook automation is also a poor fit for unattended server processes. Office desktop applications expect an interactive user environment, and a desktop session or security prompt can interrupt a job. For scheduled or high-volume sending, use an organization-approved email service, SMTP relay, or API with its required authentication and monitoring instead.
Alternatives when Outlook automation is not suitable
If a process must run without a person opening Outlook, investigate an approved service rather than assuming Access can connect to any SMTP server by itself. The service may provide SMTP relay or a REST API and may require OAuth, an application registration, or administrator approval. Microsoft Graph is one possible Microsoft 365 integration route, but it requires appropriate identity configuration and permissions; it is not a one-line replacement for Outlook automation.
Another practical option is to have Access prepare a report or data file and let a separate, supported workflow send it. This keeps database reporting separate from mail delivery and can make authentication, logging, and retries easier to manage. Compare the setup effort with the actual need: a staff member sending occasional messages may be well served by SendObject, while unattended, regulated, or large-scale email needs a deliberately designed service.
Frequently Asked Questions
Can Access VBA send email without Outlook?
Yes, if the computer has another compatible MAPI mail client for DoCmd.SendObject, or if the application connects to an approved email service or API. Access does not include a universal built-in SMTP sender for arbitrary providers.
Can Access send an email automatically without showing a draft?
Yes. In Outlook automation, call .Send instead of .Display; with SendObject, set EditMessage:=False. Test with a safe mailbox first, because security policies, account configuration, and client behavior can affect the result.
Can Access VBA send a report as a PDF attachment?
Yes. Export the report to PDF and attach the resulting file with Outlook automation, or use SendObject with the report object and a supported PDF output format. Confirm the export succeeded and the path is correct before sending.
Does this code work with new Outlook for Windows?
The Outlook COM automation example requires classic Outlook; new Outlook does not provide that same COM interface. SendObject depends instead on a configured compatible MAPI mail client, so verify the client and workflow on the target computer.
Can an Access macro send bulk email?
It can loop through records and prepare or send messages, but large or unattended mailings need careful handling of consent, privacy, provider limits, failures, and duplicates. For bulk campaigns, use an approved mailing or messaging service rather than treating desktop Outlook as a bulk-mail platform.
Related
- AI Data Validation: How It Works and Why It Matters
- Insert a Row in an Excel PivotTable: Steps and Fixes
- Conditional Formatting Greater Than or Equal To in Excel
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Excel Analysis ToolPak vs ToolPak VBA: Key DifferencesExcel’s Analysis ToolPak is the add-in for running built-in statistical and engineering analyses from the Data tab; Analysis…
- Excel VBA Substring: Extract, Find, and Replace TextExcel VBA has no built-in function named Substring, but you can work with part of a string using…
- VBA User Input Box: InputBox, Validation, and ExamplesA VBA user input box is a small dialog that asks someone to enter text, a number, or…
- VBA: Filter a PivotTable by Cell Value AutomaticallyTo filter an Excel PivotTable from a cell, use VBA to read that cell and assign its value…
- Access VBA Find Text: Methods, Examples, and FixesTo find text in Access VBA, use a DAO recordset’s FindFirst method with a criterion such as [LastName]…
- Excel VBA InputBox With Multiple InputsExcel VBA’s built-in InputBox and Application.InputBox each display one input field, not a form with several fields. To…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.