locked
Can't load images into unbound Attachment control RRS feed

  • Question

  • Hi folks. I'm new here so I hope you'll forgive any protocol infractions I may commit.

    I am working with Access 2010 in a Windows 7(64) environment. I am trying to make a form display an individual's data and up to 3 images related to the individual, where the images are obtained from an Attachment field in the individual's data record. I have succeeded in saving the data and the images to the record, but I have been unable to display them like I want to. The images I am using are jpg's, but the problem I am experiencing occurs equally with bmp's.

    In theory, the way to do what I want to do is nicely documented in the "Displaying Multiple Attachments Onscreen" section of  this MSDN article. Essentially, it says to

    1. put a hidden Attachment control on the form and bind it to the Attachment field in the form's record source
    2. put 3 unbound Attachment controls on the form
    3. using VBA, loop through the bound control and assign its images to the DefaultPicture property of the unbound controls.

    Here is the code they suggest:

    Private Sub Form_Current()
        Dim i As Integer
        Dim att As Attachment
    
        ' bind the attachments
        For i = 0 To Me.HousePictures.AttachmentCount - 1
            Set att = Me.Controls(“Attachment” & i + 1)
            att.DefaultPicture = Me.HousePictures.FileName(i)
            Me.HousePictures.Forward
        Next
    End Sub

    In my case, I didn't hide the bound control (yet) and I put a procedure like the one above in the form's OnLoad event. The form opens with all the individual's data showing plus the bound control loads fine and I can click through its 4 images. But when I get to executing my equivalent of the "att.DefaultPicture = Me.HousePictures.FileName(i)", I error out of the procedure with Error 2220, "[...database file name...] can't open the file [my image file name].jpg"

    This approach is the most recent of my many attempts to get unbound controls to show images saved in an Attachment field. I have used VBA to load them directly (ie without going through a bound Attachment). I have tried OLE controls. I have tried bmp images. In all attempts, I got the same error. My computer certainly has default programs assigned to open jpg and bmp files (although the Attachment control is said to not require them).

    There have been only two ways that I have succeeded in getting an unbound Attachment to show a picture

    1. set the DefaultPicture property to a fully qualified path to the image. But I really don't want to do this as it complicates moving the back end data and it complicates the user interface by requiring the user to not only find the image source file but to save it to a specific location. My user is not up to the second part of that task.
    2. now this is the really baffling approach: If on opening the form I preset an unbound control's DefaultPicture property to a fully qualified path (as in (1)),  I can then run VBA code (triggered by a Test button on the form) to create a recordset of  Attachment data and set the DefaultPicture property to that data (essentially using the code listed above). It seems that by first using the Path approach, the Attachment control learns how to open any other jpg file that gets assigned to its DefaultPicture property. This approach works even if the form itself is unbound.

    Well, that was a bit long. If anybody can tell me how to solve this problem, I'll be very grateful.

    Thanks,
    Doug








    Thursday, February 23, 2012 4:39 AM

Answers

  • Create a temporary table with one record with an attachment field.  Bind the three controls to the attachment field.  Open a recordset (rsTemp) on the table.

    When you want to display the contents of an attachment field in your regular table.  Copy the contents of the attachment field to the temporary table.  You need to issue an rsTemp.Edit call.  Using two recordset2 variables -- one set the to contents of the source attachment field and the other set to the contents of the target attachment field -- transfer the contents.  Issue an Update for the target attachment field recordset and then for rsTemp.  Set the each attachment control to display a different image.


    http://www.saberman.com

    Tuesday, February 28, 2012 8:45 PM
  • Although I haven't coded your approach, with what I have learned I'm sure it would work.

    My solution is less elegant but a bit more complex in that I allow the user to add, delete or replace photos using the same form and same Attachment controls and to create a unique caption for each image. Photos are not required in any of the Attachments. All Attachment controls are locked. I wound up having 3 attachment fields and 3 caption (text) fields per record, 3 bound Attachment controls on the form and limiting the user to one photo per control. Using a single hidden, bound attachment could still work, but maintaining the caption association as photos are replaced or deleted would be trickier. Having written that, I just realized that since I am allowing only one photo per Attachment, I could have used the control's Caption property instead of separate caption fields.

    The form works like this:

    Starting with a loaded form, for each Attachment control a Find Photo button brings up a File Open dialog that puts a path into the DefaultPicture property, disables the Find Photo button and enables the Delete Photo button. A Finish button uses LoadFromFile to put each DefaultPicture that contains a string longer than "(none)" into its associated attachment field, as long as AttachmentCount is currently 0.

    When the form is loaded, Add/Delete buttons are enabled/disabled based on AttachmentCount properties

    Thanks for your help saberman. It got me directed toward a solution.

    Doug


    Douglas E. Piehler

    Thursday, March 1, 2012 4:49 PM

All replies

  • Hi Doug,

    Thank you for posting.

    I tried it on my side, however I didn't encountered this problem.

    Private Sub Form_Load()
    Dim i As Integer
    Dim att As Attachment
    
    For i = 0 To Me.HiddenAttachment.AttachmentCount - 1
    Set att = Me.Controls("Attachment" & i + 1)
    att.DefaultPicture = Me.HiddenAttachment.FileName(i)
    Me.HiddenAttachment.Forward
    Next
    End Sub

    I am not sure why you got this error message. Can you share your demo project on the skydrive: http://www.skydrive.com so that we can reproduce and analyze your problem more convienently?

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us

    Monday, February 27, 2012 8:04 AM
  • I think you code is working because the pictures are in the current directory so only the file name is need to find them.  If that is the case try removing the pictures from the current director and running your code again.


    http://www.saberman.com

    Monday, February 27, 2012 4:28 PM
  • Assumption: You want to use unbound attachment controls so the user cannot click on the control and modify the stored images.

    Have you tried binding the three visible attachment controls to the underlying data and setting the Locked property to prevent editting?


    http://www.saberman.com

    Monday, February 27, 2012 4:35 PM
  • Thanks for the reply Bruce.

    Before uploading my project, I decided to strip out all the parts that were not related to the problem to make it easier for you to explore. That didn't leave very much code, so I did some more experimenting. That's why I didn't get back to you sooner.

    Before I tell you what I encountered, would you mind trying something. Would you load your images from different directories and then run your code to transfer them to the unbound controls. Let me know if something interesting happens. It might help to un-hide the hidden attachment control.

    Thanks,

    Doug


    Douglas E. Piehler

    Tuesday, February 28, 2012 2:49 AM
  • Hi saberman.

    I think you may be on to something. Look for a follow-up reply from Bruce.

    Doug


    Douglas E. Piehler

    Tuesday, February 28, 2012 2:51 AM
  • Actually, the reason I am using unbound controls is because I am updating the db from 3 separate forms via a Transaction and and all the rest of the controls (text controls) are unbound.

    I am already using locked controls. I am giving the user very limited (and controlled) access to adding and deleting images.

    In one of my experiments, I did try binding the attachments to data but that had no effect on the problem.

    Doug


    Douglas E. Piehler

    Tuesday, February 28, 2012 3:14 AM
  • Create a temporary table with one record with an attachment field.  Bind the three controls to the attachment field.  Open a recordset (rsTemp) on the table.

    When you want to display the contents of an attachment field in your regular table.  Copy the contents of the attachment field to the temporary table.  You need to issue an rsTemp.Edit call.  Using two recordset2 variables -- one set the to contents of the source attachment field and the other set to the contents of the target attachment field -- transfer the contents.  Issue an Update for the target attachment field recordset and then for rsTemp.  Set the each attachment control to display a different image.


    http://www.saberman.com

    Tuesday, February 28, 2012 8:45 PM
  • Doug, I tested according to your description and also encountered this problem and I can't find a good workaround about it. I think Saberman's suggestion is good. Did you try it and does it work for you?

    Best Regards,


    Bruce Song [MSFT]
    MSDN Community Support | Feedback to us

    Thursday, March 1, 2012 8:18 AM
  • Thanks for confirming the problem, Bruce. For the record, here's is what I think I have learned (with lots of experiments and help from you and saberman):

    When you use the Attachment control strictly as it is designed to be used (i.e bound and controlled via the Attachmant Manager), it works fine. You can load it with attachments from many different locations then move the table containing the attachments to a new location (or simply delete the original source files) and all the attachments still play back correctly. However, when you go "behind the scenes" with VBA, things are not so nice.

    You can use VBA to fill the attachment field with a series of images by repeating this code:  "rstAttachment.Fields("FileData").LoadFromFile [path]". If the images come from a mixture of paths and your Attachment control is bound to the field, the control will play back as desired, even if the images are no longer in their original path. But if it is unbound and you load it using the VBA we have been testing, it will play back only those images found in the same directory as the last image you saved, and then only if the images are still in that directory. For the others, you will get that error message. To me, having to start with all the images in a specific directory and then keep them there defeats the reason for using an attachment control.

    In the end, I got my forms to work (I'll provide details in my reply to saberman). I haven't run follow-up tests to check all the scenarios implied in the preceeding paragraph, but I think it's pretty accurate.

    Thanks again for your help with this,

    Doug


    Douglas E. Piehler

    Thursday, March 1, 2012 3:38 PM
  • Although I haven't coded your approach, with what I have learned I'm sure it would work.

    My solution is less elegant but a bit more complex in that I allow the user to add, delete or replace photos using the same form and same Attachment controls and to create a unique caption for each image. Photos are not required in any of the Attachments. All Attachment controls are locked. I wound up having 3 attachment fields and 3 caption (text) fields per record, 3 bound Attachment controls on the form and limiting the user to one photo per control. Using a single hidden, bound attachment could still work, but maintaining the caption association as photos are replaced or deleted would be trickier. Having written that, I just realized that since I am allowing only one photo per Attachment, I could have used the control's Caption property instead of separate caption fields.

    The form works like this:

    Starting with a loaded form, for each Attachment control a Find Photo button brings up a File Open dialog that puts a path into the DefaultPicture property, disables the Find Photo button and enables the Delete Photo button. A Finish button uses LoadFromFile to put each DefaultPicture that contains a string longer than "(none)" into its associated attachment field, as long as AttachmentCount is currently 0.

    When the form is loaded, Add/Delete buttons are enabled/disabled based on AttachmentCount properties

    Thanks for your help saberman. It got me directed toward a solution.

    Doug


    Douglas E. Piehler

    Thursday, March 1, 2012 4:49 PM
  • Any chance of sharing the code for this - saves me re-inventing the wheel :) I've been searching for days around this topic, and this is the closest I've come to a solution yet.
    Tuesday, December 3, 2013 2:30 PM