1

私はInterop.MSProjectをC#で使用して、概念的には世界で最も似たようなことをしようとしています。ただし、ドキュメントが最小限である不可解なAPIに問題があります。私がやりたいのは、その列の1つ(セル)に特定の文字列を含む行を見つけて、その行を削除することだけです。それが終わったら、変更したプロジェクトファイルを表示して、ユーザーがそれを保存できるようにします。これが私が試したことです:

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()

そしてこれもうまくいきませんでした。行セルの1つの値に基づいてタスクまたは行ベースを削除する方法を知っている人はいますか?

4

1 に答える 1

1

私は昨日同じ難問に直面しました。

あなたのアプローチは正しいですが、タスクはインデックスベースであるため、機能しません。これは、ストレートforループでより明白になります。

10個のタスクがあり、1つを削除した場合、たとえば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を使用すると常に正しいインデックスが返されることがわかりました。

それが役に立てば幸い

于 2010-12-14T11:44:30.573 に答える