本文へ移動
Wagby11
マニュアルのグループを選ぶ

WAGBY11 MANUAL / 05

親子モデルを同時更新する

親の登録・更新画面で明細行を編集し、親と子をまとめて保存する方法を説明します。

最終更新日:

親子関係の小目次へ

1. このページで伝える機能

受注伝票の登録・更新フォームで、複数の明細を一覧形式で入力できます。親と明細をまとめて保存するため、明細ごとに別の登録画面を開く手間を減らせます。

2. Wagby11で実現できること

2.1 親と明細をまとめて編集する

受注伝票の件名を入力し、「末尾に追加」で明細行を増やします。品名と数量を入力して保存すると、親と明細が同時に登録されます。

受注伝票の登録画面で明細行を入力します。
受注伝票の登録画面で明細行を入力します。

更新画面では、既存行の変更、新規行の追加、既存行の削除予定への変更ができます。削除予定の既存行は保存前なら「元に戻す」で取り消せます。

親の件名変更と、明細の変更・追加・削除をまとめて行う画面。
親の件名変更と、明細の変更・追加・削除をまとめて行う画面。
保存後の受注伝票と更新された明細一覧。
保存後の受注伝票と更新された明細一覧。

2.2 入力エラーを確認してから保存し直す

明細の品名を空にして保存すると入力エラーになり、更新画面に留まります。この操作では、保存済みの親の件名も変更されていないことを確認しました。

明細の品名が空のため入力エラーになった親子更新画面
子の入力エラーを解消してから、親と明細を保存し直します。

親と子は一つの保存処理で扱います。子の入力エラーや権限・同時更新の競合などで処理が失敗した場合は、親を含めて保存を取り消します。親と子の両方に操作に応じた権限が必要です。

複数の子モデルを合計した1要求の操作数上限は、「環境」の一括保存の操作数上限を設定するを参照してください。

2.3 複数の子モデルをタブで切り替える

一つの親フォームに、複数の種類の子モデルを組み込めます。表示対象の子が二つ以上あると、子モデルの名前を使ったタブが自動で表示されます。例えば「受注タブサンプル」では、品名と数量を入力する「商品明細」と、資料名とファイルを入力する「添付資料」を分けています。

親フォームの商品明細タブで品名と数量を入力した画面。
商品明細と添付資料を、同じ親フォーム内のタブで切り替えます。

「添付資料」へ切り替えて資料名を入力し、ファイルを選択できます。タブを行き来しても、それぞれのタブへ入力した値と選択済みのファイルは保持されます。

添付資料タブで資料名とファイルを指定した親子登録画面。
添付資料タブの入力と選択したファイルも、タブ切り替え後に保持されます。

「保存」は、表示中のタブだけでなく、親と設定されたすべての子タブの変更をまとめて保存します。保存後に更新画面で開き直すと、商品明細と添付資料の両方を確認・編集できます。親と全子の保存は一つの処理で行うため、どれかの子でエラーになると親を含めて保存されません。

タブごとに独立した子モデルを定義し、それぞれに親への参照と枝番による複合主キー、必要な権限と編集項目を用意します。更新時に値を復元するため、子の編集項目は子の一覧出力にも含めます。複数の親を一度に編集する機能や、一つの子モデルの項目を分けるレイアウトのタブとは用途が異なります。

2.4 入力中に明細と合計を再計算する

親子フォームの保存前計算を有効にすると、数量や単価の変更に応じて明細金額と親の合計を求め、保存前に確認できます。計算式や子の集計は別に定義します。有効にするだけで、金額の計算式や税率が自動で決まるわけではありません。

場面動作ルール
入力値の変更、明細の追加・削除画面に残っている子行全体を使って計算します。未変更の既存行も対象とし、削除予定の行は除外します。複数の子タブがある場合も、表示中のタブだけに限定しません。
子の金額と親の合計を計算子の計算項目を求めてから集計し、合計に依存する親の税額・税込合計なども順に再計算します。保存しない子の表示用計算項目も集計できます。
計算結果の表示親と各子行の読み取り専用の計算項目へ結果を反映します。計算しただけでは、レコードの保存や採番は行いません。
「保存」で登録・更新全子行の保存後に親の集計と依存項目を再計算・検証し、親子全体を一つの処理で確定します。保存時の検証などで失敗した場合は、親子全体を取り消します。

子の合計にsumを使う場合、未入力の値は集計から除き、対象が0件なら合計は0になります。明細の金額を未入力時にどう扱うか、税率、端数の丸め方もAIへの指示で決めてください。

標準の保存前計算は、親・子の宣言的なcalcとcalc.childrenを使います。保存用・表示用のJavaカスタム計算や保存時の処理は、この計算では実行しません。独自のJava処理を入力中の計算にも使う場合は、フォーム計算用の拡張を別に検討します。

2.5 保存後に完了通知を表示する

登録・更新に成功したとき、固定のメッセージや、保存後の金額などの条件に応じたメッセージを表示できます。例えば「受注と明細を保存しました。」という通知や、合計が一定額以上の場合の確認案内を用意できます。

  • 親の通知は、すべての子の保存と、保存確定前の業務処理を終えた最終状態で一度だけ判定します。親の途中の保存では通知しません。
  • 子の通知は、登録・更新した行ごとに判定します。削除行は通知せず、子が0行でも親の通知は表示できます。
  • 親の通知、子モデルの定義順、各子の要求内の行順にまとめ、各モデル内では通知の宣言順を保ちます。同じ通知IDでも、異なる行の通知を省略しません。
  • 標準画面は、入力チェックの警告とは別に完了通知を一つのダイアログへまとめて表示します。「閉じる」で閉じてから、保存後の画面へ進みます。
  • 親子の保存処理全体が失敗した場合は、完了通知を表示しません。

通知の条件と本文では、同じモデルの保存する数値・文字列などの単一値や、単一参照のキーを使えます。ファイル、パスワード、複数参照、保存しない項目、別モデルの値、変更前の値は直接参照できません。子の合計を通知したい場合は、親に保存する集計値を用意して、その値を条件にします。読取権限で非表示・マスクとなる項目を条件または本文に使う通知は、通知全体を表示しません。

通知の式の評価エラー、条件のnull、本文のnullや空白は設定・データの不備として保存を失敗させます。未入力になり得る値にはnullの判定を含めます。通知レベルのerrorとは別の動作です。

3. AIへの指示例

最小限の指示例

受注伝票と商品明細・添付資料を同じ画面で入力・変更し、子の種類ごとにタブを分けてまとめて保存できるようにしてください。金額は入力中に再計算し、保存後に完了メッセージを表示してください。

どの子をフォームへ含めるか、登録と更新の両方で使うか、必要な列や権限などをAIが類推して補います。例えば、商品明細には品名・数量、添付資料には資料名・ファイルを用意する構成が考えられます。計算については、金額の対象項目・税率・丸め方、通知については、対象操作・文言・表示条件も類推して補います。最小限の指示だけで以下と同じモデル・項目構成や計算結果になるとは限りません。既存明細の変更・削除も必要かを伝えると、確認すべき操作が明確になります。

より詳細な指示例

SalesOrderの登録・更新フォームにorder_lineの一覧編集を組み込んでください。order_lineは親参照orderIdとbranchidのlineNoを複合主キーにし、予約属性versionを保持します。品名と数量を編集でき、既存値を復元できるよう子の一覧出力にも含めます。既存行の数量変更、新規行追加、既存行の削除予定とその取消を確認してください。親の件名と全明細を一回の保存で更新し、子が入力エラーの場合は親も保存されないことを確認してください。
既存のモデル・主キー・データ・権限を保持し、guide・referenceで必要な仕様を確認してください。新規モデルにはG_ADMINの必要な登録・参照・更新・削除権限と予約属性versionを用意します。メニューと一般利用者向け操作マニュアルを更新し、設計情報の検証・コード生成・起動を行って保存後の内容を確認してください。

複数の子を持つサンプルを用意する場合は、次のように指示できます。

受注タブサンプル(TabbedOrder)を親として、自動採番の受注IDと件名を用意してください。
子モデルを二つ作成します。
・商品明細(TabbedOrderItem):品名と数量を入力する。
・添付資料(TabbedOrderDocument):資料名と添付ファイルを入力する。ファイルは1MiB以下のテキストまたはPDFとする。
各子は、親の受注IDを参照する主キーと、枝番の行番号による複合主キーにします。親と各子に予約属性versionを持たせ、必要なCRUD権限を設定してください。各子の一覧出力には、親参照・枝番と、更新時に復元するすべての編集項目を含めます。
親の登録・更新フォームのui.form.childrenへ両方を指定し、bulk_saveを有効にします。標準機能で子モデル名のタブを表示し、タブを切り替えても入力値と選択ファイルを保持してください。
両方のタブへ入力して一回の保存で登録し、更新画面で開き直して両方の値とファイルを確認してください。片方のタブを表示した状態で保存しても、もう片方の変更も保存されることを確認します。
既存のモデル・主キー・データ・権限を保持し、guide・referenceを確認してください。メニューと一般利用者向け操作マニュアルを用意し、生成・ビルド・起動後に動作を確認してください。

数量・単価・明細金額と、親の合計を持つ受注モデルへ、保存前計算と通知を追加する場合の指示例です。

親子同時登録・更新に保存前計算を追加してください。親のui.form.calculateをtrueにし、子の数量・単価の変更、行追加・削除に応じて計算します。
子の明細金額は数量×単価とし、どちらかが未入力ならnullにします。保存しない表示用の計算項目として用意してください。親の税抜合計subtotalは、子の明細金額をcalc.childrenのsumで集計して保存します。削除予定の行は除外し、未変更の行も含む全子行を使います。子が0行なら合計0とします。
親の税額は税抜合計×10%を小数0桁で四捨五入し、税込合計は税抜合計+税額とします。計算項目は直接編集させません。入力中は保存・採番せず、保存確定時にも親子全体を再計算・検証してください。
親の登録・更新成功時に「受注と明細を保存しました。」をinfoで表示してください。保存後のsubtotalが1000000以上なら「合計が100万円以上です。承認手続きを確認してください。」をwarnで追加します。ui.notificationsを使い、通知は入力チェックと区別してください。
既存のモデル・主キー・データ・権限を保持し、guide・referenceで計算順序と通知の制約を確認してください。一般利用者向け操作マニュアルも更新してください。

4. 編集されるAppSchemaの例

以下は関連する定義の抜粋です。構文を覚えなくても、実現したい動作をAIへ伝えられます。

# SalesOrder.yaml
ui:
  form:
    children:
      - entity: order_line
        bulk_save: true
        screens: [create, update]

# order_line.yaml の属性の抜粋
entity:
  attributes:
    - { name: 受注伝票, name_en: orderId, type: reference, pk: true,
        fk: { entity: SalesOrder, field: orderId } }
    - { name: 明細番号, name_en: lineNo, type: branchid, pk: true }
    - { name: 品名, name_en: itemName, type: string, length: 100 }
    - { name: 数量, name_en: quantity, type: integer }
    - { name: バージョン, name_en: version, type: number,
        hidden: true, reserved: true }
functions:
  - description: 受注明細検索
    list: [{ name_en: orderId }, { name_en: lineNo },
           { name_en: itemName }, { name_en: quantity }]

ui.form.childrenは親フォームでの同時保存用です。子単独の一覧更新用のui.list.bulk_saveとは設定先が異なります。ここでは子の項目定義と一覧設定の抜粋を示しています。入力必須などの検証や権限も別に定義します。

二つの子をタブで組み込む場合は、親に次のように指定します。各子のモデル定義は別に用意します。

# TabbedOrder.yaml
ui:
  form:
    children:
      - entity: TabbedOrderItem
        bulk_save: true
        screens: [create, update]
      - entity: TabbedOrderDocument
        bulk_save: true
        screens: [create, update]

表示対象の子が一つなら一覧を直接表示し、二つ以上ならタブへ分けます。タブ名には各子のentity.nameを使います。タブを作るために別途uidefsでタブ配置を指定する必要はありません。

以下は、金額計算用の項目を持つ親子モデルへ追加する例です。前節の複数タブのサンプルとは別の、計算と通知の設定例を示します。

# 親 SalesOrder の設定の抜粋
ui:
  form:
    calculate: true
    children:
      - entity: order_line
        bulk_save: true
        screens: [create, update]
  notifications:
    - id: SAVE_COMPLETED
      on: [create, update]
      level: info
      message:
        value: 受注と明細を保存しました。
    - id: HIGH_AMOUNT
      on: [create, update]
      level: warn
      when: 'subtotal != null and subtotal >= 1000000'
      message:
        value: 合計が100万円以上です。承認手続きを確認してください。

子の表示用金額を計算してから、親の保存する合計へ集計する属性の抜粋です。親参照・枝番・数量・単価などは別に定義します。

# 子 order_line の entity.attributes 内
- name: 明細金額
  name_en: lineAmount
  type: decimal
  precision: 14
  scale: 2
  transient: true
  calc:
    on: [display]
    expression: 'quantity == null or unitPrice == null ? null : quantity * unitPrice'

# 親 SalesOrder の entity.attributes 内
- name: 税抜合計
  name_en: subtotal
  type: decimal
  precision: 14
  scale: 2
  calc:
    on: [create, update]
    children:
      entity: order_line
      field: lineAmount
      function: sum

calculateは保存前計算を有効にする設定で、式や集計はcalcに記述します。通知はui.notificationsで対象操作・条件・本文を指定します。構文を覚えずに、計算の順序と通知したい内容をAIへ伝えられます。

5. 参考資料

guide:親子モデル同時更新
designer/docs/appschema/html/guide/07-screens/17-parent-child-bulk-edit.html
reference:ui
designer/docs/appschema/html/reference/10-ui.html
reference:式言語(子行の集計)
designer/docs/appschema/html/reference/16-expression-language.html
reference:entity
designer/docs/appschema/html/reference/06-entity.html