如何为 MS Project VBA 中的前辈编写自己的过滤器?

How to write my own filter for predecessors in VBA for MS Project?

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

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

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

我想在 VBA 中编写一个过滤器,这样它只会向我显示所选任务的已连接前置任务和后续任务。

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

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

期待前辈的前辈,等等。

希望有人能帮助我。

从 MS Project 2013 开始,有一项功能可以突出显示 活动任务的前置任务和后续任务(有关详细信息,请参阅末尾)。

但是,隐藏所有未链接到特定任务的任务需要代码。幸运的是 PredecessorTasks and SuccessorTasks 集合对象可以轻松完成这项工作。

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

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

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

仅供参考:突出显示功能位于“格式”选项卡上的“任务路径”下(查看甘特图视图时)。您可以 select 突出显示前任、驱动前任(仅限当前影响日期的前任)、后继者、and/or 受驱动后继者。这是 documentation.

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

我的代码在项目字段 "Text10"(您可以使用任何其他文本字段)中使用简单的 "Yes" 标记所有前任,然后我使用 [=26 过滤所有任务=].

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" 并筛选 "Yes"。