サンドボックス ソリューションのサンプル
適用対象: InfoPath 2010 | InfoPath Forms Services | Office 2010 | SharePoint Server 2010 | Visual Studio | Visual Studio Tools for Microsoft Office
マネージ コードを持つ InfoPath 2010 フォームを、InfoPath 2010 デザイン モードから SharePoint サンドボックス ソリューション インフラストラクチャに発行できます。このトピックでは、InfoPath サンドボックス ソリューションでフォーム テンプレートを発行する方法として使用できる 2 つのコード例について説明します。
例 1: 注文フォームでのデータの並べ替え
InfoPath フォームでコードを使用して実行できる便利な作業の例として、繰り返しテーブルでのデータの並べ替えがあります。それには、InfoPath フォームに表示されている基になる XML ドキュメントのノードについて、それらをコードを使用して並べ替えます。このトピックで説明するシナリオでは InfoPath からサンドボックス ソリューションとして直接発行することを目的としていますが、管理者承認用フォーム テンプレートとして展開することもできます。
作業を始める前に、次の条件を満たしていることを確認してください。
フォームを発行する SharePoint Server 2010 または SharePoint Foundation 2010 サイトのサイト コレクション管理者であること。
フォーム テンプレートに対して選択したプログラミング言語が、以前のバージョン名が付いていない C# または Visual Basic のどちらかであること。InfoPath 2007 互換バージョンおよび InfoPath 2003 互換バージョンのプログラミング言語およびオブジェクト モデルは、サンドボックス ソリューションではサポートされていません。プログラミング言語を指定する方法の詳細については、「[方法] Visual Studio Tools for Applications をインストールして開発に使用する方法」を参照してください。
フォーム上の Repeating Table コントロールのデータを並べ替えるフォーム テンプレートを作成するには、次の手順を実行します。
フォーム内のデータをプログラムによって並べ替えるフォーム テンプレートを作成するには
InfoPath デザイン モードで新しいフォーム テンプレートを作成し、繰り返しテーブル コントロールをフォームに追加します。この例のサンプル コードではテーブルの 1 列目を基準として行を並べ替えていますが、任意の列を基準とするように簡単にコードを変更できます。
ボタン コントロールをフォームに追加します。テーブルを並べ替えるためのコードはボタンの Clicked イベントのイベント ハンドラーに追加されますが、別のイベントを使用することもできます。
ボタンを選択し、[プロパティ] タブをクリックし、[ユーザー設定コード] をクリックします。フォームをまだ保存していない場合は、保存を促すメッセージが表示され、コード エディターが開いてカーソルがボタンのイベント ハンドラーに設定されます。
次のコードをボタンのイベント ハンドラーに貼り付けます。1 列目の要素が配列に格納され、配列が並べ替えられた後、その配列を基準として表が並べ替えられます。このコードでは、並べ替えられるデータを文字列データと仮定しています。
// Put the elements from the first column into an array. XPathNavigator root = this.CreateNavigator(); // Create a node iterator which contains only the values that you want to sort. // For this form, the entire table is in "group1", each row is a "group2" // and the rows are "field1", "field2" and "field3" respectively. XPathNodeIterator nodeIterator = root.Select( "/my:myFields/my:group1/my:group2/my:field1", this.NamespaceManager); // Create arrays to use for sorting. string[] sortArrayWords = new string[nodeIterator.Count + 1]; int[] sortArrayKeys = new int[nodeIterator.Count + 1]; int arrayPosition = 1; // Populate the arrays for sorting. while (nodeIterator.MoveNext()) { // Loop until there are no more elements sortArrayWords[arrayPosition] = nodeIterator.Current.Value; sortArrayKeys[arrayPosition] = arrayPosition; arrayPosition += 1; } // Sort the array. Array.Sort(sortArrayWords, sortArrayKeys); arrayPosition = 0; // Create new XML to update the table. string newTableXML = ""; // Iterate through the sorted array of keys. for (int i = 1; i <= sortArrayWords.Length - 1; i++) { nodeIterator = root.Select( "/my:myFields/my:group1/my:group2", this.NamespaceManager); // Go to the right position in the table. for (int j = 1; j <= sortArrayKeys[i]; j++) { nodeIterator.MoveNext(); } // Add the row to the XML. newTableXML += nodeIterator.Current.OuterXml; } // Set the table to use the new XML. root.SelectSingleNode( "/my:myFields/my:group1", this.NamespaceManager).InnerXml = newTableXML;
' Put the elements from the first column into an array. Dim root As XPathNavigator = Me.CreateNavigator ' Create a node iterator which contains only the values that you want to sort ' For this form, the entire table is in "group1", ' each row is a "group2" ' and the rows are "field1", "field2" and "field3" respectively. Dim nodeIterator As XPathNodeIterator = root.Select( _ "/my:myFields/my:group1/my:group2/my:field1", Me.NamespaceManager) ' Create arrays to use for sorting. Dim sortArrayWords(nodeIterator.Count) As String Dim sortArrayKeys(nodeIterator.Count) As Integer Dim arrayPosition As Integer = 1 ' Populate the arrays for sorting. While nodeIterator.MoveNext() ' Loop until there are no more elements sortArrayWords(arrayPosition) = nodeIterator.Current.Value sortArrayKeys(arrayPosition) = arrayPosition arrayPosition += 1 End While ' Sort the array. Array.Sort(sortArrayWords, sortArrayKeys) arrayPosition = 0 ' Create new XML to update the table. Dim newTableXML As String = "" ' Iterate through the sorted array of keys. For i As Integer = 1 To sortArrayWords.Length - 1 nodeIterator = root.Select( _ "/my:myFields/my:group1/my:group2", Me.NamespaceManager) ' Go to the right position in the table. For j As Integer = 1 To sortArrayKeys(i) nodeIterator.MoveNext() Next ' Add the row to the XML. newTableXML &= nodeIterator.Current.OuterXml Next ' Set the table to use the new XML. root.SelectSingleNode("/my:myFields/my:group1", _ Me.NamespaceManager).InnerXml = newTableXML
次の手順を実行してフォームを発行します。
Backstage の [発行] タブで [SharePoint サーバー] をクリックします。
発行先の SharePoint サイトの URL を入力し、[次へ] をクリックします。
重要
このフォーム テンプレートをサンドボックス ソリューションとして発行するためには、このサイトのサイト コレクション管理者である必要があります。
[フォーム ライブラリ] をクリックし、[次へ] をクリックします。
[新しいフォーム ライブラリを作成する] をクリックし、[次へ] をクリックします。
フォーム ライブラリの名前と説明を入力し、[次へ] をクリックします。
[発行] をクリックします。
例 2: SharePoint リストでのベンダーの管理
この例では、Microsoft SharePoint Foundation 2010 のオブジェクト モデルに対するプログラミングを行います。それには、Microsoft.SharePoint.dll アセンブリへの参照を設定する必要があります。Microsoft.SharePoint.dll は、ライセンスが付与された SharePoint Server 2010 のコピーと共にインストールされています。
Microsoft.SharePoint.Server.dll は、既定で C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI にインストールされています。この DLL を、SharePoint オブジェクト モデルに対するプログラミングを行うプロジェクトにインクルードする必要があります。Microsoft Visual Studio Tools for Applications プロジェクトの中で Microsoft.SharePoint.dll への参照を設定するには、コード エディターを開き、[プロジェクト] メニューの [参照の追加] をクリックします。[参照の追加] ダイアログ ボックスで [参照] タブをクリックし、Microsoft.SharePoint.dll ファイルの場所を指定して [OK] をクリックします。これで、Microsoft.SharePoint.dll がプロジェクト ディレクトリにコピーされ、SharePoint Foundation 2010 オブジェクト モデルのメンバーを InfoPath ソリューションの中で使用できるようになります。
フォームのデザインとコードの作成
InfoPath フォームのコードから、SharePoint オブジェクト モデルを使用して参照リスト内にアイテムを作成できます。これは、SharePoint リストからドロップダウン ボックスを設定して、別のフォームを作成せずに新しい値を追加する場合に便利です。この例ではコンボ ボックスを使用して、現在リストにあるすべての値を表示し、まだ値が存在していない場合に値をリストに追加するプログラミング ロジックを作成します。
SharePoint リストに基づいてコンボ ボックスに新しいアイテムを追加できるフォーム テンプレートを作成するには
フォーム上にコンボ ボックス コントロールを挿入し、コンボ ボックスにバインドされているフィールドの名前を myCombo に変更します。
次の手順を実行して、コンボ ボックスへの値の読み込みに使用するデータ接続をリストに追加します。
[データ] タブの [外部データの取り込み] グループで [SharePoint リスト] をクリックします。
リストのあるサイトの URL を入力し、[次へ] をクリックします。
リストを選択し、[次へ] をクリックします。
追加するフィールドを選択します。この例では、Title と ID を選択します。Title には参照用の値が格納されます。[次へ] をクリックします。
次の画面で [次へ] をクリックします。
データ接続に LookupList という名前を付け、[完了] をクリックします。
次の手順を実行して、コンボ ボックス内の値をリストから読み込みます。
手順 1. で作成したコンボ ボックスを選択します。
リボンの [コントロール ツール] の [プロパティ] タブで [選択肢の編集] をクリックします。
[外部データ ソースから選択肢を取得する] をクリックします。
[データ ソース] に、手順 2. で作成したデータ接続が設定されていることを確認します。
値と表示名を Title に設定します。
ボタン コントロールをフォームに追加します。ユーザーがボタンをクリックするとコードが実行されます。実際のフォームでは、送信時に、またはコンボ ボックスの値が変更されたときに、このロジックを実行できます。フォーム内のコードで何も実行しない場合は、不要なポストバック処理を避けるためにこのロジックを送信時に実行することをお勧めします。
ボタンをクリックします。リボンの [コントロール ツール] の [プロパティ] タブで [ユーザー設定コード] をクリックします。フォームをまだ保存していない場合は、保存を促すメッセージが表示されます。
前述の説明に従って、Microsoft.SharePoint.dll アセンブリへの参照を追加します。
コードの簡単な例を次に示します。この例では、まず、コンボ ボックスの値がリストにあるかどうかを調べ、必要に応じて新しいアイテムを作成します。コードの中で使用する SharePoint オブジェクト モデルの破棄可能なメンバーを、忘れずにすべて破棄してください。そうしないと例外が発生します。
// Get the value of the combo box XPathNavigator root = this.CreateNavigator(); string theComboVal = root.SelectSingleNode("/my:myFields/my:myCombo", this.NamespaceManager).Value; // Get the list SPSite mySite = new SPSite("http:// YourServer/YourSite/"); SPWeb myWeb = mySite.RootWeb; SPList myList = myweb.Lists("LookupList"); // Query the list to see if it contains the item SPQuery myQuery = new SPQuery(); myQuery.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + theComboVal + "</Value></Eq></Where>"; SPListItemCollection myListItemCollection = myList.GetItems(myQuery); // If the query returns no items, create one if (myListItemCollection.Count == 0) { SPListItemCollection listItems = myList.Items; SPListItem newItem = listItems.Add(); newItem("Title") = theComboVal; newItem.Update(); } // Dispose of SharePoint items myWeb.Dispose(); mySite.Dispose();
' Get the value of the combo box Dim root As XPathNavigator = Me.CreateNavigator Dim theComboVal As String = root.SelectSingleNode("/my:myFields/my:myCombo", Me.NamespaceManager).Value ' Get the list Dim mySite As SPSite = New SPSite("http:// YourServer/YourSite/") Dim myWeb As SPWeb = mySite.RootWeb Dim myList As SPList = myweb.Lists("LookupList") ' Query the list to see if it contains the item Dim myQuery As New SPQuery() myQuery.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + theComboVal + "</Value></Eq></Where>" Dim myListItemCollection As SPListItemCollection = myList.GetItems(myQuery) ' If the query returns no items, create one If myListItemCollection.Count = 0 Then Dim listItems As SPListItemCollection = myList.Items Dim newItem As SPListItem = listItems.Add() newItem("Title") = theComboVal newItem.Update() End If ' Dispose of SharePoint items myWeb.Dispose() mySite.Dispose()
次の手順を実行してフォームを発行します。
Backstage の [発行] タブで [SharePoint サーバー] をクリックします。
発行先の SharePoint サイトの URL を入力し、[次へ] をクリックします。
重要
このフォーム テンプレートをサンドボックス ソリューションとして発行するためには、このサイトのサイト コレクション管理者である必要があります。
[フォーム ライブラリ] をクリックし、[次へ] をクリックします。
[新しいフォーム ライブラリを作成する] をクリックし、[次へ] をクリックします。
フォーム ライブラリの名前と説明を入力し、[次へ] をクリックします。
[発行] をクリックします。