【问题标题】:How to write my own filter for predecessors in VBA for MS Project?如何在 VBA for MS Project 中为前辈编写我自己的过滤器?
【发布时间】:2019-11-12 08:53:31
【问题描述】:

我目前正在设置一个 GAANT 图表来确定一个大型项目的运行时间和依赖关系。

有超过 600 个任务。它们相互依赖,但不幸的是不是以线性和聚集的方式。

我可以为一项任务的前任和继任者着色。但是,因为中间还有其他任务,我需要滚动很多才能到达下一个连接的任务。

我想在 VBA 中编写一个过滤器,以便它只显示所选任务的连接的前任和继任者。

到目前为止,我什至不知道如何编写一个简单的过滤器,因为关于过滤器的在线文档非常差。

应用普通过滤器不起作用,因为它只会给我直接的前任和继任者。

我期待前辈的前辈,等等。

我希望有人可以帮助我。

【问题讨论】:

    标签: vba ms-office ms-project


    【解决方案1】:

    我在 google 的帮助下找到了解决方案。这是一种解决方法。

    我的代码在项目字段“Text10”(您可以使用任何其他文本字段)中用简单的“是”标记所有前辈,然后用“是”过滤所有任务。

    Dim ProjTasks As Tasks
    Dim ProjTasks2 As Task
    Dim ProjTasks3 As Tasks
    Dim ProjTask As Task
    Dim ProjTask2 As Task
    Dim ProjTask3 As Task
    
    Dim Deadline As String
    
    Set ProjTasks = ActiveProject.Tasks
    Set ProjTasks2 = ActiveProject.Tasks
    Set ProjTasks3 = ActiveProject.Tasks
    

    所以这里是我的代码的主要部分:

     For Each ProjTask In ProjTasks
            If ProjTask.Start < (DateValue(Deadline) + TimeValue(Deadline)) Then
                For Each ProjTask2 In ProjTasks2
                    If ProjTask2.Start < (DateValue(Deadline) + TimeValue(Deadline)) Then
                    If Not (ProjTask2 Is Nothing) Then
                        If ProjTask2.Text10 = "YES" Then
                            PredArray() = Split(ProjTask2.Predecessors, ";")
                            For Each i In PredArray()
                                For Each ProjTask3 In ProjTasks3
                                    If ProjTask3.Start < (DateValue(Deadline) + TimeValue(Deadline)) Then
                                    If ProjTask3.ID = i Then
                                        ProjTask3.Text10 = "YES"
                                    End If
                                    End If
                                Next ProjTask3
                            Next i
                        End If
                    End If
                    End If
                Next ProjTask2
            End If
        Next ProjTask
    

    因为它包含 3 个 for-loops 我试图最小化循环的任务数量。

    因为我可以看到我的目标任务何时结束 (Deadline),所以我不会循环开始时间晚于目标任务结束时间的任务。

    请注意,该代码需要一些时间才能运行。代码运行后,您可以转到“Text10”列并过滤“是”。

    【讨论】:

    • 仅供参考:如果任何任务链接包含滞后、非 FS 链接类型或指向外部项目的链接,此代码将失败。这些场景在大型计划中非常常见。最好使用 PredecessorTasks 和 SuccessorTasks 属性,而不是尝试拆分 Predecessors 和 Successors 字段。
    【解决方案2】:

    从 MS Project 2013 开始,有一个突出显示活动任务的前身和后继者的功能(详见末尾)。

    但是,隐藏所有未链接到特定任务的任务需要代码。幸运的是,PredecessorTasksSuccessorTasks 集合对象可以轻松解决此问题。

    此代码查找链接到目标任务的所有任务(在本例中为活动任务)并设置一个标志 (Text10='Yes'),以便可以过滤掉未链接的任务。代码只接触与目标任务相关联的任务,并且每次只接触一次,因此运行速度非常快。

    可以轻松修改代码以使用不同的目标任务并添加条件,例如跳过已完成的任务。

    Sub FlagTasksLinkedtoTargetTask()
    
        Dim tsk As Task
        For Each tsk In ActiveProject.Tasks
            tsk.Text10 = vbNullString
        Next tsk
    
        Dim TargetTask As Task
        Set TargetTask = Application.ActiveCell.Task
    
        FlagPredecessors TargetTask
        FlagSuccessors TargetTask
    
    End Sub
    
    Sub FlagPredecessors(tsk As Task)
    
        Dim pred As Task
        For Each pred In tsk.PredecessorTasks
            If pred.Text10 <> "Yes" Then
                pred.Text10 = "Yes"
                FlagPredecessors pred
            End If
        Next pred
    
    End Sub
    
    Sub FlagSuccessors(tsk As Task)
    
        Dim succ As Task
        For Each succ In tsk.SuccessorTasks
            If succ.Text10 <> "Yes" Then
                succ.Text10 = "Yes"
                FlagSuccessors succ
            End If
        Next succ
    
    End Sub
    

    仅供参考:突出显示功能位于“格式”选项卡上的“任务路径”下(查看甘特图视图时)。您可以选择突出显示 Predecessors、Driving Predecessors(仅限当前影响日期的那些)、Successors 和/或 Driven Successors。这是documentation

    【讨论】:

    • 嗨,瑞秋,这不是我要找的。您的解决方案仅突出前辈和后继者。但我想过滤掉所有与我的任务没有关联(以任何方式)的任务。
    • @Peter,没问题。大多数时候,当人们想看到前任/继任者时,这个突出显示的功能效果很好。我更新了答案,以提供一个快速、强大的解决方案来过滤掉所有未链接到给定任务的任务。
    猜你喜欢
    • 1970-01-01
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 1970-01-01
    相关资源
    最近更新 更多