Service Pack 2 により変更時ワークフローの自身の開始が回避される
Service Pack 2 により変更時ワークフローの自身の開始が回避される
こんにちは、SharePoint Designer を担当しているライターの Stephen です。今回は、Office SharePoint Server 2007 Service Pack 2 および Windows SharePoint Services 3.0 Service Pack 2 (英語) に含まれている修正プログラムについてご紹介します。この修正プログラムは、SharePoint Designer 2007 で設計されるワークフローに関係します。また、1 つのワークフローではなく 2 つのワークフローを使用して意図的にワークフロー ループを作成する方法についても説明します。
Service Pack 2 以前は、自身を開始して無限ループとなるワークフローを間違って設計することがよくありました。たとえば、次のシナリオを考えてみましょう。
1) アイテムが変更されるとワークフローが開始する。
2) ワークフローは現在のアイテムを更新 (または変更) する ([現在のアイテムにフィールドを設定する] (Set Field in Current Item) アクションなどの使用による)。
3) ワークフローがアイテムを変更するため、自身を開始する。
つまり、電子メールを送信し、それに続けて現在のアイテムを更新するような変更時ワークフローがある場合、受信トレイには数百もの電子メールがあっという間に届くことになります。
サーバーに Service Pack 2 をインストールすると、アイテムが変更されると開始するワークフローが、現在のアイテムの変更/更新によって自身を開始しなくなります。次のような無限ループ シナリオは起こりません。
しかし、多くの人が、無限ループを実際に利用するワークフローを設計してきました。たとえば、タスク アイテムを無限にループし、タスクが完了とマークされるまで毎日通知を送信する変更時ワークフローを設計できます。ワークフローは、この目的のためにリストに追加された Counter 列を更新することによって、自身を開始します。ワークフローには、ある条件が満たされるとワークフローを停止または "短絡" させるルールがあります。このケースでは、タスクのステータスが完了 (Status = Completed) の場合、現在のアイテムを変更せずにワークフローは停止します。SP2 以降、このワークフローは自身を開始できないため、実際には動作しません。
SP2 が無限ループをブロックすることはなく、これが役立つこともありますが、これまでの動作を再作成するには、互いを開始する 2 つ (またはそれ以上) の変更時ワークフローを設計する必要があります。現在のアイテムを更新/変更することによって互いを開始する 2 つの変更時ワークフローは、"余再帰" シナリオです。
さらに、互いを開始する複数の短いワークフローを使用して、状態ベースのワークフローを実装することも非常に一般的です。たとえば、Status フィールドを持つリストがあり、そのリストに複数の変更時ワークフローが添付されているものとします。すべてのワークフローには、Status フィールドを更新する手順が最後に含まれています。あるワークフローが Status を更新することによって複数の他のワークフローを開始すると、該当のワークフローは Status フィールドの値を調べて実行を続けるか、停止するかを決定します。現在のアイテムを変更/更新することによって、1 つのワークフローが他の多くの変更時ワークフローを開始するため、この状態ベースのワークフローも "余再帰" シナリオです。Service Pack 2 によって、余再帰を使用するこのような状態ベースのワークフローがブロックされることはありません。
要点
· SP2 以前は、1 つの変更時ワークフローが、現在のアイテムを更新することによって自身を開始し、無限ループを発生させることがありました。
· SP2 以降は、変更時ワークフローは、現在のアイテムを更新することによって他の変更時ワークフローを開始できますが、自身を開始することはできません。したがって、多くの小規模な変更時ワークフローを使用することによって状態ベースのワークフローを実装するシナリオを含めて、余再帰シナリオはブロックされません。
· 作成時ワークフローで現在のリスト内にアイテムを作成しても、無限ループは作成されないことに注意してください。どのワークフローにも、"自分が開始できないワークフロー" が格納されているプロパティがあります。このプロパティを使用することで、アイテムの作成時に開始するワークフローのループが阻止されます。
· これまでのシナリオはすべて、単一のリストまたはライブラリに添付されたワークフローのみを使用していることにも注意してください。リスト間のシナリオにおける無限ループは、変更時ワークフローでも作成時ワークフローでもブロックされません。
Service Pack 2 以前のループの作成
このセクションでは、SP2 以前の単一の変更時ワークフローが無限ループをどのように利用していたかを示す例を紹介します。SP2 以降、このワークフローは自身を開始しません。そこで、次のセクションでは、2 つの個別のワークフローを使ってループを作成する例を紹介します。
Team Tasks という名前のタスク リストがあり、タスクに完了のマークが付けられるまで通知を毎日送信するワークフローを設計するものとします。
最初に、Counter という名前の列をリストに追加し、既定値を 0 に設定します。
ワークフローのみがアクセス/更新できるように、Counter 列をリスト フォーム ([新しいアイテム] (New Item)、[アイテムの編集] (Edit Item) ) で非表示にする必要があります。最初に、リスト設定ページで [詳細設定] (Advanced Settings) をクリックし、コンテンツ タイプの管理を許可します。
リスト設定ページで各コンテンツ タイプをクリックし、次のページで Counter 列をクリックします。Counter 列を非表示にします。リスト内のすべてのコンテンツ タイプに対してこの操作を行います。
Counter 列を作成および非表示にして、これがフォームに表示されないようにしたら、ワークフローの設計を開始します。
Daily Reminder ワークフローは、アイテムの作成時または変更時に開始する必要があります。
最初の手順では、2 つのことを確認します。(1) タスクに完了のマークが既に付いている場合、ワークフローは停止します。このルールにより、タスクに完了のマークが最終的に付けられると、ループは "短絡" します。(2) タスクが完了していない場合は、期日が将来 (本日以降) の日付かどうかを確認します。これに該当する場合、期日に達するまで通知を送信する必要はないため、ワークフローは期日まで一時停止します。
2 番目の手順では、タスクが完了しているかどうかを再び確認します (前の手順でワークフローが期日まで一時停止している間にタスクが完了した場合に備えて)。タスクがまだ完了していない場合、ワークフローはもう 1 日一時停止します。
3 番目の手順では、ワークフローが一時停止していた間にタスクが完了したかどうかを再び確認します。該当する場合、ワークフローは停止します。
タスクが完了していない場合、ワークフローは、(1) 電子メールの通知を送信し、(2) 参照を行うことによって、CurrentCount 変数を現在のアイテムの Counter フィールドに設定します。次に、(3) CurrentCount に 1 を加算してその値を NewCount 変数に格納し、(4) Counter 列を NewCount 変数に格納されている値に設定します。
基本的に、この手順により、ワークフローが実行するたびに Counter 列が 1 ずつ増えるため、Counter 列を調べることで送信された通知の数を確認できます。最も重要なことは、この手順の最後における [現在のアイテムにフィールドを設定する] (Set Field in Current Item) アクションが現在のアイテムを "変更" するものであり、これによってワークフローが自身を開始して、ループが作成されます。
Service Pack 2 以降のループの作成
SP2 以降もこのループを実現できますが、自身を開始する単一のワークフローではなく、互いを開始する 2 つのワークフロー (余再帰) を設計する必要があります。
ここでは、(1) カウントを増分する Counter ワークフローと、(2) 通知メールを実際に送信する Worker ワークフローを使用します。
1 番目のワークフロー — Counter ワークフロー
上記のように、リスト内に Counter 列を作成して既定値 0 を設定し、コンテンツ タイプの管理を許可して、リスト内のすべてのコンテンツ タイプに対してこのフィールドを非表示にする必要があります。
この 2 ワークフロー設計では、Worker ワークフローのフラグとして動作する、SendMail という 2 番目の列が必要です。既定値には No を指定する必要があります。それ以外の値の場合、タスク アイテムに対するすべての変更が、通知メールの送信を引き起こします。
Counter ワークフローは、アイテムが作成または変更されると開始します。
最初の手順では、タスクのステータスを確認します。タスクが完了している場合、Counter ワークフローは停止します。
タスクの期日が将来 (本日以降) の日付の場合、期日に達するまで通知を送信する必要はないため、2 番目の手順は期日まで一時停止します。
前の手順でワークフローが一時停止している間にタスクが完了した場合に備えて、3 番目の手順では、タスクが完了しているかどうかを再び確認します。タスクがまだ完了していない場合、ワークフローはもう 1 日一時停止します。
最後の手順では、この 1 日間の一時停止中にタスクが完了したかどうかを再び確認します。タスクが完了していない場合、ワークフローは、(1) Counter 列の値を 1 だけ増分し、(2) SendMail フラグを Yes (既定値は No) に設定することによって、現在のアイテムを更新します。
2 番目のワークフロー — Worker ワークフロー
上記の Counter ワークフローは、現在のアイテムを更新 (変更) することによって終了します。この更新によって、アイテムが変更すると開始するように設定されている Worker ワークフローが開始します。
Worker ワークフローは、SendMail フラグが Yes に設定されているかどうかを確認します。Yes に設定されている場合、通知メッセージが送信され、フラグが No に戻されます。
SendMail フラグを No に設定することは、上記の Counter ワークフローを開始する変更にあたります。Counter ワークフローと Worker ワークフローは互いを開始して、タスクに完了のマークが付けられるまで毎日通知を送信します。
また、無限ループではなく、Counter 列が特定の値、たとえば 5 件の通知に達したら、タスク通知をエスカレートするように Worker ワークフローを設定することもできます。次の手順では、通知の件数に応じて、異なる分岐を実行します。カウントが 5 に達すると、マネージャーにメッセージが送信されます。マネージャーの電子メール アドレスは、[電子メールを送信する] (Send an Email) アクションにハードコードすることもできれば、ワークフロー参照を使用してリストから取得することもできます。
特定の件数の通知が送信された後、Worker ワークフローでタスクを別のユーザーやグループに再割り当てすることもできます。次の手順では、このようなエスカレートされたタスクのフォローアップを担当しているチーム メンバーで構成される SharePoint グループに、タスクを再割り当てします。
カウントが特定の値に達したらループを終了する場合は、Worker ワークフローではなく、Counter ワークフローの最初の手順に分岐を作成します。次の分岐では、Counter 列が 6 に達するとループを停止します。
このブログが皆さんのお役に立つことを願っています。
—Stephen
これはローカライズされたブログ投稿です。原文の記事は、「Service Pack 2 prevents an on-change workflow from starting itself」をご覧ください。
!-->