Is there a way of checking t osee if Outlook is open ?

eddyc

Registered User.
Local time
Today, 21:27
Joined
Mar 23, 2011
Messages
43
Hi, I have written a vb function to email from within access using outlook but have noticed that when outlook is not open it just hangs the whole schbang! Is there code i can add to check to see if outlook is open and if not open it to avoid this problem?

Cheers Ed
 
Yes and thanks to Dev - here is the code
Code:
Option Compare Database
Option Explicit

'This code was originally written by Dev Ashish.
'It is not to be altered or distributed except as part of an application.
'You are free to use it in any application provided the copyright notice is left unchanged.
'
'Code Courtesy of Dev Ashish
'
Private Const SW_HIDE = 0
Private Const SW_SHOWNORMAL = 1
Private Const SW_NORMAL = 1
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_MAXIMIZE = 3
Private Const SW_SHOWNOACTIVATE = 4
Private Const SW_SHOW = 5
Private Const SW_MINIMIZE = 6
Private Const SW_SHOWMINNOACTIVE = 7
Private Const SW_SHOWNA = 8
Private Const SW_RESTORE = 9
Private Const SW_SHOWDEFAULT = 10
Private Const SW_MAX = 10

Private Declare Function apiFindWindow Lib "user32" Alias _
    "FindWindowA" (ByVal strClass As String, _
    ByVal lpWindow As String) As Long

Private Declare Function apiSendMessage Lib "user32" Alias _
    "SendMessageA" (ByVal Hwnd As Long, ByVal Msg As Long, ByVal _
    wParam As Long, lParam As Long) As Long
    
Private Declare Function apiSetForegroundWindow Lib "user32" Alias _
    "SetForegroundWindow" (ByVal Hwnd As Long) As Long
    
Private Declare Function apiShowWindow Lib "user32" Alias _
    "ShowWindow" (ByVal Hwnd As Long, ByVal nCmdShow As Long) As Long
    
Private Declare Function apiIsIconic Lib "user32" Alias _
    "IsIconic" (ByVal Hwnd As Long) As Long
    
Function fIsAppRunning(ByVal strAppName As String, Optional fActivate As Boolean) As Boolean
    Dim lngH As Long, strClassName As String
    Dim lngX As Long, lngTmp As Long
    Const WM_USER = 1024
    On Local Error GoTo fIsAppRunning_Err
    fIsAppRunning = False
    Select Case LCase$(strAppName)
        Case "excel":           strClassName = "XLMain"
        Case "word":            strClassName = "OpusApp"
        Case "access":          strClassName = "OMain"
        Case "powerpoint95":    strClassName = "PP7FrameClass"
        Case "powerpoint97":    strClassName = "PP97FrameClass"
        Case "notepad":         strClassName = "NOTEPAD"
        Case "paintbrush":      strClassName = "pbParent"
        Case "wordpad":         strClassName = "WordPadClass"
        
        Case "Outlook":         strClassName = "rctrl_renwnd32"
        
        Case Else:              strClassName = vbNullString
    End Select
    
    If strClassName = "" Then
        lngH = apiFindWindow(vbNullString, strAppName)
    Else
        lngH = apiFindWindow(strClassName, vbNullString)
    End If
    If lngH <> 0 Then
        apiSendMessage lngH, WM_USER + 18, 0, 0
        lngX = apiIsIconic(lngH)
        If lngX <> 0 Then
            lngTmp = apiShowWindow(lngH, SW_SHOWNORMAL)
        End If
        If fActivate Then
            lngTmp = apiSetForegroundWindow(lngH)
        End If
        fIsAppRunning = True
    End If
fIsAppRunning_Exit:
    Exit Function
fIsAppRunning_Err:
    fIsAppRunning = False
    Resume fIsAppRunning_Exit
End Function

Just 'ask' like this

Code:
    If (fIsAppRunning("Outlook")) = False Then
    MsgBox "Outlook is not running!" & vbLf & vbLf & "Outlook Action cannot be prepared.", vbExclamation, "Need to Start Outlook and Try again"
    Exit Sub
    Else
    'MsgBox "Outlook is running"
    End If
 
Last edited:
Here's what I do when I need to hook into Outlook and create Outlook if it's not already running:

In its own module:
Code:
Option Compare Database
Option Explicit

#Const EarlyBind = 1 'Set to 0 & remove reference before distributing!

#If EarlyBind Then
Public Function GetOutlook() As Outlook.Application
  Dim objOutlook As Outlook.Application   
#Else 'Late binding; use for production
Public Function GetOutlook() As Object
  Dim objOutlook As Object
#End If
On Error GoTo ErrHandler:

Set GetOutlook = GetObject(vbNullString,"Outlook.Application")

ExitProc:
  Exit Function
ErrHandler:
  Select Case Err.Number
      Case 429 'No running instance of Outlook
         Set GetOutlook = CreateOutlook()
         If GetOutlook Is Nothing Then
            Err.Raise vbObjectError, "GetOutlook Function", "Cannot retrieve or create an instance of Outlook. Outlook may not be installed on this computer."
         End If
   End Select
   Resume ExitProc
   Resume
End Function

#If EarlyBind Then
Private Function CreateOutlook() As Outlook.Application
#Else
Private Function CreateOutlook() As Object
#End If
On Error Resume Next

   Set CreateOutlook = CreateObject("Outlook.Application")
   If (Err.Number <> 0) Then
      Set CreateOutlook = Nothing
   End If

End Function
 
No probs Ted.

I would use GetObject() for this and trap the error. E.g.:
Code:
Public Function OutlookIsRunning() As Boolean
On Error GoTo Error_Handler

    Dim outObj As Object
    
    Set outObj = GetObject(, "Outlook.Application")
    
    Set outObj = Nothing
    
    OutlookIsRunning = True
    
Exit_Error_Handler:
    Exit Function

Error_Handler:
    If Err.Number = 429 Then
        OutlookIsRunning = False
    Else
        MsgBox Err.Description
    End If
    Resume Exit_Error_Handler
    
End Function
Will return True if it is or False if it isn't.

Edit: Didn't see your post Banana :o
 
BRILLIANT Thank You!!! Thank You DEV!!!
 
Hey didn't see all the other ideas before!! They look great and i'm gonna have a look at them. There are definetly a lot simpler than devs. I will try and understand them before i use them ... like your const naming Banana!!
 
clever coding vbaInet - i like it!!
 
Hey didn't see all the other ideas before!! They look great and i'm gonna have a look at them. There are definetly a lot simpler than devs. I will try and understand them before i use them ... like your const naming Banana!!

It's termed "Conditional Compilation" which basically allow you to write different code and select one of them for different use. If you google, several people wisely suggest that one use late binding for maximum compatibility when using other libraries especially when you distribute Access project to people with different computer. You don't want it to error out because you were using Outlook 2007 but they're still on Outlook 2003. Late binding solves that problem, but I dislike how late binding also disables intellisense so it's harder to develop with other libraries since you have to work blind.

Hence, I use conditional compilation to allow me to quickly switch between early-bound code and late-bound code just by changing a single value (e.g. the "#Const EarlyBind") and re-compiling.
 
Really good stuff Thank You very Much!!!! Cheers ed
 
Do you run treat all you functions like this and if you want to early bind run through setting EarlyBind to 1 the nre-compile? I supppose 1 = Early Bind 0 = Late is that right? With the
Code:
If earlybind Then
i'm guessing that if it = 1 then it uses early binding terminology?

One more question i have read that you will have to have referenced the correct libraries somewhere else in your code to use early binding is that right?

Cheers Hope that all makes sense,
Ed
 
Correct.

I tend to prefer using implicit evaluation for where I expect a boolean evaluation because it more closely resemble the behavior of other languages and thus is useful for cases where we may not get the expected True value. For example, if you call an API that returns (in theory) a boolean result, the literal value would be 1. If we did this:

Code:
If 1 = True Then
...

this would actually fail because 1 <> -1 which is what VB/VBA's True actually represents. But this

Code:
If 1 Then

is more analogous to this:

Code:
If 1 <> 0 Then

which will succeed. Mind, some prefer to be more explicit and instead do this:

Code:
If CBool(1) = True Then

then this will also succeed because we're now comparing like with like (e.g. Boolean data type against another Boolean data type). I just prefer implicit because there's always the risk that I may get unexpected data type due to VBA's dynamic typing nature silently coercing what I thought was a Boolean data type into a basic integer and thus changing the behavior of the code.

All in all, this is just my personal preference; if you want to be more explicit or use different way to evaluate this, be my guest; just be aware of the differences that can arise when there's silent conversion or working with sources outside of VBA that may return 1 representing true.
 
Just a couple of comments which I use.

1. If the user does not have Outlook open and you do open it (without making it visible) if the user has any poorly written add-ins which expect Outlook to be visible to add buttons to the tool bar - you will get an error.

2. I keep track of when my code opens Outlook because i then close outlook after doing whatever it is I want to do. Otherwise Outlook will keep running. (I am not sure the code above does this).

3. When outlook is running, but not visible the user will still get reminders and the reminder window. You might want to stop this. You need to use the BeforeReminderShow event, which you can cancel. see here for 2003 http://msdn.microsoft.com/en-gb/library/aa171188(office.11).aspx
 

Users who are viewing this thread

Back
Top Bottom