使用 .net 的项目中的 TimeScaleData

TimeScaleData in Project using .net

我需要根据与我们的会计期间相匹配的自定义日期范围从 Ms Project mpp 文件中获取时间刻度数据。我在 .net 中写这个并使用互操作。我是 运行 2010 年项目女士。

这是一个概念示例:

Private Sub Process()
    Dim start As Date = Date.Now

    If txtImportFile.Text = "" Then
        Exit Sub
    End If

    Dim pjApplication As Microsoft.Office.Interop.MSProject.Application

    pjApplication = New Microsoft.Office.Interop.MSProject.Application
    pjApplication.Visible = False

    pjApplication.FileOpenEx(Name:=txtImportFile.Text, ReadOnly:=True)

    Dim project As Microsoft.Office.Interop.MSProject.Project = Nothing
    If pjApplication.Projects.Count = 0 Then
        pjApplication.FileExit(PjSaveType.pjDoNotSave)
        Exit Sub
    Else
        project = pjApplication.Projects(1)
    End If

    Dim res As Resource = Nothing
    Dim bLabor As Boolean = False
    Dim dTimeScaleValue As Decimal = 0
    Dim dPeriodValue As Decimal = 0

    Dim timeScaleVals As TimeScaleValues = Nothing
    Dim timeScaleValActuals As TimeScaleValues = Nothing

    Dim tskTimeScaleVals As TimeScaleValues = Nothing

    For Each tsk As Task In project.Tasks
        For Each a As Assignment In tsk.Assignments
            res = project.Resources(a.ResourceID)

            If res.Type = PjResourceTypes.pjResourceTypeWork Then
                bLabor = True
            Else
                bLabor = False
            End If


            If bLabor Then
                timeScaleVals = a.TimeScaleData(StartDate:=a.Start, EndDate:=a.Finish,
                                                Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledWork, TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays,
                                                Count:=1)
            Else
                timeScaleVals = a.TimeScaleData(StartDate:=a.Start, EndDate:=a.Finish,
                                                Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledCost, TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays,
                                                Count:=1)
            End If

            If bLabor Then
                timeScaleValActuals = a.TimeScaleData(StartDate:=a.Start, EndDate:=a.Finish,
                                                      Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledActualWork, TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays,
                                                      Count:=1)
            Else
                timeScaleValActuals = a.TimeScaleData(StartDate:=a.Start, EndDate:=a.Finish,
                                                      Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledActualCost, TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays,
                                                      Count:=1)
            End If


            dPeriodValue = 0
            dTimeScaleValue = 0

            For idx = 1 To timeScaleVals.Count
                If timeScaleVals(idx).Value.ToString.Trim = "" Then
                    dTimeScaleValue = 0
                Else
                    dTimeScaleValue = timeScaleVals(idx).Value
                End If

                If Not IsNothing(timeScaleValActuals) Then
                    If Not IsNothing(timeScaleValActuals(idx)) AndAlso timeScaleValActuals(idx).Value.ToString.Trim <> "" Then
                        dTimeScaleValue -= timeScaleValActuals(idx).Value
                    End If
                End If

                If bLabor Then
                    dPeriodValue += Decimal.Round(dTimeScaleValue / 60D, 2)
                Else
                    dPeriodValue += dTimeScaleValue
                End If
            Next
        Next
    Next


    pjApplication.FileExit(PjSaveType.pjDoNotSave)

    MsgBox(DateDiff(DateInterval.Second, start, Date.Now))
End Sub

我希望对 TimeScaleData 的调用是 return 单个 TimeScaleValues 对象,因为我将单位设置为天,并将计数设置为我要发送的范围内的天数。但是,我最终得到了不止一条记录,如果我查看这些记录中的数据,它超出了我传入的结束日期,所以如果我尝试从它的倍数 rreturns 中聚合值,这不是我要查看的时间段的正确值。

因此,我不得不循环遍历时间刻度数据并将计数设置为 1 并日复一日地进行,在我正在处理的 1.1mb 项目中,仅循环遍历所有任务就需要 25 分钟,作业,然后是时间刻度数据。

关于检索时间刻度数据,我有什么不明白的地方?有什么方法可以更有效地实现我想要实现的目标吗?

TimeScaleData method returns a TimeScaleValues object which is a collection of TimeScaleValue 个对象。您确实需要遍历这些每日值并将它们相加。然而,这很快,即使在大型项目中也是如此。

Sub GetWork()

Dim dteStart As Date = "3/30/19 00:00:00"
Dim dteEnd As Date = "4/27/19 00:00:00"

For Each tsk As Task In proj.Tasks
    For Each a As Assignment In tsk.Assignments

        Dim timeScaleVals As TimeScaleValues
        timeScaleVals = a.TimeScaleData(StartDate:=dteStart,
                                        EndDate:=dteEnd,
                                        Type:=PjAssignmentTimescaledData.pjAssignmentTimescaledWork,
                                        TimeScaleUnit:=PjTimescaleUnit.pjTimescaleDays)
        Dim WorkMinutes As Int32
        For Each tsv As TimeScaleValue In timeScaleVals
            WorkMinutes += Val(tsv.Value)
        Next tsv
        ' do something with WorkMinutes
    Next
Next

End Sub

由于提供了开始日期和结束日期,因此无需为 TimeScaleData 方法的 Count 参数操心。请务必使用正确的结束日期——4/27/194/27/19 12:00 AM 相同,因此不会计算当天的工作;如果您需要 4/27/19 个值,请使用 4/28/19。最后,通过除以 60 得到小时,将时间刻度值转换为小时。