我想创建一个脚本来创建一组电子表格,每个选定的 MS 项目计划行对应一个电子表格。这比我见过的“导出功能”更复杂,因为导出功能将您的 MS-Project 文件视为表格并进行表格到表格的转换。
以下是我想要的功能:
- 能够在 MS-Project 中选择一组任务并触发该功能
- 让该函数从任务中选取 3-5 个项目并将它们放在 Excel 电子表格中的特定位置。
- 理想情况下,它会让我给它一个模板电子表格,其中的字符串代表我希望数据去往的位置。
- 电子表格会有多个选项卡,我想在多个选项卡中设置数据。
- 每个任务在其自己的文件中都会有一个新的电子表格。
我很高兴能编写一个函数来执行此操作,但我不熟悉任何 MS 宏编程语言或技巧。我可以轻松地将我想要的伪代码可视化,只是不知道是否有 API 可以完成我想要的操作。
有谁知道我想要的东西是否可行,如果可行,如何最好地实现它。如果可能,请提供学习资源的参考。
答案1
是的,这是可能的,但对于刚接触宏编程的人来说可能有点困难。由于您尝试同时使用 Excel 和 Project,因此复杂性有所增加 - 但这一切都是完全可行的。
目前还没有 API 可以为你完成这种压缩包装,但 MS Office 拥有非常丰富的文档对象模型。您拥有的最佳资源之一是“F1”键。尝试以非常小的步骤记录您想要执行的操作,并修改代码以使其适当通用。记录器可以帮助您发现您需要熟悉的对象、方法和属性。
Project 中的主要工作对象是任务对象。在 Excel 中,它是范围对象。您需要熟悉两者才能完成您想要的操作。粗略概述:
- 从项目中选择的任务开始
- 对于您选择的每项任务:
a. 创建一个新工作簿
b. 从项目中获取所需的值
c. 将它们写入 Excel 中的相应范围
我对你的问题的模板部分有点模糊,所以在下面的例子中不必担心它,但你可以定义一个叫做命名范围在 excel 中。因此,这些名称可以存在于您的模板中,如果您愿意,您甚至可以在多个工作表(选项卡)上重复使用相同的名称,并使用这些名称来定义在哪里写入您的任务数据。例如,我将任务 ID 写到Range("A2")
,但它也可以是Range("Project_ID")
此外,我建议将其分解为几个功能,大纲中的每个步骤对应一个功能。下面是非常基本起点。要使用此示例,您需要从 Project 创建对 Excel 对象定义的引用。打开项目 VBA IDE 并选择工具 -> 参考资料. 查找条目Microsoft Excel XX.0 对象库并在复选框中打勾。“XX”是您的 Excel 版本。我的是 10,您的可能不同。使用此版本的任何人都必须做出相同的选择。
Option Explicit
Sub CopyTasksToExcel()
Dim xlApp As Excel.Application
Dim t As Task
Dim wb As Excel.Workbook
Set xlApp = New Excel.Application
For Each t In ActiveSelection.Tasks
Set wb = CreateWorkbook(xlApp, t.Name, t.ID)
WriteSheetHeadingOn wb
WriteTaskOn t, wb
wb.Close SaveChanges:=True
Next t
xlApp.Quit
Set xlApp = Nothing
End Sub
Function CreateWorkbook(ByVal xlApp As Excel.Application, _
ByVal TaskName As String, _
ByVal TaskID As Long) As Excel.Workbook
Dim wb As Excel.Workbook
Dim fName As String
Set wb = xlApp.Workbooks.Add 'You could specify a template here
fName = ActiveProject.Path & "\" _
& TaskID & "-" _
& TaskName & ".xls"
wb.SaveAs FileName:=fName
Set CreateWorkbook = wb
Set wb = Nothing
End Function
'Writes date from a Project Task to the provided workbook.
Sub WriteTaskOn(ByVal prjTask As Task, _
ByVal xlWb As Excel.Workbook)
With xlWb.Sheets(1)
.Range("A2").Value = prjTask.ID
.Range("B2").Value = prjTask.Name
.Range("C2").Value = prjTask.Duration
End With
End Sub
Sub WriteSheetHeadingOn(ByVal xlWb As Excel.Workbook)
With xlWb.Sheets(1)
.Range("A1").Value = "ID"
.Range("B1").Value = "Name"
.Range("C1").Value = "Duration"
End With
End Sub