Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Outlook / Programming VBA / September 2005

Tip: Looking for answers? Try searching our database.

Looping through Folders

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
David C. Holley - 22 Sep 2005 17:09 GMT
How do I loop through my Outlook folders using code? I cannot for the
life of me figure it out.
Eric Legault [MVP - Outlook] - 22 Sep 2005 20:42 GMT
Try out the code below.  Paste it into a new Module in the Outlook VBA editor
and set a breakpoint on the "Erase strPaths" line.  Execute the Run
procedure, and watch how the strPaths() array gets populated before it gets
cleared.

Option Explicit
Dim i As Integer
Dim strPaths() As String
Dim objNS As Outlook.NameSpace
Dim objFolder As Outlook.MAPIFolder
Dim objFolders As Outlook.Folders
Dim objFolders2 As Outlook.Folders

Sub Run()
   Set objNS = Application.GetNamespace("MAPI")
   Set objFolders = objNS.Folders
   RecurseFolders objFolders
   
   Erase strPaths
   Set objNS = Nothing
   Set objFolder = Nothing
   Set objFolders = Nothing
   Set objFolders2 = Nothing
End Sub

Sub RecurseFolders(objTheseFolders As Outlook.Folders)
   For Each objFolder In objTheseFolders
       Debug.Print objFolder.Name
       ReDim Preserve strPaths(i + 1)
       strPaths(i) = objFolder.FolderPath
       Set objFolders2 = objFolder.Folders
       i = i + 1
       RecurseFolders objFolders2
   Next
End Sub

Signature

Eric Legault (Outlook MVP, MCDBA, old school WOSA MCSD, B.A.)
Try Picture Attachments Wizard - http://www.collaborativeinnovations.ca
Blog: http://blogs.officezealot.com/legault/

> How do I loop through my Outlook folders using code? I cannot for the
> life of me figure it out.
David C. Holley - 22 Sep 2005 21:28 GMT
Now is it just me or does is it just plain *STUPID* that MS didn't give
us an easy way to do this?

> Try out the code below.  Paste it into a new Module in the Outlook VBA editor
> and set a breakpoint on the "Erase strPaths" line.  Execute the Run
[quoted text clipped - 31 lines]
>     Next
> End Sub
Eric Legault [MVP - Outlook] - 22 Sep 2005 21:54 GMT
I'm sorry, but how is this NOT easy?  You can't architect an object model
based on a hierarchical data structure any better than using a Parent ->
Children / one-to-many model.  Microsoft has provided the toolset; it is up
to programmers to implement it.

Futhermore, looping through a collection of information that may itself
contain sub-collections is a very common occurrence in modern object oriented
programming.

If you are having difficulties obtaining a reference to a specific folder, I
agree that walking through a hierarchy to find the parent of the desired
folder in order to retrieve that folder can get complex.  In this case, if
you know the unique EntryID value for that folder, you can call the
NameSpace.GetFolderFromID method.

Otherwise, if you know the complete path to the folder, you can use this
code sample courtesy of MicroEye (http://www.microeye.com):

'******************************************************************************
'Custom procedure: OpenMAPIFolder(ByVal strPath)
'Purpose: Return a MAPIFolder from Path argument
'Argument: String representation of folder path
'Usage:
'Set objFldr=OpenMAPIFolder("\Public Folders\All Public Folders")
'Returns: MAPIFolder objec
'******************************************************************************
Function OpenMAPIFolder(ByVal strPath) As MAPIFolder
   Dim objFldr As MAPIFolder
   Dim strDir As String
   Dim strName As String
   Dim i As Integer
   On Error Resume Next
   If Left(strPath, Len("\")) = "\" Then
           strPath = Mid(strPath, Len("\") + 1)
   Else
           Set objFldr = golApp.ActiveExplorer.CurrentFolder
   End If
   While strPath <> ""
           i = InStr(strPath, "\")
           If i Then
               strDir = Left(strPath, i - 1)
               strPath = Mid(strPath, i + Len("\"))
           Else
               strDir = strPath
               strPath = ""
           End If
           If objFldr Is Nothing Then
               Set objFldr = golApp.GetNamespace("MAPI").Folders(strDir)
           On Error GoTo 0
           Else
               Set objFldr = objFldr.Folders(strDir)
           End If
   Wend
   Set OpenMAPIFolder = objFldr
End Function

Signature

Eric Legault (Outlook MVP, MCDBA, old school WOSA MCSD, B.A.)
Try Picture Attachments Wizard - http://www.collaborativeinnovations.ca
Blog: http://blogs.officezealot.com/legault/

> Now is it just me or does is it just plain *STUPID* that MS didn't give
> us an easy way to do this?
[quoted text clipped - 34 lines]
> >     Next
> > End Sub
David C. Holley - 22 Sep 2005 23:37 GMT
I'm thinking more in terms of the Access Object Model where seems a bit
easier to grab stuff. I am about 3/4 through solving the problem with my
own code and it is easier than I thought. My thinking though was related
to the fact that seemed to take multiple levels to get to the folders.
Plus I realized today that this is actually the first time I've had to
do this. All of my other experience with Outlook has been relatively simple.

> I'm sorry, but how is this NOT easy?  You can't architect an object model
> based on a hierarchical data structure any better than using a Parent ->
[quoted text clipped - 51 lines]
>     Set OpenMAPIFolder = objFldr
> End Function
David C. Holley - 22 Sep 2005 23:46 GMT
And here is the initial code...

The final will probably take two parameters - one to designate the
namespace (where to look) and the other the specific folder name (what
to look for). In retrospect, I think that my initial problem had to do
with not realizing that there's a difference between a MAPI folder and
the folders underneath it.

Sub listOutlookFolders()

    Dim appOutlook As Outlook.Application
    Dim nms As Outlook.NameSpace
    Dim mapiParentFolder As Outlook.MAPIFolder
    Dim targetFolders As Outlook.Folders
    Dim i

    Set appOutlook = CreateObject("Outlook.Application")
    Set nms = appOutlook.GetNamespace("MAPI")

    For i = 1 To nms.Folders.Count
        Set mapiParentFolder = nms.Folders(i)
        Set targetFolders = mapiParentFolder.Folders
        For j = 1 To targetFolders.Count
            Debug.Print targetFolders(j).Name, targetFolders(j).Parent
        Next j
    Next i

    Set targetFolders = Nothing
    Set mapiParentFolder = Nothing
    Set nms = Nothing
    Set appOutlook = Nothing

End Sub

> I'm sorry, but how is this NOT easy?  You can't architect an object model
> based on a hierarchical data structure any better than using a Parent ->
[quoted text clipped - 51 lines]
>     Set OpenMAPIFolder = objFldr
> End Function
David C. Holley - 23 Sep 2005 00:10 GMT
I'm thinking that I just flat missed something initially because

nms.Folders(1).Folders(1).Name

is now doing what I was trying earlier. At any rate here is the initial
code...

The final will probably take two parameters - one to designate the
namespace (where to look) and the other the specific folder name (what
to look for). The idea is to be able to be able point my Access resident
SUBS to a specific folder thus making them more generic.

Sub listOutlookFolders()

    Dim appOutlook As Outlook.Application
    Dim nms As Outlook.NameSpace
    Dim mapiParentFolder As Outlook.MAPIFolder
    Dim targetFolders As Outlook.Folders
    Dim i
    Dim j

    Set appOutlook = CreateObject("Outlook.Application")
    Set nms = appOutlook.GetNamespace("MAPI")
    Stop
    For i = 1 To nms.Folders.Count
        Set mapiParentFolder = nms.Folders(i)
        Set targetFolders = mapiParentFolder.Folders
        Debug.Print mapiParentFolder.Name
        For j = 1 To targetFolders.Count
            Debug.Print targetFolders(j).Name
        Next j
    Next i

    Set targetFolders = Nothing
    Set mapiParentFolder = Nothing
    Set nms = Nothing
    Set appOutlook = Nothing

End Sub

> I'm sorry, but how is this NOT easy?  You can't architect an object model
> based on a hierarchical data structure any better than using a Parent ->
[quoted text clipped - 51 lines]
>     Set OpenMAPIFolder = objFldr
> End Function
Eric Legault [MVP - Outlook] - 23 Sep 2005 03:34 GMT
What exactly is your intent anyway?  Loop n levels deep, or all the way
through?  Either way, you have to design the code so that it is recursive - a
function calling itself, like my initial example.

Signature

Eric Legault (Outlook MVP, MCDBA, old-school WOSA MCSD, B.A.)
Try Picture Attachments Wizard for Outlook:
http://www.collaborativeinnovations.ca
Blog: http://blogs.officezealot.com/legault/

> I'm thinking that I just flat missed something initially because
>
[quoted text clipped - 91 lines]
> >     Set OpenMAPIFolder = objFldr
> > End Function
David C. Holley - 23 Sep 2005 04:17 GMT
To able to find a specific folder (regardless of n-level) for use by
couple of SUBS that create/delete AppointmentItems created from Access.
Currently, the SUBs add/delete AppointmentItems in the default Calendar
folder. Since the SUBS are currently dependent upon a specific folder,
the SUBS aren't as flexible as I would like. While they work for me, as
a single-user and developer, I would like to provide the users with the
ability to have the AppointmentItems placed in alternate calendar folders.

> What exactly is your intent anyway?  Loop n levels deep, or all the way
> through?  Either way, you have to design the code so that it is recursive - a
> function calling itself, like my initial example.
Michael Bednarek - 23 Sep 2005 05:59 GMT
On Thu, 22 Sep 2005 23:17:20 -0400, "David C. Holley"
<DavidCHolley@netscape.net> wrote in
microsoft.public.outlook.program_vba:

[top posting corrected]
>> What exactly is your intent anyway?  Loop n levels deep, or all the way
>> through?  Either way, you have to design the code so that it is recursive - a
[quoted text clipped - 7 lines]
>a single-user and developer, I would like to provide the users with the
>ability to have the AppointmentItems placed in alternate calendar folders.

It seems to me that Eric's "RecurseFolders()" in his initial response
provides the necessary starting point. Have you tried it?

Signature

Michael Bednarek  http://mbednarek.com/  "POST NO BILLS"

David C. Holley - 23 Sep 2005 06:27 GMT
I didn't have any subfolders setup when I ran it nor did I have multiple
*.pst files open. I'm going back to my originall opinion that it
shouldn't be this difficult to itierate through ALL folders (include
subfolders). I realized that I was wanting this to be as easy as looping
through the Nodes collection of a TreeView. I shouldn't have to use
multiple SUBs (and a recursive one at that) to get the list.

> On Thu, 22 Sep 2005 23:17:20 -0400, "David C. Holley"
> <DavidCHolley@netscape.net> wrote in
[quoted text clipped - 16 lines]
> It seems to me that Eric's "RecurseFolders()" in his initial response
> provides the necessary starting point. Have you tried it?
David C. Holley - 23 Sep 2005 06:43 GMT
I didn't have any subfolders setup when I ran it nor did I have multiple
*.pst files open. I'm going back to my originall opinion that it
shouldn't be this difficult to itierate through ALL folders (include
subfolders). I realized that I was wanting this to be as easy as looping
through the Nodes collection of a TreeView. I shouldn't have to use
multiple SUBs to get the list. If its a FOLDER it should be in the
FOLDERS collection without having to go another layer deeper.

Here's the code that I wrote somewhat inspired by the original...
Sub listOutlookFolders()

'Need to figure out a way to loop subfolders if FOLDERS.COUNT <> 0
'Will probably need to load up an array if multiple folders of the same
name exist
'but will probably just search that folder as well

    Dim appOutlook As Outlook.Application
    Dim nms As Outlook.NameSpace
    Dim mapiParentFolder As Outlook.MAPIFolder
    Dim targetFolders As Outlook.Folders
    Dim i
    Dim j

    Set appOutlook = CreateObject("Outlook.Application")
    Set nms = appOutlook.GetNamespace("MAPI")
    Stop
    For i = 1 To nms.Folders.Count
        Debug.Print
"-------------------------------------------------------------"
        Set mapiParentFolder = nms.Folders(i)
        Set targetFolders = mapiParentFolder.Folders
        Debug.Print mapiParentFolder.Name
        For j = 1 To targetFolders.Count
            Call listSubFolders(targetFolders(j))
        Next j
        Debug.Print
"-------------------------------------------------------------"
    Next i

    Set targetFolders = Nothing
    Set mapiParentFolder = Nothing
    Set nms = Nothing
    Set appOutlook = Nothing

End Sub
Sub listSubFolders(parentFolder As Object)

    Dim i As Integer
    Debug.Print parentFolder.Name, parentFolder.Folders.Count
    If parentFolder.Folders.Count <> 0 Then
        For i = 1 To parentFolder.Folders.Count
            Call listSubFolders(parentFolder.Folders(i))
        Next i
    End If

End Sub

> On Thu, 22 Sep 2005 23:17:20 -0400, "David C. Holley"
> <DavidCHolley@netscape.net> wrote in
[quoted text clipped - 16 lines]
> It seems to me that Eric's "RecurseFolders()" in his initial response
> provides the necessary starting point. Have you tried it?
Eric Legault [MVP - Outlook] - 23 Sep 2005 15:18 GMT
I see your point - you want to get folder a folder by name, regardless of its
location.  But this approach is flawed because of the underlying data model
of MAPI - folders and items can exist with duplicate names.  From a database
perspective, you would like to return a record regardless of which table it
is stored in.  But guess what - you can't do it without looping through all
of the tables and building recordsets for each.  And from the MAPI
perspective, Folders are essentially tables.  Even with ADO you cannot search
for a table without doing something like searching records in system tables
if you use SQL Server (AFAIK).  Anyway, I think you get my point.

But judging from your requirements, you simply want to create/delete
Appointments somewhere other than the default Calendar - but you don't know
*where*,  correct?  If so, then use the NameSpace.PickFolder method to
present the user with a dialog to choose the location, then pass the returned
MAPIFolder object to your procedure.  Otherwise, if you do know where the
folder is, then use the OpenMAPIFolder function I provided earlier and pass
it the full path of the folder.  If you only know a fraction of the path,
then you know how many levels deep you can start with looping code before you
must call a recursive style method to loop down the tree until the end or
until the folder you are searching for is located.

Signature

Eric Legault (Outlook MVP, MCDBA, old school WOSA MCSD, B.A.)
Try Picture Attachments Wizard for Outlook:
http://www.collaborativeinnovations.ca
Blog: http://blogs.officezealot.com/legault/

> I didn't have any subfolders setup when I ran it nor did I have multiple
> *.pst files open. I'm going back to my originall opinion that it
[quoted text clipped - 73 lines]
> > It seems to me that Eric's "RecurseFolders()" in his initial response
> > provides the necessary starting point. Have you tried it?
David C. Holley - 23 Sep 2005 16:10 GMT
Yeah that's pretty much it. I had already factored in the issue with
multiple folders. The idea was to go through the folders and if the
folder name matched the only supplied (and probably has the correct
DefaultItemType(property name?) and .ItemCount > 0) then check the
folder. Since my last post, I'm now thinking about storing the target
folder EntryId in a table that I use for system/default values. From
there I'd use the .GetFolderByEntryId to grab it, if the method fails
then I'd use the .PickFolder method to have the user find the folder and
update the system/default table accordingly. The DB example doesnt'
really apply unless you have multiple tables storing the exact data
(breaking 1 of the basic rules of having a relational DB). At any rate
it has been a nice learing experience.

> I see your point - you want to get folder a folder by name, regardless of its
> location.  But this approach is flawed because of the underlying data model
[quoted text clipped - 16 lines]
> must call a recursive style method to loop down the tree until the end or
> until the folder you are searching for is located.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.