フラットなデータ ソースから繰り返しカスケード リストを作成する - Greg Collins
in

InfoPath Dev

This Blog

Syndication

Archives

Greg Collins

フラットなデータ ソースから繰り返しカスケード リストを作成する

1 つのボックスの選択肢が別のボックスの値に依存する 2 つ以上のリスト ボックスが必要になることはよくあります。これは、カスケードリストと呼ばれます。カスケードを実行できるのは、最小 2 レベルからで、最大レベル数の制限はありません。以下はカスケードリストを必要とする一般的なシナリオの例です。

  • 場所: 州/市
  • 車両: メーカー/車種/装備
  • 学校: 年度/学期/授業科目/講師

カスケードのレベル数が増えると、それにかかわる処理と作業もより複雑になります。また、カスケードリストが繰り返しテーブルまたは繰り返しセクション内に表示される場合は、別の問題、「データのクロスオーバー」に対処する必要があります。データのクロスオーバーとは、特定の行のカスケードに表示されるオプションが、他の行で先に選択された値の影響を受けることを意味し、これによって真のカスケード効果が失われます。

このタスクでは、リストの設定に使用されるさまざまな値を含むフラットなセカンダリ データ ソースを作成します。次にドロップダウン リストボックスを使用して、レベルが 3 つある繰り返しカスケード リストを作成します。カスケード レベルを 3 つ作成するのは、レベルが 3 つ以上になると複雑さが増すことを示すためです。さらに、フラット データソースの性質を考えて、各リストをフィルタし、一意の値だけが表示されるようにします。データのクロスオーバーの問題は、current 関数を使用して解決します。最後に、カスケード内で先に選択されていた項目が変更されたときに選択済みのリストの値をクリアする方法で、選択項目の組み合わせが常に有効になるようにします。


フラットなセカンダリ データ ソース

データベース、Web サービス、および SharePoint からは、通常、フラットなデータ ソースが返されます。フラットなデータソースの構造には階層がありません。これは同一の要素を並べただけのリストで、それぞれが同じ属性セットを持っています。変更されるのは属性の値だけです。フラットなデータ ソースでは、一意の値だけがドロップダウン リストに表示されるようにフィルタすることも必要です。まず、フラットなセカンダリデータ ソースを作成します。

フラットなセカンダリ データ ソースを作成する

次のコードをテキスト エディタにコピーし、Vehicles - Flat Data Source.xml という名前でファイルを保存します。このファイルをこれから作成するフォームでセカンダリ データ ソースとして使用します。

<?xml version="1.0" encoding="UTF-8"?>
<Vehicles>
    <Vehicle year="1963" make="Chevrolet" model="Corvette"/>
    <Vehicle year="1963" make="Chevrolet" model="Nova"/>
    <Vehicle year="1963" make="Porsche" model="356"/>
    <Vehicle year="1963" make="Porsche" model="Carrera"/>
    <Vehicle year="1973" make="Ford" model="Bronco"/>
    <Vehicle year="1973" make="Ford" model="Mustang"/>
    <Vehicle year="1973" make="Ford" model="Pinto"/>
    <Vehicle year="1973" make="Toyota" model="Celica"/>
    <Vehicle year="1973" make="Toyota" model="Land Cruiser"/>
    <Vehicle year="1979" make="Jaguar" model="XJ6"/>
    <Vehicle year="1979" make="Pontiac" model="Trans Am"/>
    <Vehicle year="1979" make="Volvo" model="240"/>
    <Vehicle year="1979" make="Volvo" model="244DL"/>
    <Vehicle year="1987" make="Dodge" model="Ram Charger"/>
    <Vehicle year="1987" make="Dodge" model="Grand Caravan"/>
    <Vehicle year="1987" make="Honda" model="Civic"/>
    <Vehicle year="1987" make="Honda" model="Prelude"/>
    <Vehicle year="1987" make="Nissan" model="300ZX"/>
    <Vehicle year="1987" make="Nissan" model="Pulsar"/>
    <Vehicle year="1987" make="Nissan" model="Sentra"/>
    <Vehicle year="1999" make="GMC" model="Jimmy"/>
    <Vehicle year="1999" make="GMC" model="Sierra 2500 HD"/>
    <Vehicle year="1999" make="GMC" model="Yukon"/>
    <Vehicle year="1999" make="Honda" model="Passport"/>
    <Vehicle year="1999" make="Honda" model="Prelude"/>
    <Vehicle year="1999" make="Honda" model="CR-V"/>
    <Vehicle year="1999" make="Jeep" model="Cherokee"/>
    <Vehicle year="1999" make="Mercury" model="Grand Marquis"/>
    <Vehicle year="1999" make="Mercury" model="Sable"/>
    <Vehicle year="1999" make="Mercury" model="Villager"/>
    <Vehicle year="1999" make="Pontiac" model="Firebird"/>
    <Vehicle year="1999" make="Pontiac" model="Montana"/>
    <Vehicle year="1999" make="Pontiac" model="Sunfire"/>
    <Vehicle year="2003" make="Dodge" model="Dakota"/>
    <Vehicle year="2003" make="Dodge" model="Caravan"/>
    <Vehicle year="2003" make="Dodge" model="Ram Charger"/>
    <Vehicle year="2003" make="Dodge" model="Viper"/>
    <Vehicle year="2003" make="Mercury" model="Sable"/>
    <Vehicle year="2004" make="Dodge" model="Stratus"/>
    <Vehicle year="2004" make="Dodge" model="Viper"/>
    <Vehicle year="2004" make="Ford" model="Crown Victoria"/>
    <Vehicle year="2004" make="Ford" model="F250"/>
    <Vehicle year="2004" make="Ford" model="Thunderbird"/>
    <Vehicle year="2004" make="GMC" model="Sierra 3500"/>
    <Vehicle year="2004" make="Jeep" model="Grand Cherokee"/>
    <Vehicle year="2004" make="Jeep" model="Liberty"/>
</Vehicles>


フォーム

フラットなセカンダリ データ ソースができたので、これからフォームを作成します。まず、レベルが 3 つある繰り返しカスケードリストをサポートする単純なスキーマを設計します。次に、繰り返しテーブル内のドロップダウン リストボックスを使用して、レイアウトを設計します。レイアウトができたら、繰り返しカスケードの作成に集中します。

セカンダリ データ ソースをフォームに追加する

  1. 新しい空白のフォームをデザインします。
  2. [Tools] メニューの [Data Connections] をクリックし、[Add] をクリックします。
  3. Data Connection Wizard (データ接続ウィザード) の [Receive Data] をクリックし、[Next] をクリックします。
  4. [XML Document] をクリックし、[Next] をクリックします。
  5. [Browse] をクリックし、Vehicles - Flat Data Source.xml ファイルを探して選択し、[Open] をクリックします。次に、[Next] をクリックします。
  6. [Finish] をクリックし、[Yes] をクリックしてから、[Close] をクリックします。

スキーマの作成

  1. [Data Source] 作業ウィンドウを開きます。
  2. 「Vehicles」という名前のグループを追加します。
  3. [Vehicles] グループをクリックし、「Vehicle」という名前の繰り返しグループを追加します。
  4. [Vehicle] グループをクリックし、テキスト フィールドを 3 つ追加します。名前はそれぞれ「Year」、「Make」、および「Model」とします。

ビューの設計

  1. [Vehicle] を右クリックし、[Repeating Table] をクリックします。
  2. 見出し行の3 つのセルをすべて選択し、フォント サイズを「8」に設定します。
  3. 3 つのテキストボックスをそれぞれ右クリックし、[Change To | Drop-Down List Box] をクリックします。この結果を図 1 に示します。


図 1 繰り返しカスケード ドロップダウン リスト ボックスのレイアウト

  1. 繰り返しテーブルのラベルをダブルクリックします。
  2. [Repeating Table Properties] ダイアログボックスの [Data] タブで、挿入ボタンのヒントのテキストを「Insert Vehicle」に変更し、[OK] をクリックします。

カスケード リスト

フォームのレイアウトができたので、タスクの主目的であるリストを別のリストからカスケードさせる作業に入ります。処理はそれほど難しくありませんが、カスケード レベルの数が増えるごとに複雑さも増します。カスケードの作成にはフィルタの使用が必要です。リストボックスに表示されるオプションは、前のリスト ボックスで選択された値に基づいてフィルタされます。作成するカスケードは繰り返し構造なので、current 関数を使用して、フィルタが他の行の値にクロスオーバーしないようにする必要があります。それでは、用意しているセカンダリ データ ソースを使用して、各ドロップダウン リスト ボックスのオプションを設定し、カスケード フィルタを作成しましょう。

[Year] ドロップダウン リストを設定する

  1. [Year] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで [Look Up Values In A Data Connection] をクリックします。
  3. [Data Connection] ボックスの一覧の [Vehicles - Flat Data Source] をクリックします。
  4. [Entries] ボックスの右にある [Select XPath] ボタンをクリックし、[Vehicles/Vehicle/year] をクリックしてから、[OK] を 2 回クリックして、開いているダイアログ ボックスを閉じます。

[Make] ドロップダウン リストを設定する

  1. [Make] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで [Look Up Values In A Data Connection] をクリックします。
  3. [Data Connection] ボックスの一覧の [Vehicles - Flat Data Source] をクリックします。
  4. [Entries] ボックスの右にある [Select XPath] ボタンをクリックし、[Vehicles/Vehicle/make] をクリックします。

現在の行の [Year] の選択値に基づいて [Make] ドロップダウン リストをフィルタする

  1. [Filter Data] をクリックし、[Add] をクリックします。
  2. [Specify Filter Conditions] ダイアログ ボックスの 1 つ目のボックスの一覧の [Select A Field Or Group] をクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Vehicles/Vehicle/year] をクリックし、[OK] をクリックします。
  4. 2 つ目のボックスの一覧の [Is Equal To] をクリックします。
  5. 3 つ目のボックスの一覧の [Use A Formula] をクリックします。
  6. 次の式を入力します (図 2 を参照)。

current()/my:Year


図 2 [Year] を現在の行の値と比較するためのフィルタ

  1. [OK] を 5 回クリックして、開いているダイアログ ボックスをすべて閉じます。

データ クロスオーバーの問題が発生することは前に述べました。データ クロスオーバーの例は、図 3 と図 4 の違いに示されています (図 3 および図 4 は既に一意の値を表示するようにフィルタされています) 。current 関数を使用しない場合、車両のメーカーは、現在繰り返しテーブル内で選択されているすべての年式でフィルタされるため、無効な選択項目の組み合わせが表示されます。したがって、年式で 1963 年、1979 年、および 2004 年の 3 行が選択されている場合、それぞれの [Make] ボックスの一覧には、図 4 のように、選択されている 3 つの年式のメーカーすべてのリストが含まれます。current関数を適切に使用すると、[Make] ボックスの選択項目が、同じ行の [Year] ボックスで選択された年式の項目に限定されるので、データのクロスオーバーを回避できます。これを図 3 に示します。


図 3 current 関数を使用して年式でフィルタされた車両メーカー

図 4 current 関数を使用しないで年式でフィルタされた車両メーカー

ここまでで、レベルが 2 つの繰り返しカスケードができました。[Make] ボックスのオプションは、現在の行で選択されている [Year] の値に基づいてフィルタされます。これについては、フォームをプレビューしてテストできます。テストすると、各ドロップダウンリストに繰り返しの値が含まれていることがわかります。これは、フラットデータソースの使用による副産物ですが、後のセクションで一意の値を表示するためのフィルタを適用すると修正されます。次は、第 3 レベルのカスケードを作成します。ここから、カスケードのレベルを追加作成するたびにどんどん複雑になってくることがわかります。

[Model] ドロップダウン リストを設定する

  1. [Model] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで、[Look Up Values In A Data Connection] をクリックします。
  3. [Data Connection] ボックスの一覧の [Vehicles - Flat Data Source] をクリックします。
  4. [Entries] テキスト ボックスの右にある [Select XPath] ボタンをクリックし、[Vehicles/Vehicle/model] をクリックします。

現在の行の [Year] の選択値に基づいて [Model] ドロップダウン リストをフィルタする

  1. [Filter Data] をクリックし、[Add] をクリックします。
  2. [Specify Filter Conditions] ダイアログ ボックスの 1 つ目のボックスの一覧の [Select A Field Or Group] をクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Vehicles/Vehicle/year] をクリックし、[OK] をクリックします。
  4. 2 つ目のボックスの一覧の [Is Equal To] をクリックします。
  5. 3 つ目のボックスの一覧の [Use A Formula] をクリックします。
  6. [Insert A Formula] ダイアログ ボックスに次の式を入力します。

current()/my:Year

  1. [OK] をクリックします。

現在の行の [Make] の選択値に基づいて [Model] ドロップダウン リストをフィルタする

  1. [And] をクリックして、2 つ目のフィルタ条件を作成します。
  2. 2 つ目のフィルタ条件の 1 つ目のボックスの一覧の [Select A Field Or Group] をクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Vehicles/Vehicle/make] をクリックし、[OK] をクリックします。
  4. 2 つ目のボックスの一覧の [Is Equal To] をクリックします。
  5. 3 つ目のボックスの一覧の [Use A Formula] をクリックします。
  6. [Insert A Formula] ダイアログ ボックスに次の式を入力します。

current()/my:Make

  1. [OK] をクリックします。2 つのフィルタの条件を図 5 に示します。

図 5 繰り返しカスケード リストの第 3 レベルのフィルタ

  1. [OK] を 4 回クリックして、開いているダイアログ ボックスをすべて閉じます。

これでレベルが 3 つあるカスケードを作成できました。フォームをプレビューして、ドロップダウン リストボックスの機能をテストしてください。お気づきかもしれませんが、ここでは問題が 2 つあります。1 つは、リストオプションが一意ではないこと、もう 1 つは、無効な選択項目の組み合わせを作成できることです。この 2 つの問題を次の 2 つのセクションで解決します。


一意の値を表示するためにリストをフィルタする

通常、フラット データ ソース内の値は繰り返されます。XML の構造を考えるとこれは重要ですが、一方でリストボックスのオプションの増大につながります。同じオプションを多数を表示しても、ユーザーは混乱し、いら立つだけです。これを解決するには、リストをフィルタして一意の値だけを表示します。このためには、XPath を使用します。

カスケード レベルを追加するごとにカスケード フィルタの複雑さが増大するように、一意性フィルタの複雑さも増大することにも触れておきます。これについては、この後、一意の値を表示するために [Model] ドロップダウン リストに適用するフィルタで使用する式を見てもわかります。

[Year] ドロップダウン リストに一意性フィルタを追加する

  1. [Year] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで、[Entries] ボックスの右にある [Select XPath] ボタンをクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Filter Data] をクリックし、[Add] をクリックします。
  4. [Specify Filter Conditions] ダイアログ ボックスの 1 つ目のボックスの一覧の [The Expression] をクリックし、次の式を入力します (図 6 を参照)。

not(. = ../preceding-sibling::Vehicle/@year)


図 6 一意の値だけを表示するためにリスト オプションに適用するフィルタ

  1. [OK] を 4 回クリックして、開いているダイアログ ボックスをすべて閉じます。

[Make] ドロップダウン リストに一意性フィルタを追加する

最初のリスト ボックスから続く各カスケードレベルでは、前の各レベルの選択を考慮に入れた一意性フィルタを設定する必要があります。前の選択を考慮に入れない場合、このフィルタの性質上、気づかないうちに有効なオプションをすべてフィルタで除外してしまう可能性があります。

たとえば、サンプルのセカンダリ データ ソースでは、年式が 1987 年および 1999 年の両方に Honda の車両が含まれています。選択されている年式を考慮しない場合、年式として 1999 年が選択されたときに、メーカー名の Honda はオプションとして表示されません。これは、フィルタが、メーカー名 Honda がセカンダリ データソースで既に出現していると判断するからです。年式が 2003 年および 2004 年の Dodge も、1987 年に Dodge が既に出現しているので、完全にフィルタで除外されます。サンプルのセカンダリ データソースでこの問題が発生するメーカーおよび車種は他にもいくつかあります。

  1. [Make] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで [Entries] ボックスの右にある [Select XPath] ボタンをクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Filter Data] をクリックし、[Add] をクリックします。
  4. [Specify Filter Conditions] ダイアログ ボックスの 1 つ目のボックスの一覧の [The Expression] をクリックし、次の式を入力します。

not(. = ../preceding-sibling::Vehicle[@year = current()/my:Year]/@make)

[Year] ドロップダウン リストに配置した一意性フィルタと比較すると、Vehicle ノードに追加のサブフィルタが指定されています。サブフィルタ [@year = current()/my:Year] は、選択した年式の各メーカーの一意の値を表示しているかどうかを、メイン フィルタに強制的に検証させます。

  1. [OK] を 4 回クリックして、開いているダイアログ ボックスをすべて閉じます。

[Model] ドロップダウン リストに一意性フィルタを追加する

  1. [Model] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスで [Entries] ボックスの右にある [Select XPath] ボタンをクリックします。
  3. [Select A Field Or Group] ダイアログ ボックスの [Filter Data] をクリックし、[Add] をクリックします。
  4. [Specify Filter Conditions] ダイアログ ボックスの 1 つ目のボックスの一覧の [The Expression] をクリックし、次の式を入力します。

not(. = ../preceding-sibling::Vehicle[@year = current()/my:Year and @make = current()/my:Make]/@model)

ここでは、前述の [Make] ドロップダウン リストの一意性フィルタの場合と同様に、選択した年式およびメーカー内の車種のリストからの繰り返しオプションだけを削除していることを保証するサブフィルタを追加しました。

  1. [OK] を 4 回クリックして、開いているダイアログ ボックスをすべて閉じます。

どのカスケード レベルでも、値が常に一意であり、それが変わることがないことを保証できる場合は、一意性フィルタを追加する必要はありません。しかし、確信がない場合は追加しておく方が賢明です。一意の値を表示するためにリストに適用するフィルタの詳細については、「リストに一意のオプションだけを表示する」を参照してください。
 
変更後に選択項目をクリアする

カスケード リストで対応が必要なもう 1 つの問題は、既に選択されていた項目が、その前のレベルで選択項目が変更されたときに無効になる可能性が高いことです。たとえば、年式に 1963 年、車種に Chevrolet を選択し、後で年式に 1973 年を選択した場合、Chevrolet は 1973 年式の車種としてデータソースにリストされていないのに、選択済みの車種としてそのまま残ります。そこで、無効な選択項目の組み合わせが存在できないように、古い値をクリアする必要があります。これは、動作規則を使って簡単に修正できます。

少し時間をかければ、おそらく後に続く選択済みの値が有効かどうかを判断して、無効な値だけをクリアすることもできるでしょう。しかし、後の選択項目を単純にすべてクリアすることには利点があります。その 1 つは、ドミノ効果のように動作規則もカスケードできることです。1 つの値が変更されると、次の値がクリアされます。その値のクリアによって、さらにそれに続く値が次々にクリアされます。動作規則は自動的に現在の行に適用されるので、動作規則でcurrent関数を使用してフィルタする必要はありません。

作成する動作規則には条件を指定しないので、選択値が変更されるたびに処理されます。フィールドの選択値をクリアするために、動作規則の [Value] ボックスは空白のままにします。

[Year] の選択値が変更されたときに [Make] の選択済みの値をクリアする

  1. [Year] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスの [Rules] をクリックし、[Add] をクリックします。
  3. 動作規則に「Clear Make」という名前を付け、[Add Action] をクリックします。
  4. [Action] ダイアログ ボックスの [Action] ボックスの一覧の [Set A Field's Value] をクリックします。
  5. [Field] ボックスの右にある [Select XPath] ボタンをクリックし、メイン データ ソースの [myFields/Vehicles/Vehicle/Make] をクリックします。
  6. [OK] を 5 回クリックして、開いているダイアログ ボックスをすべて閉じます。

 

[Make] で選択値が変更されたときに [Model] の選択済みの値をクリアする

  1. [Make] ボックスをダブルクリックします。
  2. [Drop-Down List Box Properties] ダイアログ ボックスの [Rules] をクリックし、[Add] をクリックします。
  3. 動作規則に「Clear Model」という名前を付け、[Add Action] をクリックします。
  4. [Action] ダイアログ ボックスの [Action] ボックスの一覧の [Set A Field's Value] をクリックします。
  5. [Field] ボックスの右にある [Select XPath] ボタンをクリックし、メイン データ ソースの [myFields/Vehicles/Vehicle/Model] をクリックします。
  6. [OK] を 5 回クリックして、開いているダイアログ ボックスをすべて閉じます。

確認

これで、レベルが 3 つあり、一意の値を表示するためのフィルタを備え、無効な選択項目の組み合わせが表示されない繰り返しカスケード リストを作成できました。フォームをプレビューし、さまざまな選択項目の組み合わせを試してください。

©2005 Greg Collins. All rights reserved. Licensed to Autonomy Systems, LLC for display on InfoPathDev.com.

Comments

No Comments

About Kaoru Okumura

Program Manager, Qdabra.com Kaoru worked for ten years at Microsoft as a program manager, and many years at IBM Tokyo Research Lab as an advisory researcher. She led projects on natural language related research and products including Japanese search and proofing tools. Kaoru holds a Master of Science in Mathematics from Kyushu University, and BA from International Christian University. She enjoys performing Butoh dance, and taking photography.
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.