【问题标题】:VBA Try and Catch (MS Outlook)VBA 尝试和捕捉 (MS Outlook)
【发布时间】:2015-05-12 10:47:01
【问题描述】:

我使用以下功能来监视公共 Outlook 文件夹是否有新电子邮件到达:

Public Sub Application_Startup()

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

End Sub

由于某种原因,此公用文件夹的路径每周都会随着时间而变化。变化的是.Folders(3) 中的数字。它从 1 到 3 不等。 显然,为了保持函数正常工作并捕获错误,当路径发生变化时,我想实现一个 try and catch 函数,例如:

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

由于我是 VBA 新手,我正在努力实现这个 Try and Catch 函数。谁能协助处理 Outlook 中的 VBA 代码?

我认为我刚刚设法实施的一种解决方案是:

For i = 1 To 3

    On Error Resume Next

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

Next i

【问题讨论】:

  • Application.GetNamespace("MAPI").FoldersCount 属性吗?在这种情况下,您可以使用 Set NewMail = Application.GetNamespace("MAPI").Folders(Application.GetNamespace("MAPI").Folders.Count).Folders(2)
  • 你可以在 VBA 中模拟一个 TRY CTACH 块请看这里stackoverflow.com/q/30991653/4413676

标签: vba outlook try-catch


【解决方案1】:

VBA 中的错误处理基于 On Error 语句。以下文章解释了如何处理 VBA 中的错误:

Try/Catch 块用于加载项。

注意,您可以使用NameSpace.GetDefaultFolder 方法获取Exchange 公共文件夹存储中的所有公共文件夹文件夹。您只需要传递 olPublicFoldersAllPublicFolders 值。请参阅以下页面上的示例代码:

【讨论】:

    【解决方案2】:

    您可以通过首先检查文件夹集合的计数属性来避免错误,例如:

    Set NewMail = Application.GetNamespace("MAPI").Folders(Application.GetNamespace("MAPI").Folder‌​s.Count).Folders(2)
    

    【讨论】:

      【解决方案3】:

      VB(A) 没有结构化的错误处理,因此它没有 try 和 catch 语句。

      如果您希望语句失败,On Error Resume Next 和下面的 If Err.Number <> 0 Then ... 检查是要走的路。最好将On Error Resume Next 涵盖的代码部分保持在绝对最低限度。您不想默默地吞下意外的运行时错误,因为这会导致令人讨厌且难以发现的错误。

      当然,以故障安全方式编写代码是另一种可能性。

      如您所见,按编号对 Folders 集合进行索引并不是万无一失的。通常应避免将数字索引到未知的项目集合中。幸运的是,Folders 集合允许按名称进行索引。 .Folders("Foo").Folders(3)很多

      当然可能没有名为"Foo" 的子文件夹,但可以通过On Error 处理。

      这是使用path(反斜杠分隔,不包括\\Public Folders - mailbox name\All Public Folders\ 部分)的替代方法:

      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
      

      这样使用

      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
      

      【讨论】:

      • 请不要向人们推荐On Error Resume Next。我相信您了解如何正确使用它,但很少有人真正了解它的工作原理。 Cargo cult 程序员复制/粘贴这些东西,然后想知道为什么他们的代码会出现意外。
      • @RubberDuck 如果您知道在 VBA 中处理预期错误的任何其他方法,请赐教。 :) 除此之外 - 我在我的答案文本中提出了充分的警告。对于无私的复制/粘贴程序员,我几乎无能为力。
      • 另外,当推荐On Error Resume Next 时,请确保关键的On Error Goto 0 将被执行。在您的代码中,如果Err.Number &lt;&gt; 0 条件为true,则将跳过On Error Goto 0。将 On Error Goto 0 移动到 Exit For 之前应该可以解决问题。
      • @FreeMan On Error 具有过程范围。子/函数退出时会自动重置。
      • 是的@Tomalak。我知道这样做的 惯用 方式。我们不应该试图将新范式强加于旧语言。 This code review answer of mine 覆盖得很好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 2010-11-23
      • 2013-08-04
      • 2014-12-27
      相关资源
      最近更新 更多