我有一个包含任务列表的数据库。我正在使用VSTO从这个数据库中读取并从中创建一个新的Microsoft Project。任务的上限是3000。
问题是数据库中的记录是随机顺序的。当然,它们在同一个表中以主外键的形式定义了父子关系。但是,有2个限制:
第二个问题是真正的问题发生的地方。由于我可能首先获得所有OutlineLevel = 1
条记录,然后是一些OutlineLevel = 5
条记录,然后是Outline Level = 2
条记录,依此类推等等(完全随机)。
由于VSTO API在执行ParentTask.OutlineChildren.Add(<Task>)
的意义上是奇数,因此会创建该父项的子任务,但会将TASK添加到网格的最后一行!
这迫使我重新计算我遇到的每条记录的ID。使用ID
,我的意思是MS Project中的行号必须记录。
这个问题是,如果我为3000个任务重新计算它,它会越来越慢。从一开始,它每秒可以插入30-40个任务,但需要11个小时来处理所有3000个任务! (这当然是不可接受的)。
是否有一些API方法可以快速完成此操作?或者是否有另一种重新计算子任务ID的方法。
SiblingNumber
存储在我构建的数据结构中,其行为作为MSProject.Task object
)的包装。答案 0 :(得分:1)
COM接口很慢,因此最重要的是在您自己的代码中尽可能多地进行处理,并且只有在按行顺序列出任务列表之后才能将它们插入到Project中。 / p>
至于实际算法,我会创建一个树结构,当你浏览数据库时,我会创建一个新节点,不仅仅是为了读取任务,而是为了隐含的父节点,如果还没有遇到过。所以:
阅读每条记录并: 查看父级是否已存在(为此使用字典)。 如果没有,请创建它(并添加到词典中)。 查看任务是否已存在(为此使用相同的字典)。 如果没有,请创建它(并添加到词典中)。 将任务添加到父级的子项列表中。
(首先创建一个顶级任务可能更优雅,并且在父母没有这个顶级孩子的情况下完成任何任务。)
完成后,以深度优先的方式遍历树,然后按行顺序执行任务。
答案 1 :(得分:0)
解决问题的最简单方法是在Task.OutlineChildren
中列出的第一个任务之前插入子任务。但它只有在已经有一些儿童任务时才有效。
下一个足够快的解决方案是将项目结构读入加载项中的某些数据结构并扫描它,而不是每次都调用COM。当你改变你的项目时,我将不得不自己更新结构。
当然,如果你想在兄弟姐妹列表的末尾只插入几个任务,你可以使用与其父级相同的OutlineLevel扫描下一个任务,并在该任务之前插入。
但无论如何,在批量插入/更新上缓存项目结构是最合理的解决方案。