I am working on a Microsoft Project add-in in VB.NET. Each Project is of type Project
, and has its own list of Tasks that are of type Tasks
and they contain lots of tasks of type Task
. Microsoft Project has an option to add other Project files inside of it as Subprojects. These subprojects are of type Subproject
, but they have a property SourceProject
which is of type Project
. Meaning, you should be able to access each subprojects Tasks
as if it were a regular Project
type through Project.Subprojects(0).SourceProject.Tasks
.
I tried using LINQ to filter out some tasks on a Project
. I found this answer very helpful, and I managed to do it successfully without any errors. In the below code ThisProject
is of type Project
:
Dim tasksWithResources = ThisProject.Tasks.Cast(Of MSProject.Task).Where(Function(x) x.ResourceNames <> "")
However, when I try doing the exact same thing when iterating through subprojects, I get a MemberMissingException
:
For Each subproject In ThisProject.Subprojects
Dim subprojectTasksWithResources = subproject.SourceProject.Tasks.Cast(Of MSProject.Task).Where(Function(x) x.ResourceNames <> "")
Next
I tried accessing the subprojects tasks by simply assigning them to a variable thinking that there were no Tasks
in that subproject. But it was successful. So even if I write it like this (which I know is the same thing as the code block above), I get the MemberMissingException
on the row where I use Cast
:
For Each subproject In ThisProject.Subprojects
Dim tsks = subproject.SourceProject.Tasks
Dim subprojectTasksWithResources = tsks.Cast(Of MSProject.Task).Where(Function(x) x.ResourceNames <> "")
Next
This is the error message I'm getting:
Public member 'Cast' on type 'Tasks' not found.
Edit:
I understand that an easy workaround is not using LINQ, but rather iterating through the object with a For Each
, but I'm curious why LINQ is not working.
The issue might be that the subproject's tasks are not yet loaded.
Try forcing the project to load by accessing a task. For example:
For Each s As MSProject.Subproject In ThisProject.Subprojects
Dim tempTsk As MSProject.Task = s.Tasks(1)
Dim subprojectTasksWithResources = s.SourceProject.Tasks.Cast(Of MSProject.Task).Where(Function(x) x.ResourceNames <> "")
Next
I have used the following code in my add-ins to force the subprojects to load. It works well, but I think the above code might be all you need.
Friend Sub ShowAllTasks()
' expands all tasks to make sure all collapsed subprojects are loaded
With ProjApp
.SummaryTasksShow(True)
.FilterApply("All Tasks")
.SelectAll()
.OutlineShowAllTasks()
.SelectBeginning()
End With
End Sub
Note: this presumes the current view is a task view.
P.S. Use a different variable name for your subprojects as subproject
is the name of an object.