C# 如何在使用VSTO将数据加载到Microsoft Project时提高性能

C# 如何在使用VSTO将数据加载到Microsoft Project时提高性能,c#,vsto,ms-project,C#,Vsto,Ms Project,背景 我们有一个现有的应用程序,它可以将数据加载到Microsoft Project中,以便MS Project可以对其进行操作 最初的应用程序是由VB6针对MS Project 2003/2007编写的旧式COM项目外接程序,现在我们计划将它们迁移到VSTO外接程序,以MS Project 2013/2016为目标 问题 对于COM插件解决方案,我们遇到了性能问题: 测试项目有4414项活动(av_活动表)和8330项 关系(av_reln表) 负载运行期间报告了性能问题: 上述项目MSP 2

背景

我们有一个现有的应用程序,它可以将数据加载到Microsoft Project中,以便MS Project可以对其进行操作

最初的应用程序是由VB6针对MS Project 2003/2007编写的旧式COM项目外接程序,现在我们计划将它们迁移到VSTO外接程序,以MS Project 2013/2016为目标

问题

对于COM插件解决方案,我们遇到了性能问题:

测试项目有4414项活动(av_活动表)和8330项 关系(av_reln表)

负载运行期间报告了性能问题:

上述项目MSP 2003模板的加载时间约为:30-35分钟

MSP 2007和2010模板上的加载时间>3小时

对于VSTO解决方案,它会变得更好,但我们仍然希望能够通过某种方式提高加载性能

我们迄今为止所做的尝试

我们尝试了好几种技巧,但没有取得多大效果

  • 添加数据时的Diable自动计算

    \u application.Calculation=PjCalculation.pjManual

  • 在添加数据期间禁用屏幕更新

    \u application.screenUpdate=false

  • 禁用更改突出显示

    \u application.EnableChangeHighlighting=false

  • 禁用状态栏

    \u application.DisplayStatusBar=false

  • 将“撤消”值设置为1

  • 将默认视图设置为“任务表视图”(而不是“甘特图视图”,在加载过程中会产生更多开销)
寻求帮助

我正在寻求帮助,以获得有关在使用VSTO插件和C#将数据加载到MS Project时提高性能的任何解决方案

提前谢谢

是的,使用该方法创建关系非常慢

这是不幸的,因为这是使用的合乎逻辑的方法唯一的解决办法是提前构建前置列表。一旦有了该列表,您可以通过两种方式创建关系:

  • 添加到现有计划中
  • 通过导入包含前置列表的任务数据来创建新计划
由于您的数据已经是表格式的,因此使用项目导入向导从csv或Excel文件导入数据非常有效。 要使用项目导入向导,请从MS Project中选择要打开的csv或Excel文件(文件->打开)。向导将引导您完成创建导入映射的步骤,您可以保存该映射以供以后自动使用在导入数据中包含Preferences列,向导将在几秒钟内为您创建关系。

该任务包含以逗号分隔的前置任务列表。每个前置版本的格式如下:

  • 任务ID
  • 关系类型(FS、FF、SS、SF)
  • 滞后(+/-#d)
FS类型且无延迟的前置字段仅显示任务ID。以下是前置字段值的一些示例:

  • 14126127
  • 73,92SS
  • 144FS+3d,145
如何从关系表中创建前置字段值

假定一个包含前置任务ID和后续任务ID的关系表:

  • 使用整数键(后续任务ID)和字符串值(前置任务ID)创建字典
  • 循环浏览关系表,并将后续任务ID及其前置任务添加到字典中;如果该值已经存在,请更新该值以附加逗号和前置项
  • 循环浏览字典,A)更新csv文件中的前置列B)在计划中的后续任务上设置前置字段

  • 如果您正在使用数据创建一个新项目,您可以使用生成一个Microsoft project XML文件(MSPDI文件),然后可以在project中直接打开该文件。

    如果我理解这个问题,您说将4000个ish任务放入MS project大约需要30分钟。我不知道你所说的8000段感情是什么意思;你是指前任/继任者吗?也许你可以澄清一下?因此,您拥有的是一个由3个组件组成的系统:数据源、传输机制和MS项目本身;对吗

    这场表演让我感到惊讶。我编写了一些VBA代码(见文章底部)来测试添加4000个具有不同大纲级别的任务的性能+前辈,在我的系统(Proj 2016、Intel i7、Win 10)上,添加任务最多需要100秒。这告诉我项目中没有瓶颈。我怀疑瓶颈在您的数据源或传输机制中

    为了确认这一点,您可以尝试将所有任务(您称之为活动)数据添加到一个任务的notes属性中,然后查看您的性能A如果速度很快,那么可以尝试添加4000个任务,但不添加属性(名称除外),然后以增量方式添加更多属性,直到找到哪些属性添加速度较慢。根据我下面的测试,使用task.preventors属性增加了6倍的性能降低,其余的影响可以忽略不计;您可能会遇到另一个性能降级属性B但如果仅将任务数据添加到一个任务的备注中仍然很慢,则数据源或传输机制存在问题。也许您一次只发送一个任务(即活动),而可以构建一个批?不管是什么情况,都要找出问题并加以解决

    祝你好运

    Sub add4000tasks()
    
    On Error Resume Next
    
    Dim myTask As task
    Dim myProject As Project
    resPool = Split("Allice,Bob,Claire,Dave", ",")
    
    For testRun = 0 To &HF '00001111
    
        testPreds = testRun And &H1 '00000001
        testOutlines = testRun And &H2 '00000010
        testDurations = testRun And &H4 '00000100
        testAssignments = testRun And &H8 '00001000
    
        If testPreds Then Debug.Print "Testing Predcessors"
        If testOutlines Then Debug.Print "Testing Outlines"
        If testDurations Then Debug.Print "Testing Durations"
        If testAssignments Then Debug.Print "Testing Resource Assignments"
    
    
        Application.Projects.Add
        Set myProject = ActiveProject
        Application.Calculation = pjManual
    
        starttime = Now
    
        Set myTask = myProject.Tasks.Add("Task 0")
        For a = 1 To 4000
    
            Set myTask = myProject.Tasks.Add("Task " & a)
    
            If testPreds Then
                myTask.Predecessors = Rnd * 10000000 Mod a + 1 'may fail if predecessor is also a parent
            End If
    
            If testOutlines Then
                If Rnd * 10000000 Mod 10 = 0 And myTask.OutlineLevel < 10 Then
                    myTask.OutlineIndent
                ElseIf Rnd * 10000000 Mod 10 = 1 And myTask.OutlineLevel > 1 Then
                    myTask.OutlineOutdent
                End If
            End If
    
            If testDurations Then
                myTask.Duration = Rnd * 10000000 Mod 50 & "d"
            End If
    
            If testAssignments Then
                myTask.ResourceNames = resPool(Rnd * 10000000 Mod UBound(resPool) + 1)
            End If
    
    
        Next
    
        Application.Calculation = pjAutomatic
    
        Debug.Print (Now - starttime) * 86400 & vbCrLf
    
        Application.FileCloseEx (pjDoNotSave)
    
    Next
    
    Sub add4000tasks()
    出错时继续下一步
    将myTask设置为task
    将我的项目作为项目
    resPool=Split(“Allice,Bob,Claire,Dave”,“,”)
    对于testRun=0至&HF'00001111
    testPreds=testRun和&H1'0000000 1
    testOutlines=testRun和&H2'000000