Importing Outlook emails into Access

I love Microsoft Office and how we can integrate all of the apps into a cohesive solution. This article will show you how to read emails into Access and save any attachments.

Why Store Emails? Because the’re difficult to share

SQL Server Hosting

I built a custom order tracking tool for my client used by 30 employees at the company. Orders can range from $100,000 to several million dollars and can take years to build and close. During the order’s life, emails will travel back and forth between customers and employees at the company, providing a wealth of knowledge relative to the order. It was difficult to share emails with other employees on a order using Exchange, that’s when the firm asked me to come up with a way to import them into Access/SQL Server, allowing all employees to see email info in Access regardless of who received them at the company. I created a new tab on the order screen called Order Notes and added a new button called Import Emails. Users can add notes or emails to the system using the same form. If they land on a email the “View Attachments” button becomes available if there were attachments stored with the email.

The Strategy

My client wanted to save the body of the email into a SQL Server table and any attachments to a network directory set aside for document storage for the database, then display the emails on a continuous form inside Access. This strategy allows the client to search for text in the email and even perform queries against the data.

This is not the only way to store archived emails, you could for example save individual emails by selecting File Save As in Outlook and placing them on a networked drive then referencing them as a link in Access. Users can then click to open the email using Outlook. Using this approach will preserve the formatting of the message and the attachments.

Select the method that bests suits you, display email in Access and do queries or display it in Outlook and preserve formatting.

Outlook Folder Maze

One thing you will quickly realize when you try to import emails into Access is that most people’s inbox are quite large, hence, it can take a very long time to scan all emails. Instead create two folders under the inbox called Import and Imported, than have the user move any emails they wish to import into the former. The code will then move the emails to Imported once the process has been completed.

The second thing about mail folders in Outlook is they don’t follow a specific organization from user to user, since they may place folders in different places thus you’re asking for trouble if you hard code folder locations. Better to cycle through all folders until you find the ones you’re looking for and that’s what the code does.

I took the extra step of showing which emails a user can import into the system by using a temp table and a form, allowing them to cherry pick which ones they want imported into which order in Access. It reduces the need to shuffle back and forth between the two programs when you need to import into different records.

Import and Move or Import all then Move? I’m moved you asked…

I decided to move the email while I had a pointer on the message instead of importing all emails and then moving them. When you move the email it reset’s the collection, hence the code starts again to search for emails after each move.

EntryID is your ticket to ride

Each message in Outlook gets a unique number called EntryID, I use it in the code to identify which emails to import after the user has selected them on the import form. A caveat should be noted though – EntityID will be changed whenever you move a message, so don’t rely on it to reference messages as you would a primary key of a table but more like a pointer.

Beware what you wish for

Have you seen emails lately? They contain graphics, html code and who knows what. In order to save the email body as text in SQL Server, I needed to take care of apostrophes and other vermin that can interfere with my import, all of which you will see in the code.

You can find the code here.

Need to read emails into Access but find it daunting? Then hire us to do it for you! Click here to contact us.


About the Author:

Juan Soto is a Senior Access Developer at IT Impact Inc. and a Microsoft Access MVP. He specializes in Access with SQL Server databases. His passion for Access has led him to helping a wide range of businesses in helping them establish a secure, stable and efficient environment with SQL Server. He's a frequent speaker at Access user groups nationwide and recently spoke at the Orange County SQL Saturday # 73. If you wish to have Juan speak at your next group meeting you can contact him here.


  1. Ven Grollmus September 30, 2017 at 5:20 am - Reply

    Great article and code.

    Interesting thing I found was, if the sub-folder has a space in the name (i.e. “Ven’s Emails to Import” the folder will be found, but the code to loop through the mail items “For Each objMailItem In objFolder.Items” will not find any items.

    Remove the spaces, then all runs as expected.

    Is there a way to actually have the code to run?

    What is weird, if I use the following:-

    Set inbox = ns.GetDefaultFolder(olFolderInbox)
    Set sub_folder = inbox.Folders(“Ven’s Emails to Import”)

    the For Each loop runs.

  2. Floris November 9, 2015 at 9:29 am - Reply

    Hi Juan,
    I get Error 0 () in procedure Form_Load of VBA Document Form_FrmImportEmails “

  3. kassam Juma July 31, 2014 at 4:06 am - Reply


    Admire your spirit of sharing knowledge and expertise with the rest of the world. Just goes to prove it belongs to the Creator and is for all of mankind!

    With the best in life.


  4. Storing outlook emails in access July 31, 2014 at 12:46 am - Reply

    […] Access VBA import Outlook email…s-into-access/ (adsbygoogle = window.adsbygoogle || []).push({}); To provide db: Make copy, remove […]

  5. Jubilee September 9, 2013 at 9:18 pm - Reply

    This code is perfect for the project I am working on. Please guide me, where this code has to be placed. I created a command button on the access form named ‘import email’ and added the code on ‘command button click’. How should I provide reference to code. Please help.

    • Ben Clothier September 10, 2013 at 6:06 pm - Reply

      Jubilee –

      In your VBA editor, use Tools -> References, then select “Microsoft Outlook XX.X Object Library”. That should enable you to reference the object model for Outlook. That said, read up on early/late binding (which you can easily google for numerous articles and examples) so you’re aware of development and distribution issues with additional references.

  6. Outlook and Access? June 11, 2013 at 11:47 pm - Reply

    […] You have two options: 1) Read the mail directly from the mail server. I prefer this method since it does not depend on the email client. 2) Read the emails inside Outlook. See: Importing Outlook emails into Access […]

  7. Mark Godwin March 12, 2013 at 5:29 pm - Reply

    Juan, like the breakdown of how you went about this. I have incorporated the code in a new form (the global code has gone into a separate global module) but frustratingly the OnLoad event triggers an error (one of those oh so helpful MS messages!) stating “the expression On Load you entered as the event property setting produced the following error:User defined type not defined”. I have called the form frmMailImportTest and have the OnLoad property set to [Event Procedure] and placed your On Load event code in the forms code module. Any suggestions?

    • Nate September 4, 2017 at 6:45 pm - Reply

      I am also getting the same error (user defined type not defined) when compiling on the Dim Job As clsJob line. Did you resolve this?

  8. Sam December 11, 2012 at 1:08 am - Reply

    Did you experience, or have you heard of any issues with compatibility between 32 bit and 64 bit. I’ve developed similar code, but am experiencing minor issues with portability. I ran into your post here researching possible causes and alternatives.

    • Juan Soto December 15, 2012 at 2:02 am - Reply

      If you develop in 64 the file will not work in a 32 bit environment.

  9. Gib Spaman November 2, 2012 at 2:03 am - Reply

    I am also trying to process your code. In the function OutlookFolderNames, the dim oFolder as Outlook.Folder failed because the type Outlook.Folder is not defined. Have I missed something?

    • Ben Clothier November 5, 2012 at 10:25 pm - Reply

      Gib, you’d need to add VBA Reference to Microsoft Office XX.X Outlook object library to compile with Outlook’s objects.

      Alternatively, you can convert the code to use late-binding instead.

  10. Rudy July 6, 2012 at 11:22 pm - Reply

    This looks perfect for something I need to do (especially automating importing the email attachments), but I’m running into problems with clsJob – I don’t see anywhere in your code where the “Job” class is defined. Is it in a library I need to reference?

    • Juan Soto July 9, 2012 at 8:24 pm - Reply


      You can ignore the clsJob portion of it, it was only used on a project I had and is specialized. Glad to hear it worked for you!

  11. eileen July 5, 2012 at 5:35 pm - Reply

    Hi Juan,

    Thanks for the site, really useful. I was wondering whether you had a step by step guide on importing the emails, as I am a newbie to this – and am finding it difficult to follow.

    Kindest Regards,

    • Juan Soto July 9, 2012 at 8:26 pm - Reply


      Glad to hear you like the blog! No, I don’t have a step by step, it’s assumed you are already proficient with VBA when you read our posts. May I suggest a step by step guide to using Access books on Amazon?

      Kind Regards,

  12. Ed July 5, 2012 at 5:31 am - Reply

    I’m trying to use something similar but your example doesn’t seem to work.

    My architecture is Access ADP (which I think is the problem) front end on a SQL 2005 DB.

    What are you using in this example?

    • Juan Soto July 9, 2012 at 8:27 pm - Reply


      It should work fine, what issue are you having?

  13. DJ March 6, 2012 at 6:01 am - Reply

    It would be great to post a sample .mdb

    • Juan Soto March 6, 2012 at 1:03 pm - Reply

      Hi DJ,

      We have a policy of not posting MDBs and instead encourage the reader to explore, learn and if they have issues, come back here and post. Hope you can use this code in your database!


      • phil June 8, 2012 at 5:43 am - Reply

        Juan, thanks for posting this, after coping and pasting this as a txt file, where should it be placed?

        • Juan Soto June 8, 2012 at 6:37 am - Reply

          Hi Phil
          You would paste it into a generic module

Leave A Comment


Contact Us
close slider
  • This field is for validation purposes and should be left unchanged.