2

I use the following function to monitor a public Outlook folder for new E-Mails to arrive:

Public Sub Application_Startup()

   Set NewMail = Application.GetNamespace("MAPI").Folders(3).Folders(2)....

End Sub

For some reason, the path to this public folder changes over time in a weekly period. What changes is the number in .Folders(3). It varies from 1 to 3. Apparently, to keep the function working and to catch the error, when the path changes, I want to implement a try and catch function such as:

Try {
    Set NewMail = Application.GetNamespace("MAPI").Folders(1).Folders(2)....
Catch Error

Try {
    Set NewMail = Application.GetNamespace("MAPI").Folders(2).Folders(2)....
Catch Error

Try {
    Set NewMail = Application.GetNamespace("MAPI").Folders(2).Folders(2)....
Catch Error

Since I am new to VBA I am struggeling implementing this Try and Catch function. Can anyone assist with VBA code in Outlook?

I think one solution I just manage to implement is:

For i = 1 To 3

    On Error Resume Next

    Set NewMail = Application.GetNamespace("MAPI").Folders(i).Folders(2)....

Next i
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user969113
  • 2,349
  • 10
  • 44
  • 51
  • Does `Application.GetNamespace("MAPI").Folders` have a `Count` property? in which case you could use `Set NewMail = Application.GetNamespace("MAPI").Folders(Application.GetNamespace("MAPI").Folders.Count).Folders(2)` – Patrick McDonald May 12 '15 at 11:17
  • 1
    possible duplicate of [Good Patterns For VBA Error Handling](http://stackoverflow.com/questions/1038006/good-patterns-for-vba-error-handling) – RubberDuck May 12 '15 at 14:07
  • You can simulate a TRY CTACH block in VBA Please see here http://stackoverflow.com/q/30991653/4413676 – HarveyFrench Jun 22 '15 at 23:45

3 Answers3

4

Error handling in VBA is based on the On Error statement. The following articles explains how to handle errors in VBA:

Try/Catch blocks is for add-ins.

Note, you can use the NameSpace.GetDefaultFolder method to get the All Public Folders folder in the Exchange Public Folders store. You just need to pass the olPublicFoldersAllPublicFolders value. See the sample code on the following pages:

Community
  • 1
  • 1
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
1

You can avoid the Error by checking the Count property of the Folders Collection first, for example:

Set NewMail = Application.GetNamespace("MAPI").Folders(Application.GetNamespace("MAPI").Folder‌​s.Count).Folders(2)
Patrick McDonald
  • 64,141
  • 14
  • 108
  • 120
0

VB(A) does not have structured error handling, therefore it does not have try and catch statements.

If you expect a statement to fail, On Error Resume Next with a following If Err.Number <> 0 Then ... check is the way to go. It's best to keep the sections of code that are covered by On Error Resume Next to an absolute minimum. You don't want to silently swallow unexpected run-time errors, as this causes nasty and hard-to-find bugs.

Of course writing code in a fail-safe manner is another possibility.

Indexing into the Folders collection by number is not fail-safe, as you have noticed. Indexing numerically into an unknown collection of items should generally be avoided. Lucky for you the Folders collection allows indexing by name. .Folders("Foo") is a lot better than .Folders(3).

Of course there might be no subfolder named "Foo", but that can be handled via On Error.

Here is an alternative approach that uses a path (backslash-separated, not including the \\Public Folders - mailbox name\All Public Folders\ part):

Function GetPublicFolderByPath(path As String) As Folder
  Dim parent As Folder, part As Variant

  Set parent = GetNamespace("MAPI").GetDefaultFolder(olPublicFoldersAllPublicFolders)

  For Each part In Split(path, "\")
    On Error Resume Next
    Set GetPublicFolderByPath = parent.Folders(part)

    If Err.Number <> 0 Then
      Set GetPublicFolderByPath = Nothing
      Exit For
    End If

    On Error GoTo 0
  Next part
End Function

Use like this

Dim f As Folder
Set f = GetPublicFolderByPath("Folder A\Folder B\Folder C")

If f Is Nothing Then
    ' not found
Else
    ' use f
End If
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 2
    Please don't recommend `On Error Resume Next` to people. I'm sure you understand how to use it properly, but very few people actually understand how it works. Cargo cult programmers copy/paste this stuff and then wonder why their code is acting unexpectedly. – RubberDuck May 12 '15 at 14:06
  • @RubberDuck If you know of *any* other way of dealing with an expected error in VBA, please enlighten me. :) Other than that - I put ample warning in my answer text. I can hardly do anything about disinterested copy/paste programmers. – Tomalak May 12 '15 at 14:18
  • Also, when recommending `On Error Resume Next` be sure that the critical `On Error Goto 0` will be executed. In your code, the `On Error Goto 0` will be skipped if the `Err.Number <> 0` condition is `true`. Moving `On Error Goto 0` to just before the `Exit For` should do the trick. – FreeMan May 12 '15 at 14:18
  • @FreeMan `On Error` has procedure scope. It will reset automatically when the Sub/Function exits. – Tomalak May 12 '15 at 14:19
  • Yeah @Tomalak. I'm aware of an *idiomatic* way to do it. We shouldn't try to force new paradigms on old languages. [This code review answer of mine](http://codereview.stackexchange.com/a/52231/41243) covers it pretty well. – RubberDuck May 12 '15 at 14:22
  • @RubberDuck Sorry, but I don't consider `On Error Goto X` in any way better than `On Error Resume Next`. In fact, it's worse, because you have no control over which lines are allowed to fail. Been there, done that, didn't like it. (Note that I explicitly don't recommend putting `On Error Resume Next` as a global setting here, we agree that this is bad practice to say the least.) – Tomalak May 12 '15 at 14:25
  • @RubberDuck Also, about the "new paradigms on old languages" part. I don't understand what that means. I'm using a built-in, documented language feature in the way and for a task that it has been designed for. There is no "new paradigm" anywhere in my answer. – Tomalak May 12 '15 at 14:28
  • I'm not going to argue with you. It works for you. Awesome. I've just seen it bite far too many people to ever recommend `Resume Next` to anyone, ever. The CR link I shared explains that this pattern is trying very sincerely to emulate a `Try...Catch`. That's the .Net way to do it. IMHO it's much better to do it the VB6 way while we're working in VB6. Although, I'd bash just as hard on someone using `On Error GoTo` in .Net. When in Rome, do as the Romans. – RubberDuck May 12 '15 at 14:35
  • @RubberDuck Fair enough. It's a convention to use `GoTo`, and I've come to dislike it. I like my functions to crash and burn for any error condition that I did not anticipate while still allowing errors that I *did* anticipate. I even go as far as checking individual error numbers here. `On Error GoTo X` does the former, but not the latter part. I did use `On Error Resume Next` in quite a few VBA answers of mine, but never without explicit, lengthy warnings about its negative effect when used carelessly. I can't help it if people are willfully careless. – Tomalak May 12 '15 at 14:42
  • Who said anything about not checking error numbers? I do that too! Guess we'll just have to agree to disagree. ;) – RubberDuck May 12 '15 at 16:04
  • You can simulate a TRY CATCH block in VBA Please see here http://stackoverflow.com/q/30991653/4413676 – HarveyFrench Jun 22 '15 at 23:51