Business Central 的 AL 語言中篩選(Record.SETRANGE)的用法

在 Business Central 的 AL 語言中,如果您想要將 Record.SETRANGE 用於篩選包含多個不連續值(像是 SQL 語法中的 WHERE Field IN ('值A', '值B', '值C')),這是不適用的。

SETRANGE 的設計是用來篩選 連續的區間單一精確的值

Record.SETRANGE 的用途與限制

SETRANGE 的基本語法如下:

C
Record.SETRANGE(Field, [Value1], [Value2])
參數說明
Field您想要設定篩選條件的欄位名稱。
Value1篩選區間的起始值(包含)。如果只填寫這個參數,即為篩選單一精確值。
Value2篩選區間的結束值(包含)。

1. 篩選單一精確值(等於)

如果您只提供第一個值 (Value1),它會篩選欄位值精確等於該值的記錄。

範例程式碼篩選效果
Customer.SETRANGE("No.", '10000');篩選客戶編號剛好是 ‘10000’ 的記錄。
ItemLedgEntry.SETRANGE("Entry Type", ItemLedgEntry."Entry Type"::Sale);篩選所有分錄類型為 “Sale” (銷貨) 的記錄。

2. 篩選連續範圍(從 X 到 Y)

如果您提供 Value1Value2,它會篩選欄位值介於 Value1Value2 之間(包含邊界值) 的記錄。

範例程式碼篩選效果
ItemLedgEntry.SETRANGE("Posting Date", 20250101D, 20250131D);篩選過帳日期在 2025 年 1 月 1 日到 2025 年 1 月 31 日 之間的記錄。
Customer.SETRANGE("No.", '10000', '20000');篩選客戶編號從 ‘10000’ 到 ‘20000’ 的記錄。

如何篩選包含多個不連續值(模擬 IN 語法)

當您需要篩選一個欄位包含多個不連續的值時(例如:料號必須是 ‘A001’ 或 ‘A005’ 或 ‘A010’),您必須使用 Record.SETFILTER

SETFILTER 允許您使用更靈活的篩選表達式,包括 AL 中的通配符(Wildcards)。

使用 Record.SETFILTER(推薦用於不連續值集合)

在 AL 中,使用 豎線符號 | 來表示 OR (或) 邏輯,這就是模擬 IN 集合的方法。

語法:

C
Record.SETFILTER(Field, String, [Variable1], [Variable2], ...)

範例:篩選多個不連續的 Item No.

C
var
    ItemLedgEntry: Record "Item Ledger Entry";
begin
    // 篩選 Item No. 等於 A001 或 A005 或 A010 的記錄
    // 使用 | 符號連接多個 OR 條件
    ItemLedgEntry.SETFILTER("Item No.", 'A001|A005|A010');
    
    // ... 然後使用 FINDSET() 進行處理
end;

範例:篩選多個不連續的值,並結合變數

C
var
    ItemLedgEntry: Record "Item Ledger Entry";
    ItemFilter1: Code[20];
    ItemFilter2: Code[20];
begin
    ItemFilter1 := 'B001';
    ItemFilter2 := 'B002';
    
    // 使用 %1 和 %2 作為變數的佔位符
    ItemLedgEntry.SETFILTER("Item No.", '%1|%2', ItemFilter1, ItemFilter2); 
    
    // ... 這樣就會篩選出 Item No. 等於 'B001' 或 'B002' 的記錄。
end;

關鍵點和注意事項

  1. 使用 Rec 變數
    • 在 Page 和 Page Extension 的 Action 觸發器中,Rec 變數始終引用當前 Page 的 SourceTable Record 變數
    • 這個 Rec 變數已經包含了使用者在介面上設置的所有篩檢程式。例如,如果用戶在 “Posting Date” 欄位上設置了 2024/1/1..2024/12/31 的篩檢程式,那麼當您在 Action 中調用 Rec.FINDSET() 時,只會檢索這個日期範圍內的記錄。
  2. 使用 FINDSET() 啟動迴圈
    • if Rec.FINDSET() then begin … repeat … until Rec.NEXT() = 0; 是處理 Page 當前已過濾 資料集的標準和最安全的方法。它確保您從記錄集的第一條記錄開始遍歷。
  3. 強制過濾(可選)
    • 如果您想在用戶已設置的篩檢程式的基礎之上,再添加或修改一個特定的篩檢程式,您可以在 OnAction 觸發器內部使用 Rec.SETRANGE() 或 Rec.SETFILTER()。
    • 示例:
C
// 在用戶設置的篩檢程式基礎上,強制只處理 "Entry Type" 為 "Purchase" 的記錄 
Rec.SETRANGE("Entry Type", Rec."Entry Type"::Purchase); 
if Rec.FINDSET() then // ... 繼續您的處理邏輯 ...

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


內容索引