VB6 and MSOutlook 2007 - Send Email

Hi guys,

I am trying to put together a draft email from within a vb6 application using the Outlook object.

The following code does what I need - it frames the email - but I need to go one step further be able to pre-select the sender's email address and the relevant signature that goes with it.

Private Function DoMailMerge(ContactLink As Long)

Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem

Set objOutlook = CreateObject("Outlook.Application")
Set objMailItem = objOutlook.CreateItem(0) 'The constant olMailItem = 0

Dim strBody$
Dim strSender$


strSender = cboSender.Text
If Trim(strSender) = "" Then
    MsgBox "Select the sender.", vbExclamation
    Exit Function
End If

strBody = "Your Reference : " & Trim(txt(24).Text) & "<br>"
strBody = strBody & "Our Reference : " & "<br>"



    With objMailItem
        '.SenderEmailAddress = strSender 'read only property
        .To = Trim(txt(6).Text)
        .Importance = olImportanceHigh
        .ReadReceiptRequested = True
        
    'objMailItem.Attachments.Add strAttachment
        .Subject = Replace(Trim(txt(22).Text), vbCrLf, " - ", 1)
        .BodyFormat = olFormatHTML
        .HTMLBody = strBody
        
        .Display
    End With
Set objOutlook = Nothing
Set objMailItem = Nothing



End Function

Open in new window



In Outlook I have two email address under one profile. I am at present manually selecting the email account I want to send the email from and manually inserting the relevant signature.

I would like to programmatically do this ...

MTIA

DWE
LVL 1
dwe0608Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dwe0608Author Commented:
I've noted I can achieve what I want through CDOSYS

<%
Set myMail=CreateObject("CDO.Message")
myMail.Subject="Sending email with CDO"
myMail.From="mymail@mydomain.com"   <<========= setting where the email is coming from
myMail.To="someone@somedomain.com"
myMail.TextBody="This is a message."
myMail.Send
set myMail=nothing
%>

Open in new window


Can I do this from VB6 and Outlook?
0
dwe0608Author Commented:
ok - heres what I have worked out.

I've adapted the concept of selecting an account to send from using the following code:

Private Function DoMailMerge(ContactLink As Long)

Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem

Set objOutlook = CreateObject("Outlook.Application")
Set objMailItem = objOutlook.CreateItem(0) 'The constant olMailItem = 0

Dim strBody$
Dim strSender$
 
strSender = cboSender.Text
If Trim(strSender) = "" Then
    MsgBox "You forgot to select the sender.", vbExclamation
    Exit Function
End If

    strBody = "Your Reference : " & Trim(txt(24).Text) & "<br>"
    strBody = strBody & "Our Reference : " & "<br>" & "<br>"
    strBody = strBody & Trim(txt(23).Text) & "<br>" & "<br>"
    strBody = strBody & "<b>RE:</B> " & Replace(Trim(txt(22).Text), vbCrLf, " - ", 1)
    strBody = strBody & "" & "<br>" & "<br>"
    strBody = strBody & "<i>[start typing here]</i>" & "<br>" & "<br>"

    With objMailItem
        '.SenderEmailAddress = strSender
        .To = Trim(txt(6).Text)
        .CC = ""
        .BCC = ""
        .SendUsingAccount = GetAccountForEmailAddress(objOutlook, strSender)
        .Importance = olImportanceHigh
        .ReadReceiptRequested = True
        '.Attachments.Add strAttachment
        .Subject = Replace(Trim(txt(22).Text), vbCrLf, " - ", 1)
        .BodyFormat = olFormatHTML
        .HTMLBody = strBody
        
        
        .Display
    End With
    Set objOutlook = Nothing
    Set objMailItem = Nothing

End Function

Function GetAccountForEmailAddress(ByVal objOutlook As Outlook.Application, ByVal smtpAddress As String) As Outlook.account
    ' Loop over the Accounts collection of the current Outlook session.
    Dim accounts As Outlook.accounts
    Set accounts = objOutlook.Session.accounts
    Dim account As Outlook.account
    For Each account In accounts
    

        ' When the e-mail address matches, return the account.
        If account.smtpAddress = smtpAddress Then
            Set GetAccountForEmailAddress = account
            Exit Function
        End If
    Next
    'if we ge here we did not find the account for the email address entered
    MsgBox "Email Account " & smtpAddress & " Not found"

End Function

Open in new window


You can see I've added a function GetAccountForEmailAddress which returns the account from which the email is to be sent from.

Now I've also worked out that if I do not fill in the body of the message, outlook inserts the correct default signature - but if I put some text into the body of the email the default signature is not inserted and I think that might be by default.

So how do I ensure that the signature is inserted no matter what text I put into the body?

DWE
0
Robberbaron (robr)Commented:
dont think you can because the Signature is just html that is added by outlook when you start a message.

you could try setting the SendAccount as the last item , after setting the bodytext to see if that adds to the end of the bodytext.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

dwe0608Author Commented:
Theres a chance you might be right ... but ... funnily enough in Outlook 2007, the signatures are seemingly managed by Word ... given that word is the only available editor ...

the following function enumerates all of the Signatures - pass a valid message or take the reference out (it does nothing for the moment) - I was going to try to enumerate other objects off it but haven't done so yet ... given that we can get the index of the signature and given that we can get the signature name and so forth - it would be somewhat amazing of there is no way of getting the actual signature block itself - particularly since one can be created on the fly ...

Function EnumEmailSigs(msg As Outlook.MailItem)

    Dim objDoc               As Word.Document
    Dim objSel               As Word.Selection
    Dim objSig               As Word.EmailSignature
    Dim colSig               As Word.EmailSignatureEntries

    Set objDoc = msg.GetInspector.WordEditor
    Set objSig = objDoc.Application.EmailOptions.EmailSignature
    Set colSig = objSig.EmailSignatureEntries

    Dim i%

    Debug.Print colSig.Count & " Signatures Present"

    'With msg
    '    .Actions


    For i = 1 To colSig.Count '- 1

        Debug.Print i & " - "; colSig.Item(i).Name      ' name of signature
        'Debug.Print i & " - "; colSig.Item(i).Creator   '
        'Debug.Print i & " - "; colSig.Item(i).Index    '

    Next i

    Debug.Print "NewMessage - " & objSig.NewMessageSignature

End Function
0
Robberbaron (robr)Commented:
its not just word... we set our signatures via a GPO Exchange setting i believe. or at least create defaults that way.
0
dwe0608Author Commented:
ok - I think I might have a lead on the right direction ...

It seems that when creating the email to be sent, the signature can be put in depending on the email account set for the email to be sent from - to ensure that the correct signature is placed on the email, the email account the email is being sent from MUST be set before the email is displayed ... and you do this using the mail item property SendUsingAccount.

I am not qualified nor experienced enough to give the technical specifications, so maybe an expert out there can translate what I've done to suit someone else ... but I'll give it a small shot ...

the mail item property SendUsingAccount must be set to a valid account already setup in Outlook. For example, if you have two email addresses in outlook under one profile - each address constitutes an account. You can get the account properties, by using the email address using the following function which will return a valid Outlook Account

' objOutlook is a valid instantiated outlook application
' smtpAddress is a valid email address already in Outlook 
Function GetAccountForEmailAddress(ByVal objOutlook As Outlook.Application, ByVal smtpAddress As String) As Outlook.account
    ' Loop over the Accounts collection of the current Outlook session.
    Dim accounts As Outlook.accounts
    Set accounts = objOutlook.Session.accounts
    Dim account As Outlook.account
    For Each account In accounts
        ' When the e-mail address matches, return the account.
        If account.smtpAddress = smtpAddress Then
            Set GetAccountForEmailAddress = account
            Exit Function
        End If
    Next
    'if we ge here we did not find the account for the email address entered
    MsgBox "Email Account " & smtpAddress & " Not found"

End Function

Open in new window


The code is called as follows:

   ...

    With objMailItem
        .To = Trim(txt(6).Text)
        .CC = ""
        .BCC = ""
        .SendUsingAccount = GetAccountForEmailAddress(objOutlook, strSender)
        '.body = strBody
        .Save
        .Importance = olImportanceHigh
        .ReadReceiptRequested = True
        .Subject = Replace(Trim(txt(22).Text), vbCrLf, " - ", 1)
        .Display
    End With

Open in new window


Now, we have set the account the email is to be sent from - and upon display, the signature for that account is inserted.

To interact with the message and insert text etc, we use the Word object which outlook 2007 uses and setup our email for use

    Set objDoc = objMailItem.GetInspector.WordEditor
    Set objSel = objDoc.Application.Selection
    With objSel
        .Move wdStory, -1
        .InsertAfter "Your Reference : " & Space(3)
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter Trim(txt(24).Text) & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "Our Reference : " & Space(3)
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter Trim(txt(27).Text) & vbCrLf & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "RE: " & Replace(Trim(txt(22).Text), vbCrLf, " - ", 1) & vbCrLf & vbCrLf
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter Trim(txt(23).Text) & vbCrLf & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "  "
        .Collapse wdCollapseEnd
    End With

Open in new window


The signature stays in place and we get a properly formatted message ready to send.

To see a demo of the code - copy and place the following code into a form with a button on it called Command1

Private Sub Command1_Click()
    Dim objOutlook           As Outlook.Application
    Dim objMailItem          As Outlook.MailItem
    Dim objDoc               As Word.Document
    Dim objSel               As Word.Selection
    
    Set objOutlook = CreateObject("Outlook.Application")
    Set objMailItem = objOutlook.CreateItem(0) 'The constant olMailItem = 0
    
    Dim strSender$
 
    strSender = "YOUR EMAIL ADDRESS HERE" ' <<========= Replace with an email address already used by outlook


    If Trim(strSender) = "" Then
        MsgBox "You forgot to select the sender.", vbExclamation
        Exit Sub
    End If


    With objMailItem
        .To = "someone@somewhere.com"
        .CC = ""
        .BCC = ""
        .SendUsingAccount = GetAccountForEmailAddress(objOutlook, strSender)
        .Save
        .Importance = olImportanceHigh
        .ReadReceiptRequested = True
        .Subject = "Our Subject Line"
        .Display
    End With
    
    Set objDoc = objMailItem.GetInspector.WordEditor
    Set objSel = objDoc.Application.Selection
    With objSel
        .Move wdStory, -1
        .InsertAfter "Your Reference : " & Space(3)
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter "your reference is something" & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "Our Reference : " & Space(3)
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter "our rerence is something" & vbCrLf & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "RE: A SUBJECT LINE" & vbCrLf & vbCrLf
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter "Dear Someone" & vbCrLf & vbCrLf
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
        .InsertAfter "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..." & vbCrLf & vbCrLf
        .Font.Italic = True
        .Font.Bold = True
        .Collapse wdCollapseEnd
        
        .InsertAfter "There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."
        .Font.Italic = False
        .Font.Bold = False
        .Collapse wdCollapseEnd
        
    End With
    
    
    
    Set objOutlook = Nothing
    Set objMailItem = Nothing
    Set objDoc = Nothing
    Set objSel = Nothing

End Sub
Function GetAccountForEmailAddress(ByVal objOutlook As Outlook.Application, ByVal smtpAddress As String) As Outlook.account
    ' Loop over the Accounts collection of the current Outlook session.
    Dim accounts As Outlook.accounts
    Set accounts = objOutlook.Session.accounts
    Dim account As Outlook.account
    For Each account In accounts
        ' When the e-mail address matches, return the account.
        If account.smtpAddress = smtpAddress Then
            Set GetAccountForEmailAddress = account
            Exit Function
        End If
    Next
    'if we ge here we did not find the account for the email address entered
    MsgBox "Email Account " & smtpAddress & " Not found"

End Function

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Robberbaron (robr)Commented:
seems a lot just to get a signature to insert. While the sig is just a text file in the users profile directory, i cant find any way to get the association between an account and the signature to use for new message and replies.  (it is possible to have more than one signature tied to an account, and then set which one is to be used for different types of messages)

so if it works, stick with it.
0
dwe0608Author Commented:
yes it probably does seem a lot but once the coding is done its fairly simple - the next stage is working with the wordeditor to create the proper merge files .. for example, all word features are available ... including importing word documents with all the merge information in it ... but that will be another issue no doubt in the future ...

MTIA

DWE
0
dwe0608Author Commented:
I solved my own issue - and would prefer to leave this solution open for others to find ..
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.