VBA Outlook "No active explorer found" - vba

I am experiencing an issue with Outlook automation,
To keep it simple I will first show you a shorter version of my code :
Sub test()
Dim GetOutlookApp As Object
Set GetOutlookApp = CreateObject("Outlook.Application")
End Sub
First, I do want to keep the late binding solution.
This sub launch Outlook in the taskbar (small icon). When I double click on it, a message pops up: "No active explorer object found" (title of the window: "Error"). Then the Outlook Inbox window opens when I click on OK.
My script is for end users so I don't want this message appears even if the user just has to click on OK (the rest of the main sub has no one issue).
I have to solve this problem to be able to send an email with outlook and to make sure the email is not in the Outbox folder.
What I am looking for is a way to open outlook, without this message, using late binding.
Below is the full code to open outlook before sending the email (source: ron de bruin). It works perfectly except the outlook message. The message pops up on this line:
obj.Session.GetDefaultFolder(olFolderInbox).Display
I tried AppActivate and others stuffs but I did not succeed and can't find any info on google about that!
Thanks for your help
Sub send_mail ()
Dim OutApp As Object
Set OutApp = OutlookApp() 'OPEN OUTLOOK
'Set OutApp = CreateObject("Outlook.Application") 'OPEN OUTLOOK simple solution
With ActiveSheet.MailEnvelope
...
End With
End sub
Public Function OutlookApp( _
Optional WindowState As Long = olMaximized, _
Optional ReleaseIt As Boolean = True _
) As Object
'***This sub is a part to the global way to open outlook before sending an email (prevent the outbox bug, email stucked into the outbox)
'***Source: http://www.rondebruin.nl/win/s1/outlook/openclose.htm, late binding mode
Static obj As Object
On Error GoTo ErrHandler
Select Case True
Case obj Is Nothing, Len(obj.Name) = 0
Set obj = GetObject(, "Outlook.Application")
If obj.Explorers.Count = 0 Then
InitOutlook:
'Open inbox to prevent errors with security prompts
obj.Session.GetDefaultFolder(olFolderInbox).Display
obj.ActiveExplorer.WindowState = WindowState
End If
Case ReleaseIt
Set obj = Nothing
End Select
Set OutlookApp = obj
ExitProc:
Exit Function
ErrHandler:
Select Case Err.Number
Case -2147352567
'User cancelled setup, silently exit
Set obj = Nothing
Case 429, 462
MsgBox "Err.Number OutlookApp: " & Err.Number
Set obj = GetOutlookApp()
If obj Is Nothing Then
Err.Raise 429, "OutlookApp", "Outlook Application does not appear to be installed."
Else
Resume InitOutlook
End If
Case Else
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "Unexpected error"
End Select
Resume ExitProc
Resume
End Function
Private Function GetOutlookApp() As Object
'***This sub is a part to the global way to open outlook before sending an email (prevent the outbox bug, email stucked into the outbox)
'***Source: http://www.rondebruin.nl/win/s1/outlook/openclose.htm, late binding mode
'On Error GoTo ErrHandler
Set GetOutlookApp = CreateObject("Outlook.Application")
ExitProc:
Exit Function
ErrHandler:
Select Case Err.Number
Case Else
'Do not raise any errors
Set GetOutlookApp = Nothing
End Select
Resume ExitProc
Resume
End Function

Use the Add method of the Explorers class to create a new instance of the explorer window. Then you need to call the Display method of the Explorer class (not Folder).
Sub DisplayDrafts()
Dim myExplorers As Outlook.Explorers
Dim myOlExpl As Outlook.Explorer
Dim myFolder As Outlook.Folder
Set myExplorers = Application.Explorers
Set myFolder = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
Set myOlExpl = myExplorers.Add(myFolder, olFolderDisplayNoNavigation)
myOlExpl.Display
End Sub
This sub launch Outlook in the taskbar (small icon). When I double click on it, a message pops up: "No active explorer object found" (title of the window: "Error"). Then the Outlook Inbox window opens when I click on OK.
Typically you shouldn't see any icons in the task bar. Make sure that you have all the latest updates and service packs installed for the OS and Outlook. Also check out the list of running processes before automating Outlook - make sure that no Outlook instances running at the moment.
See How to automate Outlook from another program for more information.

Using the Eugene Astafiev code I have solved my issue! Thanks Eugene!
Here is the code:
Sub that send the email:
Sub Send_Mail()
'**This sub aims to send the mail that contains the job sheet
'Deactivate the screen updating : increase the speed and looks better
Application.ScreenUpdating = False
'Select the range of data
ActiveSheet.Range(FirstCol_JS & 1 & ":" & LastCol_JS & Firstrow_JS + nb_item_scanned - 1).Select
'Show the envelope on the ActiveWorkbook. This line prevents a bug (Method 'MailEnveloppe' of object '_Worksheet' failed. -2147467259, 80004005)
ActiveWorkbook.EnvelopeVisible = True
'Make sure outlook is opened or open it *****HERE IS WHY MY QUESTION*****
Call OutlookApp <------------------------------------------------
'Email error handling
On Error GoTo ErrorManagement
With ActiveSheet.MailEnvelope
'Subject is the title of the mail
.Item.Subject = "Job Sheet"
'Introduction is the content of the mail
.Introduction = "Hi John," & vbCrLf & _
"..." & vbCrLf & _
"Regards, The computer"
.Item.To = "alias#domain.com"
.Item.Send
End With
'Select the home page (main sheet)
'It is needed to activate the screenupdating so that the userform can be displayed on the sheet1
Application.ScreenUpdating = True
Else
'Normally, this message should never appear
MsgBox "You can't create a job sheet without any item. Nothing was done.", , "Action not allowed"
End If
'Exit sub before the error handling codes
Exit Sub
ErrorManagement:
'Activate the screen updating : be able to show that the outlook interface disappears
Application.ScreenUpdating = True
'Hide the outlook interface
ActiveWorkbook.EnvelopeVisible = False
'Activate the Excel windows so that the msgbox does not appear in the Windows taskbar
'This line is mandatory because the outlook interface is in front of the Excel workbook when it appears, so we have to activate again the Excel worbook
Call ActivateExcel
End Sub
Principal sub that manage to open Outlook
Sub OutlookApp(Optional ReleaseIt As Boolean = True)
'***This sub is a part to the global way to open outlook before sending an email (prevent the outbox bug, email stucked into the outbox)
'***Source: http://www.rondebruin.nl/win/s1/outlook/openclose.htm, late binding mode, and Eugene Astafiev http://stackoverflow.com/questions/31198130/vba-outlook-no-active-explorer-found
'Declaration of an object for outlook. The static mode allows to keep the object when this sub is launched more than one time
Static olObject As Object 'Early binding: Outlook.Application
'Declaration of variable objects to open the outlook window (prevent the email to be stuck in the Outbox folder)
Dim myExplorers As Object 'Early binding: Outlook.Explorers
Dim myOlExpl As Object 'Early binding: Outlook.Explorer
Dim myFolder As Object 'Early binding: Outlook.Folder
'Error handling
On Error GoTo ErrHandler
Select Case True
'If the olObject is nothing then try to create it
Case olObject Is Nothing, Len(olObject.Name) = 0
'This line will work if outlook is already opened, otherwise it will create an error and the code will go to ErrHandler
Set olObject = GetObject(, "Outlook.Application")
'If there is not already one opened windows of outlook
If olObject.Explorers.Count = 0 Then
InitOutlook:
'Open outlook window to prevent the email to be stucked in the Outbox folder (not sent)
Set myExplorers = olObject.Explorers
Set myFolder = olObject.GetNamespace("MAPI").GetDefaultFolder(6) 'olFolderInbox: 6
Set myOlExpl = myExplorers.Add(myFolder, 0) 'olFolderDisplayNoNavigation: 2, olFolderDisplayNormal:0
'Early binding code:
'Set myExplorers = Application.Explorers
'Set myFolder = Application.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
'Set myOlExpl = myExplorers.Add(myFolder, olFolderDisplayNoNavigation)
myOlExpl.Display
End If
End Select
'Delete the olObject variable is the ReleaseIt boolean is true
If ReleaseIt = True Then
Set olObject = Nothing
End If
'Possibility to set the OutlookApp function as the outlook object, if OutlookApp is declared like this: "Function OutlookApp(Optional ReleaseIt As Boolean = True) as Object"
'Set OutlookApp = olObject
ExitProc:
Exit Sub
ErrHandler:
Select Case Err.Number
Case -2147352567
'User cancelled setup, silently exit
Set olObject = Nothing
Case 429, 462 '429: outlook was not opened, the Set olObject = GetObject(, "Outlook.Application") code line above did not work
Set olObject = CreateOutlook() 'Launch the CreateOutlook function: CreateOutlook = CreateObject("Outlook.Application")
If olObject Is Nothing Then 'If the outlook object is still empty it means that there is a more serious issue (outlook not installed on the computer for example)
Err.Raise 429, "OutlookApp", "Outlook Application does not appear to be installed."
Else 'If olObject is no more nothing, go back to the code above and open the outlook window
Resume InitOutlook
End If
Case Else 'For any other error numbers
MsgBox "Error " & Err.Number & ": " & Err.Description, vbCritical, "Unexpected error"
End Select
Resume ExitProc
Resume 'For debugging
End Sub
Second sub that manage to open outlook
Private Function CreateOutlook() As Object
'***This sub is a part to the global way to open outlook before sending an email (prevent the outbox bug, email stucked into the outbox)
'***Source: http://www.rondebruin.nl/win/s1/outlook/openclose.htm, late binding mode
'Error handling
On Error GoTo ErrHandler
Set CreateOutlook = CreateObject("Outlook.Application")
ExitProc:
Exit Function
ErrHandler:
Set CreateOutlook = Nothing
Resume ExitProc
Resume 'For debugging
End Function
FYI here is the code to activate the Excel window
Sub ActivateExcel()
'***This sub aims to activate Excel windows (so that it's in front of the windows)
'Set variable title equal to exact application window title
Dim ExcelTitleCaption As String
ExcelTitleCaption = Application.Caption
'Activate Microsoft Excel
AppActivate ExcelTitleCaption
End Sub
Thanks!! Topic solved

Related

Access prints my word document but the document does not close afterwards and does not show up in the task manager

I have an access database which prints a label as a word document. The word document is filled using the information from my access database and then closed. This works on my personal laptop and prints every time. When I transfer this to my work laptop it works the first time and then fails as the document has remained open. The document does not show up in the processes in task manager, my laptop is using office 365 and my work laptop is at office 2016 is this a version issue? Code below. If this is completely wrong could you please suggest the fix
Dim appWord As Word.Application
Dim doc As Word.Document
Dim thepath As String
thepath = CurrentProject.Path
'Avoid error 429, when Word isn't open.
On Error Resume Next
Err.Clear
'Set appWord object variable to running instance of Word.
Set appWord = GetObject(, "Word.Application")
If Err.Number <> 0 Then
'If Word isn't open, create a new instance of Word.
Set appWord = New Word.Application
End If
Set doc = appWord.Documents.Open(thepath & "\label.docx", , False)
'ActiveDocument.Tables(1).Cell(1, 1).va Me.PartNumber
'
'ActiveDocument.FormFields(fldPartNumber). = Me!PartNumber
If Selection.FormFields.Count >= 1 Then
MsgBox Selection.FormFields(1).Name
End If
ActiveDocument.FormFields("Text1").Result = Me.PartNumber
ActiveDocument.FormFields("Text2").Result = Me.SerialNumber
'MsgBox (ActiveDocument.FormFields("Text1").Result)
ActiveDocument.FormFields("Text10").Result = Me.BatchNumber
ActiveDocument.FormFields("Text7").Result = Me.Qty
ActiveDocument.FormFields("Text6").Result = Me.Lifex
ActiveDocument.FormFields("Text3").Result = Me.Station
ActiveDocument.FormFields("Text4").Result = Me.Store
ActiveDocument.FormFields("Text5").Result = Me.Bin
ActiveDocument.FormFields("Text11").Result = Me.Description
'.FormFields("fldCountry").Result = Me.Country
' FormFields("fldPhone").Result = Me.Phone
'.FormFields("fldFax").Result = Me.Fax
activedocuments.FormFields.Visible = True
'ActiveDocument.FormFields.Activate
appWord.DisplayAlerts = False
doc.PrintOut Background = True
appWord.DisplayAlerts = True
'CreateObject("Shell.Application").Namespace(0).ParseName("C:\Boeing Ireland Serviceable Label editable form.docx").InvokeVerb ("Print")
Set doc = Nothing
doc.Close
appWord.Quit (True)
Set appWord = Nothing
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description
'
End Sub
I think that the problem is the order that you are doing things at the end of the code. You should be closing/quitting objects before setting them to nothing. In addition, I would recommend that you have a single exit section that cleans up objects, regardless of whether there is an error or not. Something like:
Sub sFoo
On Error GoTo E_Handle
' Word automation code here
sExit:
On Error Resume Next
doc.Close
Set doc=Nothing
appWord.Quit (True)
Set appWord=Nothing
Exit Sub
E_Handle:
MsgBox Err.Description
Resume sExit
End Sub
Regards,
Ok, the answer here was a known issue in Microsoft Office automation the document was left open due to failing to reference an object. Microsoft issue 189618 was the reference that i used to fix this.
{Cause
Visual Basic has established a reference to Word due to a line of code that calls a Word object, method, or property without qualifying it with a Word object variable. Visual Basic does not release this reference until you end the program. This errant reference interferes with automation code when the code is run more than once.
Resolution
Modify the code so that each call to a Word object, method, or property is qualified with the appropriate object variable.}
My original error catch was to use on error resume next which allowed the real issue Runtime error 426 to be bypassed. This was due to the line of code setting the doc reference as
`enter code here`Set doc = Documents.Open(thepath & "\label.docx",,False,,,,True)'
as it doesn't reference appword it leaves an instance open. Hence my second time round open document. The fix was simple.
Set doc= appword.Documents.Open(thepath & "\label".docx",,False,,,,True) The code now works, below is a fully corrected and cleaned up version of the script which includes Applecores suggestion that was so kindly provided.
Private Sub Command67_Click()
On Error GoTo E_Handle
Dim appwd As Word.Application
Dim doc As Word.Document
Dim thepath As String
thepath = CurrentProject.Path
Set appwd = CreateObject("Word.Application")
appwd.Visible = True
Set doc = appwd.Documents.Open(thepath & "\label.docx", , False, , , , True)
doc.FormFields("Text1").Result = Me.PartNumber
doc.FormFields("Text2").Result = Me.SerialNumber & nullstring
doc.FormFields("Text10").Result = Me.BatchNumber & nullstring
doc.FormFields("Text7").Result = Me.Qty
doc.FormFields("Text6").Result = Me.Lifex
doc.FormFields("Text3").Result = Me.Station
doc.FormFields("Text4").Result = Me.Store
doc.FormFields("Text5").Result = Me.Bin & nullstring
doc.FormFields("Text11").Result = Me.Description
appwd.DisplayAlerts = False
doc.PrintOut Background = True
appwd.DisplayAlerts = True
doc.Close SaveChanges:=wdDoNotSaveChanges
Set doc = Nothing
appwd.Quit
Set appwd = Nothing
Exit Sub
sExit:
On Error Resume Next
doc.Close
Set doc = Nothing
appwd.Quit
Set appwd = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description
Resume sExit
End Sub

Error 4605 on opening Word document when another document is already open

So I have this problem on the error handler when I want to open a specific word document.
What the program does so far when I start it is: First time start is fine. Then when I run again the program keeps loading until I manually close Word. And after that Word gives me and option to access the file in read-only mode.
I've searched on forums and MSDN for a few hours now and can't find a solution.
Also it keeps giving me
error code 4605
when I run the code a second time.
Code:
Sub OpenWord()
Dim WordApp As Word.Application
Set WordApp = CreateObject("Word.Application")
WordApp.DisplayAlerts = wdAlertsNone
On Error GoTo ErrorHandler:
WordApp.Documents.Open ("C:\Users\mvandalen\Desktop\Test.docx")
WordApp.Visible = True
Exit Sub
''just for testing
VariableCheese = 5 + 5
ErrorHandler:
WordApp.Documents.Close <<< Here it gives error 4605
WordApp.Quit
Resume Next
End Sub
final edit:
Thanks to #Brett I've found a solution. I copied his code and removed the following lines (tagged with >>>):
Sub final()
Set TestDoc = GetObject("C:\Users\mvandalen\Desktop\Test.docx")
>>>>If TestDoc Is Nothing Then
Set Wd = GetObject(, "Word.Application")
If Wd Is Nothing Then
Set Wd = CreateObject("Word.Application")
If Wd Is Nothing Then
MsgBox "Failed to start Word!", vbCritical
Exit Sub
End If
>>>>f = True
**Else** Added line
**MsgBox "Failed to start Word!", vbCritical** Added line
End If
>>>Set TestDoc = Wd.Documents.Open("C:\Users\mvandalen\Desktop\Test.docx")
>>>If TestDoc Is Nothing Then
>>>MsgBox "Failed to open help document!", vbCritical
>>>If f Then
>>>Wd.Quit
>>>End If
>>>Exit Sub
End If
Wd.Visible = True
>>>Else
>>>With WordDoc.Parent
>>>.Visible = True
>>>.Activate
>>>End With
>>>End If
End sub
This code opens the file once and then not again until you close it.
But for some reason this line is required Set TestDoc = GetObject("C:\Users\mvandalen\Desktop\Test.docx"). If not the Word document will become read-only.
I would start by going to File > Options > General and see if there is a check mark in the box: Open e-mail attachments and other uneditable files in reading view. If there is, remove it.
Source: https://answers.microsoft.com/en-us/msoffice/forum/msoffice_word-mso_windows8-mso_2013_release/run-time-error-4605-in-word-2013-no-information/1ca02c04-5cea-484e-bd23-f4d18183c1b2
That said, My feel is that you are trying to close a document that has already been closed (or not active) or that there is no error.
To remedy this check there is an an error:
If Err <> 0 Then
''Insert your error handling code here
Err.Clear
Resume Next
See: https://support.microsoft.com/en-au/help/813983/you-receive-run-time-error-4248-4605-or-5941-when-you-try-to-change-pr
Alternatively, the problem is that you are not checking to see if the document is already opened. This likely results in a continuous loop. I suggest using code similar to the example below to detect if the document is already opened.
Set TestDoc = GetObject("C:\Users\mvandalen\Desktop\Test.docx")
If TestDoc Is Nothing Then
Set Wd = GetObject(, "Word.Application")
If Wd Is Nothing Then
Set Wd = CreateObject("Word.Application")
If Wd Is Nothing Then
MsgBox "Failed to start Word!", vbCritical
Exit Sub
End If
f = True
End If
Set TestDoc = Wd.Documents.Open("C:\Users\mvandalen\Desktop\Test.docx")
If TestDoc Is Nothing Then
MsgBox "Failed to open help document!", vbCritical
If f Then
Wd.Quit
End If
Exit Sub
End If
Wd.Visible = True
Else
With WordDoc.Parent
.Visible = True
.Activate
End With
End If
This code will activate the document if it is already opened.
Source: https://social.msdn.microsoft.com/Forums/en-US/29265e5f-8df9-4cab-8984-1afb9b110d2f/in-excel-use-vba-to-check-if-a-word-document-is-open?forum=isvvba
Based on your new information another possible cause is that Visual Basic has established a reference to Word because of a line of code that calls a Word object, method, or property without qualifying the element with a Word object variable. Visual Basic does not release this reference until you end the program. This errant reference interferes with automation code when the code is run more than one time. To fix this, change the code so each call to a Word object, method, or property is qualified with the appropriate object variable.
The nearest to explain this is an Excel article: https://support.microsoft.com/en-hk/help/178510/excel-automation-fails-second-time-code-runs
To help you more I would need to know:
What version of Word you are using.
Are you using MacOS or Windows.
What are your macro security settings?
If you kill all Word process does the error still show?
Is the document is ready only or otherwise protected?
If you open the document and it's in the active window when you go to the Developer tab and run your macro does the error still occur?
Given we know the document keeps getting protected try removing protection by going into the trust center and ensuring Word 2003/7 Binary Documents and Templates is not ticked.
On looking at your code more closely, I think the problem is that you don't release the Word objects. Since this code is running from within Excel, those objects are being held in memory, not being released when the macro ends. And Word notoriously has problems with trying to open a document that is still open - because you have an object to it in memory holding it open.
See my changes to your code, below - the Set [variable] = Nothing lines.
(Please note that you mix the variable names "TestDoc" and "WordDoc" in your code sample - I just copied it - so the code, as it stands, cannot run correctly.)
Set TestDoc = GetObject("C:\Users\mvandalen\Desktop\Test.docx")
If TestDoc Is Nothing Then
Set Wd = GetObject(, "Word.Application")
If Wd Is Nothing Then
Set Wd = CreateObject("Word.Application")
If Wd Is Nothing Then
MsgBox "Failed to start Word!", vbCritical
Exit Sub
End If
f = True
End If
Set TestDoc = Wd.Documents.Open("C:\Users\mvandalen\Desktop\Test.docx")
If WordDoc Is Nothing Then
MsgBox "Failed to open help document!", vbCritical
If f Then
Wd.Quit
Set Wd = Nothing
End If
Exit Sub
End If
Wd.Visible = True
Else
With WordDoc.Parent
.Visible = True
.Activate
End With
End If
Set WordDoc = Nothing
Set Wd = Nothing
Try the following code. It:
• starts Word if it's not already running.
• opens the document if it's not already open.
• saves & closes the document after editing if it opened it.
• quits Word if it started it.
You can, of course, omit the document close and app quit code if you want to keep the document open. Depending on whether you want to prevent edits to the file being saved, you may want to set ReadOnly:=True, also.
Sub OpenWord()
Dim WdApp As Word.Application, WdDoc As Word.Document
Dim bQuit As Boolean, bClose As Boolean
Const StrFlNm As String = "C:\Users\mvandalen\Desktop\Test.docx"
If Dir(StrFlNm) = "" Then
MsgBox "Cannot find the file:" & vbCr & StrFlNm, vbCritical
Exit Sub
End If
bQuit = False: bClose = True
On Error Resume Next
Set WdApp = GetObject(, "Word.Application")
If WdApp Is Nothing Then
Set WdApp = CreateObject("Word.Application")
On Error GoTo 0
If WdApp Is Nothing Then
MsgBox "Can't start Word.", vbExclamation
Exit Sub
End If
bQuit = True
End If
On Error GoTo 0
With WdApp
.Visible = True
For Each WdDoc In .Documents
If WdDoc.FullName = StrFlNm Then
bClose = False: Exit For
End If
Next
If WdDoc Is Nothing Then
Set WdDoc = .Documents.Open(Filename:=StrFlNm, ReadOnly:=False, AddToRecentFiles:=False, Visible:=True)
End If
With WdDoc
'Do your document edits here
If bClose = True Then .Close SaveChanges:=True
End With
If bQuit = True Then .Quit
End With
End Sub
you have to carefully handling the possibility of having already running Word session as well as not being able to get a Word session
so you may use a helper function:
Function GetWord(WordApp As Word.Application) As Boolean
On Error Resume Next
Set WordApp = GetObject(, "Word.Application") 'try getting an already running Word instance
If WordApp Is Nothing Then Set WordApp = CreateObject("Word.Application") ' if unsuccesful then try creating a new Word instance
GetWord = Not WordApp Is Nothing ' notify the result
End Function
and therefore your main code would be refactored as follows
Option Explicit
Sub OpenWord()
Dim WordApp As Word.Application
If Not GetWord(WordApp) Then 'if unsuccesful in getting/creating a Word session then exit sub
MsgBox "Couldn't get an existing instance or create a new instance of Word", vbCritical
Exit Sub
End If
With WordApp 'reference the Word session you just got/created
.DisplayAlerts = wdAlertsNone
.Visible = True
On Error GoTo WordErrorHandler:
.Documents.Open ("C:\Users\mvandalen\Desktop\Test.docx")
' rest of your code exploiting the opened document
End With
On Error GoTo 0 'disable Word Error processing
' here goes the rest of your code to work without Word object/data
Exit Sub ' exit not to process statements following 'WordErrorHandler'
WordErrorHandler:
With WordApp
If .Documents.Count > 0 Then .Documents.Close '<<< Here it gives error 4605
.Quit
End With
Set WordApp = Nothing
Resume Next
End Sub
Save the document as a Template (.dotx) and change .Open() to .Add().
Dim WordApp As Word.Application
Dim WordDoc As Word.Document
Set WordApp = New Word.Application
Set WordDoc = WordApp.Documents.Add "C:\Users\mvandalen\Desktop\Test.dotx"
WordApp.Visible = True
'...
WordDoc.Close wdDoNotSaveChanges
Since you have a reference to Word, no need to call CreateObject("Word.Application").
Either remove the reference to Word Library and declare WordApp and WordDoc as Object, or use the New keyword.
This way you can open as many instances you want simultaneously.

Excel vba kill an invisible application after an error

I have an application that first creates an invisible application:
Dim ExcelApp As Object
Set ExcelApp = CreateObject("Excel.Application")
ExcelApp.Visible = False
ExcelApp.ScreenUpdating = False
ExcelApp.DisplayAlerts = False
ExcelApp.EnableEvents = False
And then proceeds to use it to open files invisibly:
Do While fileTitle <> ""
Dim dataWorkbook As Workbook
Set dataWorkbook = ExcelApp.Application.Workbooks.Open(folderPath & fileTitle)
At the end of the operations with the file macros closes the file:
dataWorkbook.Close
fileTitle = Dir()
Loop
At the end of the sub macros closes the application:
ExcelApp.Quit
Set ExcelApp = Nothing
End Sub
However, if an error occurs before the file is closed, the invisible file and the application would never be closed and would continue to linger in operation systems not only eating away the memory and resources, but also preventing from doing any operations with the opened filed - renaming, opening or editting it.
I wonder if there is a way to close both the file and the application if an error occurs - in the current macros or to create a separate macros that detects invisible applications no variable points to and closes it.
At the top of your procedure use an error handler like
Set ExcelApp = CreateObject("Excel.Application")
On Error Goto CLOSE_FILE_ON_ERROR
'With that line you tell VBA to jump to the closing part if an error happens
and use this goto marker before you close the file.
CLOSE_FILE_ON_ERROR:
ExcelApp.Quit
End Sub
Note: You don't need to Set ExcelApp = Nothing because Excel does this automatically on End Sub.
Edit due to comments
If you need to show error messages or something then your code has to be extended like this:
ExcelApp.Quit 'This is needed to regularly quit if there is no error
Exit Sub 'Don't run into error handling if there was no exeption
CLOSE_FILE_ON_ERROR:
Application.StatusBar = "Error occured"
ExcelApp.Quit 'This is needed to quit after an exeption if there is an error
End Sub
You can try the below code where I kill the application like Excel, Chrome and Internet Explorer. You can use the below code with the On Error Goto error handler.
Public Function fnkilltask()
Dim objWMIService
Dim colProcessList
Dim objProcess
Dim strComputer
strComputer = "."
Set objWMIService = GetObject("winmgmts://./root/cimv2") ' Task mgr
Set colProcessList = objWMIService.ExecQuery ("Select * from Win32_Process Where Name in ('EXCEL.EXE','Chrome.exe','iexplore.exe') ")
For Each objProcess in colProcessList
objProcess.Terminate()
Next
End Function

VBA project works fine on machine with outlook 2013, but not on a machine running outlook 2010

Both machines are running 64 bit versions of Win7. The project has been painfully pieced together, I am not a programmer.
The function of the project is to automatically search emails for attachments upon a reminder set to fire every night and only download attachments to specified pathway that have the string defined by the two "pos" lines of code. Basically it just checks if the file name contains the desired name/phrase. The files I am working with change slightly with every email and over the years, but always contains the one statement. If the mail was unRead, it marks it as read when it is done with all the attachments in each email.
The only other difference is the machine with outlook 2010 does have some other code running on it. I placed this code on the machine with outlook 2013 to see if it was conflicting, but it ran perfectly still.
The following code works beautifully on the machine with outlook 2013, but not at all on the machine with outlook 2010. The project compiles just fine, and "runs" but does not download any files nor mark any emails as unread.
Here is the code in "This Outlook Session"
Private WithEvents MyReminders As Outlook.Reminders
Private Sub Application_Startup()
Set MyReminders = GetOutlookApp.Reminders
End Sub
Function GetOutlookApp() As Outlook.Application
' returns reference to native Application object
Set GetOutlookApp = Outlook.Application
End Function
Private Sub MyReminders_ReminderFire(ByVal ReminderObject As Reminder)
'On Error GoTo ErrorHandler
If ReminderObject.Caption = "Daily Report" Then
ReminderObject.Dismiss
Daily_Report
End If
If ReminderObject.Caption = "Shutdown Outlook" Then
ReminderObject.Dismiss
Application.Quit
End If
ProgramExit:
Exit Sub
ErrorHandler:
MsgBox Err.Number & " - " & Err.Description
Resume ProgramExit
End Sub
And Here is the code I have on Module1, this is only because of the pre-existing code on the other machine. I know it doesnt have to be in the module. Here it is:
Sub Daily_Report()
' This Outlook macro checks a the Outlook Inbox for messages
' with attached files (of any type) and saves them to disk.
' NOTE: make sure the specified save folder exists before
' running the macro.
On Error GoTo GetAttachment_err
' Declare variables
Dim ns As NameSpace
Dim Inbox As MAPIFolder
Dim Item As Object
Dim Atmt As Attachment
Dim FileNameXLS As String
Dim FileNamePDF As String
Dim posXLS As Integer
Dim posPDF As Integer
Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
' Check each message for attachments
For Each Item In Inbox.Items
' Save any attachments found
If Item.UnRead = True Then
For Each Atmt In Item.Attachments
posXLS = InStr(Atmt.FileName, "FINAL EXCEL")
posPDF = InStr(Atmt.FileName, "Final PDF")
If posXLS <> 0 And (Right(Atmt.FileName, 4) = ".xls") Or posXLS <> 0 And (Right(Atmt.FileName, 5) = ".xlsx") Then
FileNameXLS = "C:\Users\ba\Downloads\Babcok Lab Reports\Babcock Excel\" & Atmt.FileName
Atmt.SaveAsFile FileNameXLS
End If
If posPDF <> 0 And (Right(Atmt.FileName, 4) = ".pdf") Then
FileNamePDF = "C:\Users\ba\Downloads\Babcok Lab Reports\Babcock PDF\" & Atmt.FileName
Atmt.SaveAsFile FileNamePDF
End If
Next Atmt
Item.UnRead = False
End If
Next Item
' Clear memory
GetAttachment_exit:
Set Atmt = Nothing
Set Item = Nothing
Set ns = Nothing
Exit Sub
' Handle errors
GetAttachment_err:
MsgBox "An unexpected error has occurred." _
& vbCrLf & "Please note and report the following information." _
& vbCrLf & "Macro Name: GetAttachments" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description _
, vbCritical, "Error!"
Resume Next
End Sub
You need to use the Application property in the code:
Function GetOutlookApp() As Outlook.Application
' returns reference to native Application object
Set GetOutlookApp = Application
End Function
Also I'd recommend debugging the code in the step-by-step manner. Nobody can help you until specify the exact error you get on the problematic machine.
I am not a programmer
The current web site is for developers, that's why I'd suggest learning the basics at least. See Getting Started with VBA in Outlook 2010.
Make sure that the Daily_Report sub is invoked correctly.
My code was looking at the Outlook Data File "Inbox" when all the mail was going into the gmail account Inbox that outlook was setup with. Once I redirected the mail into the "Data File Inbox" via an inbox "rule" the code worked beautifully. The Daily_Report subroutine is being invoked correctly and the application is being used properly. Alternatively, I probably could have redirected my code to look in the gmail inbox, but didn't know how to easily do this being an amateur in programming. Any suggestions for the alternate will be appreciated.

Make outlook 2003 macro work when word is the editor?

What I have, is a similar piece of code & i made it work with the outlook editor (hard enough) and I am trying to get it to now work with Word acting as the outlook editor. (Users are used to word mail) I tried: To move the code directly into word under this document and it did nothing. To follow code i saw on: creating an objword objdoc and then pairing it with the outlook class type of deal, with no luck. Here is a sample of code:
Sub SetCategory()
Dim olMessage As Outlook.MailItem
Set olMessage = Application.ActiveInspector.CurrentItem
If olMessage.SenderName = donations Then
olMessage.Categories = "donations"
ElseIf olMessage.SenderName = "Donations" Then
olMessage.Categories = "donations"
End If
With olMessage
.Send
End With
End Sub
When using "word mail" you are not using Outlook. This describes how to invoke Outlook from Word. Once Outlook is open you can use Outlook VBA.
http://www.howto-outlook.com/howto/senddocasmail.htm
Untested, and you will have to remove the parts you do not need.
Sub SendDocAsMail()
Dim oOutlookApp As Outlook.Application
Dim oItem As Outlook.MailItem
On Error Resume Next
'Start Outlook if it isn't running
Set oOutlookApp = GetObject(, "Outlook.Application")
If Err <> 0 Then
Set oOutlookApp = CreateObject("Outlook.Application")
End If
On Error GoTo 0 ' <=== Important to see errors now if there are any
'Create a new message
Set oItem = oOutlookApp.CreateItem(olMailItem)
' --------------------------
'Set oItem = oOutlookApp.ActiveInspector.CurrentItem
If oItem.SenderName = donations Then
oItem.Categories = "donations"
ElseIf oItem.SenderName = "Donations" Then
oItem.Categories = "donations"
End If
' --------------------------
'Allow the user to write a short intro and put it at the top of the body
Dim msgIntro As String
msgIntro = InputBox("Write a short intro to put above your default " & _
"signature and current document." & vbCrLf & vbCrLf & _
"Press Cancel to create the mail without intro and " & _
"signature.", "Intro")
'Copy the open document
Selection.WholeStory
Selection.Copy
Selection.End = True
'Set the WordEditor
Dim objInsp As Outlook.Inspector
Dim wdEditor As Word.Document
Set objInsp = oItem.GetInspector
Set wdEditor = objInsp.WordEditor
'Write the intro if specified
Dim i As Integer
If msgIntro = IsNothing Then
i = 1
'Comment the next line to leave your default signature below the document
wdEditor.Content.Delete
Else
'Write the intro above the signature
wdEditor.Characters(1).InsertBefore (msgIntro)
i = wdEditor.Characters.Count
wdEditor.Characters(i).InlineShapes.AddHorizontalLineStandard
wdEditor.Characters(i + 1).InsertParagraph
i = i + 2
End If
'Place the current document under the intro and signature
wdEditor.Characters(i).PasteAndFormat (wdFormatOriginalFormatting)
'Display the message
oItem.Display
'Clean up
Set oItem = Nothing
Set oOutlookApp = Nothing
Set objInsp = Nothing
Set wdEditor = Nothing
End Sub
Edit: Added, based on comment. This is a step that beginners trip on.
"Since this macro also uses Outlook functionality to create the mail we must add the reference to the project. To do this choose Tools-> References… and select Microsoft Outlook 12.0 Object Library (or 14.0 when using Outlook 2010). After this press OK."
Latest Outlook versions use Word as an email editor by default. There is no need to check out the editor type. The WordEditor property of the Inspector class returns the Microsoft Word Document Object Model of the message being displayed. You can read more about that in the Chapter 17: Working with Item Bodies .
Also you may find the How to automate Outlook and Word by using Visual C# .NET to create a pre-populated e-mail message that can be edited article helpful.