向所有人致意。
我在两个月前面临这个问题而没有解决方案。
我需要通过VBA将MS Project文件的基线开始和完成日期转换为Excel,这是一个有效的算法:
Set Prj = MSProject.Application
Dim tarea As Task
For Each tarea In Prj.ActiveProject.Tasks
Select Case BL
Case "BL0"
StartD = CDate(Format(tarea.BaselineStart, "dd/mm/yyyy"))
EndD = CDate(Format(tarea.BaselineFinish, "dd/mm/yyyy"))
Case "BL1"
StartD = CDate(Format(tarea.Baseline1Start, "dd/mm/yyyy"))
EndD = CDate(Format(tarea.Baseline1Finish, "dd/mm/yyyy"))
Case "BL2"
StartD = CDate(Format(tarea.Baseline2Start, "dd/mm/yyyy"))
EndD = CDate(Format(tarea.Baseline2Finish, "dd/mm/yyyy"))
Case "BL3"
StartD = CDate(Format(tarea.Baseline3Start, "dd/mm/yyyy"))
EndD = CDate(Format(tarea.Baseline3Finish, "dd/mm/yyyy"))
...
...等到BL10;但是这个代码效率极低,并且当Project文件有超过两千个任务行时,需要花费更多的时间来导入日期。
我尝试了在下一个链接中找到的解决方案,只为不同的基线https://social.msdn.microsoft.com/Forums/en-US/c964e627-079e-4296-9e5c-b7c82900d982/project-2010-standard-vba-export-to-excel-latest-baseline?forum=project2010custprog编写一行代码,但结果略有不同,
StartD = tarea.Baseline3Start --> StartD = 11/06/2014 07:00:00 a.m.
StartD = tarea.GetField(Application.FieldNameToFieldConstant("Baseline" & "3" & "Start", pjTask)) --> StartD = "wdn 11/06/14"
使用第二条指令vba没有得到确切的基线日期,它获得了MS Project中显示的字段值,我无法将有效日期值中的最后结果转换为Excel
我还尝试使用Eval()和Evaluate()函数编写一般代码来获取此日期
BLstring = "tarea.Baseline" & "3" & "Start"
Eval(BLstring) --> Error 2409
这是可以理解的,因为此命令不是本机Excel函数
有没有办法在不使用Select case
句子的情况下获得这些日期?
或者,可能是,有没有办法执行字符串作为MS Project外部命令来获取这些日期?
任何想法对我都有很大帮助。
编辑#0:最后,在经历了两个月的缓慢而痛苦的痛苦之后,我找到了解决方案。
Andrew Eversight解决方案对我不起作用,因为它采用相同的方法从MSProject获取值...它查找PjFiel枚举值(http://msdn.microsoft.com/en-us/library/ff867782(v=office.15).aspx),它是188744184,以获取字段任务值:
StartD = tarea.GetField(Application.FieldNameToFieldConstant("Baseline" & "3" & "Start", pjTask)) --> StartD = "wdn 11/06/14"
相当于
StartD = Tsk.GetField(tsk_fld_BaselineStart) --> StartD = "wdn 11/06/14"
对于这两种情况,我都可以通过pjFiel编号获得字段值
FieldNameToFieldConstant("Baseline" & "3" & "Start", pjTask) = 188744184
tsk_fld_BaselineStart = pjTaskBaseline3Start = 188744184
tarea.GetField
说明其余部分和结果是相同的( "wdn 11/06/14" )
正如Rachel Hettinger所说,GetField方法总是返回一个字符串,由于某种原因我不明白,CDate不会将此结果转换为有效的日期值。
更改应用程序默认日期格式,正如Rachel Heetinger所说,此时它不可靠,我不想修改任何项目文件(此时此刻)。
我可以使用CallByName获取正确的值:
BLstring = "Baseline" & "3" & "Start"
For Each tarea In Prj.ActiveProject.Tasks
StartD = CallByName(tarea, BLstring, VbGet)
StartD_aux = tarea.Baseline3Start
...
两条指令都给出了相同的结果( 11/06/2014 07:00:00 a.m. )
亲爱的Andrew和Rachel,感谢您的快速回答和准时帮助。
答案 0 :(得分:1)
当你有几千行时,性能永远不会很好,但我可以告诉你我做了什么,这是两者的组合。
首先,在开始循环执行任务之前,使用select case语句获取要使用的字段的名称:
Dim tsk_fld_BaselineStart As PjField
Dim tsk_fld_BaselineFinish As PjField
Select Case str_BaselineDestFieldSet
Case "Baseline"
tsk_fld_BaselineStart = pjTaskBaselineStart
tsk_fld_BaselineFinish = pjTaskBaselineFinish
Case "Baseline1"
tsk_fld_BaselineStart = pjTaskBaseline1Start
tsk_fld_BaselineFinish = pjTaskBaseline1Finish
Case "Baseline2"
tsk_fld_BaselineStart = pjTaskBaseline2Start
tsk_fld_BaselineFinish = pjTaskBaseline2Finish
'... and so on
End Select
在变量中捕获这些字段后,当您循环执行任务时,您不必执行那么大的select case语句,或者将字符串转换为字段值,因为它已经完成了:
Dim Tsk As Task
Dim StartD As Date
Dim EndD As Date
For Each Tsk In ActiveProject.Tasks
StartD = CDate(Tsk.GetField(tsk_fld_BaselineStart))
EndD = CDate(Tsk.GetField(tsk_fld_BaselineFinish))
Debug.Print "Task """ & Tsk.Name & """ starts " & StartD & " and ends " & EndD
Next Tsk
确保将StartD和EndD明确声明为日期变量,因为这可能是您收到错误格式的原因。这不是我以前遇到过的问题。 更新11/11: Rachel在评论中澄清了这一点 - 上面的代码已更新为包含日期的CDate功能。
如果要在大型项目中定期使用它,可能需要实现一个进度条来向用户显示它在执行期间的进展情况,因为即使使用此性能增强,也可能需要一些时间才能运行。 / p>