1

タスクのリストを含むデータベースがあります。VSTO を使用してこのデータベースから読み取り、そこから新しい Microsoft Project を作成しています。タスクの上限は 3000 です。

問題は、データベース内のレコードがランダムな順序になっていることです。確かに、同じテーブル内で主キーと外部キーの形式で定義された親子関係があります。ただし、次の 2 つの制限があります。

  1. 一度にすべてのレコードを読まなければなりません。
  2. レコードが読み取られる順序は、完全にランダムにすることができます。

2番目の問題は、実際の問題が発生する場所です。OutlineLevel = 1最初にすべてのレコードを取得し、次にいくつかのOutlineLevel = 5レコードを取得し、次にいくつかのレコードを取得する可能性が高いOutline Level = 2ため (完全にランダム)。

ParentTask.OutlineChildren.Add(<Task>)VSTO API は、 を実行するとその親の子タスクが作成されますが、グリッドの最後の行に TASK が追加されるという意味で奇妙です!

これにより、遭遇した各レコードの ID を再計算する必要があります。とは、レコードが移動する必要がある MS ProjectIDの行番号を意味します。

これに関する問題は、3000 タスクに対してこれを再計算すると、ますます遅くなることです。最初は 1 秒間に 30 ~ 40 個のタスクを挿入できますが、3000 個のタスクすべてを処理するには 11 時間かかります。(これはもちろん受け入れられません)。

これをすばやく行う API メソッドはありますか? または、子タスクの ID を再計算する別の方法があります。

  • 子タスクの ID を計算するコードは反復的です。親タスクのIDから開始し、子タスクの兄弟番号に基づいて子タスクが持つIDを計算しようとします(SiblingNumber私が構築したデータ構造に格納され、ラッパーとして機能しますMSProject.Task object)。
4

2 に答える 2

1

COM インターフェイスは遅いため、最も重要なことは、独自のコードでできるだけ多くの処理を行うことです。タスクのリストを行順に並べた後でのみ、それらを Project に挿入する必要があります。

実際のアルゴリズムに関しては、ツリー構造を作成し、データベースを調べながら、読み取りタスク用だけでなく、暗黙の親がまだ検出されていない場合は、新しいノードを作成します。そう:

各レコードを読み取り、親が既に存在するかどうかを確認します (これには Dictionary を使用します)。そうでない場合は、それを作成します (そして辞書に追加します)。タスクが既に存在するかどうかを確認します (これには同じ辞書を使用します)。そうでない場合は、それを作成します (そして辞書に追加します)。親の子のリストにタスクを追加します。

(最初にトップ レベルのタスクを作成し、親のないタスクをこのトップ レベルの子にする方がおそらくよりエレガントです。)

終了したら、ツリーを深さ優先でトラバースすると、タスクが行順に表示されます。

于 2013-03-25T22:00:13.557 に答える
0

この問題を解決する最も簡単な方法は、 にリストされている最初のタスクの前に子タスクを挿入することTask.OutlineChildrenです。ただし、いくつかの子タスクが既に存在する場合にのみ機能します。

次の十分に速い解決策は、毎回 COM を呼び出す代わりに、プロジェクトの構造をアドオンの何らかのデータ構造に読み込み、それをスキャンすることです。プロジェクトを変更するときは、自分で構造を更新する必要があります。

もちろん、兄弟のリストの最後にいくつかのタスクを挿入したい場合は、親と同じ OutlineLevel を持つ次のタスクをスキャンして、そのタスクの前に挿入することができます。

とにかく、大量の挿入/更新でプロジェクト構造をキャッシュすることが最も合理的な解決策です。

于 2012-12-19T19:49:58.153 に答える