TimeScaleData в проекте с использованием. net - PullRequest
1 голос
/ 04 апреля 2020

Мне нужно получить временные масштабы из mpp-файла Ms Project по настраиваемым диапазонам дат, которые соответствуют нашим учетным периодам. Я пишу это в. net и использую вмешательства. Я запускаю Ms Project 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 вернет один объект TimeScaleValues, потому что я устанавливаю единица к дням и количество дней в диапазоне, который я посылаю. Но в итоге я получаю более одной записи, и если я смотрю на данные из этих записей, они выходят за пределы конечной даты, которую я передал, и поэтому, если я пытаюсь агрегировать значение из множителей, которые он возвращает, это неправильное значение для период времени, на который я пытаюсь взглянуть.

Из-за этого я заканчиваю тем, что мне приходится l oop через данные шкалы времени с счетчиком, установленным в 1 и go день за днем, что на 1.1 МБ проект, с которым я работаю, занимает 25 минут, чтобы просто l oop выполнить все задачи, задания и затем шкалу времени.

Что я не понимаю о получении шкалы времени? Есть ли способ добиться того, чего я пытаюсь добиться более эффективно?

1 Ответ

0 голосов
/ 05 апреля 2020

Метод TimeScaleData возвращает объект TimeScaleValues ​​, представляющий собой коллекцию объектов TimeScaleValue . Вам нужно провести l oop через эти дневные значения и суммировать их. Однако это быстро, даже в больших проектах.

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

Нет необходимости беспокоиться о аргументе Count с методом TimeScaleData, так как указаны даты начала и окончания. Обязательно используйте правильную дату окончания - 4/27/19 совпадает с 4/27/19 12:00 AM, поэтому работа в этот день не будет засчитана; используйте 4/28/19, если вам нужно 4/27/19 значения. И наконец, преобразуйте значения шкалы времени в часы, разделив на 60, чтобы получить часы.

...