For Each コマンドのオプション節を使用すると、For Each のベーステーブルとして使用するトランザクション (またはトランザクションレベル) を定義できます。
全般的な説明については、ベーストランザクション節を参照してください。
例
For Each Invoice
Print CustomerName, InvoiceDate
Endfor
For Each Invoice.Line
Print ProductName, InvoiceLineQuantity, InvoiceLinePrice, InvoiceLineTotal
Endfor
このトランザクション (またはトランザクションレベル) を、For Each のベーストランザクションと呼びます。 For Each のベーストランザクションを定義すると、GeneXus はそのベーステーブルを直接推論します。
このベーストランザクションは、データプロバイダーおよびグリッドにも適用されます。詳細については、データプロバイダーにおけるベーストランザクションを参照してください。
シナリオ
この機能によって For Each の表現力が向上するため、従来の方法では表現しにくいナビゲーションを、より直観的に宣言できる可能性があります。For Each のベーストランザクション節を使用した場合にナビゲーション結果がより直観的になる宣言のシナリオを、いくつか示します。
I. M-N 関係での For each
次のような、2 つのテーブルがある例を示します。この 2 つのテーブル User および Role は 3 番目のテーブルである UserRole を介して関連付けられます。UserRole の主キーは User および Role テーブルの主キーで構成され、従属項目属性はありません。
この構造の詳細は次のとおりです:
User
{
UserId*
UserName
}
Role
{
RoleId*
RoleName
}
UserRole
{
UserId*
RoleId*
}
ここでは、各ロールについて、関連ユーザーを表示するとします。
この場合、次の For Each を使用します:
For Each
Print RoleName
For Each
Print UserName
Endfor
Endfor
For Each 内部で、GeneXus は User をベーステーブルとして認識します。これによって Role と User のデカルト積が生成されますが、これは求める結果ではありません。For Each 内部で関連付けのテーブル (UserRole) をナビゲートするようにしたいのですが、Defined By 節を使用したナビゲーションを強制的に行う従属項目属性をテーブルに含めなかったため、この例では表現できません。
そのため、ベーストランザクションを定義することが解決策になります。このとき、For Each は次のようになります:
For Each
Print RoleName
For Each UserRole
Print UserName
Endfor
Endfor
ここで For Each 内部のベーストランザクションが UserRole トランザクションであることを明確に宣言したため、問題が解決します。
II. 複数テーブルをナビゲートするための式の簡略化
複数テーブルをナビゲートするクエリを解決する必要がある場合、複数の For Each を使用して表現するのは困難です。また、このようなクエリは、単一の SQL 文ではベーストランザクション節を使用しない限り解決できない場合もあります。
このような場合、次の例に示すように、For Each コマンド内に複数のベーストランザクションを追加できます:
For Each User, Program
where UserType = "Administrator"
Print UserName, ProgramName
Endfor
この例ではデカルト積が作成され、"administrator" ユーザーについての、ユーザーとプログラムのすべての組み合わせが列挙されます。 このシナリオのより具体的な例については、For Each コマンドにおける複数のベーストランザクションを参照してください。
ベーステーブルが特定される仕組み
For Each 内で 1 つのベーストランザクションが宣言される場合、このトランザクションに関連付けられたテーブルはベーステーブルと見なされます。For Each、条件、順序などの文に含まれる項目属性は、拡張テーブルに含まれる必要があります。
複数のベーストランザクションが宣言される場合、これらのトランザクションに関連付けられたテーブル同士が結合されます。結合が不可能な場合、デカルト積が作成されます。For Each の項目属性は、これらのいずれかのテーブルの拡張テーブル内にある必要があります。
For Each 内でベーストランザクションを使用するメリット
前述のシナリオに加え、ベーストランザクションを For Each 内で使用するメリットには、次のようなものがあります:
• 既存のナレッジベースが理解しやすくなる。For Each にベーストランザクションがあると、そのナレッジベースで初めて作業する開発者は、反復が実行されているテーブルを確認するためにナビゲーションを参照する必要がありません。
• For Each の表現能力が向上し、より簡素化される。
• 分析時間が短縮される。 For Each のベーステーブルの計算が不要になるため、分析時間が短縮されます。
• ベーストランザクションとその For Each との間のナレッジベース内の参照。 ナレッジベースには、トランザクション、およびそのトランザクションをベーストランザクションとして使用する For Each との間の参照が格納されるため、トランザクションが変更された場合、その変更により影響を受ける For Each を直接確認できます。
使用可能バージョン
GeneXus Tilo 以降
互換性に関する注記
For Each の Order 節でのあいまいさを回避するため、Tilo Beta 3 以降では、order キーワードが必須になりました。 次のようにプログラミングすると、エラーが返されます: error: Program 'AttributeX' does not exist:
For Each AttributeX
Endfor
これは、次のように変更する必要があります:
For Each order AttributeX
Endfor
以前のバージョンの GeneXus から変換されたナレッジベース
Tilo に変換されたナレッジベース、または以前のバージョンで生成された xpz ファイルの場合、オブジェクトを開いたり、指定したりすると、自動的に変換が実行されます。
|