I've mentioned before that when looping through a collection of tasks in Project that there are a couple of holes you can fall in. This note gives an example of another problem you might run into and describes how to combine tests. The first problem is encountering a blank line. Many people insert blank lines in their project files to make the table easier to read, however when project references a task which is blank it will give an error. The easy way to do this is to test for it with an if .. then
statement.
If your original code was something like this:
Sub AllTasksLoop()
For Each Task In ActiveProject.Tasks
'do something
Next Task
End Sub
You would simply add a test to see if the task really exists.
Sub AllNonBlankTasks()
For Each Task In ActiveProject.Tasks
If Not Task Is Nothing Then
'do something
End If
Next Task
End Sub
Another thing you might want to do is to eliminate external tasks. These are a sort of "ghost" task and don't have all of the information or properties of a real task. They merely point to the project file which has the real task. We can filter them in a similar way.
Sub AllNonBlankInternalTasks()
For Each Task In ActiveProject.Tasks
If Not Task Is Nothing Then
If Not Task.ExternalTask Then
'do something
End If
End If
Next Task
End Sub
Now, you might think, "Why do I need two if statements? Can't I combine them?
, but you can't. If the task is a blank task, then it will cause an error when it is checking the second condition. Blank tasks do not have the .ExternalTask
property so the check for blank tasks always must come first on its own line. You CAN combine checks for summary tasks on the same line as for external tasks. This is commonly done when you are summing values from tasks. Since the summary task often has the sum of the tasks below it, summing and including it will give you an incorrect answer. Combining the two conditions with a booleanOR
will do the trick.
Sub AllNonBlankInternalIndividualTasks()
For Each Task In ActiveProject.Tasks
If Not Task Is Nothing Then
If Not (Task.ExternalTask Or Task.Summary) Then
MsgBox Task.Name
End If
End If
Next Task
End Sub
Comments (3)
Jack,
We've learned the hard way many times, that looping through tasks is fraught with difficulties. Instead most of our "processing" code uses a filter to select the tasks first as a collection, then process that collection.
Only for coloring and bar style setting in IMP/IMS - we use unindented schedules - do we loop through the entire schedule.
Posted by Glen B Alleman | December 8, 2005 8:28 AM
Posted on December 8, 2005 08:28
Hi Jack
Quick thanks for the Task.ExternalTask and Task.Summary. That helped me out updating fixed cost based on the quantity / unit price calculated custom cost field. There is an underlying assumption that 1 task = 1 cost.
Cheers
Grant
Posted by Grant | December 18, 2005 5:24 PM
Posted on December 18, 2005 17:24
Thanks for this info, ive been wondering about these "non tasks" for ages, i didnt like having to remove blank lines from my projects b4 runnign my macros.
Posted by Gavin | June 27, 2006 1:23 AM
Posted on June 27, 2006 01:23