<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Microsoft Access Team Blog : Attachment</title><link>http://blogs.msdn.com/access/archive/tags/Attachment/default.aspx</link><description>Tags: Attachment</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Adding multiple attachments from a folder</title><link>http://blogs.msdn.com/access/archive/2008/07/31/adding-multiple-attachments-from-a-folder.aspx</link><pubDate>Fri, 01 Aug 2008 00:55:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8795280</guid><dc:creator>James K. Rivera</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/access/comments/8795280.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=8795280</wfw:commentRss><description>&lt;P&gt;Rob Cooper recently made a post, &lt;A href="http://blogs.msdn.com/access/archive/2008/07/25/adding-attachments-from-a-folder.aspx" mce_href="http://blogs.msdn.com/access/archive/2008/07/25/adding-attachments-from-a-folder.aspx"&gt;Adding Attachments from a Folder&lt;/A&gt;, which shows how to add a single attachment file per row.&amp;nbsp; But what if you wanted to add more than one file?&amp;nbsp; One (highly contrived) scenario would be to add all of the files in a folder to one row, and do so recursively if requested, similar to Rob's example.&lt;/P&gt;
&lt;P&gt;What follows is some VBA code to do this, which borrows a bit from Rob's post and a bit from &lt;A href="http://blogs.msdn.com/access/archive/2007/08/24/adding-removing-and-saving-files-from-the-new-attachment-field-in-access-2007.aspx" mce_href="http://blogs.msdn.com/access/archive/2007/08/24/adding-removing-and-saving-files-from-the-new-attachment-field-in-access-2007.aspx"&gt;one of my earlier posts&lt;/A&gt;.&amp;nbsp; However, I should point out this (again, highly contrived scenario) is meant only as an example and not something I would recommend doing, because if you are adding more than just a few files you can (ok, WILL) bloat your database very quickly, and in doing so can negatively impact performance and potentially hit the two gigabyte file size limit very quickly (see &lt;A href="http://office.microsoft.com/en-us/access/HA100307391033.aspx" mce_href="http://office.microsoft.com/en-us/access/HA100307391033.aspx"&gt;Access 2007 Specifications&lt;/A&gt; for details on database file size and object limitations).&lt;/P&gt;
&lt;P&gt;First, to use the following sample code you will need to do some setup.&amp;nbsp; Create a new table, add the following fields, and save it as Table1:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Table1&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="" border=1 cellSpacing=0 cellPadding=2 width=400&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=200 align=middle&gt;&lt;STRONG&gt;Field Name&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class="" vAlign=top width=200 align=middle&gt;&lt;STRONG&gt;Data Type&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=200&gt;ID&lt;/TD&gt;
&lt;TD class="" vAlign=top width=200&gt;Autonumber (Primary Key)&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=200&gt;FolderPath&lt;/TD&gt;
&lt;TD class="" vAlign=top width=200&gt;Text&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" vAlign=top width=200&gt;Files&lt;/TD&gt;
&lt;TD class="" vAlign=top width=200&gt;Attachment&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/Addingmultipleattachmentsfromafolder_C2B4/image_2.png" mce_href="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/Addingmultipleattachmentsfromafolder_C2B4/image_2.png"&gt;&lt;IMG style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/Addingmultipleattachmentsfromafolder_C2B4/image_thumb.png" width=244 height=80 mce_src="http://blogs.msdn.com/blogfiles/access/WindowsLiveWriter/Addingmultipleattachmentsfromafolder_C2B4/image_thumb.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Next, open the VBE window (ALT+F11) and insert a new module (Insert -&amp;gt; Module), and paste in the following code:&lt;/P&gt;&lt;CODE&gt;
&lt;P&gt;' ------------------------------------------------------------------------- &lt;BR&gt;' Procedure : StoreFilesInTable &lt;BR&gt;' Purpose&amp;nbsp;&amp;nbsp; : Adds all files matching the specified file mask from the &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : specified folder to an attachment field. &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : Each row in the represents all files stored from the folder. &lt;BR&gt;' Arguments : strFolder - The path to the folder stored in the attachment field. &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strTable&amp;nbsp; - The name of the table containing the attachment field. &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strPathField - The name of the field for the archived folder. &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strAttachmentField - The name of the attachment field. [Files] &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strPattern - File mask. [*.*] &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : blnIncludeSubfolders - Recurse into subfolders. [False] &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : db1 - The database to operate on.&amp;nbsp; [CurrentDb] &lt;BR&gt;' Comments&amp;nbsp; : The db1 param is included so this can be used to store files in &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : a separate database, since using the attachment field this way &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : can quickly push a database beyond the 2gb file size limit. &lt;BR&gt;' ------------------------------------------------------------------------- &lt;BR&gt;Public Function StoreFilesInTable( _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal strFolder As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal strTable As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal strPathField As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByVal strAttachmentField As String = "Files", _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByVal strPattern As String = "*.*", _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByVal blnIncludeSubfolders As Boolean = False, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByRef db1 As DAO.Database) &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const CALLER = "StoreFilesInTable" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Error GoTo StoreFilesInTable_ErrorHandler &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strFilePath As String &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstParent&amp;nbsp;&amp;nbsp; As DAO.Recordset2 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild&amp;nbsp;&amp;nbsp;&amp;nbsp; As DAO.Recordset2 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach&amp;nbsp;&amp;nbsp; As DAO.Field2 &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' These objects require a reference to the "Microsoft Scripting Runtime" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' but are defined as "Object" instead to use late binding and avoid that. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' If you've added the reference, remove the "Object" and uncomment the &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' following lines to get the intellisense autocomplete for these objects. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFso&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object ' Scripting.FileSystemObject &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFolder&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object ' Scripting.Folder &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objSubFolder As Object ' Scripting.Folder &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object ' Scripting.File &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' If the user did not specify a database, use the current one. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If db1 Is Nothing Then Set db1 = Application.CurrentDb &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Instantiate the FileSystemObject. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set objFso = CreateObject("Scripting.FileSystemObject") &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Make sure the folder path always ends with a "\". &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Right(strFolder, 1) &amp;lt;&amp;gt; "\") Then strFolder = strFolder &amp;amp; "\" &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Make sure the folder exists. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Not objFso.FolderExists(strFolder) Then &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "Folder does not exist: " &amp;amp; strFolder, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; vbExclamation, CALLER &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Function &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' It exists, so get the folder object. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set objFolder = objFso.GetFolder(strFolder) &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Open the table containing the attachment field &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstParent = db1.OpenRecordset(strTable) &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.AddNew &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.Fields(strPathField).Value = objFolder.Path &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Get the first file in this directory. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFilePath = Dir(strFolder &amp;amp; strPattern) &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Store each file that meets the pattern &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; While (Len(strFilePath) &amp;gt; 0) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstParent.Fields(strAttachmentField).Value &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.AddNew &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set fldAttach = rstChild.Fields("FileData") &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fldAttach.LoadFromFile strFolder &amp;amp; strFilePath &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Update &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFilePath = Dir() ' Get the next file &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Wend &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Commit the new row with the attachments field populated &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' with all of the files from the current folder. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.Update &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Recurse into subfolders if requested. &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (blnIncludeSubfolders) Then &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each objSubFolder In objFolder.SubFolders &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StoreFilesInTable objSubFolder.Path, strTable, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strPathField, strAttachmentField, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strPattern, blnIncludeSubfolders, db1 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If &lt;/P&gt;
&lt;P&gt;Cleanup: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.Close &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstParent = Nothing &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Function &lt;BR&gt;StoreFilesInTable_ErrorHandler: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER &amp;amp; " : " &amp;amp; Err.Description &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox Err.Description, vbCritical, "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GoTo Cleanup &lt;BR&gt;End Function 'StoreFilesInTable&lt;/P&gt;&lt;/CODE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is a short routine to help you test the above code.&amp;nbsp; You will need to change the "&lt;FONT size=2 face="Courier New"&gt;&amp;lt;&lt;EM&gt;YourUserName&lt;/EM&gt;&amp;gt;&lt;/FONT&gt;" to your login name, or just change the whole path in the &lt;FONT size=2 face="Courier New"&gt;strRootFolder&lt;/FONT&gt; string constant to the folder you want to store in the table.&amp;nbsp; Note that I've set the &lt;FONT size=2 face="Courier New"&gt;blnIncludeSubfolders&lt;/FONT&gt; parameter to &lt;FONT size=2 face="Courier New"&gt;False&lt;/FONT&gt; to keep you from inadvertently bloating your database, but you can set it to True if you want to include all of the subfolders, too.&lt;/P&gt;&lt;CODE&gt;
&lt;P&gt;&lt;FONT size=2 face="Courier New"&gt;Sub TestStoreFilesInTable() &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strRootFolder As String = "C:\Users\&lt;EM&gt;&amp;lt;YourUserName&amp;gt;&lt;/EM&gt;\Pictures\" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; StoreFilesInTable strRootFolder, "Table1", "FolderPath", "Files", "*.jpg", False &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "Done adding files from: " &amp;amp; vbCrLf &amp;amp; strRootFolder &amp;amp; "*.jpg", _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VbMsgBoxStyle.vbInformation, "TestStoreFilesInTable" &lt;BR&gt;End Sub&lt;/FONT&gt;&lt;/P&gt;&lt;/CODE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8795280" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/Access+2007/default.aspx">Access 2007</category><category domain="http://blogs.msdn.com/access/archive/tags/Engine/default.aspx">Engine</category><category domain="http://blogs.msdn.com/access/archive/tags/Attachment/default.aspx">Attachment</category><category domain="http://blogs.msdn.com/access/archive/tags/Code/default.aspx">Code</category></item><item><title>Adding Attachments from a Folder</title><link>http://blogs.msdn.com/access/archive/2008/07/25/adding-attachments-from-a-folder.aspx</link><pubDate>Sat, 26 Jul 2008 05:40:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8773925</guid><dc:creator>robcooper</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/access/comments/8773925.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=8773925</wfw:commentRss><description>&lt;P&gt;Someone asked us yesterday how to add all of the .jpg files from a folder into an Attachment field in a table. In this case, the individual wanted to add one attachment into a new record in the table. This could be pretty useful, so we thought we would post it more broadly.&lt;/P&gt;
&lt;P&gt;This code accepts parameters for the folder name, table name containing the attachment, the name of the attachment field, and two optional arguments. The first optional argument is a pattern that can be used when searching a directory, such as "*.*". The second optional argument is a flag to indicate whether to iterate through subfolders. This argument is False by default. The code uses the FileSystemObject which is required on the machine. We're using it late bound so a reference to the Microsoft Scripting Runtime is not required.&lt;/P&gt;
&lt;P&gt;Next, add the following routine to the module.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;' ------------------------------------------------------------------------- &lt;BR&gt;' Procedure : AddAttachmentsFromFolder &lt;BR&gt;' Purpose&amp;nbsp;&amp;nbsp; : Adds one record to an attachment field for each file in the &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : specified folder. &lt;BR&gt;' Arguments : strFolder&amp;nbsp; - Name of the folder &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strTable&amp;nbsp;&amp;nbsp; - Name of the table containing the attachment field &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strField&amp;nbsp;&amp;nbsp; - Name of the attachment field &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strPattern - Search pattern for the directory. Defaults to &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; all files (*.*) &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : fIncludeSubfolders - Include subfolders in the specified folder &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; :&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Defaults to False &lt;BR&gt;' Comments&amp;nbsp; : This routine adds a new record to the table, then one attachment. &lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : It commits the changes and handles all cleanup &lt;BR&gt;' ------------------------------------------------------------------------- &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;Sub AddAttachmentsFromFolder(ByVal strFolder As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal strTable As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ByVal strField As String, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByVal strPattern As String = "*.*", _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Optional ByVal fIncludeSubfolders As Boolean = False)&lt;/FONT&gt; &lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strFile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As String &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim lngCount&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As Long &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstParent&amp;nbsp;&amp;nbsp;&amp;nbsp; As DAO.Recordset2 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As DAO.Recordset &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach&amp;nbsp;&amp;nbsp;&amp;nbsp; As DAO.Field2&lt;/FONT&gt; &lt;FONT face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFso&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object&amp;nbsp;' Scripting.FileSystemObject&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFolder&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object ' Scripting.Folder &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objFile&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; As Object ' Scripting.File &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim objSubFolder As Object ' Scripting.Folder&amp;nbsp; &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Error GoTo ErrorHandler &lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Instantiate the FileSystemObject &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set objFso = CreateObject("Scripting.FileSystemObject") &lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' fix up the folder &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Right(strFolder, 1) &amp;lt;&amp;gt; "\") Then strFolder = strFolder &amp;amp; "\"&amp;nbsp; &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' make sure the folder exists &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (Dir(strFolder, vbDirectory) = "") Then &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "The specified folder does not exist: " &amp;amp; strFolder, vbExclamation &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the folder object &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set objFolder = objFso.GetFolder(strFolder) &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' open the table containing the attachment field &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstParent = CurrentDb().OpenRecordset(strTable) &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the first file &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFile = Dir(strFolder &amp;amp; strPattern) &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get each file that meets the pattern &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; While (Len(strFile) &amp;gt; 0) &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' add a record to the parent table &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print strFolder &amp;amp; strFile &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.AddNew &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the attachment recordset and FileData field to contain the file &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstParent.Fields(strField).Value &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set fldAttach = rstChild.Fields("FileData") &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' add the attachment to the attachment field &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.AddNew &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fldAttach.LoadFromFile strFolder &amp;amp; strFile &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Update &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.Update &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' get the next file &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFile = Dir &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Wend &lt;BR&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' recurse subfolders? &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If (fIncludeSubfolders) Then &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; For Each objSubFolder In objFolder.SubFolders &lt;BR&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddAttachmentsFromFolder objSubFolder.Path, strTable, strField, _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strPattern, fIncludeSubfolders &lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Next &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If &lt;BR&gt;&lt;BR&gt;Cleanup: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstParent.Close &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstParent = Nothing &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub &lt;BR&gt;&lt;BR&gt;ErrorHandler: &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Error " &amp;amp; Err.Number &amp;amp; " - " &amp;amp; Err.Description &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox Err.Description &amp;amp; vbCrLf &amp;amp; _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Err.Number &amp;amp; vbCrLf &amp;amp; _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Err.Source, VbMsgBoxStyle.vbCritical, "AddAttachmentsFromFolder Failed" &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; GoTo Cleanup &lt;BR&gt;End Sub&lt;/FONT&gt; 
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;To test the routine, supply the name of a folder, as well as the name of a table and field. Here's a wrapper routine that does this. This example will load all .jpg files in the specified directory into a table called tblMyTable.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;Sub TestAddAttachmentsFromFolder()&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strRootFolder As String = "&amp;lt;EnterFolderName&amp;gt;"&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddAttachmentsFromFolder strRootFolder, "tblMyTable", "Attachments", _&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "*.jpg", True&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "Done adding files from: " &amp;amp; vbCrLf &amp;amp; strRootFolder, _&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; vbInformation, "File Import Process Completed"&lt;/FONT&gt; &lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;End Sub&lt;/FONT&gt;&lt;/BLOCKQUOTE&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8773925" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/Access+2007/default.aspx">Access 2007</category><category domain="http://blogs.msdn.com/access/archive/tags/Attachment/default.aspx">Attachment</category><category domain="http://blogs.msdn.com/access/archive/tags/Code/default.aspx">Code</category></item><item><title>Using VBA code to open a file stored in the new Access 2007 Attachment field</title><link>http://blogs.msdn.com/access/archive/2007/08/30/using-vba-code-to-open-a-file-stored-in-the-new-access-2007-attachment-field.aspx</link><pubDate>Thu, 30 Aug 2007 20:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4650547</guid><dc:creator>James K. Rivera</dc:creator><slash:comments>4</slash:comments><comments>http://blogs.msdn.com/access/comments/4650547.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=4650547</wfw:commentRss><description>&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;Someone asked me about using the Attachment data type in Access 2007 for a specific task. They wanted to use it as a simple data type where it would only be used to hold 1 file per record, and they wanted to be able to open the file in an external application using a button on a form instead of using the Attachment control on a form.&amp;nbsp; Given these constraints, I was created a simple VBA function for doing just that:&lt;/SPAN&gt; &lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;Public Function OpenFirstAttachmentAsTempFile(ByRef rstCurrent As DAO.Recordset, ByVal strFieldName As String) As String &lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild As DAO.Recordset2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach As DAO.Field2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strFilePath As String&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strTempDir As String&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strTempDir = Environ("Temp") ' Get the Temp directory from the environment variable.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Right(strTempDir, 1) &amp;lt;&amp;gt; "\" Then strTempDir = strTempDir &amp;amp; "\" ' Make sure the path always ends with a backslash.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstCurrent.Fields(strFieldName).Value ' the .Value for a complex field returns the underlying recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFilePath = strTempDir &amp;amp; rstChild.Fields("FileName").Value ' Append the name of the first (and only) attached file to temp dir.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Dir(strFilePath) &amp;lt;&amp;gt; "" Then ' the file already exists--delete it first.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VBA.SetAttr strFilePath, vbNormal ' remove any file attributes (e.g. read-only) that would block the kill command.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VBA.Kill strFilePath ' delete the file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set fldAttach = rstChild.Fields("FileData") ' The binary data of the file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fldAttach.SaveToFile strFilePath&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close ' cleanup&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; VBA.Shell "Explorer.exe " &amp;amp; Chr(34) &amp;amp; strFilePath &amp;amp; Chr(34), vbNormalFocus ' Use Windows Explorer to launch&amp;nbsp; the file.&lt;BR&gt;&lt;BR&gt;End Function 'OpenFirstAttachmentAsTempFile&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;/CODE&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;Then I wrote this function just to test it in a database that has a Table1 with an Attachment field named "Files" in which I had already placed a file: &lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;CODE&gt;Public Function TestOpenFirstAttachmentAsTempFile()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim dbs As DAO.Database&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rst As DAO.Recordset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strTable = "Table1"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strField = "Files" ' Attachment field in Table1&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set dbs = CurrentDb&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rst = dbs.OpenRecordset(strTable)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'rst.MoveNext ' Uncomment this line to go to the 2nd row in the Table.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OpenFirstAttachmentAsTempFile rst, strField&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Close&lt;BR&gt;End Function &lt;/CODE&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;By using the VBA.Shell command with Explorer.exe, the file will be opened just as if you double clicked it from Windows Explorer!&lt;BR&gt;&lt;BR&gt;See my &lt;A href="http://blogs.msdn.com/access/archive/2007/08/24/adding-removing-and-saving-files-from-the-new-attachment-field-in-access-2007.aspx" mce_href="http://blogs.msdn.com/access/archive/2007/08/24/adding-removing-and-saving-files-from-the-new-attachment-field-in-access-2007.aspx"&gt;previous blog post about attachments&lt;/A&gt; for more information about accessing attachments from DAO.&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4650547" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/Access+2007/default.aspx">Access 2007</category><category domain="http://blogs.msdn.com/access/archive/tags/Reference/default.aspx">Reference</category><category domain="http://blogs.msdn.com/access/archive/tags/Attachment/default.aspx">Attachment</category><category domain="http://blogs.msdn.com/access/archive/tags/Code/default.aspx">Code</category><category domain="http://blogs.msdn.com/access/archive/tags/Power+Tips/default.aspx">Power Tips</category></item><item><title>Adding, removing, and saving files from the new Attachment field in Access 2007</title><link>http://blogs.msdn.com/access/archive/2007/08/24/adding-removing-and-saving-files-from-the-new-attachment-field-in-access-2007.aspx</link><pubDate>Fri, 24 Aug 2007 23:41:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4548061</guid><dc:creator>James K. Rivera</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/access/comments/4548061.aspx</comments><wfw:commentRss>http://blogs.msdn.com/access/commentrss.aspx?PostID=4548061</wfw:commentRss><description>&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;One of the coolest new features in Access 2007 is the new Attachments data type.&amp;nbsp; There are some very helpful dialogs for working with this data type, but there are also some useful additions to DAO to make automating the process of adding and saving attachments easy, too.&amp;nbsp; What follows is some VBA code I've written that I hope you will find useful in understanding how do to this. &lt;BR&gt;&lt;BR&gt;&lt;BR&gt;First, let's look at the code to get a file into a table using DAO:&lt;BR&gt;&lt;BR&gt;The AddAttachment sub takes a reference to a DAO.Recordset for the table or query with the attachment field, the name of the attachment field, and the full path to the file to be attached.&amp;nbsp; The easiest way to use this is to call Database.OpenRecordset and pass in the name of the table.&amp;nbsp; Then, before calling this sub, call Recordset.AddNew or Recordset.Edit to allow changes to the Recordset (this sets Recordset.Updatable = True).&amp;nbsp; After this sub returns, you must call Recordset.Update to commit the changes.&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier"&gt;&lt;CODE&gt;&lt;BR&gt;' Module level constants used in these examples&lt;BR&gt;Const m_strFieldFileName As String = "FileName" ' The name of the attached file&lt;BR&gt;Const m_strFieldFileType As String = "FileType" ' The attached file's extension&lt;BR&gt;Const m_strFieldFileData As String = "FileData" ' The binary data of the file&lt;BR&gt;&lt;BR&gt;' -------------------------------------------------------------------------&lt;BR&gt;' Sub/Func : AddAttachment&lt;BR&gt;' Purpose&amp;nbsp; : Saves the attachments at the current row of the open Recordset&lt;BR&gt;' Arguments: rstCurrent - The recordset open at the current row to save&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strFieldName - The name of the attachment field&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strFilePath - The full path to the file to attach&lt;BR&gt;' Comments : User must call .AddNew or .Edit on the incoming Recordset&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : and then Recordset.Update when this returns to commit changes&lt;BR&gt;' -------------------------------------------------------------------------&lt;BR&gt;Sub AddAttachment(ByRef rstCurrent As DAO.Recordset, ByVal strFieldName As String, ByVal strFilePath As String)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const CALLER = "AddAttachment"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Error GoTo AddAttachment_ErrorHandler&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild&amp;nbsp; As DAO.Recordset2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach As DAO.Field2&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Dir(strFilePath) = "" Then ' the specified file does not exist!&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "The specified input file does not exist: " &amp;amp; vbCrLf &amp;amp; strFilePath, vbCritical, "File not found"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstCurrent.Fields(strFieldName).Value ' the .Value for a complex field returns the underlying Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.AddNew ' add a new row to the child Recordset&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set fldAttach = rstChild.Fields(m_strFieldFileData) ' set the DAO.Field2 object to the field that holds the binary data.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fldAttach.LoadFromFile strFilePath ' store the file's contents in the new row.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Update ' commit the new row.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close ' close the child Recordset.&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub&lt;BR&gt;AddAttachment_ErrorHandler:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'Check for Run-time error '3820': (occurs if the file with the same name is already attached)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'You cannot enter that value because it duplicates an existing value in the multi-valued lookup or attachment field.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 'Multi-valued lookup or attachment fields cannot contain duplicate values.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER &amp;amp; " : " &amp;amp; Err.Description&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Err.Number &amp;lt;&amp;gt; 3820 Then&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox Err.Description, VbMsgBoxStyle.vbCritical, "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Assert False ' always stop here when debugging&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Else&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox "File of same name already attached", VbMsgBoxStyle.vbCritical, "Cannot attach file"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub&lt;BR&gt;End Sub 'AddAttachment &lt;/CODE&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;Next, the following code will save all of the files in the attachment field of the current row.&amp;nbsp; This sub takes similar parameters: the Recordset object, the name the of the attachment field, and the directory to place all of the attachments for the field in the current row.&amp;nbsp; However, since the Recordset is not being modified, it is not necessary to call Recordset.Edit (or AddNew) before calling this sub.&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier"&gt;&lt;CODE&gt;' -------------------------------------------------------------------------&lt;BR&gt;' Sub/Func : SaveAttachments&lt;BR&gt;' Purpose&amp;nbsp; : Saves the attachments at the current row of the open Recordset&lt;BR&gt;' Arguments: rstCurrent - The recordset open at the current row to save&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strFieldName - The name of the attachment field&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : strOutputDir - The folder to put the files in (e.g. "C:\Foo\")&lt;BR&gt;' -------------------------------------------------------------------------&lt;BR&gt;Sub SaveAttachments(ByRef rstCurrent As DAO.Recordset, ByVal strFieldName As String, ByVal strOutputDir As String)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const CALLER = "SaveAttachments"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Error GoTo SaveAttachments_ErrorHandler&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild As DAO.Recordset2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach As DAO.Field2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strFilePath As String&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Right(strOutputDir, 1) &amp;lt;&amp;gt; "\" Then strOutputDir = strOutputDir &amp;amp; "\"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstCurrent.Fields(strFieldName).Value ' The .Value for a complex field returns the underlying Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; While Not rstChild.EOF ' Loop through all of the attached files in the child Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFilePath = strOutputDir &amp;amp; rstChild.Fields(m_strFieldFileName).Value 'Append the name of the attached file to output directory.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Dir(strFilePath) &amp;lt;&amp;gt; "" Then ' The file already exists--delete it first.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VBA.SetAttr strFilePath, vbNormal ' Remove any flags (e.g. read-only) that would block the kill command.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VBA.Kill strFilePath ' Delete the file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set fldAttach = rstChild.Fields(m_strFieldFileData) ' The binary data of the file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; fldAttach.SaveToFile strFilePath&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.MoveNext ' Go to the next row in the child Recordset to get the next attached file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Wend&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close ' cleanup&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub&lt;BR&gt;SaveAttachments_ErrorHandler:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER &amp;amp; " : " &amp;amp; Err.Description&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox Err.Description, VbMsgBoxStyle.vbCritical, "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Assert False ' always stop here when debugging&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Resume Next&lt;BR&gt;End Sub 'SaveAttachments&lt;BR&gt;&lt;/CODE&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;&lt;BR&gt;Next, you might want to be able to remove a file from the attachment field of the current row.&amp;nbsp; This sub takes similar parameters: the Recordset object, the name the of the attachment field, and the name of the file in the attachments field in the current row to be removed.&amp;nbsp; Since the Recordset is being modified, before calling this sub, you must call Recordset.Edit (or Recordset.AddNew) to allow changes to the Recordset (this sets Recordset.Updatable = True).&amp;nbsp; After this sub returns, you must call Recordset.Update to commit the changes. &lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier"&gt;' -------------------------------------------------------------------------&lt;BR&gt;' Sub/Func&amp;nbsp;: RemoveAttachment&lt;BR&gt;' Purpose&amp;nbsp;&amp;nbsp;: Removes the file from the attachments field in the currect row&lt;BR&gt;' Arguments: rstCurrent - The recordset open at the current row to change&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: strFieldName - The name of the attachment field&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: strFileName - The name of the file to remove&lt;BR&gt;' Comments : User must call .AddNew or .Edit on the incoming Recordset&lt;BR&gt;'&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;: and then Recordset.Update when this returns to commit changes&lt;BR&gt;' -------------------------------------------------------------------------&lt;BR&gt;Sub RemoveAttachment(ByRef rstCurrent As DAO.Recordset, ByVal strFieldName As String, ByVal strFileName As String)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const CALLER = "RemoveAttachment"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Error GoTo RemoveAttachment_ErrorHandler&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rstChild As DAO.Recordset2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim fldAttach As DAO.Field2&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strCurrent As String&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim strChop() As String&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Parent row (ID) is: " &amp;amp; rstCurrent.Fields("ID").Value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strChop = Split(strFileName, "\") ' This chops the file name up into into an array of strings delimited by "\".&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; strFileName = UCase(strChop(UBound(strChop))) ' The last element in the returned array is the filename.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rstChild = rstCurrent.Fields(strFieldName).Value ' the .Value for a complex field returns the underlying Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; While Not rstChild.EOF ' Loop through all of the attached files in the child Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; strCurrent = rstChild.Fields(m_strFieldFileName) ' The name of the file in the current row of the child Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; If UCase(strCurrent) = strFileName Then ' we found the attachment to be removed--delete it.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Delete ' There is no need to call rstChild.Edit first because the parent Recordset is in Edit mode.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub ' We're done removing the file.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; End If&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.MoveNext ' The file to remove was not the current one--move to the next row of the child Recordset.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Wend&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rstChild.Close ' cleanup&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Exit Sub&lt;BR&gt;RemoveAttachment_ErrorHandler:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Print "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER &amp;amp; " : " &amp;amp; Err.Description&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Debug.Assert False ' always stop here when debugging&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MsgBox Err.Description, VbMsgBoxStyle.vbCritical, "Error # " &amp;amp; Err.Number &amp;amp; " in " &amp;amp; CALLER&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Resume Next&lt;BR&gt;End Sub 'RemoveAttachment&lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;&lt;BR&gt;&lt;BR&gt;Finally, some sample code to test these subs would be useful.&amp;nbsp; Create a database with a Table1 consisting of an Autonumber primary key field named, "ID" and an Attachment field named, "Files".&amp;nbsp; Then add the following code to a module along with the above methods and press F5 to run it or F8 to single step through it.&lt;BR&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Courier"&gt;&lt;CODE&gt;' -------------------------------------------------------------------------&lt;BR&gt;' Sub/Func : TestAddRemoveAndSave&lt;BR&gt;' Purpose : Test AddAttachment(), RemoveAttachment(), and SaveAttachments()&lt;BR&gt;' -------------------------------------------------------------------------&lt;BR&gt;Sub TestAddRemoveAndSave()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim dbs As DAO.Database&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Dim rst As DAO.Recordset&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strTable = "Table1"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Const strField = "Files" ' Attachment field in Table1&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set dbs = CurrentDb&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Set rst = dbs.OpenRecordset(strTable)&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Add a new row and an attachment&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.AddNew&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddAttachment rst, strField, "C:\Windows\Media\chimes.wav"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Update&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.MoveLast&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Add another attachment to the last row&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Edit&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AddAttachment rst, strField, "C:\Windows\Media\chord.wav"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Update&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ' Remove the first attachment from the last row&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Edit&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; RemoveAttachment rst, strField, "chimes.wav"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Update&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; If Dir("C:\Foo\", vbDirectory) = "" Then MkDir "C:\Foo"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; SaveAttachments rst, strField, "C:\Foo\"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rst.Close&lt;BR&gt;End Sub 'TestAddRemoveAndSave &lt;/CODE&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="FONT-FAMILY: Tahoma"&gt;And there you have it.&amp;nbsp; I hope this code helps you in adding, removing, and saving attachments in Access!&lt;BR&gt;&lt;/SPAN&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4548061" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/access/archive/tags/Access+2007/default.aspx">Access 2007</category><category domain="http://blogs.msdn.com/access/archive/tags/Attachment/default.aspx">Attachment</category><category domain="http://blogs.msdn.com/access/archive/tags/Code/default.aspx">Code</category></item></channel></rss>