« Hall of Mirrors | Main | Working with the Project Object »

Working with the Tasks Collection

The First in a Series of Short Notes About Using Project VBA
The tasks collection is simply a collection of all the tasks in a project. It is the starting point for most Visual Basic programming exercises so it is important to know how to use it. The first thing is in how to set it. This is done using the Set keyword.
Typically one sets a collection to all the tasks in the project, but it is possible to set it to some other task collection.

Here is an example of setting it to the tasks in the active project:

Dim ts as Tasks
Set ts = ActiveProject.Tasks

Another useful trick is to filter the project first and then set the task collection to the set of filtered tasks:

SelectAll
Set ts = ActiveSelection.Tasks

Once we have the task collection we can go through it in a number of ways. If we want a specific task we can ask for it by index. For example if we want the first task the code would be:

Dim t as task
Set t = ts(1)

Quite often we want to do something to all tasks in the project. In that case we would set the task collection as above and then loop through it using a for..next structure:

For Each t in ts
t.Text5 = "Foo"
Next t

This approach works until you hit a blank line in the project. In the case of the blank line the task is what Project refers to as "Nothing". You can do nothing with Nothing, so setting the Text5 value for Nothing will give you an error. Luckily you can check to see if a task is Nothing and therefore skip doing anything that would cause an error and stop your code. To do this we add a simple If statement:

For Each t in ts
If not t is Nothing then
t.Text5 = "Foo"
End If
Next t

We can do a similar thing to ignore summary tasks. You might want to do this when altering a value like duration which is not something that you can edit directly for a summary task. I use something like this:

If not t.Summary Then
'do stuff
End If

Putting it all together we have this generic structure to loop through all tasks in a project:

Dim ts as Tasks
Dim t as Task
Set ts = ActiveProject.Tasks
For Each t in ts
If Not t is Nothing Then
If Not t.Summary Then
'do something
End If
End If
Next t

By putting your code in the middle of this structure (where it says "do something" you can be sure it will be applied to all the regular tasks in the project and won't generate an error when it hits a blank line.

RELATED POSTS
  • Analyze Microsoft Project Resource Usage Data In Excel
  • VBA Writing to a text file (MS Project, Excel)
  • Working with the Project Object
  • Setting Microsoft Project Level Custom fields using VBA
  • Iterating through Microsoft Project Subprojects
  • Microsoft Project Undo Levels and Macros
  • VBA and Visual Basic For ... to ... statements
  • VBA to VSTO Tutorial Part Two - Adding a Command Bar and Buttons
  • Making the move from VBA to VSTO in Microsoft Project
  • Office VBA for Mac After 2008

  • Comments (5)

    Simon:

    This keeps giving me a 424 error, i'm using 2003 is there anything else I need to consider

    Jack:

    Simon,

    Hard to say why you are getting the error because you haven't mentioned which of these snippets you are using. It may be that you are missing the start and end.

    This for example is a valid subprocedure:

    sub foo()
    dim t as task
    dim ts as tasks
    set ts = activeproject.tasks
    for each t in ts
    if not t is nothing then
    if not t.summary then
    t.text5 = "foo"
    end if
    end if
    next t
    end sub

    If you don't include the "sub" and "end sub" then nothing will happen. If you want me to debug further, please post the actual code you are using. It is difficult to figure out where it might have gone wrong without seeing it.

    Denys Lebedev:

    I learn something new every day from your website. Jack, thank you for the information! Regards, Denys

    Jay:

    I need a macro that selects tasks and sets the "Free Slack" amount to a value which I set. I've been using a flag field and if "yes" then set jTask.FreeSlack = " 30 d" - the macro is hung up on the jTask.Flag5 = "Yes" I can't get pass this line of code - help! thanks - Jay.
    ------------
    FreeSlack is calculated based on your task durations and dependencies. Unfortunately you can not set it manually. -JD

    VBARookE:

    Thank you! After poring over countless VBA examples and compiling snippets of code, I found this example and it worked perfectly. Thanks again!

    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 Hall of Mirrors.

    The next article is Working with the Project Object.

    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