VBA frustration (long, code included) 
Author Message
 VBA frustration (long, code included)

My office has just switched to new desktops with Windows XP Pro and
Office XP Small Business. I've been configuring Outlook.

I am on a lot of email lists, and I have a corresponding amount of
Rules to filter the incoming email. It occurs to me that I can
minimise the delivery time on a Mon morning by having the most
commonly used rule at the top of the chain, and the least used rule at
the bottom. So, how to count?

I discover the "run a script" action and learn about creating scripts
in the included VBA environment. This is my first time doing VBA
although I am a long-time programmer. Here's my idea:
application_startup will initialise an array of records, each record
is a name and a count. Each script sub will update its record in the
array, when it is called from the rule. application_quit will load the
previously stored stats from a file, update them with the in-memory
array and save it once again.

I've got the rules to trigger my scripts just fine. application_start
inits the array just fine. If I run the application_quit routine from
the environment (via F5) it runs fine. But it does not run properly on
actual Outlook shutdown. (It's currently in debug mode and prints the
in-memory stats array to screen with MsgBox, I'll figure out files
when it works.)

Some web research reveals lots of helpful info. Turns out that
application_quit is running as the very last thing, when it's
practically useless. Meaning my stats array has been destroyed
already, so there's nothing there to reference anymore.

I find a number of posts from Ken Slovak detailing that one needs to
capture the Explorer_Close and Inspector_Close events and check if
Outlook is actually closing or not.

Here's my frustration: I cannot get this solution to work. I've tried
code from his posts. I have a copy of Randy Byrne's Building Apps
Outlook 2002, and have tried code from its pages. I installed the
sample VbaProject.otm included on the book's cd. None of these work
and they all display the same symptom: Explorer_Close events are not
triggered when Outlook closes.

A sample sequence:

Outlook starts up
Application_Startup runs, inits stats array
Email is downloaded, filtered, filtering triggers VBA script
VBA script updates stats array
I push the close button (upper right corner x) or select File -> Exit
Application_Quit runs
Outlook is dead

The sample code from the book shows many events in the environment's
immediate window, and it clearly shows that Explorer_Close is not
triggering, even though Outlook always has 1 Explorer window open.

Triggering on Inspector_Close works, but does not help, as in the
above sequence no Inspector objects are even instantiated.

I thought it was me; I'm a heavy tweaker and have modified the XP
environment a fair bit, although not the office environment (yet). So
I installed the sample code from the book on a coworker's machine
who's unlikely to have tweaked anything affecting this situation. His
machine shows the same symptoms.

I do have Office SP-2 installed.

I'm hoping someone has some insight on this problem. Code attached
below.

Having read a lot of info on automation today, I also find it
disappointing that the rules aren't part of the Outlook Object Model.
Then it could pick up new rules automatically, and maybe even keep
them sorted.

Thanks for any help, responses or "I have the same problems",
...Stu

ThisOutlookSession:

Public WithEvents objExplorer As Outlook.Explorer

Private Sub Application_Quit()
    On Error Resume Next

    objExplorer = Nothing
    objInspector = Nothing
    ' Open "c:\test.rtk" For Random As FreeFile(1) Len = 64
    ' Close
    'Dim i As Integer
    'Dim text As String
    'Dim file As Integer

    'For i = 0 To RtkNumRecs
        'text = text & "Rule " & Trim(RtkStats(i).Name) & " had " &
Str(RtkStats(i).Count) & " hits" & vbCrLf
    'Next
    'MsgBox text

    'file = FreeFile(0)
    'Open "C:\test.rtk" For Random As file Len = Len(RtkRecord)
End Sub

Private Sub Application_Startup()
    Dim i As Integer

    Set objExplorer = Application.ActiveExplorer
    Set objInspector = Application.ActiveInspector

MsgBox "# expls " & Str(Application.Explorers.Count)

    RtkStats(0).Name = "bugtraq"

    For i = 0 To RtkNumRecs
        RtkStats(i).Count = 0
    Next
End Sub

Private Sub objExplorer_Close()
  'On Error Resume Next
MsgBox "expl_close"
  If objOutlook.Explorers.Count <= 1 Then
    MsgBox "Explorer closed"
  End If
End Sub

Modules:Rtk:

Option Explicit

Public Type RtkRecord
  Name As String * 32
  Count As Integer
End Type

Public Const RtkNumRecs As Integer = 0
Public RtkStats(RtkNumRecs) As RtkRecord

Private Sub RtkUpdate(Name As String)
    Dim i As Integer

    For i = 0 To RtkNumRecs
MsgBox "Compare"
        If (StrComp(Trim(RtkStats(i).Name), Name) = 0) Then
MsgBox "Equal"
            RtkStats(i).Count = RtkStats(i).Count + 1
            Exit For
        End If
    Next
End Sub

Sub BugTraq(Item As Outlook.MailItem)
    RtkUpdate ("bugtraq")
End Sub



Wed, 19 Oct 2005 09:38:18 GMT  
 VBA frustration (long, code included)
Setting the Outlook objects = Nothing in Application.Quit is useless,
they are already not available.

I've never done what you are trying to do in VBA code, only in COM
addins. In the case of addins you need an Explorer wrapper class and a
declaration of an Explorers collection using WithEvents. See the
ItemsCB COM addin sample on the Resources page at www.microeye.com for
an example of a working Explorer wrapper.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Lead Author, Professional Outlook 2000 Programming, Wrox Press
Lead Author, Beginning VB 6 Application Development, Wrox Press
Attachment Options
http://www.slovaktech.com/attachmentoptions.htm
Extended Reminders
http://www.slovaktech.com/extendedreminders.htm


Quote:
> My office has just switched to new desktops with Windows XP Pro and
> Office XP Small Business. I've been configuring Outlook.

> I am on a lot of email lists, and I have a corresponding amount of
> Rules to filter the incoming email. It occurs to me that I can
> minimise the delivery time on a Mon morning by having the most
> commonly used rule at the top of the chain, and the least used rule
at
> the bottom. So, how to count?

> I discover the "run a script" action and learn about creating
scripts
> in the included VBA environment. This is my first time doing VBA
> although I am a long-time programmer. Here's my idea:
> application_startup will initialise an array of records, each record
> is a name and a count. Each script sub will update its record in the
> array, when it is called from the rule. application_quit will load
the
> previously stored stats from a file, update them with the in-memory
> array and save it once again.

> I've got the rules to trigger my scripts just fine.
application_start
> inits the array just fine. If I run the application_quit routine
from
> the environment (via F5) it runs fine. But it does not run properly
on
> actual Outlook shutdown. (It's currently in debug mode and prints
the
> in-memory stats array to screen with MsgBox, I'll figure out files
> when it works.)

> Some web research reveals lots of helpful info. Turns out that
> application_quit is running as the very last thing, when it's
> practically useless. Meaning my stats array has been destroyed
> already, so there's nothing there to reference anymore.

> I find a number of posts from Ken Slovak detailing that one needs to
> capture the Explorer_Close and Inspector_Close events and check if
> Outlook is actually closing or not.

> Here's my frustration: I cannot get this solution to work. I've
tried
> code from his posts. I have a copy of Randy Byrne's Building Apps
> Outlook 2002, and have tried code from its pages. I installed the
> sample VbaProject.otm included on the book's cd. None of these work
> and they all display the same symptom: Explorer_Close events are not
> triggered when Outlook closes.

> A sample sequence:

> Outlook starts up
> Application_Startup runs, inits stats array
> Email is downloaded, filtered, filtering triggers VBA script
> VBA script updates stats array
> I push the close button (upper right corner x) or select File ->
Exit
> Application_Quit runs
> Outlook is dead

> The sample code from the book shows many events in the environment's
> immediate window, and it clearly shows that Explorer_Close is not
> triggering, even though Outlook always has 1 Explorer window open.

> Triggering on Inspector_Close works, but does not help, as in the
> above sequence no Inspector objects are even instantiated.

> I thought it was me; I'm a heavy tweaker and have modified the XP
> environment a fair bit, although not the office environment (yet).
So
> I installed the sample code from the book on a coworker's machine
> who's unlikely to have tweaked anything affecting this situation.
His
> machine shows the same symptoms.

> I do have Office SP-2 installed.

> I'm hoping someone has some insight on this problem. Code attached
> below.

> Having read a lot of info on automation today, I also find it
> disappointing that the rules aren't part of the Outlook Object
Model.
> Then it could pick up new rules automatically, and maybe even keep
> them sorted.

> Thanks for any help, responses or "I have the same problems",
> ...Stu

> ThisOutlookSession:

> Public WithEvents objExplorer As Outlook.Explorer

> Private Sub Application_Quit()
>     On Error Resume Next

>     objExplorer = Nothing
>     objInspector = Nothing
>     ' Open "c:\test.rtk" For Random As FreeFile(1) Len = 64
>     ' Close
>     'Dim i As Integer
>     'Dim text As String
>     'Dim file As Integer

>     'For i = 0 To RtkNumRecs
>         'text = text & "Rule " & Trim(RtkStats(i).Name) & " had " &
> Str(RtkStats(i).Count) & " hits" & vbCrLf
>     'Next
>     'MsgBox text

>     'file = FreeFile(0)
>     'Open "C:\test.rtk" For Random As file Len = Len(RtkRecord)
> End Sub

> Private Sub Application_Startup()
>     Dim i As Integer

>     Set objExplorer = Application.ActiveExplorer
>     Set objInspector = Application.ActiveInspector

> MsgBox "# expls " & Str(Application.Explorers.Count)

>     RtkStats(0).Name = "bugtraq"

>     For i = 0 To RtkNumRecs
>         RtkStats(i).Count = 0
>     Next
> End Sub

> Private Sub objExplorer_Close()
>   'On Error Resume Next
> MsgBox "expl_close"
>   If objOutlook.Explorers.Count <= 1 Then
>     MsgBox "Explorer closed"
>   End If
> End Sub

> Modules:Rtk:

> Option Explicit

> Public Type RtkRecord
>   Name As String * 32
>   Count As Integer
> End Type

> Public Const RtkNumRecs As Integer = 0
> Public RtkStats(RtkNumRecs) As RtkRecord

> Private Sub RtkUpdate(Name As String)
>     Dim i As Integer

>     For i = 0 To RtkNumRecs
> MsgBox "Compare"
>         If (StrComp(Trim(RtkStats(i).Name), Name) = 0) Then
> MsgBox "Equal"
>             RtkStats(i).Count = RtkStats(i).Count + 1
>             Exit For
>         End If
>     Next
> End Sub

> Sub BugTraq(Item As Outlook.MailItem)
>     RtkUpdate ("bugtraq")
> End Sub



Fri, 21 Oct 2005 22:52:35 GMT  
 VBA frustration (long, code included)


Quote:
> Setting the Outlook objects = Nothing in Application.Quit is useless,
> they are already not available.

I had noticed that but in one of your previous posts you said it was
good programming practice to do so, and all the example code I've seen
does this. Hm. My bad. The post I was thinking of
http://groups.google.com/groups?q=set+nothing+good+practice+author:sl...
you're talking about CDO, not VBA.

So I can kill that code. Good.

Quote:
> I've never done what you are trying to do in VBA code, only in COM
> addins.

Darn. I'm not up to speed on the addins yet.

Quote:
>         In the case of addins you need an Explorer wrapper class and a
> declaration of an Explorers collection using WithEvents. See the

Except for the fact that in a COM addin you have to declare your own
Dim objApplication As Outlook.Application and then instantiate it, and
in VBA you already have an Application object handy, don't the two
work the same? And wouldn't my observation that the final closing of
Outlook doesn't send an Explorer_Close to the final instance of an
Explorer apply to COM addins equally? Which makes the trapping of that
event useless, as the one instance of the Explorer that you're
interested in (the Application.ActiveExplorer during
Application_Startup) is killed without notification.

I just reread that paragraph and noticed you are implying that if you
don't have an Explorer collection wrapper class for your Explorer
object then your object will never get events. Do I read you
correctly? Even so, the sample code included with Randy Byrne's book
does implement an Explorer wrapper, and it still doesn't register an
Explorer_Close for that last instance.

Quote:
> ItemsCB COM addin sample on the Resources page at www.microeye.com for
> an example of a working Explorer wrapper.

I'll take a look at it.

Thanks,
...Stu



Fri, 21 Oct 2005 23:59:05 GMT  
 VBA frustration (long, code included)
Actually, in a COM addin that is properly written all Outlook objects
including any Application objects should be inherited from the
Application object passed along in the On_Connection event. So it's
not that different.

In the case of COM addins I always get an event when an Explorer
closes, even the final one. In fact, due to a bug in On_Disconnect you
don't get that event if Outlook is closed if any Outlook objects are
instantiated and Outlook can't shut down until those objects are all
released. A Catch-22 situation. So we use Explorer.Close and
Inspector.Close to see how many are still around in the collections
and call an uninithandler procedure when they are all 0.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Lead Author, Professional Outlook 2000 Programming, Wrox Press
Lead Author, Beginning VB 6 Application Development, Wrox Press
Attachment Options
http://www.slovaktech.com/attachmentoptions.htm
Extended Reminders
http://www.slovaktech.com/extendedreminders.htm


Quote:


> > Setting the Outlook objects = Nothing in Application.Quit is
useless,
> > they are already not available.

> I had noticed that but in one of your previous posts you said it was
> good programming practice to do so, and all the example code I've
seen
> does this. Hm. My bad. The post I was thinking of

http://groups.google.com/groups?q=set+nothing+good+practice+author:slo
vak&hl=en&lr=lang_en&ie=UTF-8&selm=%235d60p6h%24GA.1732%40cppssbbsa06&
rnum=1
Quote:
> you're talking about CDO, not VBA.

> So I can kill that code. Good.

> > I've never done what you are trying to do in VBA code, only in COM
> > addins.

> Darn. I'm not up to speed on the addins yet.

> >         In the case of addins you need an Explorer wrapper class
and a
> > declaration of an Explorers collection using WithEvents. See the

> Except for the fact that in a COM addin you have to declare your own
> Dim objApplication As Outlook.Application and then instantiate it,
and
> in VBA you already have an Application object handy, don't the two
> work the same? And wouldn't my observation that the final closing of
> Outlook doesn't send an Explorer_Close to the final instance of an
> Explorer apply to COM addins equally? Which makes the trapping of
that
> event useless, as the one instance of the Explorer that you're
> interested in (the Application.ActiveExplorer during
> Application_Startup) is killed without notification.

> I just reread that paragraph and noticed you are implying that if
you
> don't have an Explorer collection wrapper class for your Explorer
> object then your object will never get events. Do I read you
> correctly? Even so, the sample code included with Randy Byrne's book
> does implement an Explorer wrapper, and it still doesn't register an
> Explorer_Close for that last instance.

> > ItemsCB COM addin sample on the Resources page at www.microeye.com
for
> > an example of a working Explorer wrapper.

> I'll take a look at it.

> Thanks,
> ...Stu



Sat, 22 Oct 2005 04:54:15 GMT  
 VBA frustration (long, code included)

Quote:
> In the case of COM addins I always get an event when an Explorer
> closes, even the final one. In fact, due to a bug in On_Disconnect you
> don't get that event if Outlook is closed if any Outlook objects are
> instantiated and Outlook can't shut down until those objects are all
> released. A Catch-22 situation. So we use Explorer.Close and
> Inspector.Close to see how many are still around in the collections
> and call an uninithandler procedure when they are all 0.

I gathered something like that from dejagoogling.

Here's a very simple bit of code. I start Outlook, hit the run button
after the stop, switch back to Outlook from the VBA window, hit new
email, type hello, hit the close button, switch back to the VBA
window, switch back to Outlook, and hit the exit button. The log of
this follows the code. I can get inspector close events now, which is
one better than before, but still no explorer close events.

It almost feels like my objExplorer is losing its association with the
boot-time ActiveExplorer.

Should this code work? If not, why not?

I'm also confused about what an Explorer is exactly. If someone could
fill me in I'd appreciate it.

...Stu

--- Code ---
Public WithEvents colExplorer As Outlook.Explorers
Public WithEvents objExplorer As Outlook.Explorer
Public WithEvents colInspector As Outlook.Inspectors
Public WithEvents objInspector As Outlook.Inspector

Private Sub Application_Quit()
    Debug.Print "application quit"
    Stop
End Sub

Private Sub Application_Startup()
    Stop
    Set colExplorer = Application.Explorers
    Set objExplorer = Application.ActiveExplorer
    Set colInspector = Application.Inspectors
    Set objInspector = Application.ActiveInspector
End Sub

Private Sub colExplorer_NewExplorer(ByVal Explorer As Explorer)
    Debug.Print "explorers new"
    Set objExplorer = Explorer
End Sub

Private Sub colInspector_NewInspector(ByVal Inspector As Inspector)
    Debug.Print "inspectors new"
    Set objInspector = Inspector
End Sub

Private Sub objExplorer_Activate()
    Debug.Print "explorer activate"
End Sub

Private Sub objExplorer_Close()
    Stop
    Debug.Print "explorer close"
End Sub

Private Sub objInspector_Activate()
    Debug.Print "inspector activate"
End Sub

Private Sub objInspector_Close()
    Stop
    Debug.Print "inspector close"
End Sub
--- Code ---

--- Immediate Window ---
explorer activate
inspectors new
inspector activate
inspector activate
explorer activate
inspector close
explorer activate
explorer activate
explorer activate
explorer activate
application quit
--- Immediate Window ---



Sat, 22 Oct 2005 13:19:33 GMT  
 VBA frustration (long, code included)
An Explorer is an Outlook window used to view a folder, just as an
Inspector is an Outlook window used to view Outlook items.

You will get Explorer.Close if you right-click in a folder name in the
Folder List and select Open in New Window, then close that new
Explorer.

You are still not using an Explorer wrapper class as I recommended.
Look at the ItemsCB code sample I mentioned for a working Explorer
wrapper class and the code that adds each new Explorer to a collection
of those classes.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Lead Author, Professional Outlook 2000 Programming, Wrox Press
Lead Author, Beginning VB 6 Application Development, Wrox Press
Attachment Options
http://www.slovaktech.com/attachmentoptions.htm
Extended Reminders
http://www.slovaktech.com/extendedreminders.htm


<snip>

Quote:
> I gathered something like that from dejagoogling.

> Here's a very simple bit of code. I start Outlook, hit the run
button
> after the stop, switch back to Outlook from the VBA window, hit new
> email, type hello, hit the close button, switch back to the VBA
> window, switch back to Outlook, and hit the exit button. The log of
> this follows the code. I can get inspector close events now, which
is
> one better than before, but still no explorer close events.

> It almost feels like my objExplorer is losing its association with
the
> boot-time ActiveExplorer.

> Should this code work? If not, why not?

> I'm also confused about what an Explorer is exactly. If someone
could
> fill me in I'd appreciate it.

> ...Stu

> --- Code ---
> Public WithEvents colExplorer As Outlook.Explorers
> Public WithEvents objExplorer As Outlook.Explorer
> Public WithEvents colInspector As Outlook.Inspectors
> Public WithEvents objInspector As Outlook.Inspector

> Private Sub Application_Quit()
>     Debug.Print "application quit"
>     Stop
> End Sub

> Private Sub Application_Startup()
>     Stop
>     Set colExplorer = Application.Explorers
>     Set objExplorer = Application.ActiveExplorer
>     Set colInspector = Application.Inspectors
>     Set objInspector = Application.ActiveInspector
> End Sub

> Private Sub colExplorer_NewExplorer(ByVal Explorer As Explorer)
>     Debug.Print "explorers new"
>     Set objExplorer = Explorer
> End Sub

> Private Sub colInspector_NewInspector(ByVal Inspector As Inspector)
>     Debug.Print "inspectors new"
>     Set objInspector = Inspector
> End Sub

> Private Sub objExplorer_Activate()
>     Debug.Print "explorer activate"
> End Sub

> Private Sub objExplorer_Close()
>     Stop
>     Debug.Print "explorer close"
> End Sub

> Private Sub objInspector_Activate()
>     Debug.Print "inspector activate"
> End Sub

> Private Sub objInspector_Close()
>     Stop
>     Debug.Print "inspector close"
> End Sub
> --- Code ---

> --- Immediate Window ---
> explorer activate
> inspectors new
> inspector activate
> inspector activate
> explorer activate
> inspector close
> explorer activate
> explorer activate
> explorer activate
> explorer activate
> application quit
> --- Immediate Window ---



Sat, 22 Oct 2005 21:56:42 GMT  
 VBA frustration (long, code included)

Quote:
> Clue attained, thanks. If I "Open a New Window", my code from last
> post sees the Explorer_Close when the new window closes iff it is
> closed first. If I open a new window, close the original Outlook
> window, then close the new window, no Explorer_Close event is trapped,
> although the Application_Quit event is trapped.

An addendum to my post: If I open a new window, and close the original
window first, I do get an Explorer_Close for the original window, but
not for the new window when it finally closes.

...Stu



Sun, 23 Oct 2005 10:14:38 GMT  
 VBA frustration (long, code included)
Yes, but are you using an Explorer wrapper? You haven't answered that
question and you haven't shown from your code that you are.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Lead Author, Professional Outlook 2000 Programming, Wrox Press
Lead Author, Beginning VB 6 Application Development, Wrox Press
Attachment Options
http://www.slovaktech.com/attachmentoptions.htm
Extended Reminders
http://www.slovaktech.com/extendedreminders.htm


Quote:

> > Clue attained, thanks. If I "Open a New Window", my code from last
> > post sees the Explorer_Close when the new window closes iff it is
> > closed first. If I open a new window, close the original Outlook
> > window, then close the new window, no Explorer_Close event is
trapped,
> > although the Application_Quit event is trapped.

> An addendum to my post: If I open a new window, and close the
original
> window first, I do get an Explorer_Close for the original window,
but
> not for the new window when it finally closes.

> ...Stu



Sun, 23 Oct 2005 21:52:20 GMT  
 VBA frustration (long, code included)

Quote:
> Yes, but are you using an Explorer wrapper? You haven't answered that
> question and you haven't shown from your code that you are.

The code in my last post was adapted from the microeye example code
that you pointed me at, and yes, uses an Explorer wrapper.
Specifically the code in the Class Module ExplWrap. Please check my
last post. Ah, I did see that my addendum post showed up before my
code post, I think because I attached the .otm file which is fairly
large. I'll repost the code post without the attachment in a second.

At least, that's my understanding of what you mean by an Explorer
wrapper. Am I misunderstanding?

Interesting side note: I tried to use Outlook Spy to see if the final
Explorer instance is getting a close event, but when the Spy window is
open, the stop/debug.assert false statements in my application_quit
event do not stop the app from exiting, and the whole thing disappears
too quickly to see.

...Stu



Mon, 24 Oct 2005 00:18:27 GMT  
 VBA frustration (long, code included)

Quote:
> An Explorer is an Outlook window used to view a folder, just as an
> Inspector is an Outlook window used to view Outlook items.

Clue attained, thanks. If I "Open a New Window", my code from last
post sees the Explorer_Close when the new window closes iff it is
closed first. If I open a new window, close the original Outlook
window, then close the new window, no Explorer_Close event is trapped,
although the Application_Quit event is trapped.

Quote:
> You will get Explorer.Close if you right-click in a folder name in the
> Folder List and select Open in New Window, then close that new
> Explorer.

Indeed I do. (I should read the whole post before replying.) However,
I do not get the Close event if the new window is closed after the
original Outlook window.

Quote:
> You are still not using an Explorer wrapper class as I recommended.
> Look at the ItemsCB code sample I mentioned for a working Explorer
> wrapper class and the code that adds each new Explorer to a collection
> of those classes.

I've studied this example more thoroughly. It seems that any Explorer
is added to a private collection for later handling, including
trapping the events thereof.

I've cut down the example code to what I believe is the minimum
necessary for my purposes and put it into a clean VbaProject.otm. The
result is the same: I can get the Close event for the new window, but
not for the original Outlook window, even though the Application_Quit
event is trapped.

I've posted the code, and attached the .otm. Is it correct enough to
still function?

I suspect that the problem lies here: the ThisOutlookSession that is
supplied to the vba programmer isn't co-operating in regards to the
final Explorer_Close, and this non-co-operation is an artifact of the
VBA environment, and is not present in the ComAddIn environment.

Whether or not that is true, I've begun to suspect that there is no
way to trap the final usable Outlook shutdown event from within VBA.

...Stu

--- ThisOutlookSession ---
Option Explicit

Private WithEvents objOutlook As Outlook.Application
Private WithEvents colExpl As Outlook.Explorers

Private Sub Application_Startup()
    On Error Resume Next
    Stop
    Set golApp = Me
    Set objOutlook = Me
    Set colExpl = objOutlook.Explorers
    AddExpl objOutlook.ActiveExplorer
End Sub

Private Sub Application_Quit()
    On Error Resume Next
    Stop
    Set colExpl = Nothing
    Set golApp = Nothing
    Set objOutlook = Nothing
End Sub

Private Sub colExpl_NewExplorer(ByVal Explorer As Outlook.Explorer)
    On Error Resume Next
    Stop
    AddExpl Explorer
End Sub
--- ThisOutlookSession ---

--- Module modOutlExpl ---
Option Explicit

Public gcolExplWrap As New Collection

Dim nID As Integer

Public Sub AddExpl(Explorer As Outlook.Explorer)
    Dim objExplWrap As New ExplWrap

    objExplWrap.Explorer = Explorer

    objExplWrap.Key = nID
    gcolExplWrap.Add objExplWrap, CStr(nID)
    nID = nID + 1
End Sub

Public Sub KillExpl(anID As Integer, objExplWrap As ExplWrap)
    Dim objExplWrap2 As ExplWrap

    Set objExplWrap2 = gcolExplWrap.Item(CStr(anID))
    If Not objExplWrap2 Is objExplWrap Then
        Err.Raise 1, Description:="Unexpected Error in KillExpl"
        Exit Sub
    End If

    gcolExplWrap.Remove CStr(anID)
End Sub
--- Module modOutlExpl ---

--- Module modOutlook ---
Option Explicit

Public golApp As Outlook.Application
--- Module modOutlook ---

--- Class Module ExplWrap ---
Option Explicit

Private WithEvents m_objExpl As Outlook.Explorer
Private m_nID As Integer

Private Sub Class_Initialize()
    Set m_objExpl = Nothing
End Sub

Private Sub Class_Terminate()
    Set m_objExpl = Nothing
End Sub

Public Property Let Explorer(objExpl As Outlook.Explorer)
    Set m_objExpl = objExpl
End Property

Public Property Get Explorer() As Outlook.Explorer
    Set Explorer = m_objExpl
End Property

Public Property Let Key(anID As Integer)
    m_nID = anID
End Property

Private Sub m_objExpl_Close()
    On Error Resume Next
    Stop
    modOutlExpl.KillExpl m_nID, Me
    Set m_objExpl = Nothing
    If golApp.Explorers.Count <= 1 Then
        ' uninit here
        Stop
    End If
End Sub
--- Class Module ExplWrap ---



Mon, 24 Oct 2005 00:19:34 GMT  
 VBA frustration (long, code included)
I ran some tests and it seems that the Explorer wrapper idea won't
work in the Outlook VBA project. You never get an Explorer.Close event
when closing Outlook and the Explorer is actually closed if you use an
Explorer wrapper before the wrapper class Close event has a chance to
fire. So it just won't work.

I'd suggest using a COM addin, where the Explorer wrapper class idea
does work. Besides, a COM addin is much easier to distribute to other
users than a VBA project and won't overwrite their existing macros.

--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Lead Author, Professional Outlook 2000 Programming, Wrox Press
Lead Author, Beginning VB 6 Application Development, Wrox Press
Attachment Options
http://www.slovaktech.com/attachmentoptions.htm
Extended Reminders
http://www.slovaktech.com/extendedreminders.htm


Quote:

> > Yes, but are you using an Explorer wrapper? You haven't answered
that
> > question and you haven't shown from your code that you are.

> The code in my last post was adapted from the microeye example code
> that you pointed me at, and yes, uses an Explorer wrapper.
> Specifically the code in the Class Module ExplWrap. Please check my
> last post. Ah, I did see that my addendum post showed up before my
> code post, I think because I attached the .otm file which is fairly
> large. I'll repost the code post without the attachment in a second.

> At least, that's my understanding of what you mean by an Explorer
> wrapper. Am I misunderstanding?

> Interesting side note: I tried to use Outlook Spy to see if the
final
> Explorer instance is getting a close event, but when the Spy window
is
> open, the stop/debug.assert false statements in my application_quit
> event do not stop the app from exiting, and the whole thing
disappears
> too quickly to see.

> ...Stu



Tue, 25 Oct 2005 02:56:02 GMT  
 VBA frustration (long, code included)

Quote:
> I'd suggest using a COM addin, where the Explorer wrapper class idea
> does work. Besides, a COM addin is much easier to distribute to other
> users than a VBA project and won't overwrite their existing macros.

I've come to that conclusion as well; that a COM addin is the way to
go.

Thanks for your help Ken.

...Stu



Tue, 25 Oct 2005 23:15:11 GMT  
 
 [ 12 post ] 

 Relevant Pages 

1. Sending messages with VBA (code included this time)

2. Problem Filtering in VBA (includes code)

3. Macros and VBA code not included

4. Invalid data format, no longer runs VBA code

5. VBA for Excel Chartwizard frustration

6. Help with some VB Code (Code included)

7. HELP - Manually Place Long Lines of Code over Several Lines in Code Window

8. How do I Include FormFeed in Module (VBA)

9. way to not include a library in VBA outlook

10. Include file for Word VBA constants

11. How to create a HTML-body including a picture in VBA

12. WORD X: VBA macro including find/replace with styles much slower than regular macro

 

 
Powered by phpBB® Forum Software