Project has a bug where accessing time scaled values causes an exception after a few calls. You can get around it by calling GC.Collect() and GC.WaitForPendingFinalizers() but this is super slow. Here is an example of what that looks like.
Here is a glorious hack that involves injecting a temporary macro into the Global.MPT and then calling the macro via reflection to have the TimescaleData method be called inside Project to avoid the problem.
First, inject this macro:
Public Sub GetAssignmentTSV(ByVal projectName As String, ByVal taskIndex As Long, ByVal assignmentIndex As Long, ByVal startDate As String, ByVal endDate As String, ByVal tsvType As Long, byref totalTSV As Variant) Dim tsv As TimeScaleValues Set tsv = Application.Projects(projectName).Tasks(taskIndex).Assignments(assignmentIndex).TimeScaleData(startDate, endDate, tsvType , pjTimescaleDays) Dim t As TimeScaleValue For Each t In tsv totalTSV = totalTSV + Val(t.Value) Next End Sub
By doing this (it attempts to clean up old version of the macro first):
Then call the macro like this:
RunTSVMacro looks like this:
The two constants are:
The RunTSVMacro method has to use the parameter modifier to let reflection know that the 7 argument is an out argument because you can call a VBA function using Project’s Run method.
Hope this helps.