使用 .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/19
与 4/27/19 12:00 AM
相同,因此不会计算当天的工作;如果您需要 4/27/19
个值,请使用 4/28/19
。最后,通过除以 60 得到小时,将时间刻度值转换为小时。
我需要根据与我们的会计期间相匹配的自定义日期范围从 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/19
与 4/27/19 12:00 AM
相同,因此不会计算当天的工作;如果您需要 4/27/19
个值,请使用 4/28/19
。最后,通过除以 60 得到小时,将时间刻度值转换为小时。