1

Here is the code I have so far:

Option Explicit

Call OpenOutlook()

Function OpenOutlook()
    Dim ObjShell

    Set ObjShell = CreateObject("WScript.Shell")
    ObjShell.Run("Outlook.exe")

    Call SendEmail()

    'I tried closing from here but this didn't work either
    'ObjShell.Quit
End Function

Function SendEmail()
    'Declaring variables used through out this function
    Dim ObjOutlook
    Dim objMail

    Set ObjOutlook = CreateObject("Outlook.Application")
    'CreateItem(0) opens a New Email window...MailItem
    set objMail = ObjOutlook.CreateItem(0)
    objMail.Display 

    'MailItem Options
    objMail.to = "test@mail.com.com"    
    'objMail.cc = "test2@mail.com"
    objMail.Subject = "Did it work!?"
    objMail.Body = "If you got this email, my VBs test worked!"
    'objMail.Attachments.Add("C:\Attachment\abc.jpg")
    objMail.Send

    'This didn't work either
    'If objMail.Sent = True Then 
    'ObjOutlook.Quit
    'End If

    'Quit closes Outlook like I want but it doesn't wait for the email to send 
    'ObjOutlook.Quit
End Function

What I'm trying to automate using VBScript:

  1. Open Outlook
  2. Send an email
  3. Wait for email to send (Outbox to finish sending)
  4. Close Outlook AFTER the email has been sent

Where I'm stuck:

  1. First of all, I was having trouble opening Outlook. Below is the code that I used to create an Outlook Object:

    Set ObjOutlook = CreateObject("Outlook.Application")
    'CreateItem(0) opens a New Email window...MailItem
    set objMail = ObjOutlook.CreateItem(0)
    objMail.Display 
    

    What I did (Not even sure if this is the right way to do it):

    Set ObjShell = CreateObject("WScript.Shell")
    ObjShell.Run("Outlook.exe")
    

    Why can't I just do ObjShell.Quit after I call the SendEmail() Function? Using .Quit gives me an error.

  2. I just want to close the Outlook application once the email has been sent and I can't figure out how.

Edrei
  • 11
  • 4
  • 1
    Do you need to use Outlook? Most VBScripters use the CDO library to send e-mail. See [this](http://stackoverflow.com/questions/7041938/vbscript-to-send-email-without-running-outlook). – Bond Jun 26 '15 at 17:16

3 Answers3

1

MailItem has a Sent property that indicates when the message has been sent. Try this:

...
objMail.Send

Do Until objMail.Sent
    WScript.Sleep 500
Loop

' Safe to close...
ObjOutlook.Quit
Bond
  • 15,435
  • 6
  • 28
  • 53
  • This will never work. The message becomes sent after it is sent and moved to the Sent Items folder. It will be a different message from the one you sent. More than that, touching a message in any way after calling Send will abort the submission process. – Dmitry Streblechenko Jun 26 '15 at 17:39
  • @DmitryStreblechenko Really? You can't check a `MailItem`'s properties while it's in the process of sending? Seems odd. Guess that rules out my next idea... checking to see if the `MailItem`'s parent folder is the "Sent" folder. – Bond Jun 26 '15 at 17:48
  • 1
    Yes, after calling Send the only allowed operation on the MialItem object is releasing it - the message now belongs to the spooler. – Dmitry Streblechenko Jun 26 '15 at 17:49
0

Try this:

Option Explicit
Sub SendMail()
  Dim outobj, mailobj
  Set outobj = CreateObject("Outlook.Application")

  Set mailobj = outobj.CreateItem(0)

    With mailobj
        .To = "user@test.com"
        .Subject = "Testmail"
        .Body = "If you got this email, my VBs test worked!"
        .Send
    End With

    'Clear the memory
    Set outobj = Nothing
    Set mailobj = Nothing
End Sub
SendMail()
Msgbox("Done")
Bk_
  • 99
  • 9
  • Thank you all! @Bk, I tried your code and it worked perfectly! Can you tell me what your last chunk of code is doing? – Edrei Jun 26 '15 at 20:23
  • @Edrei Of course. The line "SendMail()" calls the subroutine " Sub Sendmail()" (the second line). After the code is processed between "Sub Sendmail()" and "End Sub" (from top to down) it goes back again to the second-to-last line "SendMail()". The next line creates a Messagebox with the text "Done". – Bk_ Jun 27 '15 at 11:24
0

Firstly, what if it was the user who opened Outlook? I don't think any user will appreciate your code closing Outlook. You might want to check that both Application.Explorers.Count and Application.Inspectors.Count are zero before closing Outlook. Newest version of Outlook will automatically exist if there are no open explorers or inspectors even if you hold a reference to an Outlook object - that was done to guard ageist misbehaving apps that leaked references. To prevent Outlook from closing, hodl a reference to an Explorer object t(even if you do not show it) - call Namespace.getDefaultFolder(olFolderInbox), then hold a reference to the object returned by MAPIFolder.GetExplorer .

Secondly, after calling Send, use Namespace,SyncObjects collection to retrieve the very first SyncObject. Hook up the SyncObject.SyncEnd event and call SyncObject.Start. When SyncEnd event fires, you will be all done. But I don't think you can work with events in VB script...

Dmitry Streblechenko
  • 56,873
  • 3
  • 44
  • 75