Question Find a good example of Access and Email functionality

Petros

Registered User.
Local time
Today, 09:21
Joined
Jun 30, 2010
Messages
145
Hi ,
Anny suggestions were i can find examples describing Access and Outllook interacting.
I want to email records, store emailed records (emails) and if possible also receive or at least, flag received emails corresponding to previously transmitted...

Thanks!
 
Hi ,
Anny suggestions were i can find examples describing Access and Outllook interacting.
I dont have one great example. In the FAQ and database here there would be lots of examples.

I want to email records,
I am not sure you can email "a record" what format would you like to email it in.
store emailed records (emails)
Outlook is already a database that stores emails. It is a lot of work to duplicate this.

and if possible also receive or at least, flag received emails corresponding to previously transmitted...

Thanks!
You can "flag" emails in a number of ways. One way is to add something unique to a field of an email that is not used or add your own field. Thus you can quickly find it again by searching that field and unique ID.

You might need to explain a little more on what your plans are.
 
I dont have one great example. In the FAQ and database here there would be lots of examples.


I am not sure you can email "a record" what format would you like to email it in.
Outlook is already a database that stores emails. It is a lot of work to duplicate this.


You can "flag" emails in a number of ways. One way is to add something unique to a field of an email that is not used or add your own field. Thus you can quickly find it again by searching that field and unique ID.

You might need to explain a little more on what your plans are.



It is quite complex.
Actually i do not want to email a “record” but to populate an email-template with certain data from a form. On the click of an command button i want to find and open a email template (name corresponds to the value in one of the controls in the form), edit the template, and by the click of a second command button, send the email and confirm this action by populating a control in the same form...all form data is the result of a select query ...And also flag this specific record in order to be able to match the incoming email from the Outlook inbox...
I am dreaming J..but if i can achieve just a little more than half of my dreams..its Christmas!
...and so far Access 2007 has proved to be a great Santa Claus..
 
Hi Petros,

I use Outlook to send record(s) from Access by using the SendObject command. (Using Access 2003)

Create your message by using lines like...

MsgStr = "Report No: " & Me!rptNo & Chr$(13) & Chr$(10)
MsgStr = MsgStr & "Report Date: " & Me!RptDate & Chr$(13) & Chr$(10)
MsgStr = MsgStr & "report Time: " & Me!RptTime & Chr$(13) & Chr$(10)
.
and repeat for all the fields you want to include...(the Chr$(13) & Chr$(10) are added to force new lines in the email.)

Then use SendObject in the form -

DoCmd.SendObject , , , EmailAddr, copyEmail, BCCEmail, "Email Subject", Msgstr, False

Hope this helps...

Dave
 
Access 2003

The following cycles through a query to get the e-mail address from a set of records and then places those addresses in an e-mail and brings it up the blank e-mail up on screen with potentially hundreds of e-mail addresses. No text is transferred to the body of the e-mail.

Code:
Private Sub Command29_Click()

On Error GoTo Err_Command29_Click

DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70

Dim parameterID As Long
Dim MyDB As DAO.Database
Dim rsEmail As DAO.Recordset
Dim sToName As String
parameterID = Me.ProjectID
Set MyDB = OpenDatabase("C:\Program files\BlueCoyote\EducationConsultation" & "\EducationConsultation_fe2000.mdb")
Set rsEmail = MyDB.OpenRecordset("SELECT T013ProjectInvolvement.ProjectID, T001Global.[e-mail address 1] FROM T001Global INNER JOIN T013ProjectInvolvement ON T001Global.ID = T013ProjectInvolvement.PersonID WHERE (((T013ProjectInvolvement.ProjectID)=" & parameterID & "))", dbOpenSnapshot)

With rsEmail
.MoveFirst
Do Until rsEmail.EOF
If IsNull(![e-mail address 1]) = False Then
sToName = sToName & rsEmail![e-mail address 1] & ";"
sSubject = ""
sMessageBody = ""
End If
.MoveNext
Loop
End With

DoCmd.SendObject , , , strEaddress, , sToName, sSubject, sMessageBody, True

Set MyDB = Nothing
Set rsEmail = Nothing

 
Exit_Command29_Click:
    Exit Sub

Err_Command29_Click:
    If (Err = ERR_OBJNOTEXIST) Or (Err = ERR_OBJNOTSET) Or (Err = ERR_CANTMOVE) Then
      Resume Next
    End If
    Resume Exit_Command29_Click
    
End Sub

And the following code will take an e-mail address and a memo field and create a single e-mail placing the information from within access a memo field into the main body of the e-mail ready for sending

Code:
Private Sub Command83_Click()
On Error GoTo Err_Command83_Click

Dim strMessage As String
Dim strEmailbody As String
Dim strSendTo As String
Dim Position As Integer
Dim Tstr As String
Dim IntGet As Long

Tstr = Me.Details
strSendTo = Me.Combo86.Column(2)
strMessage = Me.Details
IntGet = InStr(strMessage, vbCrLf)
strEmailbody = Mid(strMessage, IntGet)

Position = 0

DoCmd.SendObject , , , strSendTo, , , (Split(Tstr, vbCrLf)(Position)), strEmailbody, True

Exit_Command83_Click:
    Exit Sub

Err_Command83_Click:
    'MsgBox Err.Description
    Resume Exit_Command83_Click
    
End Sub
 
So in Dave and my e-mails the variables MsgStr, sMessageBody and strEmailBody are different names for the same variable.
 
Last edited:
So in Dave and my e-mails the variables MsgStr, sMessageBody and strEmailBody are different names for the same variable.

This is most valuable information..and i can see i have lot ahead..i am indeed very greatful for you effort and assistance.

Thanks a lot!
 
There are other ways to go in and flag things that you have sent or received, but you have to be very familiar with VBA. I will perhaps have a chance to post some code for you in a couple of days. Right now, I'm swamped and the code is in flux. But specifically, I have code for Office 2007 environment that would give you an overview.
 
This code works for me, including Encryption and Digital Signatures, for the Office 2007 environment.

Build the To, CC, Subject, and Body parameters as strings before you call. I use the UID to event-log a user transmission, bEnc is TRUE when you must encrypt the message. lImprt is one of the Outlook constants for high, medium, or low importance.

I didn't include the logging routines. Side note: If you don't open the inspector object outside of the segment that does the encryption, the mail does not get sent. If you DO open it, you still might get an error 287. I catch that and just eat it, but do something different for other errors.

Code:
Public Function SendAMsg(UID As Long, OLSbj As String, OLTo As String, _
    OLCC As String, OLBdy As String, bEnc As Boolean, lImprt As Long) As Long

'   Send a message for which the recipients, subject line, and message body have been prepared
'   Because this is Access-resident, it does not silently send through Outlook.

'   ON ENTRY:
'       OLSbj = subject line
'       OLTo = to-recipients
'       OLCC = cc-recipients
'       OLBdy = body of message
'       bEnc = Yes/No - digitally sign and encrypt the message
'       lImprt = olImportanceHigh, olImportanceNormal, olImportanceLow
'       UID = internal PK of user table corresponding to sender of message, needed because
'           when we finish, we will audit-log the event.
'   ON RETURN:
'       Function value is a code showing what happened
'           0 = all is well, message was sent, no problems
'           1 = error, any sanity check failed.  usually means a missing parameter.
'           2 = error, trap tripped

Dim OLApp As Outlook.Application        'ACCESS construct to allow us to bit-twiddle Outlook
Dim OLMsg As Outlook.MailItem           'a mail message within Outlook
Dim OLNS As Outlook.NameSpace           'need this to get to the MAPI name space
Dim OLFld As Outlook.MAPIFolder         'need this for sending mail
Dim OLIns As Outlook.Inspector          'need this to set encryption
Dim OLBar As Office.CommandBar          'make this a command-bar object
Dim OLEnc As Office.CommandBarButton    'a reference to a specific button
Dim OLSgn As Office.CommandBarButton    'a reference to another specific button

Dim TrapPoint As String
Dim TrapError As String                 'working strings
Dim EvtMsg As String

Dim lRetSts As Long                     'status code we will return

Dim OLNew As Boolean                    'flag for case of new instance of Outlook

'   sanity checks - we need to know who is sending the message.  we need to know the message body.
'   we need a subject line.  we need a list of to-recipients.  we do not care about the CC list.

    If UID = 0 Then
        lRetSts = 1                     'sanity check - no user identification
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
    
    If OLTo = "" Then
        lRetSts = 1                     'sanity check - no TO list
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
    
    If OLBdy = "" Then
        lRetSts = 1                     'sanity check - no message body
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
    
    If OLSbj = "" Then
        lRetSts = 1                     'sanity check - no subject lline
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If

'   Next, let us look into the outlook application.  Outlook does not like to have two instances in
'   memory at one time, so check for an existing instance first.
    
    Set OLApp = Nothing                 'start with simplest assumption
    
    On Error Resume Next                'block traps while we poke around
    Set OLApp = GetObject(, "Outlook.Application") 'find existing instance of Outlook
    On Error GoTo 0                     'remove the trap block
    On Error GoTo SAM_Trapped           'ok, we are good now, restore intended trap.
    
    TrapPoint = "Create New Outlook Application"
    lRetSts = 0                         'assume we are going to work
    
'   at this point, either we got an application link or we did not
    
    OLNew = False                       'assume we found one
    If OLApp Is Nothing Then            'did we find an existing Outlook we could use?
        OLNew = True                    'no, have to create one, so ...
        Set OLApp = CreateObject("Outlook.Application")    'create a private apps object
    End If
    
'   we have an application.  use it to connect to an MAPI session so we can send something

    TrapPoint = "Login to MAPI namespace"

    Set OLNS = OLApp.GetNamespace("MAPI")   'get into the namespace
    OLNS.Logon , , False, False         'we created or tested the app already
    
'   point to the MAPI Outbox (folder)

    TrapPoint = "Select and work in Outbox"

    Set OLFld = OLNS.GetDefaultFolder(olFolderOutbox) 'find the outbox folder
    
'   create a new message in the Outbox folder
    
    TrapPoint = "Create message and define properties"
    
    Set OLMsg = OLFld.Items.Add(olMailItem)   'from which we will send a single mail message
    
'   populate that puppy
    
    OLMsg.Importance = lImprt           'start populating the mail message
    OLMsg.To = OLTo                     'fill in first set of recipients
    OLMsg.cC = OLCC                     'fill in second set of recipients
                                        'no BCC recipients at this time
    OLMsg.Subject = OLSbj               'fill in the message subject
    OLMsg.Body = OLBdy                  'fill in the message body
    OLMsg.BodyFormat = olFormatPlain    'make it totally plaintext
    
    Set OLIns = OLMsg.GetInspector      'get the inspector so we can open the toolbars
    OLIns.Activate                      'ok, now that we have it, let us actually use it
    
'   now, if we NEED to do this, let us try to set the ENCRYPT flag.  Site rules say if we
'   are going to encrypt it, we must also digitally sign it.

    If bEnc = True Then                 'see if we even need to bother
                
        
        Set OLBar = OLIns.CommandBars("Standard")   'get to the standard toolbar
        
        Set OLEnc = OLBar.FindControl(, EncryptMsgCtrl) 'which has ENCRYPT and SIGNDIGITAL
        Set OLSgn = OLBar.FindControl(, DigitalSigCtrl)
        
        If Not OLSgn Is Nothing Then    'if we found it, ...
            If OLSgn.Enabled = True Then    'and if it is enabled, ...
                If OLSgn.State = msoButtonUp Then   'and if it is not already set, ...
                    OLSgn.Execute
                End If
            End If
        End If
        
        If Not OLEnc Is Nothing Then    'if we found it, ...
            If OLEnc.Enabled = True Then    'and if it is enabled, ...
                If OLEnc.State = msoButtonUp Then   'and if it is not already set, ...
                    OLEnc.Execute       'make it encrypted.
                End If
            End If
        End If
        
    End If                              'end - if we are going to encrypt the message

'   message exists.  if encryption was required, that has been set.

    TrapPoint = "Send message on its way"
    
    OLMsg.Send                          'send it on its way, Nellie Forbush
    
'   start cleaning up after us

    EvtMsg = "Sent mail (subject = " & OLSbj & ")"
    If bEnc Then EvtMsg = EvtMsg & " (Encryption requested)"
    AuditEvent evtSentMail, UID, EvtMsg

    GoTo SAM_Finished
    
SAM_Trapped:
    
    If Err.Number = 287 Then
        AuditEvent evtErrTrap, UID, "Error 287 just after trap point " & TrapPoint
        Resume Next
    End If
    
    TrapError = "Trap: Error number is " & CStr(Err.Number) & vbCrLf
    TrapError = TrapError & Err.Description & vbCrLf
    TrapError = TrapError & "In SendAMsg\" & TrapPoint & vbCrLf
    
    MsgBox TrapError, vbOKOnly, "Trap Detected"     'note the error as a message box
    AuditEvent evtErrTrap, UID, TrapError   'make a record of it
    lRetSts = 2                         'return trap status
    Resume SAM_Finished                 'fall into final cleanup code
    
SAM_Finished:

    On Error Resume Next                'disallow traps
    Set OLSgn = Nothing                 'release these objects
    Set OLEnc = Nothing
    Set OLBar = Nothing
    Set OLMsg = Nothing                 'release the link to the message
    Set OLFld = Nothing                 'dereference the folder
    If Not OLNS Is Nothing Then
        OLNS.Logoff                     'done with this session
    End If
    Set OLNS = Nothing                  'dereference this puppy
    If OLNew Then
        OLApp.Quit                      'release the application
    End If
    Set OLApp = Nothing                 'done with the application
    
    SendAMsg = lRetSts                  'return a status code
    On Error GoTo 0                     'revoke trap interceptor
    
End Function
 
This code works for me, including Encryption and Digital Signatures, for the Office 2007 environment.

Build the To, CC, Subject, and Body parameters as strings before you call. I use the UID to event-log a user transmission, bEnc is TRUE when you must encrypt the message. lImprt is one of the Outlook constants for high, medium, or low importance.

I didn't include the logging routines. Side note: If you don't open the inspector object outside of the segment that does the encryption, the mail does not get sent. If you DO open it, you still might get an error 287. I catch that and just eat it, but do something different for other errors.

Code:
Public Function SendAMsg(UID As Long, OLSbj As String, OLTo As String, _
    OLCC As String, OLBdy As String, bEnc As Boolean, lImprt As Long) As Long
 
'   Send a message for which the recipients, subject line, and message body have been prepared
'   Because this is Access-resident, it does not silently send through Outlook.
 
'   ON ENTRY:
'       OLSbj = subject line
'       OLTo = to-recipients
'       OLCC = cc-recipients
'       OLBdy = body of message
'       bEnc = Yes/No - digitally sign and encrypt the message
'       lImprt = olImportanceHigh, olImportanceNormal, olImportanceLow
'       UID = internal PK of user table corresponding to sender of message, needed because
'           when we finish, we will audit-log the event.
'   ON RETURN:
'       Function value is a code showing what happened
'           0 = all is well, message was sent, no problems
'           1 = error, any sanity check failed.  usually means a missing parameter.
'           2 = error, trap tripped
 
Dim OLApp As Outlook.Application        'ACCESS construct to allow us to bit-twiddle Outlook
Dim OLMsg As Outlook.MailItem           'a mail message within Outlook
Dim OLNS As Outlook.NameSpace           'need this to get to the MAPI name space
Dim OLFld As Outlook.MAPIFolder         'need this for sending mail
Dim OLIns As Outlook.Inspector          'need this to set encryption
Dim OLBar As Office.CommandBar          'make this a command-bar object
Dim OLEnc As Office.CommandBarButton    'a reference to a specific button
Dim OLSgn As Office.CommandBarButton    'a reference to another specific button
 
Dim TrapPoint As String
Dim TrapError As String                 'working strings
Dim EvtMsg As String
 
Dim lRetSts As Long                     'status code we will return
 
Dim OLNew As Boolean                    'flag for case of new instance of Outlook
 
'   sanity checks - we need to know who is sending the message.  we need to know the message body.
'   we need a subject line.  we need a list of to-recipients.  we do not care about the CC list.
 
    If UID = 0 Then
        lRetSts = 1                     'sanity check - no user identification
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
 
    If OLTo = "" Then
        lRetSts = 1                     'sanity check - no TO list
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
 
    If OLBdy = "" Then
        lRetSts = 1                     'sanity check - no message body
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
 
    If OLSbj = "" Then
        lRetSts = 1                     'sanity check - no subject lline
        GoTo SAM_Finished               'skip the rest of this clap-trap
    End If
 
'   Next, let us look into the outlook application.  Outlook does not like to have two instances in
'   memory at one time, so check for an existing instance first.
 
    Set OLApp = Nothing                 'start with simplest assumption
 
    On Error Resume Next                'block traps while we poke around
    Set OLApp = GetObject(, "Outlook.Application") 'find existing instance of Outlook
    On Error GoTo 0                     'remove the trap block
    On Error GoTo SAM_Trapped           'ok, we are good now, restore intended trap.
 
    TrapPoint = "Create New Outlook Application"
    lRetSts = 0                         'assume we are going to work
 
'   at this point, either we got an application link or we did not
 
    OLNew = False                       'assume we found one
    If OLApp Is Nothing Then            'did we find an existing Outlook we could use?
        OLNew = True                    'no, have to create one, so ...
        Set OLApp = CreateObject("Outlook.Application")    'create a private apps object
    End If
 
'   we have an application.  use it to connect to an MAPI session so we can send something
 
    TrapPoint = "Login to MAPI namespace"
 
    Set OLNS = OLApp.GetNamespace("MAPI")   'get into the namespace
    OLNS.Logon , , False, False         'we created or tested the app already
 
'   point to the MAPI Outbox (folder)
 
    TrapPoint = "Select and work in Outbox"
 
    Set OLFld = OLNS.GetDefaultFolder(olFolderOutbox) 'find the outbox folder
 
'   create a new message in the Outbox folder
 
    TrapPoint = "Create message and define properties"
 
    Set OLMsg = OLFld.Items.Add(olMailItem)   'from which we will send a single mail message
 
'   populate that puppy
 
    OLMsg.Importance = lImprt           'start populating the mail message
    OLMsg.To = OLTo                     'fill in first set of recipients
    OLMsg.cC = OLCC                     'fill in second set of recipients
                                        'no BCC recipients at this time
    OLMsg.Subject = OLSbj               'fill in the message subject
    OLMsg.Body = OLBdy                  'fill in the message body
    OLMsg.BodyFormat = olFormatPlain    'make it totally plaintext
 
    Set OLIns = OLMsg.GetInspector      'get the inspector so we can open the toolbars
    OLIns.Activate                      'ok, now that we have it, let us actually use it
 
'   now, if we NEED to do this, let us try to set the ENCRYPT flag.  Site rules say if we
'   are going to encrypt it, we must also digitally sign it.
 
    If bEnc = True Then                 'see if we even need to bother
 
 
        Set OLBar = OLIns.CommandBars("Standard")   'get to the standard toolbar
 
        Set OLEnc = OLBar.FindControl(, EncryptMsgCtrl) 'which has ENCRYPT and SIGNDIGITAL
        Set OLSgn = OLBar.FindControl(, DigitalSigCtrl)
 
        If Not OLSgn Is Nothing Then    'if we found it, ...
            If OLSgn.Enabled = True Then    'and if it is enabled, ...
                If OLSgn.State = msoButtonUp Then   'and if it is not already set, ...
                    OLSgn.Execute
                End If
            End If
        End If
 
        If Not OLEnc Is Nothing Then    'if we found it, ...
            If OLEnc.Enabled = True Then    'and if it is enabled, ...
                If OLEnc.State = msoButtonUp Then   'and if it is not already set, ...
                    OLEnc.Execute       'make it encrypted.
                End If
            End If
        End If
 
    End If                              'end - if we are going to encrypt the message
 
'   message exists.  if encryption was required, that has been set.
 
    TrapPoint = "Send message on its way"
 
    OLMsg.Send                          'send it on its way, Nellie Forbush
 
'   start cleaning up after us
 
    EvtMsg = "Sent mail (subject = " & OLSbj & ")"
    If bEnc Then EvtMsg = EvtMsg & " (Encryption requested)"
    AuditEvent evtSentMail, UID, EvtMsg
 
    GoTo SAM_Finished
 
SAM_Trapped:
 
    If Err.Number = 287 Then
        AuditEvent evtErrTrap, UID, "Error 287 just after trap point " & TrapPoint
        Resume Next
    End If
 
    TrapError = "Trap: Error number is " & CStr(Err.Number) & vbCrLf
    TrapError = TrapError & Err.Description & vbCrLf
    TrapError = TrapError & "In SendAMsg\" & TrapPoint & vbCrLf
 
    MsgBox TrapError, vbOKOnly, "Trap Detected"     'note the error as a message box
    AuditEvent evtErrTrap, UID, TrapError   'make a record of it
    lRetSts = 2                         'return trap status
    Resume SAM_Finished                 'fall into final cleanup code
 
SAM_Finished:
 
    On Error Resume Next                'disallow traps
    Set OLSgn = Nothing                 'release these objects
    Set OLEnc = Nothing
    Set OLBar = Nothing
    Set OLMsg = Nothing                 'release the link to the message
    Set OLFld = Nothing                 'dereference the folder
    If Not OLNS Is Nothing Then
        OLNS.Logoff                     'done with this session
    End If
    Set OLNS = Nothing                  'dereference this puppy
    If OLNew Then
        OLApp.Quit                      'release the application
    End If
    Set OLApp = Nothing                 'done with the application
 
    SendAMsg = lRetSts                  'return a status code
    On Error GoTo 0                     'revoke trap interceptor
 
End Function


Thank you very much Mr Doc...interesting indeed and very helpful..i iwill revert with results at appropriate moment..

Nothing can replace a grand pa, :-)

And a valubale MPV indeed your..title or not.. :-)
 
Is there anything like this within a 2003 environment? (Access and Outlook)
I can't seem to find anyway into the encryption section within the Outlook automation process. ("Options">"Security")
I realise this is set for all outgoing mail at this point, but I was hoping to be able to send an individual email encrypted. Basically just get into the Security tab and check the "Encypt contents and attachments" option. :rolleyes:

Any suggestions?

Cheers
Matt
 
Is there anything like this within a 2003 environment? (Access and Outlook)
I can't seem to find anyway into the encryption section within the Outlook automation process. ("Options">"Security")
I realise this is set for all outgoing mail at this point, but I was hoping to be able to send an individual email encrypted. Basically just get into the Security tab and check the "Encypt contents and attachments" option. :rolleyes:

Any suggestions?

Cheers
Matt

That is impossible to do in 2003 - most likely also impossible in 2007 and maybe possible in 2010.

There are no exposed methods or function for security in 2003 Outlook object model.

The only way to do it is to click on the tool bar.

here is an example of that.

http://www.access-programmers.co.uk/forums/showthread.php?t=195360&highlight=Security+outlook
 
That is impossible to do in 2003 - most likely also impossible in 2007 and maybe possible in 2010.

There are no exposed methods or function for security in 2003 Outlook object model.

The only way to do it is to click on the tool bar.

here is an example of that.

http://www.access-programmers.co.uk/forums/showthread.php?t=195360&highlight=Security+outlook
Oh well. It was worth a try. :D
I shall have a look into that as another option.

Thank you very much for your reply darbid.
 
Oh well. It was worth a try. :D
I shall have a look into that as another option.

Thank you very much for your reply darbid.
hey by the way "impossible" might be a little bit too hard.

I for example would like to be able to choose the certificate i use and cannot.

There is one way and that would be to use Windows API to click the controls etc on the windows.
 
Doc_Man:

I wanted to thank you for the code and appreciate your generosity. Vets always seem to keep serving.

I had adapted your code related to Secure email and used it in a 2007 dB without issue, but we just converted to Office 365 and it stopped looking for the;
Set OLEnc = OLBar.FindControl(, EncryptMsgCtrl)
Set OLSgn = OLBar.FindControl(, DigitalSigCtrl)

In my mind I think its missing the reference back to the Outlook as when I loop through the items on the commandbar it only sees the items in the Access dB. I tryiing to figure out how to tell it in the

Set OLBar = OLIns.CommandBars("Standard")

to look at Outlook instead of the dB.

I never did figure out your Audit section :banghead:
 
Oh, that... The "AuditEvent" subroutine opens a recordset into my audit log, essentially an event log but where I was working, that was an audit log to them so I called it what they liked. The security wonks wanted to be able to know who was doing what to whom, including anyone who sent out a message. The Event being audited was simply a statement of either someone taking a trap while trying to send a message, or of someone sending a message. And the error 287 stuff is because at the time there was a bunch of chatter about how even though you thought you did EVERYTHING meticulously right, you often got an error 287. MSDN even had an article on it if I recall correctly, saying that it was an "after the fact" event but the message went out anyway. So if it occurred, I just ate the error and let things flow normally via RESUME NEXT.

As to what happens in Office 365, I haven't got this version and therefore cannot look for it for you. However, typically you get these items translated from having both Outlook and general Office entries in your References list.

If you want to do a search for these items yourself, here is what I would do.

1. Get into Access and open a VBA Code window.

2. Open up Tools >> References and check the Outlook library and the Office library. Close the reference dialog box.

3. Open Object Browser. In the upper left corner there are two boxes. One is a combo that selects a library. You want that on "all libraries". Under that is a SEARCH box. Type the "EncryptMsgCtrl" in that box and click the SEARCH ICON. If what you want is in one of the libraries, you will see it. (Might occur in more than one, and in that case you get a list.)

4. If that doesn't work, go back into the references list and see if other similar libraries exist, specifically focusing on things that relate to Office, because with Ofc2007, all ribbons switched over to become an Office feature rather than an individual app feature from the Command menu. (They did that because I believe they wanted a uniform interface for customizing ribbons.)

In the bottom of the post, you question making Access use the Outlook bar. But if the OLIns (inspector object) resolves correctly, anything based on it IS using whatever is in the Outlook context. That is because if you follow the resolution chain, OLIns is set based on OLMsg, which is based on OLFld, which is based on OLNS, which is based on OLApp.

In English, the Outlook bar derives context from the Inspector (window), which derives context from the Message, which we created in the Folder, which we opened from the Name Space associated with the Outlook Application. Via inheritance, the OLBar variable IS using the context of OLApp, whatever it is.

Glad to hear my code is still working for others.
 
Doc_Man,
I have to admit I didn't expect a response from you, as to the date this was last touched, so I appreciate your advice! I checked on the reference library (F2) of the EncryptMsgCrtl and it was in the module I have so I think we can eliminate that is an issue.

I did step into the OLIns and found it seems correct, and when that fires the email pops open correctly. When the OLEnc, OLSgn fire they are set to nothing and it will step over the olsgn.enabled, sending the email unencrypted. I don't expect you to lose time grandpa - ing but if you see something a fresh set of eyes is appreciated.

Public Function SendAMsg(OLName As String, OLTo As String, OLCC As String, OLBdy As String, bEnc As Boolean, lImprt As Long) As Long
Dim dbs As Database, Rst As Recordset
Dim strArray() As String
Dim I, intItems As Integer
Dim OLApp As Outlook.Application 'ACCESS construct to allow us to bit-twiddle Outlook
Dim OLMsg As Outlook.MailItem 'a mail message within Outlook
Dim OLNS As Outlook.NameSpace 'need this to get to the MAPI name space
Dim OLFld As Outlook.MAPIFolder 'need this for sending mail
Dim OLIns As Outlook.Inspector 'need this to set encryption
Dim OLBar As Office.CommandBar 'make this a command-bar object
Dim OLEnc As Office.CommandBarButton 'a reference to a specific button
Dim OLSgn As Office.CommandBarButton 'a reference to another specific button
Dim TrapPoint As String
Dim TrapError As String 'working strings
Dim EvtMsg As String
Dim lRetSts As Long 'status code we will return
Dim OLNew As Boolean 'flag for case of new instance of Outlook
Set dbs = CurrentDb

Set OLApp = Nothing 'start with simplest assumption

On Error Resume Next 'block traps while we poke around
Set OLApp = GetObject(, "Outlook.Application") 'find existing instance of Outlook
On Error GoTo 0 'remove the trap block
On Error GoTo SAM_Trapped 'ok, we are good now, restore intended trap.

TrapPoint = "Create New Outlook Application"
lRetSts = 0 'assume we are going to work

' at this point, either we got an application link or we did not

OLNew = False 'assume we found one
If OLApp Is Nothing Then 'did we find an existing Outlook we could use?
OLNew = True 'no, have to create one, so ...
Set OLApp = CreateObject("Outlook.Application") 'create a private apps object
End If


strArray = Split(OLBdy, "|")
intItems = UBound(strArray)

' we have an application. use it to connect to an MAPI session so we can send something
TrapPoint = "Login to MAPI namespace"
Set OLNS = OLApp.GetNamespace("MAPI") 'get into the namespace
OLNS.Logon , , False, False 'we created or tested the app already

' point to the MAPI Outbox (folder)
TrapPoint = "Select and work in Outbox"
Set OLFld = OLNS.GetDefaultFolder(olFolderOutbox) 'find the outbox folder

' create a new message in the Outbox folder

TrapPoint = "Create message and define properties"

Set OLMsg = OLFld.Items.Add(olMailItem) 'from which we will send a single mail message

' populate that puppy

OLMsg.Importance = lImprt 'start populating the mail message
OLMsg.To = OLTo 'fill in first set of recipients
OLMsg.CC = OLCC 'fill in second set of recipients
'no BCC recipients at this time
OLMsg.Subject = "Missing Lab Orders" ' OLSbj 'fill in the message subject

OLBdy = ""

OLMsg.Body = OLBdy 'fill in the message body

OLMsg.BodyFormat = olFormatRichText 'make it totally plaintext
For I = 0 To intItems
If Len(OLMsg.HTMLBody) < 5 Then
OLMsg.HTMLBody = strArray(I) & " <br>"
Else
OLMsg.HTMLBody = OLMsg.HTMLBody & strArray(I) & " <br>"
End If
Next I
OLMsg.HTMLBody = OLName & "," & "<br><br> If you are receiving this email, you scheduled a lab appointment for a Veteran and no order is near the date of appointment (howdy window date +/-3 days from appointment). Please look up the patient and address the missing orders. A copy of this e-mail has been sent to your leadership team to ensure completion. <br><br>" & OLMsg.HTMLBody

Set OLIns = OLMsg.GetInspector 'get the inspector so we can open the toolbars
OLIns.Activate 'ok, now that we have it, let us actually use it

If bEnc = True Then 'see if we even need to bother
Set OLBar = OLIns.CommandBars("Standard") 'get to the standard toolbar
Set OLEnc = OLBar.FindControl(, EncryptMsgCtrl) 'which has ENCRYPT and SIGNDIGITAL
Set OLSgn = OLBar.FindControl(, DigitalSigCtrl)

If Not OLSgn Is Nothing Then 'if we found it, ...
If OLSgn.Enabled = True Then 'and if it is enabled, ...
If OLSgn.State = msoButtonUp Then 'and if it is not already set, ...
OLSgn.Execute
End If
End If
End If

If Not OLEnc Is Nothing Then 'if we found it, ...
If OLEnc.Enabled = True Then 'and if it is enabled, ...
If OLEnc.State = msoButtonUp Then 'and if it is not already set, ...
OLEnc.Execute 'make it encrypted.
End If
End If
End If

End If 'end - if we are going to encrypt the message
' message exists. if encryption was required, that has been set.
TrapPoint = "Send message on its way"

OLMsg.Send 'send it on its way, Nellie Forbush

' start cleaning up after us
EvtMsg = "Sent mail (subject = " & OLMsg.Subject & ")"
If bEnc Then EvtMsg = EvtMsg & " (Encryption requested)"
'AuditEvent evtSentMail, UID, EvtMsg
GoTo SAM_Finished

SAM_Trapped:

If Err.Number = 287 Then
'AuditEvent evtErrTrap, UID, "Error 287 just after trap point " & TrapPoint
Resume Next
End If

' TrapError = "Trap: Error number is " & CStr(Err.Number) & vbCrLf
' TrapError = TrapError & Err.Description & vbCrLf
' TrapError = TrapError & "In SendAMsg" & TrapPoint & vbCrLf
'
' MsgBox TrapError, vbOKOnly, "Trap Detected" 'note the error as a message box
'AuditEvent evtErrTrap, UID, TrapError 'make a record of it
lRetSts = 2 'return trap status
Resume SAM_Finished 'fall into final cleanup code

SAM_Finished:
On Error Resume Next 'disallow traps
Set OLSgn = Nothing 'release these objects
Set OLEnc = Nothing
Set OLBar = Nothing
Set OLMsg = Nothing 'release the link to the message
Set OLFld = Nothing 'dereference the folder
If Not OLNS Is Nothing Then
OLNS.Logoff 'done with this session
End If
Set OLNS = Nothing 'dereference this puppy
If OLNew Then
OLApp.Quit 'release the application
End If
Set OLApp = Nothing 'done with the application

SendAMsg = lRetSts 'return a status code
On Error GoTo 0 'revoke trap interceptor

End Function
 
Specifically regarding why things don't get signed or encrypted, look at this line of code:

Code:
Set OLBar = OLIns.CommandBars("Standard") 'get to the standard toolbar

This will ONLY work if you are in fact using the standard ribbon. Can you tell or do you know if a customized ribbon was developed for your site? If so, you need to know its name and use that in place of "Standard." If that's not the problem then I have no clue.
 
I have it working!!

So from what I can determine the new office doesn't reference the Tool bar like anything we have done previously. So I started looking at this as an office encryption, instead of an Access to Outlook process. after it sets the OLIns active I went to straight to checking if its encrypted;

prop = CLng(OLMsg.PropertyAccessor.GetProperty(PR_SECURITY_FLAGS))

If prop comes back as 0 then we know there is no encryption or signature. Then I just set it to encrypt and sign with;

ulFlags = ulFlags Or &H1 ' SECFLAG_ENCRYPTED
ulFlags = ulFlags Or &H2 ' SECFLAG_SIGNED
OLMsg.PropertyAccessor.SetProperty PR_SECURITY_FLAGS, ulFlags

I know this is not as elegant and well written which you have provided, and I am ashamed of my lack of knowledge in this aspect, but with all the craziness happening around the new Office I am happy this works. I think without explaining this to you I wouldn't have thought this process through, so thank you for the code and the patients!
 

Users who are viewing this thread

Back
Top Bottom