MS Project VBA - 当过滤器不返回任何内容时如何避免错误

Posted

技术标签:

【中文标题】MS Project VBA - 当过滤器不返回任何内容时如何避免错误【英文标题】:MS Project VBA - how to avoid errors when a filter returns nothing 【发布时间】:2021-12-12 01:59:02 【问题描述】:

我的代码将过滤器应用于项目(仅显示下周特定资源的活动),我需要捕获过滤器不返回任何内容的实例。

我找到了这个article,它导致了这个MS Entry。从这里我想出了测试:

If ActiveSelection.Tasks Is Nothing Then GoTo NextResource

退出当前资源循环并转到下一个,但是,这不起作用。错误 (424) 仅在我尝试使用 ActiveSelection 时生成

上下文的代码片段:

For Each Resource In Proj.Resources
    If Not (Resource Is Nothing) Then
    If Resource.Work > 0 Then
     'setup and apply filter for each resource
     FilterEdit name:="filter4people", TaskFilter:=True, Create:=True, OverwriteExisting:=True, FieldName:="Start", Test:="is less than or equal to", Value:=finish, ShowInMenu:=True, ShowSummaryTasks:=True
     FilterEdit name:="filter4people", TaskFilter:=True, FieldName:="", NewFieldName:="% Complete", Test:="is less than", Value:="100%", Operation:="And", ShowSummaryTasks:=True
     FilterEdit name:="filter4people", TaskFilter:=True, FieldName:="", NewFieldName:="Resource names", Test:="contains", Value:=Resource.name, Operation:="And", ShowSummaryTasks:=True
         
     FilterApply "filter4people" ' apply the filter
        If Not (Err.Number = 91 Or Err.Number = 0) Then            ' saw an error applying filter
             Err.Clear                   ' clear out the error
             GoTo NextResource           ' jump to the next resource
         End If

    Application.SelectSheet 'need to select the sheet so that ActiveSelection works properly
    
    'CStr(ActiveSelection.Tasks.Count)
    If ActiveSelection.Tasks Is Nothing Then GoTo NextResource

【问题讨论】:

听起来 ActiveSelection 没什么,所以你的代码也应该检查这个。 @BrianMStafford,输入If ActiveSelection Is Nothing Then GoTo NextResource 并没有改变行为。 Err.number 保持在 0 并且代码继续像以前一样失败 然而,进一步的测试表明,在一种测试情况下,它确实返回了 0 而不是什么也没有。这是有希望的,我会做更多的测试来确认它是否可以按需工作。 【参考方案1】:

您的问题是 ActiveSelection 对象无法解析 .Tasks 属性,如果没有任务符合所应用过滤器的条件。我不喜欢将 GoTos 用于不是 VBA 中的错误处理程序的任何内容,因此我建议创建一个单独的函数来检查过滤器中是否有任何任务:

Public Function CurrentFilterHasTasks() As Boolean

   Dim result As Boolean
   On Error GoTo ErrHandler

   Application.SelectAll 'select everything in the current filter

   'Application.ActiveSelection.Tasks will fail if there are only blank rows in the active selection
   If Application.ActiveSelection.Tasks.Count > 0 Then
        result = True
   End If

   CurrentFilterHasTasks = result

   'call exit function here so the code below the error handler does not run
   Exit Function

ErrHandler:
   result = False
   CurrentFilterHasTasks = result
    
End Function

现在你可以在你的代码中调用这个函数了:

For Each Resource In Proj.Resources
    If Not (Resource Is Nothing) Then
        If Resource.Work > 0 Then
         'setup and apply filter for each resource
         FilterEdit Name:="filter4people", TaskFilter:=True, Create:=True, OverwriteExisting:=True, FieldName:="Start", test:="is less than or equal to", Value:=Finish, ShowInMenu:=True, ShowSummaryTasks:=True
         FilterEdit Name:="filter4people", TaskFilter:=True, FieldName:="", NewFieldName:="% Complete", test:="is less than", Value:="100%", Operation:="And", ShowSummaryTasks:=True
         FilterEdit Name:="filter4people", TaskFilter:=True, FieldName:="", NewFieldName:="Resource names", test:="contains", Value:=Resource.Name, Operation:="And", ShowSummaryTasks:=True
             
         FilterApply "filter4people" ' apply the filter
         
         If Not (Err.Number = 91 Or Err.Number = 0) Then ' saw an error applying filter
             Err.Clear                   ' clear out the error
             GoTo NextResource           ' jump to the next resource
         End If
        
        ''''' Calling the new function ''''''
        If CurrentFilterHasTasks Then
            'whatever you want to do with the filtered tasks here
        End If

此外,我可能会卸载您的代码以创建过滤器并将其应用到它自己的方法中,这样您就可以检查其中的任何错误,而不是您的主要方法。

【讨论】:

感谢您的解决方案肯尼,快速提问;应该 res = False 读取 Result = False 吗?关于将事物放入函数的学习非常有趣,我一直认为函数对于重复代码很有用,但使用它们来隔离错误是一个有趣的学习,谢谢:) @Miles 是的,res = False 应该是 result = False。我的错字。我已经编辑了帖子以反映这一点。放弃你所说的关于函数的内容——如果你认为有机会在你正在构建的任何东西中重复一段代码块,那么创建它们是很好的,不仅是现在,而且在未来。我可以设想许多用例,您希望检查过滤器中是否有任务。

以上是关于MS Project VBA - 当过滤器不返回任何内容时如何避免错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 VBA 将文件添加到 MS-Project 任务注释字段

如何禁用 MS Project VBA 中的另存为按钮?

如何使用VBA代码从ms-project的另一列中的文本中自动添加文本

MS Access 2016 VBA 导致“输入参数值”窗口

如何在 ms-access 2007 VBA 中计算 mod 97

访问过滤器 VBA