Sending emails from Excel using Outlook without security warning - vba

I am using code from Ron de Bruin's website to send emails through Excel using Outlook. I get this security warning "A program is trying to send e-mail message on your behalf" asking me to allow or deny.
How can I avoid this warning and send emails directly"
Note: I am using Excel 2007.
Here is the code:
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Dim cell As Range
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Sheets("" & Sheet & "").Select
With Sheets("" & Sheet & "")
strbody = ""
End With
On Error Resume Next
With OutMail
.To = " email1#a.com"
.CC = ""
.BCC = ""
.Subject = ""
.Body = strbody
.From = ""
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
' restore default application behavior
Application.AlertBeforeOverwriting = True
Application.DisplayAlerts = True
ActiveWindow.SelectedSheets.PrintOut Copies:=3, Collate:=True

In addition to the methods described in the link from the comment, assuming you are the sender "...asking me to allow or deny", if you have Excel running you can have Outlook already running as well.
The simplest way would be:
Set OutApp = GetObject(, "Outlook.Application")

I found the code below somewhere on the internet a couple of years ago. It automatically answers 'Yes' for you.
Option Compare Database
' Declare Windows' API functions
Private Declare Function RegisterWindowMessage _
Lib "user32" Alias "RegisterWindowMessageA" _
(ByVal lpString As String) As Long
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" (ByVal lpClassName As Any, _
ByVal lpWindowName As Any) As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
Function TurnAutoYesOn()
Dim wnd As Long
Dim uClickYes As Long
Dim Res As Long
uClickYes = RegisterWindowMessage("CLICKYES_SUSPEND_RESUME")
wnd = FindWindow("EXCLICKYES_WND", 0&)
Res = SendMessage(wnd, uClickYes, 1, 0)
End Function
Function TurnOffAutoYes()
Dim wnd As Long
Dim uClickYes As Long
Dim Res As Long
uClickYes = RegisterWindowMessage("CLICKYES_SUSPEND_RESUME")
wnd = FindWindow("EXCLICKYES_WND", 0&)
Res = SendMessage(wnd, uClickYes, 0, 0)
End Function
Function fEmailTest()
TurnAutoYesOn '*** Add this before your email has been sent
Set appOutLook = CreateObject("Outlook.Application")
Set MailOutLook = appOutLook.CreateItem(olMailItem)
With MailOutLook
.To = " <Receipient1#domain.com>; <Receipient2#domain.com"
.Subject = "Your Subject Here"
.HTMLBody = "Your message body here"
.Send
End With
TurnOffAutoYes '*** Add this after your email has been sent
End Function

Related

How to copy embeded object and paste in temp folder with VBA

I have to create a code to save configuration script of routers from specified list.
Using telnet and VBA I'm able to fulfill my requirement. But telnet window is visible every time and also I have to rely on SendKeys to send Commands properly to that telnet window.
I have embedded 'plink.exe' as an "Object 7" in Sheet1. below is the code which copies this object and paste created of today's date in temp folder:
EmbeddedObject.Copy
Set oFolder = CreateObject("Shell.Application").Namespace(sFolder & Chr(0))
oFolder.Self.InvokeVerb "Paste"
Here the problem is after copy-paste, the file is showing as corrupted. I tried adding a zip file, but zip also gets corrupted.
So I had added a code to open the object within Excel and using SendKeys and 7z Extractor I extract to temp folder again relying on SendKeys.
Please help me with to copy it in better way without getting file corrupted.
Here is my code.
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function EmptyClipboard Lib "user32" () As Long
Private Declare PtrSafe Function OpenClipboard Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
Private Declare PtrSafe Function CloseClipboard Lib "user32" () As Long
#Else
Private Declare Function EmptyClipboard Lib "user32" () As Long
Private Declare Function OpenClipboard Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function CloseClipboard Lib "user32" () As Long
#End If
Private Type FUNC_OUT_RESULTS
SUCCESS As Boolean
SAVED_FILE_PATH_NAME As String
ERROR As String
End Type
Sub test()
Dim tRes As FUNC_OUT_RESULTS
Dim oleObj As OLEObject
tRes = SaveEmbeddedOleObjectToDisk _
(EmbeddedObject:=ActiveSheet.OLEObjects("Object 7"), FilePathName:="C:\Users\user\AppData\Local\Temp\20170512\")
With tRes
If .SUCCESS Then
MsgBox "OleObject successfully saved as : '" & .SAVED_FILE_PATH_NAME & " '", vbInformation
Else
MsgBox .ERROR, vbCritical
End If
End With
End Sub
Private Function SaveEmbeddedOleObjectToDisk( _
ByVal EmbeddedObject As OLEObject, _
ByVal FilePathName As String _
) _
As FUNC_OUT_RESULTS
Dim oFolder As Object
Dim sFolder As String
On Error GoTo errHandler
If Len(Dir$(FilePathName)) <> 0 Then 'Err.Raise 58
Dim FSO As Object
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefile FilePathName & "\*.*", True 'Delete files
FSO.deletefolder FilePathName 'Delete Todays Date folder
MkDir FilePathName 'Make Todays Date folder
End If
'\---------------------------------------\
sFolder = Left$(FilePathName, InStrRev(FilePathName, "\") - 10)
If Len(Dir$(sFolder, vbDirectory)) = 0 Then
MkDir sFolder
End If
If EmbeddedObject.OLEType = xlOLEEmbed Then
EmbeddedObject.Verb Verb:=xlPrimary '\---Here it opens within excel
Set EmbeddedObject = Nothing
Application.DisplayAlerts = True
Dim oShell
Set oShell = CreateObject("WScript.Shell")
Application.Wait (Now + TimeValue("0:00:02"))
oShell.AppActivate sFolder & "\plink*"
oShell.SendKeys "{F5}" '\----it extracts to temp-----------\
oShell.SendKeys FilePathName
oShell.SendKeys "{ENTER}"
Application.Wait (Now + TimeValue("0:00:01"))
oShell.AppActivate sFolder & "\plink*"
oShell.SendKeys ("%{F4}")
'----Copy the object without opening-----
' EmbeddedObject.Copy
' Set oFolder = CreateObject("Shell.Application").Namespace(sFolder & Chr(0))
' oFolder.Self.InvokeVerb "Paste"
'\---------------------------------------\
SaveEmbeddedOleObjectToDisk.SAVED_FILE_PATH_NAME = FilePathName
SaveEmbeddedOleObjectToDisk.SUCCESS = True
End If
Call CleanClipBoard
Exit Function
errHandler:
SaveEmbeddedOleObjectToDisk.ERROR = Err.Description
Call CleanClipBoard
End Function
Private Function GetPastedFile( _
ByVal Folder As String _
) _
As String
Dim sCurFile As String
Dim sNewestFile As String
Dim dCurDate As Date
Dim dNewestDate As Date
Folder = Folder & "\"
sCurFile = Dir$(Folder & "*.*", vbNormal)
Do While Len(sCurFile) > 0
dCurDate = FileDateTime(Folder & sCurFile)
If dCurDate > dNewestDate Then
dNewestDate = dCurDate
sNewestFile = Folder & sCurFile
End If
sCurFile = Dir$()
Loop
GetPastedFile = sNewestFile
End Function
Private Sub CleanClipBoard()
OpenClipboard 0
EmptyClipboard
CloseClipboard
End Sub

File sent as email attachment via Excel VBA is always corrupt

I'm using the following error handling method to save a copy of the file that's currently open and send it to my email if it causes an error.
Private Declare Function GetTempPath _
Lib "kernel32" Alias "GetTempPathA" _
(ByVal nBufferLength As Long, _
ByVal lpBuffer As String) As Long
Private Const MAX_PATH As Long = 260
Sub MainSub()
Dim OutApp As Object, OutMail As Object
Dim wb As Workbook
On Error GoTo NotifyandRepair
Call Sub1
Call Sub2
Call Subn
Exit Sub
NotifyandRepair:
Set wb = ThisWorkbook
Application.DisplayAlerts = False
wb.SaveAs TempPath & "ErroringFile.xlsx", FileFormat:= _xlNormal,AccessMode:=xlExclusive,ConflictResolution:=Excel.XlSaveConflictResolution.xlLocalSessionChanges
Application.DisplayAlerts = True
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "name#company.com"
.Subject = "Error Occured - Error Number " & Err.Number
.Body = Err.Description
.Attachments.Add TempPath & "ErroringFile.xlsx"
.Send '~~> Change this to .Display for displaying the email
End With
Set OutApp = Nothing: Set OutMail = Nothing
End Sub
Function TempPath() As String
TempPath = String$(MAX_PATH, Chr$(0))
GetTempPath MAX_PATH, TempPath
TempPath = Replace(TempPath, Chr$(0), "")
End Function
It appears to work fine. When an unhandled error occurs it sends me a copy of the file and its been renamed "ErroringFile.xlsx". The problem is the file is always corrupt.
Am I doing something wrong?
How do I fix this issue so the file isn't corrupt?
It's the wrong FileFormat you SaveAs.
See XlFileFormat Enumeration, you should be saving it as xlOpenXMLWorkbook.

Saving webpage as PDF to certain directory

I have it where it will open Internet Explorer give the user the save as box and then exit. However, I would prefer if instead of the user having to navigate to the correct folder, the directory comes from a cell in the worksheet and saves the webpage as a PDF. I have full Adobe installed. The code:
Sub WebSMacro()
Dim IE As Object
Dim Webloc As String
Dim FullWeb As String
Webloc = ActiveSheet.Range("B39").Value
FullWeb = "http://www.example.com=" & Webloc
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate FullWeb
Do While IE.Busy
Application.Wait DateAdd("s", 1, Now)
Loop
IE.ExecWB OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
Application.Wait DateAdd("s", 10, Now)
IE.Quit
Set IE = Nothing
End Sub
Today, you win the Internet!
Since I wanted to learn this more in depth for my own personal benefit, I used the code in the 2nd link I referenced in my comment to get the code to work as you have defined it.
The code will enter the FilePath and Name (gathered from a Cell) into the SaveAs Dialog Box and save it to the entered location.
Here is the main sub (with comments):
Sub WebSMacro()
'set default printer to AdobePDF
Dim WSHNetwork As Object
Set WSHNetwork = CreateObject("WScript.Network")
WSHNetwork.SetDefaultPrinter "Adobe PDF"
'get pdfSave as Path from cell range
Dim sFolder As String
sFolder = Sheets("Sheet1").Range("A1") 'assumes folder save as path is in cell A1 of mySheets
Dim IE As Object
Dim Webloc As String
Dim FullWeb As String
Webloc = ActiveSheet.Range("B39").Value
FullWeb = "http://www.example.com" & Webloc
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True
.Navigate FullWeb
Do While .Busy
Application.Wait DateAdd("s", 1, Now)
Loop
.ExecWB 6, 2 'OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER
Application.Wait DateAdd("s", 3, Now)
Call PDFPrint(sFolder & Webloc & ".pdf")
.Quit
End With
Set IE = Nothing
End Sub
You will also need to place this two subs somewhere in your workbook (can be the same module as the main sub (or different one)):
Sub PDFPrint(strPDFPath As String)
'Prints a web page as PDF file using Adobe Professional.
'API functions are used to specify the necessary windows while
'a WMI function is used to check printer's status.
'By Christos Samaras
'http://www.myengineeringworld.net
Dim Ret As Long
Dim ChildRet As Long
Dim ChildRet2 As Long
Dim ChildRet3 As Long
Dim comboRet As Long
Dim editRet As Long
Dim ChildSaveButton As Long
Dim PDFRet As Long
Dim PDFName As String
Dim StartTime As Date
'Find the main print window.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
Ret = 0
DoEvents
Ret = FindWindow(vbNullString, "Save PDF File As")
If Ret <> 0 Then Exit Do
Loop
If Ret <> 0 Then
SetForegroundWindow (Ret)
'Find the first child window.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
ChildRet = 0
DoEvents
ChildRet = FindWindowEx(Ret, ByVal 0&, "DUIViewWndClassName", vbNullString)
If ChildRet <> 0 Then Exit Do
Loop
If ChildRet <> 0 Then
'Find the second child window.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
ChildRet2 = 0
DoEvents
ChildRet2 = FindWindowEx(ChildRet, ByVal 0&, "DirectUIHWND", vbNullString)
If ChildRet2 <> 0 Then Exit Do
Loop
If ChildRet2 <> 0 Then
'Find the third child window.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
ChildRet3 = 0
DoEvents
ChildRet3 = FindWindowEx(ChildRet2, ByVal 0&, "FloatNotifySink", vbNullString)
If ChildRet3 <> 0 Then Exit Do
Loop
If ChildRet3 <> 0 Then
'Find the combobox that will be edited.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
comboRet = 0
DoEvents
comboRet = FindWindowEx(ChildRet3, ByVal 0&, "ComboBox", vbNullString)
If comboRet <> 0 Then Exit Do
Loop
If comboRet <> 0 Then
'Finally, find the "edit property" of the combobox.
StartTime = Now()
Do Until Now() > StartTime + TimeValue("00:00:05")
editRet = 0
DoEvents
editRet = FindWindowEx(comboRet, ByVal 0&, "Edit", vbNullString)
If editRet <> 0 Then Exit Do
Loop
'Add the PDF path to the file name combobox of the print window.
If editRet <> 0 Then
SendMessage editRet, WM_SETTEXT, 0&, ByVal " " & strPDFPath
keybd_event VK_DELETE, 0, 0, 0 'press delete
keybd_event VK_DELETE, 0, KEYEVENTF_KEYUP, 0 ' release delete
'Get the PDF file name from the full path.
On Error Resume Next
PDFName = Mid(strPDFPath, WorksheetFunction.Find("*", WorksheetFunction.Substitute(strPDFPath, "\", "*", Len(strPDFPath) _
- Len(WorksheetFunction.Substitute(strPDFPath, "\", "")))) + 1, Len(strPDFPath))
On Error GoTo 0
'Save/print the web page by pressing the save button of the print window.
Sleep 1000
ChildSaveButton = FindWindowEx(Ret, ByVal 0&, "Button", "&Save")
SendMessage ChildSaveButton, BM_CLICK, 0, 0
'Sometimes the printing delays, especially in large colorful web pages.
'Here the code checks printer status and if is idle it means that the
'printing has finished.
Do Until CheckPrinterStatus("Adobe PDF") = "Idle"
DoEvents
If CheckPrinterStatus("Adobe PDF") = "Error" Then Exit Do
Loop
'Since the Adobe Professional opens after finishing the printing, find
'the open PDF document and close it (using a post message).
StartTime = Now()
Do Until StartTime > StartTime + TimeValue("00:00:05")
PDFRet = 0
DoEvents
PDFRet = FindWindow(vbNullString, PDFName & " - Adobe Acrobat")
If PDFRet <> 0 Then Exit Do
Loop
If PDFRet <> 0 Then
PostMessage PDFRet, WM_CLOSE, 0&, 0&
End If
End If
End If
End If
End If
End If
End If
End Sub
Function CheckPrinterStatus(strPrinterName As String) As String
'Provided the printer name the functions returns a string
'with the printer status.
'By Christos Samaras
'http://www.myengineeringworld.net
Dim strComputer As String
Dim objWMIService As Object
Dim colInstalledPrinters As Variant
Dim objPrinter As Object
'Set the WMI object and the check the install printers.
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery("Select * from Win32_Printer")
'If an error occurs in the previous step, the function will return error.
If Err.Number <> 0 Then
CheckPrinterStatus = "Error"
End If
On Error GoTo 0
'The function loops through all installed printers and for the selected printer,
'checks it status.
For Each objPrinter In colInstalledPrinters
If objPrinter.Name = strPrinterName Then
Select Case objPrinter.PrinterStatus
Case 1: CheckPrinterStatus = "Other"
Case 2: CheckPrinterStatus = "Unknown"
Case 3: CheckPrinterStatus = "Idle"
Case 4: CheckPrinterStatus = "Printing"
Case 5: CheckPrinterStatus = "Warmup"
Case 6: CheckPrinterStatus = "Stopped printing"
Case 7: CheckPrinterStatus = "Offline"
Case Else: CheckPrinterStatus = "Error"
End Select
End If
Next objPrinter
'If there is a blank status the function returns error.
If CheckPrinterStatus = "" Then CheckPrinterStatus = "Error"
End Function
And finally Declare these constants and functions in a module as well (can be the same module as the main sub (or different one).
Option Explicit
Public Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Public Declare Function SetForegroundWindow Lib "user32" _
(ByVal hWnd As Long) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Function SendMessageByString Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Public Declare Sub keybd_event Lib "user32" _
(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
'Constants used in API functions.
Public Const SW_MAXIMIZE = 3
Public Const WM_SETTEXT = &HC
Public Const VK_DELETE = &H2E
Public Const KEYEVENTF_KEYUP = &H2
Public Const BM_CLICK = &HF5&
Public Const WM_CLOSE As Long = &H10

VBA/Outlook extracting attachments from .eml files

I'm trying to take a folder full of .eml messages with attachments and then extract/rename/save the attachments in another folder. My code :
Sub SaveAttachments()
Dim OlApp As Outlook.Application
Set OlApp = GetObject(, "Outlook.Application")
Dim MsgFilePath
Dim Eml As Outlook.MailItem
Dim att As Outlook.Attachments
Dim Path As String
Path = "C:\Users\richard\Desktop\Inbox\"
If OlApp Is Nothing Then
Err.Raise ERR_OUTLOOK_NOT_OPEN
End If
Dim fs As Object
Set fs = CreateObject("Scripting.FileSystemObject")
Dim temp As Object
Set temp = fs.GetFolder(Path)
For Each MsgFilePath In temp.Files
Set Eml = OlApp.CreateItemFromTemplate(Path & MsgFilePath.Name)
Set att = Eml.Attachments
If att.Count > 0 Then
For i = 1 To att.Count
fn = "C:\Users\richard\Desktop\cmds\" & Eml.SenderEmailAddress
att(i).SaveAsFile fn
Next i
End If
Set Eml = Nothing
Next
Set OlApp = Nothing
End Sub
But I'm getting straightaway this error on the first file in the loop, ie the line
Set Eml = OlApp.CreateItemFromTemplate(Path & MsgFilePath.Name) :
-2147286960 (80030050) %1 already exists.
Any ideas on what is going on much appreciated !
Try this (TRIED AND TESTED)
Private Declare Function ShellExecute Lib "shell32.dll" Alias _
"ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As _
String, ByVal lpFile As String, ByVal lpParameters As String, _
ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL As Long = 1
Private Const SW_SHOWMAXIMIZED As Long = 3
Private Const SW_SHOWMINIMIZED As Long = 2
Sub SaveAttachments()
Dim OlApp As Outlook.Application
Set OlApp = GetObject(, "Outlook.Application")
Dim MsgFilePath
Dim Eml As Outlook.MailItem
Dim att As Outlook.Attachments
Dim sPath As String
sPath = "C:\Users\richard\Desktop\Inbox\"
If OlApp Is Nothing Then
Err.Raise ERR_OUTLOOK_NOT_OPEN
End If
sFile = Dir(sPath & "*.eml")
Do Until sFile = ""
ShellExecute 0, "Open", sPath & sFile, "", sPath & sFile, SW_SHOWNORMAL
Wait 2
Set MyInspect = OlApp.ActiveInspector
Set Eml = MyInspect.CurrentItem
Set att = Eml.Attachments
If att.Count > 0 Then
For i = 1 To att.Count
fn = "C:\Users\richard\Desktop\cmds\" & i & "-" & Eml.SenderEmailAddress
att(i).SaveAsFile fn
Next i
End If
sFile = Dir$()
Loop
Set OlApp = Nothing
End Sub
Private Sub Wait(ByVal nSec As Long)
nSec = nSec + Timer
While nSec > Timer
DoEvents
Wend
End Sub

How to send mail when outlook is closed

i have following lines of code. It works fine when outlook is opened but i want it to work even though outlook is closed. I kept the code in command button click event.
Private Sub btnSend_Click()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = GetObject("", Outlook.Application)
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "adbc#adbc.com"
.CC = ""
.BCC = ""
.Subject = "Test mail from Excel Sheet-OutLook Closed"
.Body = "This is body of the mail"
.Display
.Send
.ReadReceiptRequested = True
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I tried it with both GetObject and CreateObject methods. If i execute this code after closing outlook it's not showing any error but it's not sending any mail.
The following lines of code sending the mails but they are queuing in the outlook's outbox. when user opens outlook then only they are moving out from outbox.
Private Sub btnSend_Click()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "adbc#adbc.com"
.CC = ""
.BCC = ""
.Subject = "Test mail from Excel Sheet-OutLook Closed"
.Body = "This is body of the mail"
.Display
.Send
.ReadReceiptRequested = True
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
You can use shell commands to actually open outlook before sending a mail.Precisely being
Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Public Sub OpenOutlook()
Dim ret As Long
On Error GoTo aa
ret = ShellExecute(Application.hwnd, vbNullString, "Outlook", vbNullString, "C:\", SW_SHOWNORMAL)
If ret < 3 Then
MsgBox "Outlook is not found.", vbCritical, "SN's Customised Solutions"
End If
aa:
End Sub
keep this in a separate module and call the module from the code where you are sending the mail.The part i am trying to work on is how to hide this so that activation is still with excel
For Outlook 2013, this is an issue with Outlook settings, not the VBA code.
Open OUTLOOK
Go To FILE -> OPTIONS -> ADVANCED
Scroll to 'Send and Receive' heading and click 'Send/Receiveā€¦' button
Under 'Setting for group 'All Accounts' ', ensure that 'Perform an
automatic send/receive when exiting' is CHECKED
This ensures all items in the OUTLOOK 'Outbox' are sent when Outlook closes. This fixed the issue for me. Likely similar for other versions of Outlook.