Video – Analyze the Near-Longest Paths in Microsoft Project using BPC Logic Filter

In the presence of Deadlines, Constraints, variable Calendars, and resource leveling, Total Slack becomes unreliable as an indicator of the Critical Path (or of nearness to the Critical Path).  For projects where the project completion is designated by the last task in the schedule, I use the Near Longest Path Filter to keep an eye on next week’s concerns….

See also a related blog entry: Tracing Near Longest Paths with BPC Logic Filter

Video – Find the Longest Path in Microsoft Project Using BPC Logic Filter

In the presence of Deadlines, Constraints, variable Calendars, and resource leveling, Total Slack becomes unreliable as an indicator of the Critical Path.  For projects where the project completion is designated by the last task in the schedule, I use the Longest Path Filter to identify the Critical Path….

For more information and some background, have a look at this entry:  What is the Longest Path in a Project Schedule

Video – Using BPC Logic Filter to Analyze Resource-Leveled Critical Path

Here’s another video of BPC Logic Filter in action – this time revisiting the themes of  previous blog entry:  The Resource Critical Path

 

Tracing Near Longest Paths with BPC Logic Filter

This article highlights the creation of a new targeted report from BPC Logic Filter to identify the “Near Longest Paths” of a project.

While BPC Logic Filter was originally developed as a pure logic tracer, I added a few targeted reports early on to reflect some specific needs, including the “Longest Path Filter” and the “Local Network Filter.”  This article highlights the creation of a new targeted report to identify the “Near Longest Paths” of a project.

Often, when presented with a new project schedule in Microsoft Project, my first step (in concert with a logic health check) has been to run a Longest Path Filter analysis using BPC Logic Filter.  This report quickly and clearly identifies the driving path to project completion.  While the resulting filtered task list is useful for reporting, it rarely satisfies the needs of a serious analysis.  The second step, therefore, is to identify the associated near-longest-paths of the project by running a “Task Logic Tracer” predecessor analysis – with a positive relative float limit – for the project completion task.  The result is a clear description of the driving and near-driving paths to project completion.  The latest release of BPC Logic Filter adds a specific command to combine these two actions and generate a single “Near Longest Path Filter” for the project.

The mechanics are pretty simple.  As usual – with a Gantt view active in a project that contains logic – just open the Add-Ins ribbon [changed to the BPC ribbon in subsequent versions] and click on the button for “Near Longest Path Filter.”

bpclogicfilter-ribbongroup1611

The add-in will initialize, and the user is given a choice of modifying the default analysis parameters.  Some of the parameters are pre-set and can’t be changed here.  The key parameter for a formal Near-Longest-Path analysis is the Relative Float Limit, highlighted below.  Any related task with a Path Relative Float that is less than the specified limit will be included in the filter; all others will be ignored and considered unrelated.  The default value is 100 days away from the driving/longest path (which can be changed in the Settings).

bpclogicfilter-near-longest-path-window

The standard output for a simple project (using the parameters selected above) is provided here.  Selecting “Re-Color Bars” instructs the add-in to generate the custom output shown, including the header, the legend, and five different bar colors depending on proximity to the Longest Path.  Thresholds for applying these bar colors can be manually adjusted in the program settings or, if desired, automatically adjusted by the add-in.  nlp_tensixexampleltr

Here’s an alternate view showing the Near Longest Paths in-line in the context of an existing Outline/WBS organization.  In this analysis I reduced the Relative Float Limit from 100 to 20 days, and the three tasks at the bottom of the earlier figure were ignored.  Here they are given a green “BPC Unrelated Task” bar.

nlp_tensixexampleinlineltr

While I’ve always hated redundant work, this particular improvement to BPC Logic Filter was kick-started by my recent review of the draft of “Analyzing Near-Critical Paths,” a pending Recommended Practice from AACE International.  The new draft recommended practice is based largely on the previously-published (2010) Recommended Practice 49R-06 – Identifying the Critical Path.  According to both documents, Critical- and Near-Critical paths may be identified on the basis of total float/slack thresholds (in the absence of variable calendars, constraints, or other complicating factors) and – when total float/slack does not suffice – “closeness to the longest path.”  For the latter cases, 49R-06 suggests two methods of analysis:

  • Longest Path Value – a metric that appears similar to Path Relative Float (in BPC Logic Filter) for the project completion task. This metric has been applied as an add-on to Oracle Primavera scheduling tools: See Ron Winter’s Schedule Analyzer.
  • Multiple Float Path analysis. Like the Longest Path Value, Multiple Float Path analysis is primarily associated with Oracle’s Primavera scheduling tools – it is presented as an advanced scheduling option in P6.  As I’ve noted in Beyond the Critical Path – multiple float path analysis indicates closeness to the longest path without explicitly measuring and presenting it.  Detailed examination of the results, including relationship free floats, is necessary to determine the apparent relative float of each activity.

From its start, BPC Logic Filter has supported a similar analysis for Microsoft Project schedules through its Path Relative Float metric, Multiple-Float-Paths views, and other reporting.  The new “Near Longest Path Filter” offers a single-step approach to identifying and analyzing near-critical paths in the presence of variable calendars, constraints, and other complicating factors – when Total Slack becomes unreliable as an indicator of logical significance.

See also Video:

Video – Analyze the Near-Longest Paths in Microsoft Project using BPC Logic Filter

 

A Logic Tracing Example in Microsoft Project

This article uses BPC Logic Filter to present the progression of a single logic tracing example from a simple approach to a more focused analysis. [June 2020: revised for updated versions of MS Project and BPC Logic Filter.]

[If you came here looking for a simple logic tracing macro and are comfortable using Visual Basic for Applications (VBA), have a look at these two other entries: Macro for tracing filtering and sorting task paths in Microsoft Project and Simple Macro for Listing Driving Predecessor(s) in MS Project.  They may give you what you want as long as your project has simple logic.]

BPC Logic Filter is an excellent tool for defining and visualizing the Critical Path and Near-Critical Paths of a project when Total Slack proves inadequate – namely in the presence of constraints, variable calendars, and resource leveling.  As I’ve written elsewhere, however, the first version of BPC Logic Filter was prompted by a very different, though straightforward stakeholder request: “My people can’t see why they need to finish these tasks so soon. Isn’t there a report or something to show what other tasks (in other departments) are depending on them?”  In other words, couldn’t I group, filter, and sort tasks simply according to logical relationships – in addition to Work Breakdown Structure, responsible department, and other codes.  At its core, the resulting solution was a simple logic tracing routine for exploring, marking, and displaying logical relationships in an existing project schedule.

This article presents the progression of a single logic tracing example from a simple approach to a more focused analysis.

Consider the example of the small installation project presented below. There is a deadline on the “Substantial Completion” milestone, and the project is 10-days behind schedule. For unrelated reasons, the project manager has identified a need to examine the predecessor and successor logic paths around one task – “A3 Install Line D” – which is selected in the figure.

 

Task Inspector

We can first examine the task’s dependencies using MSP’s Task Detail Form and the Task Inspector pane.  The form shows that the task has two finish-to-start predecessors and two finish-to-start successors, but it provides no other schedule information for these dependencies.  Task Inspector identifies the second predecessor — ID 22 – A3 Install Line C — as the driving predecessor.  That is the predecessor whose logic is controlling the start date for our task.

This driving predecessor is hyperlinked, so clicking on it automatically selects the corresponding task in the task table and updates the details.  In addition, a new “Go back to” task link is added to the Inspector pane.  Starting from a specific ending task, the user can use these tools to “click-trace” backwards and forwards along the driving predecessor logic path to the selected task.

Click-tracing of driven successor paths is not possible using the Inspector pane, and predecessors that are hidden by filtering or outlining can’t be traced.  Moreover, neither external links nor resource-driving links can be traced.  Finally, the driving predecessors can be incorrect when relationships other than finish-to-start are used.

BPC Logic Filter – Task Logic Inspector

The Logic Inspector in BPC Logic Filter presents consolidated views of a task’s driving and non-driving predecessors and successors, including other relevant information like dates, resources, or user-selected fields.  Driving relationships are highlighted and listed at the top, while links to inactive predecessors are de-emphasized and listed at the bottom.  For logical significance, the ERF column indicates how far (in days) the predecessor is from controlling/driving the successor’s early dates, and the LRF column indicates how far the successor is from controlling/driving the predecessor’s late dates.  The latter is most useful when click-tracing to explore successor logic paths.  (The yellow-on-red color scheme in the figure highlights relationships that are driving in both directions.)

With the Jump buttons in the Logic Inspector windows, users can click-trace logic paths forward and backward through the project schedule.  Unlike the built-in tools, the Logic Inspector windows allow inspection and click-tracing of both driving and non-driving logic along successor paths, external (i.e. master/sub-project) paths, resource-constrained logic paths, and hierarchical logic paths.

Task Paths and Task Path Filters

Recent versions of MS Project (2013+) include Task Path bar styles for graphically highlighting predecessor and successor paths on the Gantt chart.  In addition, it is possible to use a simple “QuickTrace” macro (like the one linked above or one of the freeware settings in BPC Logic Filter), to identify the same set of related tasks.  In the next figure, the Path Predecessors bar style has been applied to color the bars of all tasks that are path predecessors of the selected one.  The QuickTrace macro (included in BPC Logic Filter) has also been used to highlight the same related tasks.

Alternately, QuickTrace can display the related tasks using a filter rather than a highlighter, as shown below.  In either case, the actual driving logic for the selected task is not apparent.  (And no, Total Slack does not define driving logic for this task.)

The next figure displays both the Path Predecessors (orange) and the Path Driving Predecessors (red-orange) bar styles for the selected task, and QuickTrace has been used to highlight the driving predecessors in the table.  A corresponding filter could also be applied.

Although generally less useful for analysis, corresponding bar styles and filters can be applied for the path successors and path driven successors of the selected task.

BPC Logic Filter – Advanced Tracing

With advanced logic analysis features, the relative float of all the predecessor task paths can be defined and displayed.  The following chart shows the entire project, with the predecessor paths of the selected task highlighted according to their path relative float in days.  (Path relative float indicates how much a particular task or path may be delayed before affecting the selected task; i.e. “days away from driving”.)  Path relative float is indicated numerically at the right side of each related bar.  Unrelated bars are de-emphasized and colored green.  The bar chart shown is similar to that obtained using the Task Path bar styles, with the key exception that non-driving predecessor paths can be ranked.

BPC Logic Filter allows one variation – bounded network analysis – to only show connections to a particular target task.  The figure below highlights the connections between the selected task, A3 Install Line D, and the target task, A2 Civil.

The previous two figures displayed the related task paths in-line and within the context of the overall project view.  A more focused view of the driving and near-driving paths is provided by applying a filter to hide all unrelated tasks, as shown here.

It is often useful to group and sort tasks to clearly display the chain of driving logic and associated near-driving paths.  The first group in the figure below – “BPC Relative Float (d): 0” – indicates the driving logical path for the selected activity.  The next two groups depict branching logical paths (one task each) that are 10- and 20-days away from driving the selected task.

Finally, when attempting to accelerate a task by shortening its driving logical path, Drag quantifies the maximum acceleration that may be gained by shortening a particular task along that path.  Drag is limited by the existence of parallel paths, as clearly evidenced by Tasks 6 and 11 in the figure below.  For focused acceleration of complex projects, the Drag metric can assist in prioritizing actions.

The examples shown here represent successively more powerful analyses of driving logic for an arbitrary task in a project schedule.  If that task were the final task or a key completion milestone for the project, then the resulting special case of the driving path would be the “Critical Path” for the project.

See a related video entry:

Video – Logic Tracing Example in Microsoft Project

 

Inactive Tasks in Microsoft Project

Beware inactive tasks in MSP 2013+, especially if you use non-finish-to-start relationships.  

The other day Dominic Moss posted a nice Pulse article over on LinkedIn called Inactive Tasks – more than meets the eye.  I liked the article, though I pointed out some fundamental issues with Inactive Tasks that were introduced in MSP 2013.  [Note: the link takes you to a new, improved version of Dominic’s article; our original discussion was lost.]  Here’s a recap of the lost comments:

“Dominic, this is a nice write-up. I was an early adopter of inactive tasks in MSP 2010 for the reasons you mentioned. With MSP 2013, however, Microsoft introduced a substantial change to schedule calculation around inactive tasks – the program inserts a hidden FS link between inactive task predecessors and successors at run time. I imagine that change persists in 2016. It seems a large number of users complained about the logical consequences of inactivating a task – i.e. its successors lose their driving logical constraints and slide back to the project start date. While the change seems to make life easier for the complainers, users should recognize that inactivating a task does not reliably remove it from the scheduling calculations (except in MSP 2010). That defeats most of their benefits for my purposes….  I stumbled across that ‘feature’ by accident, when a client’s planners (newly upgraded to 2013) started getting different end dates than I was (on 2010) from exactly the same mpp file. We had a number of contingent tasks that were inactivated – some with FF links. MSP 2013 was replacing those FF links with FS links and driving out the project completion!”

So the conclusion is – Beware Inactive Tasks on MSP 2013+.

[Edit: July 2018 – having finally upgraded a dedicated machine to MSP Professional 2016, I can confirm that the program’s updated behavior is a bit more refined than I had experienced with MSP 2013.  In the absence of complications caused by lags and multiple calendars, the run-time adjustments generally comply with expectations of a “dissolved” activity.  That is, relationships are applied through a zero-duration inactive task – at least on the Forward Pass (the calculations leading to the Early Dates.)  This can still extend the scheduled project completion if the inactivated task… 1. was on the driving path to project completion, and 2. possesses reverse logic flow, as in the case of a driven finish and a driving start.  Unfortunately, all this sleight of hand seems to wreak havoc on the Backward Pass and the corresponding Late Dates; if the inactive task has a parallel logic path, the late dates (and corresponding Total Slack values) of its predecessors are typically incorrect.  Lags and multiple calendars make things even more complex.  We’ll have to address all these behaviors in the pending upgrade to BPC Logic Filter, our MSP add-in.]

Musings on Critical Path Drag and Calendars in CPM Schedules

As is the case for Total Float/Slack, introducing variable task calendars can significantly confuse the understanding of Critical Path Drag in Project Schedules.  

[See also Simple Macro for Computing (Duration) Drag in MS Project and

Video – Compute Critical Path Drag in Microsoft Project]

Critical Path Drag is a useful metric in CPM scheduling that Stephen Devaux introduced in his book Total Project Control, but it is not widely computed or used.  Drag represents the individual contribution of any single schedule element (e.g. a task) to the overall duration of a project.  By definition, only “Critical Path” tasks have it, and a task’s Drag indicates the total theoretical project acceleration that could be gained if the task’s remaining duration were reduced to zero.  Viewed simplistically another way: if Total Float/Slack represents how much a non-critical task may slip before becoming Critical; Critical Path Drag represents how much a Critical task may be compressed* before becoming non-Critical.  This can be very useful in focusing a project acceleration (e.g. Crashing) exercise.

It’s clear that theoretically many components in a CPM schedule can possess Drag: activity durations, early constraints, and predecessor lags to start with. Activity calendars can also possess Drag.  I originally incorporated Drag analysis into BPC Logic Filter with the aim of correctly analyzing the Drag possessed by each component, but I recently decided to at least temporarily set aside that idea for the following reasons:

  • Drag seems so rarely used in practice that using even a single number for each activity is a stretch for the typical user; parsing it out to its many components seems unhelpful to most.
  • Allocating Drag purely by passive network analysis is hard.
  • Most importantly, other Drag-computing software (namely Spider and Asta) seem to compute only a single figure for each activity.  Allocating Drag to different components could conflict with these single-value metrics under some circumstances, leading to confusion and possible loss of confidence in the tool.

Now BPC Logic Filter provides an option to compute a single driving path Drag number for each task included in a logical analysis – using a brute-force, remove-and-recalculate approach.  This Drag reflects the maximum acceleration of the project’s completion milestone (or any other selected milestone or task in the project) to be gained by modifying the task’s duration alone.  A negative value indicates that the project is shortened by lengthening a particular task – this is reverse logic flow.

As is the case for Float/Slack, introducing variable task calendars can significantly confuse the understanding of Drag.  Consider a simple project comprising three 1-day tasks in sequence, beginning on a Friday and with the first two tasks assigned the “Standard” calendar, i.e. 5dx8h. The concluding task “Activity 3” (perhaps a management task) is on a “Monday-Only” calendar.**  As shown in the figure below, Activity 3 is scheduled to complete on the second Monday.***   Clearly, removing the duration of Activity 1 (or 2) will accelerate the Completion Task – Activity 3 – by seven calendar days, from the second Monday to the first Monday.

spiderdragex

So what is the Drag of Activity 1?  As shown by the combined figures below, the answer depends on the calendar used to quantify the acceleration.  Measured according to Activity 1’s own calendar, a Monday-to-Monday acceleration is 5 days – indicating 5 days of Drag.  That same Monday-to-Monday acceleration is only 1 working day according to the calendar of the Completion Task – resulting in 1 day of Drag.  Using the Project’s overall calendar could provide different results altogether.  For Activity 3 of this example, the Project Calendar is neither the Local Task Calendar nor the calendar of the Completion Task (also Activity 3); then it becomes like the first two tasks with a Drag of 5 days.

dragcal

Which is the correct calendar to use?  My own preference is to use the calendar of the Completion Task to quantify potential acceleration of the Completion Task (i.e. the middle option above), and this is the default selection in BPC Logic Filter. A detailed logical analysis would assign 1 day of Duration Drag to each of the tasks in the example and a further 4 days of Calendar Drag to Activity 3.  There is no logical basis for adding these 4 days of Calendar Drag to any other task, but using a mismatched calendar in a brute-force Drag analysis does exactly that, as shown in the top and bottom options above.  Those options remain in BPC Logic Filter to allow consistent comparisons with Drag calculations from other tools.

*In the absence of constraints, variable calendars, and certain relationship lags; the compression of a particular Critical Path task can lead directly to compression of the project.  Then the idea that Drag represents the potential productive compression of the task itself (i.e. the mirror image of Total Float/Slack) can appear true.  Such a simplified view should not be generalized for complex projects, however.  

**Credit and thanks for this example go to Vladimir Liberzon of Spider Project.  Spider is one of the few scheduling tools to compute Drag.

***Project correctly computes Total Slack of 4 days for the first two tasks, meaning they could each slip 4 days – according to their own calendars – without delaying the project.  MSP marks them non-Critical.  They are nonetheless on the driving path to project completion, as shown by BPC Logic Filter, and they possess Drag.

 

No Summary Tasks on the Critical Path – Calculating Total Slack for Summary Tasks in Microsoft Project

Total Slack as presented in Microsoft Project is not a valid metric for logical analysis of Summary Tasks.  Users are advised to ignore it.

Underlying the “automatic” project scheduling in Microsoft Project are some simple mathematical processes that are commonly referred to as the Critical Path Method (CPM).  CPM schedule calculation starts with a “Forward-Pass” through the schedule network to identify the earliest POSSIBLE start and finish dates that can be scheduled for each task – subject to its calendars, predecessors, and early constraints.  Next – starting from the project completion – comes the “Backward-Pass” to identify the latest ALLOWABLE start and finish dates for each task, subject to its calendars, successors, and late constraints.  For each task the difference between the late and early dates is called “Slack”.

“Start Slack” = Late Start – Early Start

“Finish Slack” = Late Finish – Early Finish

“Total Slack” = the lesser of Start Slack or Finish Slack (with some exceptions).

In traditional CPM, the “Critical Path” – i.e. that collection of tasks that controls the completion date of the project – is identified using Total Slack according to one of the following definitions depending on the complexity of the project and other factors:

  1. Total Slack = 0; or
  2. Total Slack = the lowest observed value.

Microsoft Project identifies critical tasks based on Total Slack <=0 (or some other threshold). [As noted in another post, this often leads to an incorrect identification of Critical Path for a project.]

Summary tasks are not anticipated in traditional CPM algorithms, so calculation and interpretation of Slack/Float for summaries can vary significantly between scheduling tools.  In some (or most) CPM tools, summaries exist primarily to roll-up cost and schedule data (including slack/float) from the underlying sub-tasks.  In Project, however, each summary task exists first as a task in its own right, with corresponding logical and hierarchical relationships to other tasks.  This leads to common misunderstandings of exactly what is meant by “Total Slack” of a summary task in Microsoft Project.

In general, the following observations hold true for MSP 2010 Professional:

  1. Each summary task inherits its early and late dates from its sub-tasks according to the following:
    1. Early Start = the earliest Early Start of all the sub-tasks;
    2. Late Start = the earliest Late Start of all the sub-tasks*;
    3. Early Finish = the latest Early Finish of all the sub-tasks;
    4. Late Finish = the latest Late Finish of all the sub-tasks*.
      [* Behavior shown is for normal scheduling, i.e. schedule from project start with ASAP constraints.]
  2. The Start Slack, Finish Slack, and Total Slack of the summary task are computed according to the inherited early and late dates.
  3. Since Total Slack of the summary task is derived from up to four different, logically unconnected sub-tasks, it has no significance with respect to the Critical Path or any other logic path in the project schedule.  This is illustrated in the figure above:  Summary task B inherits its Early Start and Late Finish from task B1 and inherits its Late Start and Early Finish from task B4.  The resulting 4 days of Total Slack shown for the summary task reflects the difference between the Late Finish of task B1 and the Early Finish of task B4 – completely meaningless in the absence of any logical connections between the two tasks.  The 4 days of Total Slack for the summary task is also unrelated to the Total Slack values of any of its underlying sub-tasks.
  4. If the summary task possesses logical successors – or if its parent or any outline-ancestor summary tasks possess logical successors – then the late dates can be  further accelerated through hierarchical inheritance.  The result is total slack that is sometimes zero or negative.
  5. If the summary task possesses a manually-scheduled sub-task whose start date precedes that of any other sub-task under the summary, then the manual sub-task’s scheduled start date will be written to both the early and late start of the summary task, resulting in zero start (and total) slack.

 

Some tools have allowed summaries to display the “most-critical” (or lowest) float of the associated activities – which at least means something.  Similar behavior may be obtained in Microsoft Project by inserting a custom duration field – say “Rolled Up Total Slack” – using a simple formula (“=[Total Slack]”) with “Rollup” set to Minimum.

Many modern MSP schedules incorporate variable calendars, deadlines, late constraints, or resource leveling; and the basic CPM assumptions no longer apply. Under such conditions Total Slack for any task – summary or sub-task – becomes unreliable for identifying the Critical Path or any other logical path through the schedule. That’s when a utility like BPC Logic Filter is needed.

Simple Macro for Imposing Zero Free Float Constraints in Microsoft Project

Here I outline a method – including the ImposeZFF macro – to provide “just-in-time” scheduling of flagged tasks in MSP.  I also include a separate macro, RemoveZFF, to restore the tasks to as-soon-as-possible scheduling.

Another missing feature for anyone coming to MSP from Primavera’s planning tools is the “Zero Free Float (ZFF)” constraint.  (Primavera now calls this the “As Late as Possible (ALAP)” constraint – NEVER to be confused with MSP’s identically-named version, which is pretty useless for forward scheduling.)  The ZFF constraint delays an activity as much as possible without impacting any successor activities.  It is useful for scheduling just-in-time works and deliveries while preserving the correct logic flow through the project schedule.

Consider the simple project shown here.  The overall project completion is limited by a constraint on task B.  (I never use such mandatory constraints in practice but use it here to avoid having to add other extraneous logic to the example.)  Task A must be completed before B, but for maximum efficiency it is desired to perform this work just-in-time.  Because MSP has no other obvious feature to arrive at the desired schedule outcome, the scheduler is tempted to make task A a Start-to-Finish successor of B.  Such an approach is unsound and is to be avoided for a number of reasons.  All links in a logic-driven project schedule must reflect real logical constraints, and real Start-to-Finish constraints are extremely rare.

ZFF1a

So what is the scheduler to do?  Most situations are easily solved by adding logical milestones to the project schedule.  For example, a logic-driven “Site Ready for Delivery” milestone as a Finish-to-Finish predecessor of “Eqpt Delivery” would be quite normal.  In the very few occasions when suitable logical workarounds cannot be devised, then it may be useful to impose early-start constraints to achieve the zero-free-float objectives.  For good control over the process, I use a custom flag field to designate specific tasks requiring ZFF constraints.  Then I run a macro that automatically computes and assigns the appropriate constraint to all the ZFF tasks in the project at once.  This makes ZFF constraints easy to audit, review, and justify.

For our simple project example, I inserted the Flag20 local field into the Gantt Chart entry table and called it ZFF.  Then I marked task A with the ZFF flag and ran the macro.  The macro automatically imposed a new early-start constraint on the task.  As a result, the 12 days of Total Slack (like the 12 days of Free Slack) that previously existed have been consumed.  Task A is now correctly shown as Critical.ZFF2a

If your project has a logical chain of tasks that are all ZFF-flagged, then you’ll have to re-run the macro several times (or add a simple iteration loop to the code.  I have one but didn’t include it here for simplicity.)

[May 2019 Edit: Though I don’t use this macro, one user has reminded me that when used to delay a string of connected tasks, selecting the tasks in reverse order may be more efficient than the forward order first included in this article.  I.e. use the “For i…” block shown here in place of the “For each t” block originally included.  I might get around to modifying that code eventually.]

    Dim i As Long
    For i = ActiveProject.Tasks.Count To 1 Step -1
        Set t = ActiveProject.Tasks(i)
        If Not t Is Nothing Then

            'If t.GetField(Application.FieldNameToFieldConstant(FieldName))....
               '...
               '...
             End If  
        End If
    Next i

 

The code for imposing the constraints is shown below.  Drop it into a VBA module in your Global.mpt file (or in a specific .mpp file if necessary), then look for and run macro “ZFFImpose”.  I normally use another function to find the ZFF flag field in a project, but that function was too big to include here.  So if you want to use a custom flag field other than Flag20, just change the “FieldName = “Flag20″” statement in the code.

Sub ZFFImpose()
' Macro Coded 31-08-16 by Thomas Boyle PE PSP PMP.
On Error GoTo 0
    
    Dim i As Integer
    Dim t As Task
    Dim L1 As String
    Dim L2 As String
    Dim SW1 As Boolean
    Dim SW2 As Boolean
    Dim SW3 As Boolean
    Dim FieldName As String
    
    'FieldName = FindField_Flag("ZFF") 'Function not included here
    Fieldname="Flag20"
    If FieldName = "" Then
        MsgBox Prompt:="No ZFF Flag Field Found", Title:="ZeroFreeFloat Constraints"
        Exit Sub
    End If
                
    CalculateProject

        For Each t In ActiveProject.Tasks
            If Not t Is Nothing Then
                If t.GetField(Application.FieldNameToFieldConstant(FieldName)) = "Yes" Then
                    If t.FreeSlack > 0 Then
                        t.ConstraintType = pjSNET
                        If t.Calendar = "None" Then
                            t.ConstraintDate = Application.DateAdd(t.Start, t.FreeSlack)
                        Else
                            t.ConstraintDate = Application.DateAdd(t.Start, t.FreeSlack, t.CalendarObject)
                        End If
                        CalculateProject
                        L1 = L1 & t.ID & " " & t.Name & " " & t.ConstraintDate & vbCrLf
                        SW1 = True
                    Else
                        L2 = L2 & t.ID & " " & t.Name & vbCrLf
                        SW2 = True
                    End If
                End If
            End If
        Next t
    GoTo Finish

tEHandler:
    MsgBox ("Failed to impose Zero Free Float Constraints")
    Exit Sub
    
Finish:
    CalculateProject
    If SW1 = True Then MsgBox Prompt:="Imposed Early Start Constraints to remove free float:" & vbCrLf & L1, Title:="ZeroFreeFloat Constraints"
    If SW2 = True Then MsgBox Prompt:="No free float to remove on tasks: " & vbCrLf & L2, Title:="ZeroFreeFloat Constraints"
    If SW1 = False And SW2 = False Then MsgBox Prompt:="No tasks marked for ZFF", Title:="ZeroFreeFloat Constraints"
    
End Sub

What is done with the “ZFFImpose” macro is easily undone with the “ZFFRemove” macro shown below.  This macro returns all ZFF-flagged tasks to “As Early As Possible” scheduling.

Sub ZFFRemove()
' Macro Coded 31-08-16 10:30 by Thomas Boyle PE PSP PMP.
On Error GoTo 0
    
    Dim t As Task
    Dim L1 As String
    Dim SW1 As Boolean
    Dim FieldName As String
    
    FieldName = "Flag20"
    'FieldName = FindField_Flag("ZFF")
    If FieldName = "" Then
        MsgBox Prompt:="No ZFF Flag Field Found", Title:="ZeroFreeFloat Constraints"
        Exit Sub
    End If
                
    For Each t In ActiveProject.Tasks
        If Not t Is Nothing Then
            If t.GetField(Application.FieldNameToFieldConstant(FieldName)) = "Yes" Then
                If t.ConstraintType = pjSNET Then
                    t.ConstraintType = pjASAP
                    CalculateProject
                    L1 = L1 & t.ID & " " & t.Name & vbCrLf
                    SW1 = True
                End If
            End If
        End If
    Next t
    GoTo Finish

tEHandler:
    MsgBox ("Failed to remove Zero Free Float Constraints")
    Exit Sub
    
Finish:
    CalculateAll
    If SW1 = True Then MsgBox Prompt:="Removed Early Start Constraints from designated ZFF tasks:" & vbCrLf & L1, Title:="ZeroFreeFloat Constraints"
    If SW1 = False Then MsgBox Prompt:="No tasks marked for ZFF", Title:="ZeroFreeFloat Constraints"
End Sub