locked
Total lag. RRS feed

  • Question

  • I am looking to extract the lag amount from your schedule, would someone explain which values I should loop over

    perhaps something like this (pseudo)

    foreach (task t in tasks)

    {

    total+= Datediff (dd,t-1.finishdate, t.startdate);

    }

    or is there a more direct way.


    Friday, July 13, 2012 12:38 PM

Answers

  • Toomanyhats,

    It isn't quite clear just what you are looking for. Are you trying to find if and how much lag is associated with each task? Are you trying to get a grand total of lag for the whole schedule? Or what?

    The TaskDepedencies collection object contains various properties including the lag property. That's probably your best bet.

    Please mark your post on the main forum as answered. No need to leave it open now that you have posted here.

    John


    Friday, July 13, 2012 2:18 PM
  • The code above should be giving you a number that is too high since each link between tasks is represented twice, once as a dependancy on the 'From' task and then again as a dependancy on the 'To' task. Yours should be about double.

    Also, by only taking the lags that are greater than 0 you will not get a number that represents the actual total lag since for a given subset of tasks the total lag might be negative if the sum of negative lags is greater than the sum of positive ones. The code below is a starting point. It has one issue I know of for sure: It will return a number that is too high if a selected task has more than one successor and they both have the same lag value.

    For example:

    If you selected tasks 1-4 and ran my code it would return a value of 6 days. This is wrong since the sum of the effective lags is really 4 since the 2nd link from 2 does not really add to the effective total.

    This would have to be taken into account for sure.

    My code only runs on the ActiveSelection so you need to select some tasks. it checks to make sure that the link that the TaskDependency object represents is also inside the activeselection. I used a goto to kickout of hte loop when the task was found. This is not great but it was faster while I was testing things. You might want to change it to a do while or something more elegant.

    I hope this helps.

    Sub ROUGHOUT_LagTotaler()
    Dim T As Task
    Dim TD As TaskDependency
    Dim DepTask As Task
    Dim FoundTask As Boolean
    Dim TT As Task
    Dim LagTot As Long
    
    For Each T In ActiveSelection.Tasks
        If Not (T Is Nothing) Then
            For Each TD In T.TaskDependencies
                For Each TT In ActiveSelection.Tasks
                    If Not (TT Is Nothing) Then
                        If TD.To.ID = TT.ID Then
                            FoundTask = True
                            GoTo Kickout
                            
                        End If
                    End If
                Next TT
    Kickout:
                If FoundTask = True Then
                    If TD.From.ID = T.ID Then
                        LagTot = LagTot + TD.Lag
                        'Debug.Print T.ID & ": " & TD.Lag
                        FoundTask = False
                    End If
                End If
    
            Next TD
        End If
    Next T
    MsgBox "Total Lag (In Days) for Links between Selected Tasks: " & (LagTot / 60) / ActiveProject.HoursPerDay
    End Sub
    


    Brian Kennemer - Project MVP
    DeltaBahn Senior Architect
    endlessly obsessing about Project Server…so that you don’t have to.
    Blog | Twitter | LinkedIn

    Monday, July 16, 2012 7:22 AM

All replies

  • Toomanyhats,

    It isn't quite clear just what you are looking for. Are you trying to find if and how much lag is associated with each task? Are you trying to get a grand total of lag for the whole schedule? Or what?

    The TaskDepedencies collection object contains various properties including the lag property. That's probably your best bet.

    Please mark your post on the main forum as answered. No need to leave it open now that you have posted here.

    John


    Friday, July 13, 2012 2:18 PM
  • thanks for the object reference,

    lag per each task is kind of confusing to me, lag I believe needs at least two tasks so the requirement would be total lag for a set of tasks.

    I originally thought it would be entire project but "selected tasks" would also be very effective. I'm sure this macro must have been built already.

    Friday, July 13, 2012 5:14 PM
  • This worked....  again thanks for the TaskDependencies clue

    Sub GetProjectLag()

        Dim T As Task
        Dim TS As Tasks
        Dim totallagminutes As Long
        Dim totallagdays As Double
        Dim TaskDep As TaskDependency
        
        Set TS = ActiveProject.Tasks
       
        If ActiveProject.Calendar = "Standard" Then
            For Each T In TS
                If Not T Is Nothing Then
                    If Trim(T.Name) <> "" Then
                        If Not T.Summary Then
                            If Not T.ExternalTask Then
                                For Each TaskDep In T.TaskDependencies
                                    If TaskDep.Lag > 0 Then
                                        totallagminutes = totallagminutes + TaskDep.Lag
                                    End If
                                Next TaskDep
                            End If
                        End If
                    End If
                End If
            Next T
        End If
       
       
        
        totallagdays = totallagminutes / 960
        
        
        MsgBox "total lag days not counting negative lag is " & totallagdays
      
    End Sub


    Friday, July 13, 2012 7:40 PM
  • Toomanyhats,

    You're welcome and thanks for the feedback. If you want to only total up the lag for a select number of tasks you could use the following:

    Set TS = ActiveSelection.Tasks

    You could either manually select the desired tasks or you could also create a filter that selects a limited number of tasks based on your criteria. I use SelectTaskColumn after the filter is applied to get the ActiveSelection object.

    John

    Friday, July 13, 2012 8:39 PM
  • The code above should be giving you a number that is too high since each link between tasks is represented twice, once as a dependancy on the 'From' task and then again as a dependancy on the 'To' task. Yours should be about double.

    Also, by only taking the lags that are greater than 0 you will not get a number that represents the actual total lag since for a given subset of tasks the total lag might be negative if the sum of negative lags is greater than the sum of positive ones. The code below is a starting point. It has one issue I know of for sure: It will return a number that is too high if a selected task has more than one successor and they both have the same lag value.

    For example:

    If you selected tasks 1-4 and ran my code it would return a value of 6 days. This is wrong since the sum of the effective lags is really 4 since the 2nd link from 2 does not really add to the effective total.

    This would have to be taken into account for sure.

    My code only runs on the ActiveSelection so you need to select some tasks. it checks to make sure that the link that the TaskDependency object represents is also inside the activeselection. I used a goto to kickout of hte loop when the task was found. This is not great but it was faster while I was testing things. You might want to change it to a do while or something more elegant.

    I hope this helps.

    Sub ROUGHOUT_LagTotaler()
    Dim T As Task
    Dim TD As TaskDependency
    Dim DepTask As Task
    Dim FoundTask As Boolean
    Dim TT As Task
    Dim LagTot As Long
    
    For Each T In ActiveSelection.Tasks
        If Not (T Is Nothing) Then
            For Each TD In T.TaskDependencies
                For Each TT In ActiveSelection.Tasks
                    If Not (TT Is Nothing) Then
                        If TD.To.ID = TT.ID Then
                            FoundTask = True
                            GoTo Kickout
                            
                        End If
                    End If
                Next TT
    Kickout:
                If FoundTask = True Then
                    If TD.From.ID = T.ID Then
                        LagTot = LagTot + TD.Lag
                        'Debug.Print T.ID & ": " & TD.Lag
                        FoundTask = False
                    End If
                End If
    
            Next TD
        End If
    Next T
    MsgBox "Total Lag (In Days) for Links between Selected Tasks: " & (LagTot / 60) / ActiveProject.HoursPerDay
    End Sub
    


    Brian Kennemer - Project MVP
    DeltaBahn Senior Architect
    endlessly obsessing about Project Server…so that you don’t have to.
    Blog | Twitter | LinkedIn

    Monday, July 16, 2012 7:22 AM
  • It also seems to want to include some tasks outside the selection. It looks like it is including the first set of links to successors just after the current selection. I will work on fixing this tomorrow.

    Brian Kennemer - Project MVP
    DeltaBahn Senior Architect
    endlessly obsessing about Project Server…so that you don’t have to.
    Blog | Twitter | LinkedIn

    Monday, July 16, 2012 7:31 AM
  • wow very nice,

    Thanks John

    I was definitely going to rewrite for ActiveSelection.Tasks, That will probably have more usefulness to my user.

    Very good point about the double counting Brian, I had a gut feeling it wasn't correct but I didn't test enough,

    As I was reading the double count problem even before I read your code I was thinkiong the the Task Dependency object may have a property of predecessor/successor. If so then one could count only successors.

    But if the ID "to / from" condition works that is great also,

    thanks so much to both.

    Monday, July 16, 2012 12:41 PM
  • Thanks again my user likes it.

    here is what I publish as the final code

    Sub GetProjectLag()

    Dim T As Task
    Dim TD As TaskDependency
    Dim DepTask As Task
    Dim FoundTask As Boolean
    Dim TT As Task
    Dim LagTot As Long
    Dim mess As String
    Dim intResponse As Integer

    For Each T In ActiveSelection.Tasks
        If Not (T Is Nothing) Then
            For Each TD In T.TaskDependencies
                For Each TT In ActiveSelection.Tasks
                    If Not (TT Is Nothing) Then
                        If TD.To.ID = TT.ID Then
                            FoundTask = True
                            GoTo Kickout                        
                        End If
                    End If
                Next TT
    Kickout:
                If FoundTask = True Then
                    If TD.From.ID = T.ID Then
                    If TD.Lag > 0 Then
                        LagTot = LagTot + TD.Lag
                        'Debug.Print T.ID & ": " & TD.Lag
                        End If
                        FoundTask = False                    
                    End If
                End If

           Next TD
        End If
    Next T


    mess = "Total Lag (In Days) for Links between Selected Tasks: " & (LagTot / 60) / ActiveProject.HoursPerDay & vbCrLf & "Do you want to add this as the project lag value"

    intResponse = MsgBox(mess, vbYesNo)

    If intResponse = vbYes Then
        ActiveProject.ProjectSummaryTask.EnterpriseProjectNumber4 = (LagTot / 60) / ActiveProject.HoursPerDay
    End If

      
    End Sub

    Tuesday, July 24, 2012 3:00 PM