Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
今回は VSTO
からのワークフローの開始について取り上げたいと思います。
VSTO を利用した Office ドキュメントをワークフローのフロントエンドとして利用する場合、リボンUIや操作ウィンドウからワークフローを操作するようなケースがあるとは思います。
今後、このようなネタは増えてくると思いますが、これもあまりにも情報が少なくいため、(日本語だけでなく、英語も少ないです。)一緒に仕事をされたパートナー様が非常に苦労されてました。
実はこのネタですが、既にテンプレートを作成している場合はゴッド松崎さんが公開されている以下のページがあります。
SharePoint の Workflow 用 Web Service を使ってシステム連携をおこなう
https://blogs.msdn.com/tsmatsuz/archive/2007/08/27/part-6-sharepoint-workflow-web-service.aspx
ここでは少し切り口を変えて、アイテム単位の既定の承認ワークフローを VSTO から利用したい場合についてご紹介したいと思います。
そもそも、各ライブラリやリストにはいくつかの既定のワークフローが用意されています。
アイテム単位の既定の承認ワークフローのメリットですが、既定の承認ワークフローの利用は任意の承認者を順次処理したり、任意に承認者を追加/更新したい場合などがあげられると思います。
ここでは任意の承認者を順次承認者に登録する処理の手順をご紹介します。
手順としては以下のコードを VSTO のプロジェクトの任意の部分に貼り付けます。
※一応、該当ドキュメントをライブラリに保存した後の処理を想定しています。
private void button1_Click(object sender, EventArgs e)
{
//ワークフロー Web サービスの利用
Workflow ws = new Workflow();
ws.Url = "https://<SharePoint のサーバーとライブラリ名>/_vti_bin/Workflow.asmx";
ws.Credentials = CredentialCache.DefaultCredentials;
//ワークフローアイテムの選択
XmlNode wfTemplatesXML = ws.GetTemplatesForItem("SharePoint のライブラリ上のファイル名");
//ワークフローパラメーターの定義
XmlNamespaceManager nsmgr = new XmlNamespaceManager(wfTemplatesXML.OwnerDocument.NameTable);
nsmgr.AddNamespace("wf","https://schemas.microsoft.com/sharepoint/soap/workflow/");
nsmgr.AddNamespace("my", "https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlNode dataNode = wfTemplatesXML.SelectSingleNode("//wf:AssociationData/wf:string", nsmgr);
XmlDocument doc = new XmlDocument();
doc.LoadXml(dataNode.InnerText);
//承認者1の指定
XmlNode nodeReviewers = doc.SelectSingleNode("//my:myFields/my:Reviewers", nsmgr);
XmlElement nodeParson_01 = doc.CreateElement
("my:Person", "https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeDisplayName_01 = doc.CreateElement("my:DisplayName","https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeAccountId_01 = doc.CreateElement("my:AccountId", "https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeAccountType_01 = doc.CreateElement("my:AccountType", "https://schemas.microsoft.com/office/infopath/2003/myXSD");
nodeDisplayName_01.InnerText = @"ドメイン名¥ユーザー名";
nodeAccountId_01.InnerText = @"ドメイン名¥ユーザー名";
nodeAccountType_01.InnerText = "User";
nodeParson_01.AppendChild(nodeDisplayName_01);
nodeParson_01.AppendChild(nodeAccountId_01);
nodeParson_01.AppendChild(nodeAccountType_01);
nodeReviewers.AppendChild(nodeParson_01);
//承認者2の指定
XmlElement nodeParson_02 = doc.CreateElement("my:Person", "https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeDisplayName_02 = doc.CreateElement("my:DisplayName","https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeAccountId_02 = doc.CreateElement("my:AccountId","https://schemas.microsoft.com/office/infopath/2003/myXSD");
XmlElement nodeAccountType_02 = doc.CreateElement("my:AccountType","https://schemas.microsoft.com/office/infopath/2003/myXSD");
nodeDisplayName_02.InnerText = @"<ドメイン名¥ユーザー名>";
nodeAccountId_02.InnerText = @"ドメイン名¥ユーザー名";
nodeAccountType_02.InnerText = "User";
nodeParson_02.AppendChild(nodeDisplayName_02);
nodeParson_02.AppendChild(nodeAccountId_02);
nodeParson_02.AppendChild(nodeAccountType_02);
nodeReviewers.AppendChild(nodeParson_02);
XmlNode idNode = wfTemplatesXML.SelectSingleNode("//wf:WorkflowTemplateIdSet", nsmgr);
//テンプレートの GUID を指定
//SharePoint Manager の利用により取得
Guid templateID = new Guid("任意のGUID");
//ワークフローの開始
ws.StartWorkflow("SharePoint のライブラリ上のファイル名",templateID, doc.DocumentElement)
}
コードの解説です。
//ワークフローパラメーターの定義
ここではワークフローWebサービスに渡すパラメータの定義をおこないます。
ワークフローパラーメーターは StartWorkflow メソッドの第3引数になります。
//承認者1の指定
と //承認者2の指定
StartWorkflow メソッドに渡す実際のパラメータになります。
他のパラメータも渡すことができますが、他のパラメータの確認は以下が参考になるかと思います。
Using Smart Clients to Communicate with Workflows in Windows SharePoint Services 3.0
https://msdn.microsoft.com/en-us/library/cc296356.aspx
以下、抜粋
<TemplateData xmlns=
"https://schemas.microsoft.com/sharepoint/soap/workflow/">
<Web Title="MSDN" Url="https://moss/sitedirectory/msdn" />
<List Title="Shared Documents"
Url="https://moss/sitedirectory/msdn/Shared Documents" />
<WorkflowTemplates>
<WorkflowTemplate Name="MSDN Approval" Description=
"Routes a document for approval. Approvers can approve or reject
the document, reassign the approval task, or request changes
to the document." InstantiationUrl=
"https://moss/sitedirectory/msdn/_layouts/IniWrkflIP.aspx?
List=545dc556-b8ba-4628-886a-00fc2ce6bd02&ID=1&TemplateID=
{4ee560ed-01f8-4466-a9d6-9d4a53068eec}">
<WorkflowTemplateIdSet
TemplateId="4ee560ed-01f8-4466-a9d6-9d4a53068eec"
BaseId="c6964bff-bf8d-41ac-ad5e-b61ec111731c" />
<AssociationData>
<string>
<my:myFields xml:lang="en-us"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:my="https://schemas.microsoft.com/office/infopath/2003/myXSD">
<my:Reviewers>
<my:Person>
<my:DisplayName>LitwareInc Administrator</my:DisplayName>
<my:AccountId>LITWAREINC\administrator</my:AccountId>
<my:AccountType>User</my:AccountType>
</my:Person>
</my:Reviewers>
<my:CC></my:CC>
<my:DueDate xsi:nil="true"></my:DueDate>
<my:Description></my:Description>
<my:Title></my:Title>
<my:DefaultTaskType>1</my:DefaultTaskType>
<my:CreateTasksInSerial>true</my:CreateTasksInSerial>
<my:AllowDelegation>true</my:AllowDelegation>
<my:AllowChangeRequests>true</my:AllowChangeRequests>
<my:StopOnAnyReject xsi:nil="true"></my:StopOnAnyReject>
<my:WantedTasks xsi:nil="true"></my:WantedTasks>
<my:SetMetadataOnSuccess>false</my:SetMetadataOnSuccess>
<my:MetadataSuccessField></my:MetadataSuccessField>
<my:MetadataSuccessValue></my:MetadataSuccessValue>
<my:ApproveWhenComplete>false</my:ApproveWhenComplete>
<my:TimePerTaskVal xsi:nil="true"></my:TimePerTaskVal>
<my:TimePerTaskType xsi:nil="true"></my:TimePerTaskType>
<my:Voting>false</my:Voting>
<my:MetadataTriggerField></my:MetadataTriggerField>
<my:MetadataTriggerValue></my:MetadataTriggerValue>
<my:InitLock>false</my:InitLock>
<my:MetadataStop>false</my:MetadataStop>
<my:ItemChangeStop>false</my:ItemChangeStop>
<my:GroupTasks>false</my:GroupTasks>
</my:myFields></string>
</AssociationData>
<Metadata>
<Instantiation_FormURN>
<string>urn:schemas-microsoft-com:office:infopath:workflow:
ReviewRouting-Init:$Subst:LCID;</string>
</Instantiation_FormURN>
</Metadata>
</WorkflowTemplate>
</WorkflowTemplates>
</TemplateData>
//テンプレートの GUID を指定
//SharePoint Manager の利用により取得
GUID の確認はおなじみ Codeplex 上の SharePoint Manager を利用しています。
該当ライブラリの [Items] 内の各ドキュメントの [Item]-[ドキュメント]-[Workflow Associations]-[承認]内の[ID]から取得します。
//ワークフローの開始
引数として必要なパラメータを渡しワークフローが開始されます。
このネタはアバナードさんとデモ構築を共同でおこなっていた案件なのですが、
最初、私の思い込みでカスタムの Web サービスでしか呼び出せないという見解を出して大変ご迷惑をおかけしました。
この場を借りてお詫び申し上げます。
この内容自体の情報は非常に少なく、普通だと Workflow Web サービスを呼び出して戻り値を見てみないと分からない内容でした。
アバナードさんのエンジニアさんはそのような情報量の少ない状況できちんと解を見出されたので、非常に素晴らしい仕事をされたと思います。
VSTO からの SharePoint ワークフロー連携というところではノウハウを持たれていますので、何かございましたらアバナードさんにご連絡いただければと思います。
アバナードさんありがとうございました。<m(__)m>