Attachments with Access Front End / SQL Back end (1 Viewer)

gojets1721

Registered User.
Local time
Today, 15:34
Joined
Jun 11, 2019
Messages
430
I have a DB full of customer complaints. It is a SQL backend with Access as a front end.

I'd like to have an attachment field for each record. If a complaint stems from a customer letter, we could add it to the record for easy access, etc. I have learned that the specific attachment 'field type' is unique to Access though.

Are there any options to still use attachments in a SQL backend?
 

Isaac

Lifelong Learner
Local time
Today, 15:34
Joined
Mar 14, 2017
Messages
8,777
Highly recommend you don't do this. Store the attachment on a shared network drive and only store the path as plain text in the db. many good reasons for doing so - and no, it won't be harder to access / download / copy / display the document......it will be even easier and there will be more options.
 

theDBguy

I’m here to help
Staff member
Local time
Today, 15:34
Joined
Oct 29, 2018
Messages
21,474
Maybe you could look into BLOBs or File Streams?
 

CJ_London

Super Moderator
Staff member
Local time
Today, 23:34
Joined
Feb 19, 2013
Messages
16,616
a suggestion made on a recent thread was to have an access table to store the attachments, together with a FK field to the sql table so the two were linked one to one. I'm not suggesting this is a good way to go but might be a temporary solution until you decide what to do
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 18:34
Joined
Feb 19, 2002
Messages
43,292
The attachment data type is actually stored in a normalized fashion except that the many-side table is hidden. A2007 just added a control to make viewing the attachments easier. You don't need an attachment data type. Just create your own many-side table and use a subform to display the images or whatever you are storing.

Here's a picture from one of my apps.
accAttachment.JPG
 
Last edited:

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 06:34
Joined
May 7, 2009
Messages
19,245
see post #3 and there are many ways to Retrieve/Save the blob in MS sql server, you just need to be patient
finding the right solution.
 

gojets1721

Registered User.
Local time
Today, 15:34
Joined
Jun 11, 2019
Messages
430
see post #3 and there are many ways to Retrieve/Save the blob in MS sql server, you just need to be patient
finding the right solution.
Sounds good. Any suggestions on any good guides/walkthroughs on how to achieve?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 18:34
Joined
Feb 19, 2002
Messages
43,292
Any suggestions on any good guides/walkthroughs on how to achieve?
Bind it to a form as I showed in the picture???
accAttachmentSubform.JPG
acctblAttachments.JPG
 

spaLOGICng

Member
Local time
Today, 15:34
Joined
Jul 27, 2012
Messages
127
I have a DB full of customer complaints. It is a SQL backend with Access as a front end.

I'd like to have an attachment field for each record. If a complaint stems from a customer letter, we could add it to the record for easy access, etc. I have learned that the specific attachment 'field type' is unique to Access though.

Are there any options to still use attachments in a SQL backend?
SQL Server does not have an Attachment Column like Access does.

What you can do is create a Column that is of the VARBINARY Type, then use the File System Object to "Stream" the File into the Column. It is pretty slick.

I recommend having the separate Table with a One-to-One Relationship, not placing the streamed file into the main table, because it could impede performance. Be very discretionary, but do not let others discourage you. Not sure what SQL Version you are using. If Standard, you should be okay. If Express, then you could potentially use more space. I have stored literally hundreds of thousands of documents in SQL Server.

Alternatively, and as others suggested, you could though just as easily seed the File Path to a Field and treat it as a Hyperlink. You could also use the Browser Control to create a Document Viewer.
 

gojets1721

Registered User.
Local time
Today, 15:34
Joined
Jun 11, 2019
Messages
430
Highly recommend you don't do this. Store the attachment on a shared network drive and only store the path as plain text in the db. many good reasons for doing so - and no, it won't be harder to access / download / copy / display the document......it will be even easier and there will be more options.
@Isaac This is what I would prefer to do. Any good guides that walk through how to construct that?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 18:34
Joined
Feb 19, 2002
Messages
43,292
The picture I posted shows the use of the OLEObject NOT the ACE Attachment type. This works regardless of the attachment type. We never store objects in an ACE BE because of the bloating but SQL Server can handle it. If you want to store the attachments as links, then instead of an image in a subform as I posted, the subform would show a list of document names and then use the double-click event to run a FollowHyperlink to open them. Here's code from one of my apps. It is using a button to open the doc so it uses the click event.

The FollowHyperlink works with any document type that is registered with windows. In this app they were mostly word and excel but some pdf's and jpg's
Code:
Private Sub cmdOpenDoc_Click()
    Dim strInput As String
    
On Error GoTo Err_cmdOpenDoc_Click
    If Me.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If

    If Right(Me.ScannedDocPath, 1) = "\" Then
        strInput = Me.ScannedDocPath & Me.txtFullDocName
    Else
        strInput = Me.ScannedDocPath & "\" & Me.txtFullDocName
    End If
    
    Application.FollowHyperlink strInput, , True

Exit_cmdOpenDoc_Click:
    Exit Sub

Err_cmdOpenDoc_Click:
    Select Case Err.Description
        Case 2501
            Resume Next
        Case 490    '   cannot open file
            MsgBox "This file cannot be found.  Please check its name and path.", vbOKOnly + vbInformation
            Exit Sub
        
        Case Else
            MsgBox Err.Description
            Resume Exit_cmdOpenDoc_Click
    End Select
 

gojets1721

Registered User.
Local time
Today, 15:34
Joined
Jun 11, 2019
Messages
430
The picture I posted shows the use of the OLEObject NOT the ACE Attachment type. This works regardless of the attachment type. We never store objects in an ACE BE because of the bloating but SQL Server can handle it. If you want to store the attachments as links, then instead of an image in a subform as I posted, the subform would show a list of document names and then use the double-click event to run a FollowHyperlink to open them. Here's code from one of my apps. It is using a button to open the doc so it uses the click event.

The FollowHyperlink works with any document type that is registered with windows. In this app they were mostly word and excel but some pdf's and jpg's
Code:
Private Sub cmdOpenDoc_Click()
    Dim strInput As String
   
On Error GoTo Err_cmdOpenDoc_Click
    If Me.Dirty Then
        DoCmd.RunCommand acCmdSaveRecord
    End If

    If Right(Me.ScannedDocPath, 1) = "\" Then
        strInput = Me.ScannedDocPath & Me.txtFullDocName
    Else
        strInput = Me.ScannedDocPath & "\" & Me.txtFullDocName
    End If
   
    Application.FollowHyperlink strInput, , True

Exit_cmdOpenDoc_Click:
    Exit Sub

Err_cmdOpenDoc_Click:
    Select Case Err.Description
        Case 2501
            Resume Next
        Case 490    '   cannot open file
            MsgBox "This file cannot be found.  Please check its name and path.", vbOKOnly + vbInformation
            Exit Sub
       
        Case Else
            MsgBox Err.Description
            Resume Exit_cmdOpenDoc_Click
    End Select
Thank you so much for the help. Would you ever be able to attach the DB itself? Specifically the one that uses links?
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 18:34
Joined
Feb 19, 2002
Messages
43,292
No. It is proprietary. I copied the code and told your where to put it. What else do you need? In the code I posted, the path to the documents is separate from the document names so you see code putting the two together. That is because the app works with multiple client companies and each company has its own folder which is stored in the company record . It reduces the size of the file name field because you don't have to duplicate the path in every row. If you don't do that, then just include the path in the file name field and ignore the if statement.

Here's two more procedures that you will find helpful. Put them in a standard module so you can reuse them on multiple forms. One opens the common dialog to pick a folder, the other opens it to pick a file name. The commented out code is to remind me of other options I might want to use. You can look up these functions in help to read about them. This code is called from a button next to where I want the code to place the result:


Code:
Option Compare Database
Option Explicit

Public Function fChooseFile()

   ' Requires reference to Microsoft Office 11.0 Object Library.

   Dim fDialog As Office.FileDialog
   Dim varFile As Variant


   ' Set up the File Dialog.
   Set fDialog = Application.FileDialog(msoFileDialogFilePicker)

   With fDialog

      ' Allow user to make multiple selections in dialog box
      .AllowMultiSelect = False
           
      ' Set the title of the dialog box.
      .Title = "Please select one file"

      'starting location
      .InitialFileName = CurrentProject.path
     
      ' Clear out the current filters, and add our own.
      .Filters.Clear
''''      .Filters.Add "Excel ", "*.XLSX"
      .Filters.Add "Access Databases", "*.ACCDB, *.MDB"
''''      .Filters.Add "Access Projects", "*.ADP"
      .Filters.Add "All Files", "*.*"

      ' Show the dialog box. If the .Show method returns True, the
      ' user picked at least one file. If the .Show method returns
      ' False, the user clicked Cancel.
      If .Show = True Then
         'Loop through each file selected and add it to our list box.
         For Each varFile In .SelectedItems
            fChooseFile = varFile
''''            Me.FileList.AddItem varFile
         Next
       
      Else
         MsgBox "You clicked Cancel in the file dialog box."
      End If
   End With

End Function


''https://msdn.microsoft.com/en-us/library/hww8txat%28v=vs.84%29.aspx?f=255&MSPPError=-2147217396
''https://www.exceltrick.com/formulas_macros/filesystemobject-in-vba/
''https://bettersolutions.com/vba/files-directories/file-system-object.htm
''http://www.xl-central.com/list-files-fso.html
''http://www.thevbprogrammer.com/ch06/06-09-fso.htm


Public Function fChooseDirectory()

    ' requires a reference to the Office xx Object library
    'Declare a variable as a FileDialog object.
    'Dim fd As FileDialog

   '''' Const msoFileDialogFolderPicker = 4 'use for late binding
   
    Dim fd As Object
   
    'Create a FileDialog object as a File Picker dialog box.
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)

    'Declare a variable to contain the path
    'of each selected item. Even though the path is a String,
    'the variable must be a Variant because For Each...Next
    'routines only work with Variants and Objects.
    Dim vrtSelectedItem As Variant

    'Use a With...End With block to reference the FileDialog object.
    With fd

        'Use the Show method to display the File Picker dialog box and return the user's action.
        'The user pressed the action button.
        If .Show = -1 Then

            'Step through each string in the FileDialogSelectedItems collection.
            For Each vrtSelectedItem In .SelectedItems

                'vrtSelectedItem is a String that contains the path of each selected item.
                'You can use any file I/O functions that you want to work with this path.
                'This example simply displays the path in a message box.

                'Only one item will be returned since the file dialog is a folder picker
                'MsgBox "The path is: " & vrtSelectedItem
                fChooseDirectory = vrtSelectedItem
                Exit Function
            Next vrtSelectedItem
        'The user pressed Cancel.
        Else
        End If
    End With

    'Set the object variable to Nothing.
    Set fd = Nothing
    fChooseDirectory = "Error - nothing chosen"
End Function
Code:
Private Sub cmdBrowse_Click()
Me.txtDBName = fChooseFile()
End Sub
accOpenFileDialog.JPG
 

gojets1721

Registered User.
Local time
Today, 15:34
Joined
Jun 11, 2019
Messages
430
No. It is proprietary. I copied the code and told your where to put it. What else do you need? In the code I posted, the path to the documents is separate from the document names so you see code putting the two together. That is because the app works with multiple client companies and each company has its own folder which is stored in the company record . It reduces the size of the file name field because you don't have to duplicate the path in every row. If you don't do that, then just include the path in the file name field and ignore the if statement.

Here's two more procedures that you will find helpful. Put them in a standard module so you can reuse them on multiple forms. One opens the common dialog to pick a folder, the other opens it to pick a file name. The commented out code is to remind me of other options I might want to use. You can look up these functions in help to read about them. This code is called from a button next to where I want the code to place the result:


Code:
Option Compare Database
Option Explicit

Public Function fChooseFile()

   ' Requires reference to Microsoft Office 11.0 Object Library.

   Dim fDialog As Office.FileDialog
   Dim varFile As Variant


   ' Set up the File Dialog.
   Set fDialog = Application.FileDialog(msoFileDialogFilePicker)

   With fDialog

      ' Allow user to make multiple selections in dialog box
      .AllowMultiSelect = False
          
      ' Set the title of the dialog box.
      .Title = "Please select one file"

      'starting location
      .InitialFileName = CurrentProject.path
    
      ' Clear out the current filters, and add our own.
      .Filters.Clear
''''      .Filters.Add "Excel ", "*.XLSX"
      .Filters.Add "Access Databases", "*.ACCDB, *.MDB"
''''      .Filters.Add "Access Projects", "*.ADP"
      .Filters.Add "All Files", "*.*"

      ' Show the dialog box. If the .Show method returns True, the
      ' user picked at least one file. If the .Show method returns
      ' False, the user clicked Cancel.
      If .Show = True Then
         'Loop through each file selected and add it to our list box.
         For Each varFile In .SelectedItems
            fChooseFile = varFile
''''            Me.FileList.AddItem varFile
         Next
      
      Else
         MsgBox "You clicked Cancel in the file dialog box."
      End If
   End With

End Function


''https://msdn.microsoft.com/en-us/library/hww8txat%28v=vs.84%29.aspx?f=255&MSPPError=-2147217396
''https://www.exceltrick.com/formulas_macros/filesystemobject-in-vba/
''https://bettersolutions.com/vba/files-directories/file-system-object.htm
''http://www.xl-central.com/list-files-fso.html
''http://www.thevbprogrammer.com/ch06/06-09-fso.htm


Public Function fChooseDirectory()

    ' requires a reference to the Office xx Object library
    'Declare a variable as a FileDialog object.
    'Dim fd As FileDialog

   '''' Const msoFileDialogFolderPicker = 4 'use for late binding
  
    Dim fd As Object
  
    'Create a FileDialog object as a File Picker dialog box.
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)

    'Declare a variable to contain the path
    'of each selected item. Even though the path is a String,
    'the variable must be a Variant because For Each...Next
    'routines only work with Variants and Objects.
    Dim vrtSelectedItem As Variant

    'Use a With...End With block to reference the FileDialog object.
    With fd

        'Use the Show method to display the File Picker dialog box and return the user's action.
        'The user pressed the action button.
        If .Show = -1 Then

            'Step through each string in the FileDialogSelectedItems collection.
            For Each vrtSelectedItem In .SelectedItems

                'vrtSelectedItem is a String that contains the path of each selected item.
                'You can use any file I/O functions that you want to work with this path.
                'This example simply displays the path in a message box.

                'Only one item will be returned since the file dialog is a folder picker
                'MsgBox "The path is: " & vrtSelectedItem
                fChooseDirectory = vrtSelectedItem
                Exit Function
            Next vrtSelectedItem
        'The user pressed Cancel.
        Else
        End If
    End With

    'Set the object variable to Nothing.
    Set fd = Nothing
    fChooseDirectory = "Error - nothing chosen"
End Function
Code:
Private Sub cmdBrowse_Click()
Me.txtDBName = fChooseFile()
End Sub
View attachment 104506
So I've implemented everything and it works well.

The only issue is, my attachments are showing up for every record in the main form despite each attachment having an ID equal to only one record (i.e. propertyID in your example). I made the tblAttachments table have a many to one relationship with the tblComplaint table but still, the attachments show up on every record. It's not filtering down based on ID
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 18:34
Joined
Feb 19, 2002
Messages
43,292
Is the join in the query correct? You might want to paste the SQL string for us to look at. If you are using a subform as in my example, then make sure you set the master/child links and Access will sync the subform with the main form automagically:)
 

Isaac

Lifelong Learner
Local time
Today, 15:34
Joined
Mar 14, 2017
Messages
8,777
Congrats on getting this to work .. we are happy to help. :cautious:
 

Users who are viewing this thread

Top Bottom