Macro for Filtering based on “Task Path” in Microsoft Project

Here in the TaskPathFilters module, I provide five simple macros for applying a filter (or table highlighting) that corresponds to Task Path bar highlighting output.

For users of Microsoft Project 2013+, including the desktop versions of Project for Office 365, the Task Path bar styles provide a useful method for highlighting logical connections between tasks.  Four different sets of bar styles can be created, corresponding to the Predecessors, Driving Predecessors, Successors, and Driven Successors of the selected task.  Unfortunately, the “show for…” criteria used to apply the bar styles are not available for creating a filtered display of tasks – say the driving path to a key milestone – while hiding the non-driving tasks.

[The “driving” and “driven” Task Paths are defined (by MSP) using the task StartDriver object, the same as in the Task Inspector.  As shown here, StartDriver has proven unreliable in identifying driving logic in the presence of non-FS relationships, actual progress, splits, and resource leveling.

In another blog entry here, you can find a set of macros for duplicating the results of the Task Path bars, with the added benefit of being able to re-sort tasks according to logic flow, so concurrent logic paths are easily separated.  Those macros use the same underlying data as Task Paths, so their results should be identical to these.  Unlike these, they can be used in versions of MSP prior to 2013.]

Here’s the code (requires MSP 2013+).

Note, for real logic analysis, have a look at BPC Logic Filter.

'TaskPathFilters Module
'This module includes five procedures to mark tasks according to their TaskPath
'characteristics.  A sixth procedure applies a filter to display only the marked tasks.
'The module is intended only for users of Microsoft Project 2013+, which incorporates TaskPath
'formatting of task bars.  If the applicable TaskPath formatting has not been applied,
'then no filter will be created.  VBA code developed by TMBoyle, 14Sep'18
'   1. Install all code into a new module, with "TaskPathFilters Module" above as the top line.
'   2. Assign buttons or hotkeys to the first five procedures only (the other one is called by these):
        'a. AllTaskPathFilter() - Filters all the marked task paths.
        'b. TaskPathPredecessorFilter() - Filters the marked "predecessors" of the selected task.
        'c. TaskPathDrivingPredecessorFilter() - Filters the marked "driving predecessors" of the selected task.
        'd. TaskPathSuccessorFilter() - Filters the marked "successors" of the selected task.
        'e. TaskPathDrivenSuccessorFilter() - Filters the marked "driven successors" of the selected task.
'
Public MsgBase As String, Tsel As Task
Sub AllTaskPathFilter()
    Dim t As Task
    Dim Apply As Boolean
    
    Set Tsel = ActiveCell.Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If (t.PathPredecessor = True) Or (t.PathDrivingPredecessor = True) Or _
                (t.PathSuccessor = True) Or (t.PathDrivenSuccessor = True) Then
                t.Marked = True
                Apply = True
            Else
                t.Marked = False
            End If
        End If
    Next t
    Tsel.Marked = "Yes"
    If Apply Then
        MarkedFilter
        MsgBox (MsgBase & "All Selected for task " & vbCrLf & _
            Tsel.ID & " - " & Tsel.Name)
    Else
        MsgBox "No Filter Applied."
    End If
End Sub
Sub TaskPathPredecessorFilter()
    Dim t As Task
    Dim Apply As Boolean
    
    Set Tsel = ActiveCell.Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If t.PathPredecessor = True Then
                t.Marked = True
                Apply = True
            Else
                t.Marked = False
            End If
        End If
    Next t
    Tsel.Marked = "Yes"
    If Apply Then
        MarkedFilter
        MsgBox (MsgBase & "Predecessors of task " & vbCrLf & _
            Tsel.ID & " - " & Tsel.Name)
    Else
        MsgBox "No Filter Applied."
    End If
End Sub

Sub TaskPathDrivingPredecessorFilter()
    Dim t As Task
    Dim Apply As Boolean
    
    Set Tsel = ActiveCell.Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If t.PathDrivingPredecessor = True Then
                t.Marked = True
                Apply = True
            Else
                t.Marked = False
            End If
        End If
    Next t
    Tsel.Marked = "Yes"
    If Apply Then
        MarkedFilter
        MsgBox (MsgBase & "Driving Predecessors of task " & vbCrLf & _
            Tsel.ID & " - " & Tsel.Name)
    Else
        MsgBox "No Filter Applied."
    End If
End Sub

Sub TaskPathSuccessorFilter()
    Dim t As Task
    Dim Apply As Boolean
    
    Set Tsel = ActiveCell.Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If t.PathSuccessor = True Then
                t.Marked = True
                Apply = True
            Else
                t.Marked = False
            End If
        End If
    Next t
    Tsel.Marked = "Yes"
    If Apply Then
        MarkedFilter
        MsgBox (MsgBase & "Successors of task " & vbCrLf & _
            Tsel.ID & " - " & Tsel.Name)
    Else
        MsgBox "No Filter Applied."
    End If
End Sub

Sub TaskPathDrivenSuccessorFilter()
    Dim t As Task
    Dim Apply As Boolean
    
    Set Tsel = ActiveCell.Task
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If t.PathDrivenSuccessor = True Then
                t.Marked = True
                Apply = True
            Else
                t.Marked = False
            End If
        End If
    Next t
    Tsel.Marked = "Yes"
    If Apply Then
        MarkedFilter
        MsgBox (MsgBase & "Driven Successors of task " & vbCrLf & _
            Tsel.ID & " - " & Tsel.Name)
    Else
        MsgBox "No Filter Applied."
    End If
End Sub

Sub MarkedFilter()
Dim HL As Boolean

    If MsgBox("Apply Highlighting Only?", vbYesNo) = vbYes Then
        HL = True
        MsgBase = "Highlighting TaskPath "
    Else
        MsgBase = "Filtered for TaskPath "
    End If
    On Error Resume Next
    FilterApply Name:="Marked Tasks", Highlight:=HL
    If Err.Number <> 0 Then
        FilterEdit Name:="Marked Tasks", TaskFilter:=True, Create:=True, OverwriteExisting:=True, _
           FieldName:="Marked", Test:="equals", Value:="Yes", ShowInMenu:=True, ShowSummaryTasks:=True
        FilterApply Name:="Marked Tasks", Highlight:=HL
    End If
    EditGoTo ID:=Tsel.ID
End Sub


8 thoughts on “Macro for Filtering based on “Task Path” in Microsoft Project”

  1. I edited the code to allow highlighting the marked tasks rather than the default hiding of un-marked tasks. This allows easier verification of results and provides similar output to the referenced macro that doesn’t require MSP 2013+.

  2. I added a consolidated procedure “AllTaskPathFilter(),” which marks and displays any task that would be included in any of the four bar style groups. This single consolidated filter can then be used in combination with the selective application of the filter bar styles.

  3. The macro unfortunately does work for projects with external predecessors or successors in Project Online. Is it possible to correct this? It would be very usefull?

    1. Hi Peter. Thanks for the question. Task Paths simply don’t work in multi-project scenarios, so a filter based on them won’t work either. A macro-based workaround might be done by combining the QuickTrace macros with a robust external-task handler. Achieving a general-purpose version of that second part isn’t easy, so it requires the Pro Edition of BPC Logic Filter (our logic-analysis add-in). You might want to give that a try. Alternately, a fellow named Malcolm Farrelle shared some fairly simple code (on LinkedIn, around 2015-2016) that would trace logic through external tasks under the right conditions. Good luck, tom

  4. I’m using Project Server 2016. Driving Predecessor was working great & has recently stopped working. I’m now getting the “No Filter Applied” message. However, if I use the MS Project icon button “Highlight Driving Predecessors” , driving predecessors are highlighted & then run the macro and driving predecessors are filtered. I’m not sure why this is happening- any insight?

    1. Mark,
      These macros only work if the corresponding task path functionality has been enabled locally.
      I.e. If “Highlight: Driving Predecessors” has been enabled in the “Task Path” group on the “Gantt Chart Format” ribbon, then the “TaskPathDrivingPredecessorFilter()” macro will work. Otherwise the macro will return “No Filter Applied.”
      The highlighting of the ribbon icons are not foolproof in indicating whether the particular task path functionality is actually enabled. You sometimes need to enable/disable several times and confirm that the corresponding bar styles are added, removed, and added back. Good luck.

  5. Fantastic content. Thank you so much. My Planning team thinks I’m a rock star today and all I did was copy your text into a new Module.

Leave a Reply

Your email address will not be published. Required fields are marked *