« Oh so special! | Main | Ginkgo Biloba in Fall »

More about working with the tasks collection

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

RELATED POSTS

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.

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

Gavin:

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.

Post a comment

(Comments are moderated to fight SPAM and will be published after I have a chance to approve them. Thanks for waiting.)

About

The previous article is Oh so special!.

The next article is Ginkgo Biloba in Fall.

Current articles are in the main index page and you can find a complete list of articles in the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.
Powered by
Movable Type 3.34