如何使用 Interop.MSProject 删除任务(行)

发布于 2024-09-25 05:44:38 字数 971 浏览 10 评论 0原文

我正在尝试将 Interop.MSProject 与 C# 一起使用,从概念上讲,这应该是世界上最简单的事情。然而,我在使用它的神秘 api 时遇到了一些麻烦,它的文档很少。我想要做的就是找到其中一列(单元格)中包含特定字符串的行并删除该行。完成此操作后,我只想显示修改后的项目文件,以便用户可以选择保存它。这是我尝试过的:

MSProject.Application app = new MSProject.Application();
app.FileOpenEx(
    filePath,
    false,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    MSProject.PjPoolOpen.pjPoolReadWrite,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing);

foreach(MSProject.Task task in proj.Tasks)
{
    if (task == null) continue;
    string cellValue = task.OutlineCode3;
    if (cellValue == searchString)
       task.Delete();
}  

app.Visible = true;

似乎 task.Delete 不起作用。我什至尝试将此代码概括为以下内容:

foreach (MSProject.Task task in proj.Tasks)
   task.Delete()

但这也不起作用。有谁知道我可以根据其中一个行单元格中的值删除任务或行的方法吗?

I'm trying to use Interop.MSProject with C# to do something that conceptually, should be the simiplest thing in the world to do. However, I am having some trouble with it's cryptic api which has minimal documentation. All I wish to do is to find a row that contains a specific string in one of it's columns (cell) and remove that row. After I've done that, I just want to display the modified project file so that the user has the option to save it. Here is what I've tried:

MSProject.Application app = new MSProject.Application();
app.FileOpenEx(
    filePath,
    false,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    MSProject.PjPoolOpen.pjPoolReadWrite,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing,
    Type.Missing);

foreach(MSProject.Task task in proj.Tasks)
{
    if (task == null) continue;
    string cellValue = task.OutlineCode3;
    if (cellValue == searchString)
       task.Delete();
}  

app.Visible = true;

It seems as though task.Delete is not working. I've even tried to generalize this code to the following:

foreach (MSProject.Task task in proj.Tasks)
   task.Delete()

and this did not work either. Does anyone know a way that I can remove a task or a row base on a value in one of the rows cells?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终止放荡 2024-10-02 05:44:39

昨天我遇到了同样的难题。

您的方法是正确的,但它不起作用,因为任务是基于索引的。这在直接 for 循环中更为明显。

如果您有 10 个任务并删除其中一个,假设是 5,那么现在下一个任务 (6) 现在是 5,但您的循环将尝试删除 6,而现在是 7。这将使一切变得混乱。

如果您想删除所有任务,您应该执行以下操作:

// Task Indexes are 1-based not 0-based
for(int i = 1; i <= proj.Tasks.Count; i++) {
    proj.Tasks[i].Delete();
    i--;
}

按照这个思路,让我们将其应用于 foreach 循环

foreach(Task t in tasksToDelete) {
    proj.Tasks[proj.GetTaskIndexByGuid(t.Guid)].Delete();
}

为什么我使用 GetTaskIndexByGuid?似乎每个任务的 Index 属性在删除任务时如果没有正确(或立即)更新,但我发现使用 GetTaskIndexByGuid 总是返回正确的索引。

希望有帮助

I faced the same conundrum yesterday.

Your approach is correct but it doesn't work because the tasks are Index-based. This is more obvious in a straight for loop.

If you have 10 tasks and delete one, let's say number 5, now the next task (6) is now 5 but your loop will try to delete 6 which is now 7. This will mess everything up.

If you want to delete all tasks you should do something like:

// Task Indexes are 1-based not 0-based
for(int i = 1; i <= proj.Tasks.Count; i++) {
    proj.Tasks[i].Delete();
    i--;
}

Following this train of thought let's apply this to a foreach loop

foreach(Task t in tasksToDelete) {
    proj.Tasks[proj.GetTaskIndexByGuid(t.Guid)].Delete();
}

Why am I using GetTaskIndexByGuid? It seems that the Index property of each task if not properly (or immeadiately) updated when you delete a task but I found that using GetTaskIndexByGuid always returns the correct index.

Hope it helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文