Adding Attachments to an Access Database

Why You Should Avoid Using Attachment Data Type in Microsoft Access

The Attachment data type, introduced in Access 2007, allows users to insert files which get embedded directly into databases. However, this feature comes with significant drawbacks:

Database Bloat

Using Attachment fields causes rapid database size increase. Each attached file adds its full size to the database, quickly turning a small database into a large one.

Performance Impact

Large databases resulting from Attachment fields can negatively affect performance, slowing down initial load times, queries and overall operations.

Complex Interaction

Programmatically managing Attachment fields requires specialized code, making it challenging to insert, extract, or manipulate attached files.

 

Recommended Alternative

Instead of using Attachment fields, the preferred method still remains to keep the files (documents, workbooks, PDFs, images, videos, …) on the PC and simply to store file paths and filenames (including extensions) in the database as plain text. This approach:

  • Minimizes the database size
  • Maintains better performance
  • Simplifies file management and access
  • Ensure compatibility with older systems

By avoiding Attachment fields and using file paths instead, you create more efficient, performant database.

Handling Attachments - Startup Form

Handling Attachments - Form with File Dialog to Add New Attachment

Disclaimer/Notes:

If you do not have Microsoft Access, simply download and install the freely available runtime version (this permits running MS Access databases, but not modifying their design):

Microsoft Access 2010 Runtime
Microsoft Access 2013 Runtime
Microsoft Access 2016 Runtime
Microsoft 365 Access Runtime

All code samples, download samples, links, ... on this site are provided 'AS IS'.

In no event will Devhut.net or CARDA Consultants Inc. be liable to the client/end-user or any third party for any damages, including any lost profits, lost savings or other incidental, consequential or special damages arising out of the operation of or inability to operate the software which CARDA Consultants Inc. has provided, even if CARDA Consultants Inc. has been advised of the possibility of such damages.

 

Download

Feel free to download a copy (unlocked accdb) by using the link provided below:

Download “How to Handle Attachments Demo in MS Access” HowToHandleAttachments_Demo.zip – Downloaded 18039 times – 67.12 KB

The demo features two closely related approaches and includes all the necessary coding components (such as file selection, opening files, deleting files, etc.). Feel free to explore it and modify it to suit your requirements.
 

Version History

Version Date Changes
V1.000 2016-10-03 Initial Public Release
V1.001 2022-04-03 Added Conditional Compilation to the API to make it compatible with both 32 and 64-bit versions of Access
V1.002 2022-09-28 Split the database to properly reflect multi-user setup
Adapted ‘Server’ code to properly place attachments in a sub-folder of Back-End folder
V1.003 2024-02-17 Removed any limiting copyright notices. You may use any part of this application for your own purposes.
Thank you to George Bowyer for bringing this issue to my attention!

32 responses on “Adding Attachments to an Access Database

  1. Tom Hendry

    Hi,

    What do you think to the idea of having a separate back end to only store attachments?

    Thanks

    Tom

    1. Daniel Pineault Post author

      I’ve seen people suggest this in the past, as it can limit potential issues to just the attachments, thus leaving the data intact. Personally, I still wouldn’t use such an approach and will stick with storing paths as text entries.

      It’s one thing if you only need to store a couple attachments, things like logos, etc, but if you need to attach various files as part of entries within your database on a regular basis, I wouldn’t ever consider using the Attachment data type. I have seen too many people post questions regarding hitting the 2GB file size limit because of attachments, rendering their database unusable! Simply not worth the risk when the alternative is so easy to implement.

  2. Barry Stoker

    Hi,

    thanks for such a great article. I would like to use this method in a back end data tables, front end interface setup.

    I’ve put the tables into the 3 tables from your example into my back end database, linked them into the front end where I have also placed the forms and the modules.
    I’m having an issue with the form throwing a compile error, “Variable not defined” , when I click the elipses on the form to kickstart the file selection dialogs.

    In the debug screen it is highlighting ‘msoFileDialogFilePicker’ as being the cause.

    Have you any advice?

    Thanks,

    Barry

    1. Daniel Pineault Post author

      Have you set an Reference to Microsoft Office XX.X Object Library? Or I have a Late bound version also available on my site.

  3. Shankar5

    Excellent Article!!! It was very helpful..

    Just one thing I wanted to know as to how do I send the attachments via email.

  4. Andy

    Hey,
    I try to use the very nice code for managing attachments published by You.
    The published version works fine – great code!
    I use your solution in the subform.
    However, I need to collect additional information about the history of the attachment being added / removed
    and here I encountered a problem …
    To track the history of changes in the form and / or subForm, I use published solutions, e.g. (https://answers.microsoft.com/en-us/msoffice/forum/msoffice_access-mso_mobile/making-audit-trial-work-on-subforms/d1a23190-cb9e-4d9c-9e5f-f20a7160d085).
    Unfortunately, I can not complete the code to get full information.
    Currently registered;
    – who (UserName),
    – when (datetime),
    – name of the subform (FormName) ‘
    – action (new, delete)

    I do not register the name of the added or delete file and this is important because one record in the main form can be assigned several records in the subform!
    also does not register NewValue, (eg filename / path to the file) and OldValue.
    Is it possible to modify in this respect?
    Could I ask for some help?
    BEST REGARDS.

    1. Daniel Pineault Post author

      It depends on the context. You can use the FileDialog to perform multiple selections and process each item. You could select a folder, and process each item contained within. It depends on the scenario, but it’s just a question of iterating over a list of items rather than just one item.

  5. Sam Harper

    Great piece of work, I stumbled across this by chance, just after setting my DB up using the built in attachment function… Its saved me a lot of trouble down the line..
    I am struggling with one piece though and was wondering if there a suggestion to get around it..
    Its possible to overwrite uploaded files by using the same file name, in my DB the uploaded files are part of the manufacturing history so users being able to unwittily overwrite files is dangerous.
    Is there a suggestion on how to either block overwriting with a warning if the file name already exists or re-name the uploaded by adding the by date and time to the file name prior to saving on the server?
    I have tried a few approaches but cannot seem to get it working

      1. Sam Harper

        Hi Daniel,
        I’m sure its my lack of talent… I can’t seem to get it to work,
        I’ve copied the function from the link and pasted it into the Mod_ExternalFiles Module,

        In the locate file sub
        If FileExist(sFile) = True Then
        MsgBox (“File Name Exist”)
        GoTo Error_Handler
        End If
        But its always popping up the msgbox… even if the files doesn’t exist

        1. Daniel Pineault Post author

          sFile is the original file, so it will always exist, you need to test against the destination file. I’d probably do something like

          Private Sub cmd_LocateFile_Click()
              On Error GoTo Error_Handler
              Dim sFile                 As String
              Dim sFolder               As String
          
              sFile = FSBrowse("", msoFileDialogFilePicker, "All Files (*.*),*.*")
              If sFile <> "" Then
                  sFolder = Application.CodeProject.path & "\" & sAttachmentFolderName & "\"
                  'Ensure the Attachment folder exists
                  If FolderExist(sFolder) = False Then MkDir (sFolder)
                  'Check if the File Already Exists
                  If FileExist(sFolder & GetFileName(sFile)) = True Then
                      MsgBox "The File Already Exists", vbCritical Or vbOKOnly, "Operation Aboarted"
                      GoTo Error_Handler_Exit
                  End If
                  'Copy the file to the Attachment folder
                  If CopyFile(sFile, sFolder & GetFileName(sFile)) = True Then
                      'Add this new path to our db
                      Me.FullFileName = sFolder & GetFileName(sFile)
                  Else
                      'Probably should report something here about the File Copy failing
                  End If
              End If
          
          Error_Handler_Exit:
              On Error Resume Next
              Exit Sub
          
          Error_Handler:
              MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
                     "Error Number: " & Err.Number & vbCrLf & _
                     "Error Source: " & sModName & "\cmd_LocateFile_Click" & vbCrLf & _
                     "Error Description: " & Err.Description & _
                     Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
                     , vbOKOnly + vbCritical, "An Error has Occured!"
              Resume Error_Handler_Exit
          End Sub
          1. Paul

            How could I rename the file in the above code in this comment when copying to the attachments folder (rename copy not the orig)? Could I just create a Dim sRenamedFile as string and make it equal (“Quote_For_Requsition_Number_” & [txt_Req_Num] & “_” & [txtReq_Desc] & “.*” to be able to rename “Example.pdf” to “Quote_For_Requisition_Number_123456_new computers.pdf” when copying to the Attachments folder? Would I have to now define CopyFile above as (sfile, sFolder & sRenamedFile)? I would change Me.FullFilName = sFolder & sRenamedFile.

  6. Paulie P

    This works great but I’d like to be able to rename the file chosen on FileCopy to the Attachments folder (rename the copied file when copying not the original file) and then of course Me.FullName would have the new file name in it. I guess there would have to be a StrNewFileName or something declared? I would probably want to add two fields to the underlying table/form that would pre-populate OnOpen from another currently opened form say fields [Req_Num] and [Req_Desc]. StrNewFileName would be something like (“Quote_For_Requisition_” & [Req_Num] & “_” & [Req_Desc] & “.*”) so that the copied file in the Attachments folder would be re-named ex: “Quote_For_Requisition_123456_New Servers.pdf” if the original file was a pdf. Is that possible with this project’s code (I realize my code is probably erroneous, I’m just trying to guess what it should look like off the top of my head).

  7. Paulie P

    I have run into a problem where the FullFileName field can only be a certain length in characters (259 I think from playing around with it). I changed the field in the attachment_server table to be long text (even deleted the field in design view and then created new as long text and I also deleted/re-created the bound field in the server attachment form. However, it still throws The error 53 message from the mod_ExternalFiles if the total length of FullFile name is too long (over 259 characters). Is there anyway this can be fixed so that it will support longer total file name paths? I have searched all over in the code and can’t find anywhere to define the max string length. Thanks.

  8. Chris Symonds

    Hello, This is great thank you very much for posting such a wonderful resource. My, well they’re not attachments I guess, better to call them associated files or referenced files? My associated files are of several types, .documents, .pdf, spreadsheets and images and your system works wonderfully for all of them. It also allows me to make a change to the associated files with no problem as long as the filename remains the same which is an added bonus.

    I need to print the associated files in a report. I created a subreport for them which lists them just fine. And, I have code that prints them correctly from the subreport if I put it in the On Current event and manually advance to the report page. But can’t figure out where to put the code to just print automatically when I print the entire report. I was wondering if you had any advice?
    With Thanks,
    Chris

  9. Arettha

    Hello! Excellent article!
    I have the same problem like “Barry Stoker March 8, 2017 at 7:40 am”
    but i have set an Reference to Microsoft Office 16.0 Object Library
    any idea?

  10. Ruud de Gelder

    Hi Daniel,
    Hope you are doing well. Great article on adding Attachments. Exactly the thing I needed.
    I have a question about the “mod_DB_Variables”. There is a static folder location “Attachment”. Would it be possible to make this variable? Like project-specific name or project number? In my table, I added a column “Project” that shows me to which project a certain attachment belongs to. It would be great if this could be project-specific.
    Another question about opening the file. Currently, it opens the specific file. Would it also be possible to open the file location instead of the file?
    Thanks in advance,
    Ruud

    1. Daniel Pineault Post author

      Question 1:
      You should simply be able to switch ‘Public Const sAttachmentFolderName = “Attachments”‘ to a public variable or even a TempVars, then you could use your form’s current even to set it to you project value that represents the proper foldername.

      Question 2:
      You can use code like what is found at https://www.devhut.net/vba-extract-the-path-from-a-file-name/ to get the path from the FullFileName field and use the ExecutreFile on that value, or Application.FollowHyperlink, …

  11. Graham Smithwick

    Thank you for the great help with all around dilemma
    I almost got the Template to work. The link fires in t_attachments_local, bur the BUTTON doesn’t work, at least for me, in the f_Method1_Local:

  12. josephbupe

    Hello,
    Please, i need an updated code to run this sample on my ms access version 2016
    Any ideas?

  13. ۤFanaee

    Hello
    I will contact you from Iran
    Please help
    How can I attach an image file to a table in the Access database by VBA?
    All the best to you

  14. Jason Kaloyanides

    Hi there-
    Thx so much for posting this… Very cool feature…
    I tested it and it worked fine. Created a new folder in the backend folder on a network drive.
    I then added to my database, separate table and form for each, companies, contacts, products and employees so we can store attachments for each.
    When I was done and started testing, I realized it was creating the “Attachment” Folder on my desktop instead of the network drive.
    I think they only thing I modified was the CopyFile name from CopyFile to CopyFile2 because that name is already in use.
    I like that it’s being copied to the network…
    Any ideas? Something stupid I did? Thx so much…

    1. Daniel Pineault Post author

      No, you are not doing anything wrong and I’m surprised no one has flagged this in all these years. The current code relies on:

      ...
      sFolder = Application.CodeProject.path & "\" & sAttachmentFolderName & "\"
      ...

      but for a properly split setup we need to use the path of the back-end.

      So the quick fix is:

      I will work on updating this sample in the coming days.

  15. EA

    Hello,

    This is a great solution that works perfectly for me. The only problem I seem to be having with it is that I’m trying to run it in parallel with Control Application Interface by Isladogs. You see, when a user opens the form, I want the form to show up but for the user to not be able to open the access itself.

    I know it’s not specific to the version I’m referring to, because I’ve tried a few different ways to minimize and make it impossible to reopen the actual access window, but every time I do this – it clashes with part of this code. Specifically, I run into a problem with variable msoFileDialogFilePicker, which is now considered “undefined” (the moment I remove the code it starts working fine again).

    I understand the code somehow relies on access itself appearing active, but I’m not technically adept enough at VBA to figure out how to alter how this variable is defined to make both these applications work at the same time.

    Have you ever tried or know of an alternative way of having the user open their database and not be able to view access itself (but the form(s) appear as an application) that does not clash with this great solution for file attachments.

    Thank you in advance for your response.

  16. EA

    Sorry, this was my mistake so ignore this comment. I created a new database to try both applications together and forgot to input necessary reference library which I was sure was there.

    Newbie mistake. Thank you for this great solution!

  17. Tom Hall

    Thanks – used this for a school admin that wanted to use the default student tracking template, but wanted attachments on the Students. Works great so far (still in test).