Application Dictionary Deep Dive

Level: Intermediate Module: General Foundation 15 min read Lesson 13 of 47

Overview

  • What you’ll learn: Advanced Application Dictionary techniques including building custom windows from scratch, mastering reference types, configuring validation rules, and leveraging virtual columns.
  • Prerequisites: Lessons 1-12 (Beginner level)
  • Estimated reading time: 25 minutes

Introduction

The Application Dictionary (AD) is the beating heart of iDempiere. Every window, tab, field, and process you see in the UI is defined as metadata in the AD. While the beginner curriculum introduced you to the AD concept, this lesson takes you deep into the mechanics of building and customizing the dictionary. By the end of this lesson, you will be able to create a fully functional window from scratch, understand every reference type available, and configure sophisticated validation logic — all without writing a single line of Java code.

Creating a Window from Scratch

Building a new window in iDempiere follows a precise sequence. Each step builds on the previous one, and skipping steps leads to errors. Here is the complete workflow:

Step 1: Register the Table (AD_Table)

Navigate to Application Dictionary > Table and Column. Create a new record with these essential fields:

  • DB Table Name: Your physical database table name (e.g., Z_MyCustomTable). By convention, custom tables use the Z_ prefix or your organization prefix.
  • Name: A human-readable name (e.g., “My Custom Table”).
  • Table Type: Usually left as the default. Options are Table, View, and Single Row.
  • Data Access Level: Controls which roles can access records. Common values include Client+Organization, System+Client, and All.
  • EntityType: Set to “User Maintained” for custom work. This is critical — it prevents your customizations from being overwritten during migrations.
  • Maintain Change Log: Enable this to track who changed what and when.

After saving, use the Create Columns from DB process (gear icon) if the physical table already exists. If you are starting fresh, you will define columns manually.

Step 2: Define Columns (AD_Column)

Switch to the Column tab. Every column in your table needs an AD_Column record. Essential columns that every table should have:

  • AD_Client_ID — Multi-tenant client identifier
  • AD_Org_ID — Organization identifier
  • Created, CreatedBy, Updated, UpdatedBy — Audit trail fields
  • IsActive — Soft-delete flag
  • The primary key column (e.g., Z_MyCustomTable_ID)
  • Z_MyCustomTable_UU — UUID column for replication and migration

For each column, you must configure:

  • DB Column Name: The physical column name in the database.
  • Name: The label shown in the UI.
  • Reference: The data type/display type (String, Integer, Table Direct, List, etc.).
  • Mandatory: Whether the field requires a value.
  • Default Logic: An expression that pre-fills the field (covered in detail below).
  • Key Column: Check this for the primary key column.

After defining your columns, run the Synchronize Column process to create or alter the physical database columns.

Step 3: Create the Window (AD_Window)

Navigate to Application Dictionary > Window, Tab & Field. Create a new window record:

  • Name: The window title (e.g., “My Custom Window”).
  • Window Type: “Maintain” for standard CRUD windows, “Transaction” for document-style windows (with header/line structure), or “Query Only” for read-only views.
  • EntityType: “User Maintained” for custom work.

Step 4: Add Tabs (AD_Tab)

Switch to the Tab sub-tab. Every window needs at least one tab:

  • Name: The tab label.
  • Table: Link to the AD_Table you created in Step 1.
  • Tab Level: 0 for the main (header) tab. Child tabs use 1, 2, etc.
  • Sequence: Controls the display order of tabs.
  • Link Column: For child tabs, this is the foreign key that links to the parent tab.
  • WHERE Clause: Optional SQL filter applied to the tab.
  • Order By Clause: Default sort order.
  • Read Only: Makes the entire tab non-editable.

Step 5: Configure Fields (AD_Field)

After saving the tab, use the Create Fields process to auto-generate AD_Field records from your columns. Then customize each field:

  • Sequence: Controls field display order.
  • Displayed: Whether the field is visible.
  • Display Logic: Conditional visibility expression.
  • Read Only Logic: Conditional editability expression.
  • Field Group: Groups fields under collapsible sections.
  • Same Line / Span Column: Layout controls.

Step 6: Add to Menu

Finally, add a menu entry via Application Dictionary > Menu to make the window accessible. Set the Action to “Window” and select your new window.

Reference Types Deep Dive

References determine how a column is stored, displayed, and edited. Choosing the right reference type is one of the most important decisions in AD design.

Table Direct

The simplest foreign key reference. The column name must exactly match the target table’s key column (e.g., a column named C_BPartner_ID automatically references the C_BPartner table). The UI renders a dropdown populated with all active records from that table.

-- Column name: C_BPartner_ID
-- Automatically links to C_BPartner table
-- No additional configuration needed

Table

A more flexible foreign key reference. Unlike Table Direct, the column name does not need to match the target table. You configure a Reference Key (AD_Ref_Table) that specifies:

  • Table: The source table.
  • Key Column: Which column provides the stored value.
  • Display Column: Which column is shown to the user.
  • WHERE Clause: Optional filter on available records.
  • ORDER BY Clause: Sort order of the dropdown.

This is the reference type you use when you need filtered dropdowns, custom display values, or when your column name does not follow the naming convention.

List

Stores a short string value selected from a predefined set. Configure a Reference List (AD_Ref_List) with value-name pairs. Ideal for status fields, type fields, and any enumeration with a small, fixed set of values.

-- Example: DocStatus reference list
-- Value: DR  Name: Drafted
-- Value: CO  Name: Completed
-- Value: VO  Name: Voided
-- Value: CL  Name: Closed

Search

Similar to Table, but renders as a search dialog instead of a dropdown. Used for tables with many records (e.g., Products, Business Partners) where a dropdown would be impractical. The user can type to filter or click the search icon to open a lookup dialog with multiple search criteria.

Button

Renders as a clickable button. Can trigger a process (AD_Process) or open a specialized dialog. The column typically stores a status code that the button action updates. Document processing buttons (DocAction) are the most common example.

Location

A specialized reference for address fields. Links to the C_Location table and renders the location editor dialog (Address 1, Address 2, City, State/Region, ZIP, Country). The dialog auto-adapts based on the selected country’s address format.

Account

Opens the GL Account combination editor. Used for fields that store accounting combinations (Account + Organization + Business Partner + Product + Activity + Campaign + etc.). Links to the C_ValidCombination table.

PAttribute (Product Attribute)

Opens the Product Attribute Set Instance editor. Used for fields that need to capture lot numbers, serial numbers, guarantee dates, and other attribute set instance values. Links to M_AttributeSetInstance.

Validation Rules

Validation Rules (AD_Val_Rule) restrict the records shown in a dropdown or search dialog. They are SQL WHERE clauses that dynamically filter available options.

Creating a Validation Rule

Navigate to Application Dictionary > Validation Rules and create a new record:

-- Name: Active Vendors Only
-- Type: SQL
-- Validation Code:
C_BPartner.IsVendor='Y' AND C_BPartner.IsActive='Y'

You then assign this validation rule to a column (AD_Column.AD_Val_Rule_ID) or a column’s reference table configuration. When the user opens the dropdown, iDempiere appends this WHERE clause to the lookup SQL.

Context Variables in Validation Rules

Validation rules become powerful when you use context variables to create dynamic filters:

-- Only show products from the selected warehouse's organization
AD_Org_ID = @AD_Org_ID@

-- Only show BPartner locations for the selected Business Partner
C_BPartner_ID = @C_BPartner_ID@

-- SQL-based context variable
@SQL=SELECT SalesRep_ID FROM C_BPartner WHERE C_BPartner_ID=@C_BPartner_ID@

Context variables use the @VariableName@ syntax. iDempiere resolves them at runtime from the current window context (field values, login defaults, preferences).

Display Logic and Read Only Logic

Display Logic controls whether a field is visible. Read Only Logic controls whether a field is editable. Both use the same expression syntax.

Column-Based Expressions

-- Show field only when IsSOTrx is Yes
@IsSOTrx@='Y'

-- Show field only when DocStatus is Drafted
@DocStatus@=DR

-- Combine conditions
@IsSOTrx@='Y' & @DocStatus@=DR

-- OR logic
@IsSOTrx@='Y' | @PaymentRule@=S

-- Not equal
@DocStatus@!CO

SQL-Based Display Logic

-- Show field only if user has a specific role
@SQL=SELECT COUNT(*) FROM AD_User_Roles
WHERE AD_User_ID=@#AD_User_ID@ AND AD_Role_ID=1000000 AND IsActive='Y'

The @SQL= prefix tells iDempiere to execute the SQL and use the result. If the result is greater than 0 (or not empty), the condition is true.

Default Values

Default values pre-populate fields when creating new records. iDempiere supports several expression types:

System Context Variables

@#Date@          -- Current system date
@#AD_Client_ID@  -- Current client ID
@#AD_Org_ID@     -- Current organization ID
@#AD_User_ID@    -- Current user ID
@#AD_Role_ID@    -- Current role ID
@#AD_Language@   -- Current language

Window Context Variables

@C_BPartner_ID@  -- Value from C_BPartner_ID field in current window
@IsSOTrx@        -- Value from IsSOTrx field (Sales Transaction flag)
@M_Warehouse_ID@ -- Value from parent tab's warehouse field

SQL-Based Defaults

-- Default to the first warehouse for this org
@SQL=SELECT M_Warehouse_ID FROM M_Warehouse
WHERE AD_Org_ID=@AD_Org_ID@ AND IsActive='Y'
ORDER BY IsDefault DESC, M_Warehouse_ID LIMIT 1

Literal Values

Y        -- Boolean Yes
N        -- Boolean No
0        -- Zero
DR       -- String literal (e.g., for DocStatus)

EntityType and Customization Tracking

The EntityType field exists on most AD tables (Table, Column, Window, Tab, Field, Process, etc.). It serves as a namespace mechanism that identifies who owns a particular piece of metadata:

  • D (Dictionary): Core iDempiere elements. Never modify these directly.
  • C (Compiere): Legacy Compiere elements. Also should not be modified.
  • U (User Maintained): Your custom elements. Safe to modify and migrate.
  • Custom EntityTypes: You can register your own (e.g., “MYORG”) in the AD_EntityType table.

EntityType is critical for migrations and pack-in/pack-out. The 2Pack migration tool uses EntityType to determine which elements belong to your customization and should be exported. Always set your custom elements to an appropriate EntityType.

Virtual Columns (Column SQL)

Virtual columns are computed columns that do not exist in the physical database table. They are defined entirely in the AD using the Column SQL field on AD_Column. iDempiere injects the Column SQL as a subquery into the SELECT statement.

Example: Total Line Amount

-- Column SQL for a virtual column "TotalLines" on C_Order
(SELECT COALESCE(SUM(LineNetAmt), 0)
 FROM C_OrderLine ol
 WHERE ol.C_Order_ID = C_Order.C_Order_ID)

Configuration requirements for virtual columns:

  • The column must exist in AD_Column but not in the physical table.
  • Set Column SQL to your subquery expression (enclosed in parentheses).
  • The column is automatically read-only — you cannot edit computed values.
  • Virtual columns can be used in grid views, printed in reports, and referenced in other logic.

Example: Days Since Creation

-- Column SQL for a virtual "DaysSinceCreated" column
(EXTRACT(DAY FROM (now() - Created)))

Field Groups

Field Groups (AD_FieldGroup) organize fields into collapsible sections within a tab. This improves usability for windows with many fields. Configure a Field Group record with a Name and Group Type (Label or Collapsible), then assign it to individual fields via the AD_Field.AD_FieldGroup_ID column. Fields with the same Field Group are visually grouped together.

Key Takeaways

  • Building a window requires a precise sequence: Table, Columns, Window, Tab, Fields, Menu.
  • Reference types (Table Direct, Table, List, Search, Button, Location, Account, PAttribute) control how fields store and display data.
  • Validation Rules add dynamic SQL WHERE clauses to filter dropdown options based on context.
  • Display Logic and Read Only Logic use @Variable@ expressions to control field visibility and editability.
  • Default values can reference system context, window context, SQL queries, or literal values.
  • EntityType tracks ownership of AD elements and is essential for proper migration packaging.
  • Virtual columns (Column SQL) let you add computed fields without altering the database schema.

What’s Next

In Lesson 14, you will learn about Callouts — Java code that executes when a user changes a field value. Callouts bring dynamic, real-time behavior to the UI and are the bridge between the declarative AD approach you learned here and the programmatic customization that powers advanced business logic.

繁體中文

概述

  • 學習內容:進階應用程式字典技術,包括從零開始建立自訂視窗、精通參照類型、配置驗證規則以及運用虛擬欄位。
  • 先修條件:第 1-12 課(初級)
  • 預估閱讀時間:25 分鐘

簡介

應用程式字典(AD)是 iDempiere 的核心。您在使用者介面中看到的每個視窗、頁籤、欄位和流程都是在 AD 中定義為中繼資料。雖然初級課程已經介紹了 AD 的概念,本課將深入探討建立和自訂字典的機制。完成本課後,您將能夠從零開始建立完整功能的視窗、了解所有可用的參照類型,並配置精密的驗證邏輯——完全不需要撰寫任何一行 Java 程式碼。

從零開始建立視窗

在 iDempiere 中建立新視窗需要遵循精確的步驟順序。每個步驟都建立在前一個步驟之上,跳過步驟會導致錯誤。以下是完整的工作流程:

步驟一:註冊資料表(AD_Table)

導覽至應用程式字典 > 資料表和欄位。使用以下必要欄位建立新記錄:

  • 資料庫資料表名稱:您的實體資料庫資料表名稱(例如 Z_MyCustomTable)。依慣例,自訂資料表使用 Z_ 前綴或您的組織前綴。
  • 名稱:易於閱讀的名稱(例如「My Custom Table」)。
  • 資料表類型:通常保留預設值。選項包括 Table、View 和 Single Row。
  • 資料存取層級:控制哪些角色可以存取記錄。常見值包括 Client+Organization、System+Client 和 All。
  • EntityType:自訂工作設為「User Maintained」。這非常重要——它可以防止您的自訂設定在遷移過程中被覆蓋。
  • 維護變更日誌:啟用此選項以追蹤誰在何時更改了什麼。

儲存後,如果實體資料表已存在,請使用從資料庫建立欄位流程(齒輪圖示)。如果從頭開始,您將手動定義欄位。

步驟二:定義欄位(AD_Column)

切換至欄位頁籤。資料表中的每個欄位都需要一筆 AD_Column 記錄。每個資料表應具備的必要欄位:

  • AD_Client_ID — 多租戶用戶端識別碼
  • AD_Org_ID — 組織識別碼
  • CreatedCreatedByUpdatedUpdatedBy — 稽核追蹤欄位
  • IsActive — 軟刪除旗標
  • 主鍵欄位(例如 Z_MyCustomTable_ID
  • Z_MyCustomTable_UU — 用於複寫和遷移的 UUID 欄位

對於每個欄位,您必須配置:

  • 資料庫欄位名稱:資料庫中的實體欄位名稱。
  • 名稱:在使用者介面中顯示的標籤。
  • 參照:資料類型/顯示類型(String、Integer、Table Direct、List 等)。
  • 必填:該欄位是否需要值。
  • 預設邏輯:預先填入欄位的表達式(下面將詳細介紹)。
  • 主鍵欄位:勾選此項以設定主鍵欄位。

定義完欄位後,執行同步欄位流程以建立或修改實體資料庫欄位。

步驟三:建立視窗(AD_Window)

導覽至應用程式字典 > 視窗、頁籤和欄位。建立新的視窗記錄:

  • 名稱:視窗標題(例如「My Custom Window」)。
  • 視窗類型:標準 CRUD 視窗選擇「Maintain」,文件樣式視窗(具有表頭/明細行結構)選擇「Transaction」,唯讀檢視選擇「Query Only」。
  • EntityType:自訂工作設為「User Maintained」。

步驟四:新增頁籤(AD_Tab)

切換至頁籤子頁籤。每個視窗至少需要一個頁籤:

  • 名稱:頁籤標籤。
  • 資料表:連結至步驟一中建立的 AD_Table。
  • 頁籤層級:主(表頭)頁籤為 0。子頁籤使用 1、2 等。
  • 順序:控制頁籤的顯示順序。
  • 連結欄位:對於子頁籤,這是連結至父頁籤的外鍵。
  • WHERE 子句:套用至頁籤的可選 SQL 篩選條件。
  • 排序子句:預設排序順序。
  • 唯讀:使整個頁籤不可編輯。

步驟五:配置欄位(AD_Field)

儲存頁籤後,使用建立欄位流程從欄位自動產生 AD_Field 記錄。然後自訂每個欄位:

  • 順序:控制欄位顯示順序。
  • 顯示:欄位是否可見。
  • 顯示邏輯:條件式可見性表達式。
  • 唯讀邏輯:條件式可編輯性表達式。
  • 欄位群組:將欄位分組至可折疊區段。
  • 同行 / 跨欄:版面配置控制。

步驟六:加入選單

最後,透過應用程式字典 > 選單新增選單項目以使視窗可存取。將動作設定為「Window」並選擇您的新視窗。

參照類型深入探討

參照決定了欄位的儲存、顯示和編輯方式。選擇正確的參照類型是 AD 設計中最重要的決策之一。

Table Direct

最簡單的外鍵參照。欄位名稱必須與目標資料表的主鍵欄位完全匹配(例如,名為 C_BPartner_ID 的欄位會自動參照 C_BPartner 資料表)。UI 會呈現一個下拉選單,填入該資料表中所有作用中的記錄。

-- 欄位名稱:C_BPartner_ID
-- 自動連結至 C_BPartner 資料表
-- 不需要額外配置

Table

更靈活的外鍵參照。與 Table Direct 不同,欄位名稱不需要匹配目標資料表。您配置一個參照鍵(AD_Ref_Table)來指定:

  • 資料表:來源資料表。
  • 鍵值欄位:提供儲存值的欄位。
  • 顯示欄位:顯示給使用者的欄位。
  • WHERE 子句:可用記錄的可選篩選條件。
  • ORDER BY 子句:下拉選單的排序順序。

當您需要篩選後的下拉選單、自訂顯示值,或您的欄位名稱不遵循命名慣例時,請使用此參照類型。

List

從預定義集合中選擇並儲存短字串值。使用值-名稱配對配置參照清單(AD_Ref_List)。適合狀態欄位、類型欄位以及具有小型固定值集合的任何列舉。

-- 範例:DocStatus 參照清單
-- Value: DR  Name: Drafted(草稿)
-- Value: CO  Name: Completed(已完成)
-- Value: VO  Name: Voided(已作廢)
-- Value: CL  Name: Closed(已關閉)

Search

與 Table 類似,但呈現為搜尋對話方塊而非下拉選單。用於具有大量記錄的資料表(例如產品、業務夥伴),在這種情況下下拉選單不切實際。使用者可以輸入文字進行篩選或點擊搜尋圖示開啟具有多個搜尋條件的查詢對話方塊。

Button

呈現為可點擊的按鈕。可以觸發流程(AD_Process)或開啟專用對話方塊。該欄位通常儲存按鈕動作更新的狀態碼。文件處理按鈕(DocAction)是最常見的範例。

Location

地址欄位的專用參照。連結至 C_Location 資料表並呈現地址編輯器對話方塊(地址 1、地址 2、城市、州/地區、郵遞區號、國家)。對話方塊會根據所選國家的地址格式自動調整。

Account

開啟總帳科目組合編輯器。用於儲存會計組合的欄位(科目 + 組織 + 業務夥伴 + 產品 + 活動 + 行銷活動等)。連結至 C_ValidCombination 資料表。

PAttribute(產品屬性)

開啟產品屬性集實例編輯器。用於需要擷取批號、序號、保固日期和其他屬性集實例值的欄位。連結至 M_AttributeSetInstance

驗證規則

驗證規則(AD_Val_Rule)限制下拉選單或搜尋對話方塊中顯示的記錄。它們是動態篩選可用選項的 SQL WHERE 子句。

建立驗證規則

導覽至應用程式字典 > 驗證規則並建立新記錄:

-- 名稱:Active Vendors Only
-- 類型:SQL
-- 驗證碼:
C_BPartner.IsVendor='Y' AND C_BPartner.IsActive='Y'

然後將此驗證規則指定至欄位(AD_Column.AD_Val_Rule_ID)或欄位的參照資料表配置。當使用者開啟下拉選單時,iDempiere 會將此 WHERE 子句附加至查詢 SQL。

驗證規則中的上下文變數

當您使用上下文變數建立動態篩選時,驗證規則會變得更加強大:

-- 只顯示所選倉庫組織的產品
AD_Org_ID = @AD_Org_ID@

-- 只顯示所選業務夥伴的地址
C_BPartner_ID = @C_BPartner_ID@

-- 基於 SQL 的上下文變數
@SQL=SELECT SalesRep_ID FROM C_BPartner WHERE C_BPartner_ID=@C_BPartner_ID@

上下文變數使用 @VariableName@ 語法。iDempiere 在執行時從當前視窗上下文(欄位值、登入預設值、偏好設定)中解析它們。

顯示邏輯和唯讀邏輯

顯示邏輯控制欄位是否可見。唯讀邏輯控制欄位是否可編輯。兩者使用相同的表達式語法。

基於欄位的表達式

-- 僅當 IsSOTrx 為 Yes 時顯示欄位
@IsSOTrx@='Y'

-- 僅當 DocStatus 為 Drafted 時顯示欄位
@DocStatus@=DR

-- 組合條件
@IsSOTrx@='Y' & @DocStatus@=DR

-- OR 邏輯
@IsSOTrx@='Y' | @PaymentRule@=S

-- 不等於
@DocStatus@!CO

基於 SQL 的顯示邏輯

-- 僅當使用者具有特定角色時顯示欄位
@SQL=SELECT COUNT(*) FROM AD_User_Roles
WHERE AD_User_ID=@#AD_User_ID@ AND AD_Role_ID=1000000 AND IsActive='Y'

@SQL= 前綴告訴 iDempiere 執行 SQL 並使用結果。如果結果大於 0(或非空),則條件為真。

預設值

預設值在建立新記錄時預先填入欄位。iDempiere 支援多種表達式類型:

系統上下文變數

@#Date@          -- 當前系統日期
@#AD_Client_ID@  -- 當前用戶端 ID
@#AD_Org_ID@     -- 當前組織 ID
@#AD_User_ID@    -- 當前使用者 ID
@#AD_Role_ID@    -- 當前角色 ID
@#AD_Language@   -- 當前語言

視窗上下文變數

@C_BPartner_ID@  -- 當前視窗中 C_BPartner_ID 欄位的值
@IsSOTrx@        -- IsSOTrx 欄位的值(銷售交易旗標)
@M_Warehouse_ID@ -- 父頁籤倉庫欄位的值

基於 SQL 的預設值

-- 預設為此組織的第一個倉庫
@SQL=SELECT M_Warehouse_ID FROM M_Warehouse
WHERE AD_Org_ID=@AD_Org_ID@ AND IsActive='Y'
ORDER BY IsDefault DESC, M_Warehouse_ID LIMIT 1

字面值

Y        -- 布林值 Yes
N        -- 布林值 No
0        -- 零
DR       -- 字串字面值(例如用於 DocStatus)

EntityType 與自訂追蹤

EntityType 欄位存在於大多數 AD 資料表中(Table、Column、Window、Tab、Field、Process 等)。它作為命名空間機制,識別特定中繼資料的擁有者:

  • D(Dictionary):iDempiere 核心元素。切勿直接修改。
  • C(Compiere):舊版 Compiere 元素。同樣不應修改。
  • U(User Maintained):您的自訂元素。可安全修改和遷移。
  • 自訂 EntityType:您可以在 AD_EntityType 資料表中註冊自己的類型(例如「MYORG」)。

EntityType 對於遷移和 pack-in/pack-out 至關重要。2Pack 遷移工具使用 EntityType 來確定哪些元素屬於您的自訂設定並應被匯出。請務必將您的自訂元素設定為適當的 EntityType。

虛擬欄位(Column SQL)

虛擬欄位是不存在於實體資料庫資料表中的計算欄位。它們完全在 AD 中使用 AD_Column 上的 Column SQL 欄位定義。iDempiere 將 Column SQL 作為子查詢注入 SELECT 語句中。

範例:明細行總金額

-- C_Order 上虛擬欄位 "TotalLines" 的 Column SQL
(SELECT COALESCE(SUM(LineNetAmt), 0)
 FROM C_OrderLine ol
 WHERE ol.C_Order_ID = C_Order.C_Order_ID)

虛擬欄位的配置要求:

  • 欄位必須存在於 AD_Column 中,但不存在於實體資料表中。
  • Column SQL 設定為您的子查詢表達式(用括號括起來)。
  • 欄位自動為唯讀——您無法編輯計算值。
  • 虛擬欄位可用於格線檢視、列印在報表中,以及在其他邏輯中參照。

範例:建立以來的天數

-- 虛擬欄位 "DaysSinceCreated" 的 Column SQL
(EXTRACT(DAY FROM (now() - Created)))

欄位群組

欄位群組(AD_FieldGroup)將頁籤內的欄位組織為可折疊的區段。這提高了具有多個欄位之視窗的可用性。使用名稱和群組類型(Label 或 Collapsible)配置欄位群組記錄,然後透過 AD_Field.AD_FieldGroup_ID 欄位將其指定至各個欄位。具有相同欄位群組的欄位會在視覺上分組在一起。

重點摘要

  • 建立視窗需要精確的步驟順序:資料表、欄位、視窗、頁籤、欄位、選單。
  • 參照類型(Table Direct、Table、List、Search、Button、Location、Account、PAttribute)控制欄位的儲存和顯示方式。
  • 驗證規則新增動態 SQL WHERE 子句,根據上下文篩選下拉選項。
  • 顯示邏輯和唯讀邏輯使用 @Variable@ 表達式控制欄位的可見性和可編輯性。
  • 預設值可以參照系統上下文、視窗上下文、SQL 查詢或字面值。
  • EntityType 追蹤 AD 元素的所有權,對於正確的遷移打包至關重要。
  • 虛擬欄位(Column SQL)讓您無需修改資料庫架構即可新增計算欄位。

下一步

在第 14 課中,您將學習 Callout——當使用者更改欄位值時執行的 Java 程式碼。Callout 為 UI 帶來動態即時行為,是您在本課中學到的宣告式 AD 方法與驅動進階業務邏輯的程式化自訂之間的橋樑。

日本語

概要

  • 学習内容:カスタムウィンドウのゼロからの構築、リファレンスタイプの習得、バリデーションルールの設定、仮想カラムの活用など、アプリケーション辞書の高度なテクニック。
  • 前提条件:レッスン1〜12(初級レベル)
  • 推定読了時間:25分

はじめに

アプリケーション辞書(AD)はiDempiereの心臓部です。UIに表示されるすべてのウィンドウ、タブ、フィールド、プロセスはADにメタデータとして定義されています。初級カリキュラムではADの概念を紹介しましたが、本レッスンでは辞書の構築とカスタマイズの仕組みを深く掘り下げます。このレッスンを終えると、ゼロから完全に機能するウィンドウを作成し、利用可能なすべてのリファレンスタイプを理解し、高度なバリデーションロジックを設定できるようになります——Javaコードを一行も書くことなく。

ゼロからのウィンドウ作成

iDempiereで新しいウィンドウを構築するには、正確な手順に従う必要があります。各ステップは前のステップに基づいており、ステップを飛ばすとエラーが発生します。以下が完全なワークフローです:

ステップ1:テーブルの登録(AD_Table)

アプリケーション辞書 > テーブルとカラムに移動します。以下の必須フィールドで新しいレコードを作成します:

  • DBテーブル名:物理データベーステーブル名(例:Z_MyCustomTable)。慣例により、カスタムテーブルにはZ_プレフィックスまたは組織のプレフィックスを使用します。
  • 名前:人間が読みやすい名前(例:「My Custom Table」)。
  • テーブルタイプ:通常はデフォルトのまま。オプションはTable、View、Single Rowです。
  • データアクセスレベル:どのロールがレコードにアクセスできるかを制御します。一般的な値はClient+Organization、System+Client、Allです。
  • EntityType:カスタム作業には「User Maintained」を設定します。これは非常に重要で、マイグレーション中にカスタマイズが上書きされるのを防ぎます。
  • 変更ログの維持:誰がいつ何を変更したかを追跡するために有効にします。

保存後、物理テーブルが既に存在する場合はDBからカラムを作成プロセス(歯車アイコン)を使用します。ゼロから始める場合は、カラムを手動で定義します。

ステップ2:カラムの定義(AD_Column)

カラムタブに切り替えます。テーブル内のすべてのカラムにはAD_Columnレコードが必要です。すべてのテーブルが持つべき必須カラム:

  • AD_Client_ID — マルチテナントクライアント識別子
  • AD_Org_ID — 組織識別子
  • CreatedCreatedByUpdatedUpdatedBy — 監査証跡フィールド
  • IsActive — ソフトデリートフラグ
  • 主キーカラム(例:Z_MyCustomTable_ID
  • Z_MyCustomTable_UU — レプリケーションとマイグレーション用のUUIDカラム

各カラムについて以下を設定する必要があります:

  • DBカラム名:データベース内の物理カラム名。
  • 名前:UIに表示されるラベル。
  • リファレンス:データタイプ/表示タイプ(String、Integer、Table Direct、Listなど)。
  • 必須:フィールドに値が必要かどうか。
  • デフォルトロジック:フィールドを事前に入力する式(以下で詳しく説明)。
  • キーカラム:主キーカラムの場合にチェックします。

カラムを定義した後、カラムの同期プロセスを実行して物理データベースカラムを作成または変更します。

ステップ3:ウィンドウの作成(AD_Window)

アプリケーション辞書 > ウィンドウ、タブ&フィールドに移動します。新しいウィンドウレコードを作成します:

  • 名前:ウィンドウタイトル(例:「My Custom Window」)。
  • ウィンドウタイプ:標準CRUDウィンドウは「Maintain」、ドキュメントスタイルのウィンドウ(ヘッダー/明細構造)は「Transaction」、読み取り専用ビューは「Query Only」。
  • EntityType:カスタム作業には「User Maintained」。

ステップ4:タブの追加(AD_Tab)

タブサブタブに切り替えます。すべてのウィンドウには少なくとも1つのタブが必要です:

  • 名前:タブのラベル。
  • テーブル:ステップ1で作成したAD_Tableにリンク。
  • タブレベル:メイン(ヘッダー)タブは0。子タブは1、2などを使用。
  • シーケンス:タブの表示順序を制御。
  • リンクカラム:子タブの場合、親タブにリンクする外部キー。
  • WHERE句:タブに適用されるオプションのSQLフィルター。
  • Order By句:デフォルトのソート順。
  • 読み取り専用:タブ全体を編集不可にします。

ステップ5:フィールドの設定(AD_Field)

タブを保存した後、フィールドの作成プロセスを使用してカラムからAD_Fieldレコードを自動生成します。その後、各フィールドをカスタマイズします:

  • シーケンス:フィールドの表示順序を制御。
  • 表示:フィールドが表示されるかどうか。
  • 表示ロジック:条件付き表示の式。
  • 読み取り専用ロジック:条件付き編集可能性の式。
  • フィールドグループ:フィールドを折りたたみ可能なセクションにグループ化。
  • 同一行 / カラムスパン:レイアウト制御。

ステップ6:メニューに追加

最後に、アプリケーション辞書 > メニューでメニューエントリを追加してウィンドウにアクセスできるようにします。アクションを「Window」に設定し、新しいウィンドウを選択します。

リファレンスタイプの詳細

リファレンスはカラムの保存方法、表示方法、編集方法を決定します。適切なリファレンスタイプを選択することは、AD設計において最も重要な決定の1つです。

Table Direct

最もシンプルな外部キーリファレンス。カラム名がターゲットテーブルのキーカラムと正確に一致する必要があります(例:C_BPartner_IDという名前のカラムは自動的にC_BPartnerテーブルを参照します)。UIはそのテーブルのすべてのアクティブなレコードで構成されるドロップダウンを表示します。

-- カラム名:C_BPartner_ID
-- 自動的にC_BPartnerテーブルにリンク
-- 追加設定不要

Table

より柔軟な外部キーリファレンス。Table Directとは異なり、カラム名がターゲットテーブルと一致する必要はありません。以下を指定するリファレンスキー(AD_Ref_Table)を設定します:

  • テーブル:ソーステーブル。
  • キーカラム:保存される値を提供するカラム。
  • 表示カラム:ユーザーに表示されるカラム。
  • WHERE句:利用可能なレコードのオプションフィルター。
  • ORDER BY句:ドロップダウンのソート順。

フィルター付きドロップダウン、カスタム表示値が必要な場合、またはカラム名が命名規則に従わない場合に使用するリファレンスタイプです。

List

事前定義されたセットから選択された短い文字列値を保存します。値と名前のペアでリファレンスリスト(AD_Ref_List)を設定します。ステータスフィールド、タイプフィールド、小規模で固定された値セットの列挙に最適です。

-- 例:DocStatusリファレンスリスト
-- Value: DR  Name: Drafted(下書き)
-- Value: CO  Name: Completed(完了)
-- Value: VO  Name: Voided(無効)
-- Value: CL  Name: Closed(クローズ)

Search

Tableと似ていますが、ドロップダウンの代わりに検索ダイアログとして表示されます。多数のレコードを持つテーブル(例:製品、取引先)で使用され、ドロップダウンが実用的でない場合に適しています。ユーザーはフィルターを入力するか、検索アイコンをクリックして複数の検索条件を持つ検索ダイアログを開くことができます。

Button

クリック可能なボタンとして表示されます。プロセス(AD_Process)をトリガーするか、専用のダイアログを開くことができます。カラムは通常、ボタンアクションが更新するステータスコードを保存します。ドキュメント処理ボタン(DocAction)が最も一般的な例です。

Location

住所フィールド用の専用リファレンス。C_Locationテーブルにリンクし、ロケーションエディターダイアログ(住所1、住所2、市区町村、都道府県、郵便番号、国)を表示します。ダイアログは選択された国の住所フォーマットに基づいて自動的に適応します。

Account

GL勘定科目組み合わせエディターを開きます。会計組み合わせ(勘定科目 + 組織 + 取引先 + 製品 + 活動 + キャンペーンなど)を保存するフィールドに使用します。C_ValidCombinationテーブルにリンクします。

PAttribute(製品属性)

製品属性セットインスタンスエディターを開きます。ロット番号、シリアル番号、保証日、その他の属性セットインスタンス値を取得する必要があるフィールドに使用します。M_AttributeSetInstanceにリンクします。

バリデーションルール

バリデーションルール(AD_Val_Rule)は、ドロップダウンまたは検索ダイアログに表示されるレコードを制限します。利用可能なオプションを動的にフィルタリングするSQL WHERE句です。

バリデーションルールの作成

アプリケーション辞書 > バリデーションルールに移動して新しいレコードを作成します:

-- 名前:Active Vendors Only
-- タイプ:SQL
-- バリデーションコード:
C_BPartner.IsVendor='Y' AND C_BPartner.IsActive='Y'

次に、このバリデーションルールをカラム(AD_Column.AD_Val_Rule_ID)またはカラムのリファレンステーブル設定に割り当てます。ユーザーがドロップダウンを開くと、iDempiereはこのWHERE句をルックアップSQLに追加します。

バリデーションルールのコンテキスト変数

コンテキスト変数を使用して動的フィルターを作成すると、バリデーションルールは強力になります:

-- 選択した倉庫の組織の製品のみ表示
AD_Org_ID = @AD_Org_ID@

-- 選択した取引先の住所のみ表示
C_BPartner_ID = @C_BPartner_ID@

-- SQLベースのコンテキスト変数
@SQL=SELECT SalesRep_ID FROM C_BPartner WHERE C_BPartner_ID=@C_BPartner_ID@

コンテキスト変数は@VariableName@構文を使用します。iDempiereは実行時に現在のウィンドウコンテキスト(フィールド値、ログインデフォルト、設定)からこれらを解決します。

表示ロジックと読み取り専用ロジック

表示ロジックはフィールドが表示されるかどうかを制御します。読み取り専用ロジックはフィールドが編集可能かどうかを制御します。両方とも同じ式構文を使用します。

カラムベースの式

-- IsSOTrxがYesの場合のみフィールドを表示
@IsSOTrx@='Y'

-- DocStatusがDraftedの場合のみフィールドを表示
@DocStatus@=DR

-- 条件の組み合わせ
@IsSOTrx@='Y' & @DocStatus@=DR

-- ORロジック
@IsSOTrx@='Y' | @PaymentRule@=S

-- 等しくない
@DocStatus@!CO

SQLベースの表示ロジック

-- ユーザーが特定のロールを持つ場合のみフィールドを表示
@SQL=SELECT COUNT(*) FROM AD_User_Roles
WHERE AD_User_ID=@#AD_User_ID@ AND AD_Role_ID=1000000 AND IsActive='Y'

@SQL=プレフィックスはiDempiereにSQLを実行して結果を使用するよう指示します。結果が0より大きい(または空でない)場合、条件は真です。

デフォルト値

デフォルト値は新しいレコードを作成するときにフィールドを事前入力します。iDempiereはいくつかの式タイプをサポートしています:

システムコンテキスト変数

@#Date@          -- 現在のシステム日付
@#AD_Client_ID@  -- 現在のクライアントID
@#AD_Org_ID@     -- 現在の組織ID
@#AD_User_ID@    -- 現在のユーザーID
@#AD_Role_ID@    -- 現在のロールID
@#AD_Language@   -- 現在の言語

ウィンドウコンテキスト変数

@C_BPartner_ID@  -- 現在のウィンドウのC_BPartner_IDフィールドの値
@IsSOTrx@        -- IsSOTrxフィールドの値(販売取引フラグ)
@M_Warehouse_ID@ -- 親タブの倉庫フィールドの値

SQLベースのデフォルト

-- この組織の最初の倉庫をデフォルトに
@SQL=SELECT M_Warehouse_ID FROM M_Warehouse
WHERE AD_Org_ID=@AD_Org_ID@ AND IsActive='Y'
ORDER BY IsDefault DESC, M_Warehouse_ID LIMIT 1

リテラル値

Y        -- ブーリアン Yes
N        -- ブーリアン No
0        -- ゼロ
DR       -- 文字列リテラル(例:DocStatus用)

EntityTypeとカスタマイズ追跡

EntityTypeフィールドはほとんどのADテーブル(Table、Column、Window、Tab、Field、Processなど)に存在します。特定のメタデータの所有者を識別する名前空間メカニズムとして機能します:

  • D(Dictionary):iDempiereのコア要素。直接変更しないでください。
  • C(Compiere):レガシーCompiereの要素。同様に変更すべきではありません。
  • U(User Maintained):カスタム要素。安全に変更およびマイグレーションできます。
  • カスタムEntityType:AD_EntityTypeテーブルに独自のタイプ(例:「MYORG」)を登録できます。

EntityTypeはマイグレーションとpack-in/pack-outに不可欠です。2Packマイグレーションツールは、EntityTypeを使用してどの要素がカスタマイズに属し、エクスポートされるべきかを判断します。カスタム要素には常に適切なEntityTypeを設定してください。

仮想カラム(Column SQL)

仮想カラムは物理データベーステーブルに存在しない計算カラムです。AD_ColumnのColumn SQLフィールドを使用してAD内で完全に定義されます。iDempiereはColumn SQLをサブクエリとしてSELECTステートメントに注入します。

例:明細行合計金額

-- C_Orderの仮想カラム "TotalLines" のColumn SQL
(SELECT COALESCE(SUM(LineNetAmt), 0)
 FROM C_OrderLine ol
 WHERE ol.C_Order_ID = C_Order.C_Order_ID)

仮想カラムの設定要件:

  • カラムはAD_Columnに存在する必要がありますが、物理テーブルには存在しません。
  • Column SQLをサブクエリ式(括弧で囲む)に設定します。
  • カラムは自動的に読み取り専用になります——計算値は編集できません。
  • 仮想カラムはグリッドビューで使用、レポートに印刷、他のロジックで参照できます。

例:作成からの日数

-- 仮想カラム "DaysSinceCreated" のColumn SQL
(EXTRACT(DAY FROM (now() - Created)))

フィールドグループ

フィールドグループ(AD_FieldGroup)は、タブ内のフィールドを折りたたみ可能なセクションに整理します。これにより、多くのフィールドを持つウィンドウの使いやすさが向上します。名前とグループタイプ(LabelまたはCollapsible)でフィールドグループレコードを設定し、AD_Field.AD_FieldGroup_IDカラムを通じて個々のフィールドに割り当てます。同じフィールドグループを持つフィールドは視覚的にグループ化されます。

重要ポイント

  • ウィンドウの構築には正確な手順が必要:テーブル、カラム、ウィンドウ、タブ、フィールド、メニュー。
  • リファレンスタイプ(Table Direct、Table、List、Search、Button、Location、Account、PAttribute)はフィールドのデータ保存と表示方法を制御します。
  • バリデーションルールはコンテキストに基づいてドロップダウンオプションをフィルタリングする動的SQL WHERE句を追加します。
  • 表示ロジックと読み取り専用ロジックは@Variable@式を使用してフィールドの表示と編集可能性を制御します。
  • デフォルト値はシステムコンテキスト、ウィンドウコンテキスト、SQLクエリ、またはリテラル値を参照できます。
  • EntityTypeはAD要素の所有権を追跡し、適切なマイグレーションパッケージングに不可欠です。
  • 仮想カラム(Column SQL)を使用すると、データベーススキーマを変更せずに計算フィールドを追加できます。

次のステップ

レッスン14では、コールアウトについて学びます——ユーザーがフィールド値を変更したときに実行されるJavaコードです。コールアウトはUIに動的なリアルタイム動作をもたらし、このレッスンで学んだ宣言的なADアプローチと、高度なビジネスロジックを駆動するプログラム的なカスタマイズとの架け橋となります。

You Missed