I just wanted to share a great solution I’ve recently developed in Emailing from Microsoft Access. When I was researching email methods from Access a thought occurred to me that there should be an A.P.I. that would do this the easy way. In fact there are several available… but none that I could find provided VBA code examples (which didn’t surprise me).
All of them did have a web A.P.I. which was all I needed to translate a web request from the other language examples given. In the End I ended up taking Eli the Computer Guy’s recommendation and used the SendGrid API. I’ve found that SendGrid seems to have 24/7 online support which is great for contractors like me who seem to burn the late night hours.
IMPORTANT NOTE: This script has been changed due to SendGrid API changes which broke the former attachment functionality. Justin Steele provided the key to fixing the attachment issues. The solution shown below is my own implementation with her provided attachment fix:
	
	
	
		
 All of them did have a web A.P.I. which was all I needed to translate a web request from the other language examples given. In the End I ended up taking Eli the Computer Guy’s recommendation and used the SendGrid API. I’ve found that SendGrid seems to have 24/7 online support which is great for contractors like me who seem to burn the late night hours.
IMPORTANT NOTE: This script has been changed due to SendGrid API changes which broke the former attachment functionality. Justin Steele provided the key to fixing the attachment issues. The solution shown below is my own implementation with her provided attachment fix:
		Code:
	
	
	Sub SendEmail()
    Dim HttpReqURL As String
    Dim eUser As String
    Dim ePass As String
    Dim eTo As String
    Dim eToName As String
    Dim eSubject As String
    Dim eBody As String
    Dim eFrom As String
    Dim multiPartBoundary As String
    Dim outputStream As Object
    Dim binaryStream As Object
    Dim rs As DAO.Recordset
    Dim SQL As String
 
    Const adSaveCreateNotExist = 1
    Const adSaveCreateOverWrite = 2
    Const adTypeBinary = 1
    Const adTypeText = 2
    Const adModeReadWrite = 3
    multiPartBoundary = "123456789abc"
    HttpReqURL = "https://api.sendgrid.com/api/mail.send.json"
    
    eSubject = Me.txtSubject
    eBody = Me.txtMessage
    eFrom = SenderEmail
    eUser = SendGridUser
    ePass = SendGridPass
    ' If Groups List/ Else Contacts List
    If Me.chkGroups <> 0 Then
        SQL = "SELECT * FROM qryContactsInSelectedGroups WHERE ContactType = 'Email'"
    Else
        SQL = "SELECT * FROM qrySelectedContacts WHERE ContactType = 'Email'"
    End If
    Set rs = CurrentDb.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
    If Not (rs.EOF And rs.BOF) Then
        rs.MoveFirst
        Do Until rs.EOF = True
            eTo = rs.Fields("ContactValue").value
            eToName = rs.Fields("FirstName").value & " " & rs.Fields("LastName").value
            
            Set outputStream = CreateObject("adodb.stream")
            outputStream.Type = adTypeText
            outputStream.Mode = adModeReadWrite
            outputStream.Charset = "windows-1252"
            outputStream.Open
        
            AddStreamParam outputStream, multiPartBoundary, "api_user", eUser
            AddStreamParam outputStream, multiPartBoundary, "api_key", ePass
            AddStreamParam outputStream, multiPartBoundary, "to", eTo
            AddStreamParam outputStream, multiPartBoundary, "toname", eToName
            AddStreamParam outputStream, multiPartBoundary, "subject", eSubject
            AddStreamParam outputStream, multiPartBoundary, "text", eBody
            AddStreamParam outputStream, multiPartBoundary, "from", eFrom
            ' Add Attachments
            AddAttachmentsToStream outputStream, multiPartBoundary
            outputStream.WriteText "--" + multiPartBoundary + "--" + vbCrLf
            
            Set binaryStream = CreateObject("ADODB.Stream")
            binaryStream.Mode = 3 'read write
            binaryStream.Type = 1 'adTypeText 'Binary
            binaryStream.Open
        
            ' copy text to binary stream so xmlHttp.send works correctly
            outputStream.Position = 0
            outputStream.CopyTo binaryStream
            outputStream.Close
            
            binaryStream.Position = 0
        
            Dim xmlHttp As Object
            Set xmlHttp = CreateObject("MSXML2.XMLHTTP")
            xmlHttp.Open "POST", HttpReqURL, False
            xmlHttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=" + multiPartBoundary
            xmlHttp.setRequestHeader "Content-Length", Len(binaryStream.Size)
            xmlHttp.send binaryStream.Read(binaryStream.Size)
        
            binaryStream.Close
            rs.MoveNext
        Loop
    End If
    Set rs = Nothing
End Sub
Sub AddStreamParam(stream As Variant, boundary As String, paramName As String, value As String)
    stream.WriteText "--" + boundary + vbCrLf
    stream.WriteText "Content-Disposition: form-data; name=""" + paramName + """" + vbCrLf
    stream.WriteText vbCrLf
    stream.WriteText value + vbCrLf
End Sub
Sub AddFileToStream(stream As Variant, boundary As String, name As String, filePath As String)
    Dim fileBytes As String
    fileBytes = ReadBinaryFile(filePath)
    stream.WriteText "--" + boundary + vbCrLf
    stream.WriteText "Content-Disposition: form-data; name=""files[" + name + "]""; filename=""" + name + """" + vbCrLf
    stream.WriteText "Content-Type: application/octet-stream" + vbCrLf
    stream.WriteText vbCrLf
    stream.WriteText fileBytes + vbCrLf
End Sub
Sub AddAttachmentsToStream(stream As Variant, boundary As String)
    Dim rs As DAO.Recordset
    Dim rsAttach As DAO.Recordset
    Dim SQL As String
    Dim currentAttachment As String
    Dim strAttachments As String
    Dim fileName As String
    SQL = "SELECT * FROM tblMessageAttachments WHERE [MessageID] = " & MessageID
    Set rsAttach = CurrentDb.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
    If Not (rsAttach.EOF And rsAttach.BOF) Then
        rsAttach.MoveFirst
        Do Until rsAttach.EOF = True
            ' Set Current Attachment
            fileName = rsAttach.Fields("AttachmentName").value
            currentAttachment = rsAttach.Fields("AttachmentLocation").value & fileName
            'Debug.Print currentAttachment
            
            ' Add Attachement to outputStream
            AddFileToStream stream, boundary, fileName, currentAttachment
            rsAttach.MoveNext
        Loop
    End If
End Sub
Function ReadBinaryFile(strPath)
    Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
    Dim oFile: Set oFile = oFSO.GetFile(strPath)
    If IsNull(oFile) Then MsgBox ("File not found: " & strPath): Exit Function
    With oFile.OpenAsTextStream()
        ReadBinaryFile = .Read(oFile.Size)
        .Close
    End With
End Function
	
			
				Last edited: