StartBC.comค้นหาบทเรียน

พื้นฐาน AL และ Object: Table, Page, Codeunit และ Extension

รู้จักโครงสร้าง Extension และ object พื้นฐานของ Business Central จากนั้นสร้าง Table และ Page ที่บันทึกข้อมูลได้จริง ก่อนอ่านตัวแปร เงื่อนไข และ Procedure ใน Codeunit พร้อมแบบฝึกคำนวณ

ตรวจเอกสารอ้างอิง: 22 ตุลาคม 2569
บริบท: Business Central · ใช้กับแล็บ on-premises หรือ online Sandbox ตามบท 12 · ตัวอย่าง AL ยังไม่ได้ compile/run กับระบบจริง

เป้าหมายและพื้นฐาน

เมื่อจบ: เข้าใจ object สร้าง Table/Page และอ่านตรรกะใน Codeunit

พื้นฐานที่ต้องรู้: 12

แบบฝึกหลัก: สร้างตารางและหน้าฝึก แล้วทดสอบ Procedure คำนวณ

ภาพรวมก่อนลงมือทำ

ภาพสรุปบทเรียน · 13

object ของ AL เชื่อมกันอย่างไร

จากข้อมูลที่บันทึกได้สู่ตรรกะที่เรียกใช้ซ้ำ

  1. table 50102

    SBC Practice: fields และ key(PK; "No.")

  2. page 50102

    SourceTable = "SBC Practice"; field ผูกกับ Rec

  3. codeunit 50100

    CalculateAmount รับ Decimal และคืน Decimal

  4. Extension (.app)

    รวม object + app.json แล้ว Package และ Publish

สิ่งที่ควรจำภาพนี้เป็นแผนที่ส่วนประกอบ ไม่ใช่ลำดับรัน: Page ฝึกข้อมูลผูก Table ส่วน Page คำนวณเรียก Codeunit

Extension และ object คืออะไร

AL คือภาษาที่ใช้พัฒนา Business Central ส่วน Extension คือแอปที่บรรจุ object และ metadata ใน app.json แล้ว Package เป็นไฟล์ .app หนึ่ง Extension มีได้หลาย object; tableextension เป็น object ชนิดหนึ่งภายในแอป ไม่ใช่ชื่อเรียกแทนแอปทั้งชุด

Objectหน้าที่ตัวอย่างที่ต้องเข้าใจ
Tableกำหนด fields, data types, keys และกฎข้อมูลตาราง SBC Practice เก็บ No. และ Description
Pageหน้ารายการ/การ์ดที่ผู้ใช้โต้ตอบSourceTable ผูกกับตาราง; Rec คือ record ปัจจุบัน
Codeunitรวม procedure และตรรกะที่เรียกซ้ำSBC Calculation คำนวณยอด
Table Extensionเพิ่ม fields และพฤติกรรมให้ตารางที่ขยายได้เพิ่ม SBC Training Note บน Customer
Page Extensionเพิ่ม/ปรับส่วนแสดงผลและ action บนหน้าที่ขยายได้แสดง Training note บน Customer Card
Report / Report Extensionสร้าง dataset และผลลัพธ์รายงาน / ขยายรายงานที่รองรับแยกข้อมูลใน dataset ออกจาก layout ที่ใช้พิมพ์
Queryอ่านหรือรวมข้อมูลจาก dataitemsข้อมูลสรุปสำหรับวิเคราะห์ ไม่ใช่หน้าจอกรอกข้อมูล
XMLportกำหนดรูปแบบนำเข้า/ส่งออกข้อมูลไฟล์ XML หรือข้อความตาม schema
Enum / Enum Extensionชุดค่าที่มีชื่อ / ขยายชุดค่าที่อนุญาตสถานะ Open และ Completed แทนตัวเลขที่ไม่มีความหมาย
Interfaceกำหนดสัญญา procedure ให้ codeunit นำไป implementหลาย implementation ทำงานผ่านสัญญาเดียวกัน
Permission Set / Extensionกำหนดหรือเพิ่มสิทธิ์ object/dataอนุญาตเปิดหน้าฝึกและอ่านเขียนตารางฝึก
Profile / Page Customizationจัดประสบการณ์ตามบทบาทและปรับหน้าจอเลือก Role Center และปรับ UI ตามผู้ใช้

Trigger, Procedure และ Event ไม่ใช่ object แยก: trigger เช่น OnAction ทำงานเมื่อเกิดเหตุการณ์ที่กำหนด; procedure เป็นหน่วยงานที่เรียกใช้; event publisher/subscriber ช่วยเชื่อมตรรกะเข้ากับจุดขยายของระบบ

อ่านไฟล์ AL และชนิดข้อมูล

หนึ่งไฟล์ตัวอย่างมีหนึ่ง object เริ่มด้วยชนิด, ID และชื่อ แล้วมี properties และส่วนประกอบในวงเล็บปีกกา ชื่อที่มีช่องว่างใช้ double quotes ส่วนข้อความใช้ single quotes และ statement จบด้วย semicolon

ชนิด / คำสั่งใช้เมื่อใด
Code[20], Text[100]รหัสและข้อความที่กำหนดความยาว
Integer, Decimal, Boolean, Dateจำนวนเต็ม ทศนิยม จริง/เท็จ และวันที่
Record Customerตัวแปร record สำหรับทำงานกับตาราง Customer
Labelข้อความที่รองรับการแปล เช่น error/message
if … then / case / foreachเลือกเงื่อนไขและวนทำงาน
:= / = / exit(...)กำหนดค่า / เปรียบเทียบ / คืนค่าจาก procedure

เรียน field ID และ object ID แยกกัน: field ID อยู่ภายในตาราง ส่วน object ID อยู่ในประเภท object และต้องอยู่ในช่วงที่โปรเจกต์อนุญาต ชื่อ Caption ที่ผู้ใช้เห็นเปลี่ยนได้โดยไม่จำเป็นต้องเปลี่ยน identity ของ schema

ลงมือสร้าง Table และ Page แรก

  1. จากโปรเจกต์บท 12 ที่เชื่อมระบบได้แล้ว เพิ่มไฟล์ StartBCPractice.Table.al, StartBCPractice.Page.al และ StartBCPractice.PermissionSet.al จาก source ด้านล่าง
  2. อ่าน table 50102: fields กำหนด No. และ Description; key PK ใช้ No. เพื่อแยกแต่ละ record
  3. อ่าน page 50102: PageType = List, SourceTable = "SBC Practice" และแต่ละ field ผูกกับ Rec จึงบันทึกข้อมูลลงตารางฝึก ไม่ใช่ตัวแปรชั่วคราว
  4. ตั้ง idRanges ให้ครอบคลุม 50102 และ startupObjectId เป็น 50102 จากนั้น Download Symbols → Package → publish ไปแล็บ
  5. ให้ผู้ดูแล assign permission set SBC PRACTICE แก่ผู้ฝึกตามขอบเขตงาน ชุดนี้ให้สิทธิ์เฉพาะตารางและหน้าฝึก ไม่ใช่สิทธิ์พัฒนาหรือสิทธิ์ Customer ทั้งหมด
  6. ค้น StartBC practice records เพิ่ม No. = TEST-001 และ Description = First AL record ออกจากหน้าแล้วเปิดใหม่เพื่อตรวจว่าข้อมูลยังอยู่

เกณฑ์ผ่าน: ข้อมูลคงอยู่เมื่อเปิดหน้าใหม่ และ No. เดียวกันไม่ถูกสร้างซ้ำในตาราง จากนั้นทดลองหน้าคำนวณเดิมซึ่งผูกกับตัวแปรแทน SourceTable เพื่อเปรียบเทียบความแตกต่าง

อ่านโครงสร้างก่อนคัดลอก

CalculateAmount รับ Quantity กับ UnitPrice ชนิด Decimal และคืน Decimal ชื่อพารามิเตอร์บอกความหมายชัดเจน โค้ดใช้ if เพื่อปฏิเสธค่าติดลบ ใช้ Error ยุติกรณีนั้น แล้ว exit คืนผลคูณที่ปัดไว้สองตำแหน่ง

Procedure ใน Codeunit นี้ไม่ได้ประกาศ local จึงเรียกจาก Page อื่นได้ ถ้าประกาศ local จะเรียกได้ภายใน object นั้น ใช้ Label สำหรับข้อความ error เพื่อแยกข้อความจากตรรกะ ไม่ฝังการตรวจนี้ในหน้าจอเพียงแห่งเดียว

ขั้นตอนทดลองกับหน้าฝึก

  1. ทำบท 12 ให้ได้โปรเจกต์ที่ Download Symbols สำเร็จ อ่าน README ชุดโค้ดและตรวจช่วง ID ก่อน
  2. นำ StartBCCalculation.Codeunit.al และ StartBCExercise.Page.al ไปไว้ใน src/ ไฟล์ละ object ไม่เก็บสำเนา .al ซ้ำอีกที่ในโปรเจกต์
  3. อ่าน codeunit ตามตัวอย่างด้านล่าง แล้วเปิด page เพื่อดู field ที่ผูกกับตัวแปรและ OnAction ที่เรียก procedure
  4. AL: Package ตรวจ Problems ให้ไม่มี error ก่อน Run Without Debugging ไป Sandbox
  5. เปิด Tell Me ค้น StartBC calculation exercise ป้อน Quantity = 2 และ Unit price = 150 แล้วเลือก Calculate จดผลในช่อง Amount
  6. เปลี่ยน Quantity เป็น 0 แล้วคำนวณ จากนั้นลอง -1 ตรวจข้อความผิดพลาด สังเกตว่า Amount เดิมอาจยังคงอยู่เมื่อการคำนวณใหม่ error ต้องไม่ตีความว่าเป็นผลใหม่
  7. บันทึกผลจริงในตารางพร้อมเวอร์ชันที่ใช้ ไม่ใช้ตาราง expected แทนหลักฐานการรัน

แบบฝึกและผลที่คาดหวัง

QuantityUnitPriceคาดหวัง
2150300
01500
312.34537.04
-1150error จำนวน
1-5error ราคา

ตารางเป็นผลตามตรรกะที่ตั้งใจ ยังไม่ใช่ผลจาก AL runtime ที่ StartBC ทดสอบแล้ว รูปแบบทศนิยมที่แสดงอาจต่างตาม locale

โจทย์คิด: ถ้าจะอนุญาตจำนวนติดลบเพื่อใบลดหนี้ ต้องกลับไปออกแบบกฎใด ไม่ใช่ลบ if โดยไม่ทบทวนกระบวนการ

ขอบเขตของสูตรตัวอย่าง

Round(..., 0.01) เป็นการเลือกความละเอียดสำหรับโจทย์ฝึก ไม่ใช่การอ่าน Currency/General Ledger Setup สูตรนี้ไม่รวมส่วนลด ภาษี หน่วยแปลง และ pricing engine ของ Business Central จึงไม่ใช้แทนยอดเอกสารจริง

Source AL ที่ใช้ในบทนี้

StartBCPractice.Table.al
table 50102 "SBC Practice"
{
    Caption = 'StartBC practice';
    DataClassification = CustomerContent;
    fields
    {
        field(1; "No."; Code[20])
        {
            Caption = 'No.';
            NotBlank = true;
        }
        field(2; Description; Text[100])
        {
            Caption = 'Description';
        }
    }
    keys
    {
        key(PK; "No.")
        {
            Clustered = true;
        }
    }
}

ดาวน์โหลด StartBCPractice.Table.al

StartBCPractice.Page.al
page 50102 "SBC Practice List"
{
    Caption = 'StartBC practice records';
    PageType = List;
    SourceTable = "SBC Practice";
    ApplicationArea = All;
    UsageCategory = Lists;
    layout
    {
        area(Content)
        {
            repeater(Records)
            {
                field("No."; Rec."No.")
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the unique code for a training record.';
                }
                field(Description; Rec.Description)
                {
                    ApplicationArea = All;
                    ToolTip = 'Specifies the description of the training record.';
                }
            }
        }
    }
}

ดาวน์โหลด StartBCPractice.Page.al

StartBCPractice.PermissionSet.al
permissionset 50102 "SBC PRACTICE"
{
    Assignable = true;
    Caption = 'StartBC practice records';
    Permissions = tabledata "SBC Practice" = RIMD,
                  table "SBC Practice" = X,
                  page "SBC Practice List" = X;
}

ดาวน์โหลด StartBCPractice.PermissionSet.al

StartBCCalculation.Codeunit.al
codeunit 50100 "SBC Calculation"
{
    procedure CalculateAmount(Quantity: Decimal; UnitPrice: Decimal): Decimal
    begin
        if Quantity < 0 then
            Error(NegativeQuantityErr);
        if UnitPrice < 0 then
            Error(NegativePriceErr);
        exit(Round(Quantity * UnitPrice, 0.01));
    end;

    var
        NegativeQuantityErr: Label 'Quantity must be zero or greater.';
        NegativePriceErr: Label 'Unit price must be zero or greater.';
}

ดาวน์โหลด StartBCCalculation.Codeunit.al

StartBCExercise.Page.al
page 50101 "SBC Calculation Exercise"
{
    PageType = Card;
    ApplicationArea = All;
    UsageCategory = Tasks;
    Caption = 'StartBC calculation exercise';

    layout
    {
        area(Content)
        {
            group(Inputs)
            {
                Caption = 'Inputs';
                field(QuantityInput; Quantity)
                {
                    ApplicationArea = All;
                    Caption = 'Quantity';
                    ToolTip = 'Specifies a nonnegative training quantity.';
                }
                field(PriceInput; UnitPrice)
                {
                    ApplicationArea = All;
                    Caption = 'Unit price';
                    ToolTip = 'Specifies a nonnegative training price.';
                }
                field(AmountOutput; Amount)
                {
                    ApplicationArea = All;
                    Caption = 'Amount';
                    Editable = false;
                    ToolTip = 'Shows the calculated training amount.';
                }
            }
        }
    }
    actions
    {
        area(Processing)
        {
            action(CalculateTraining)
            {
                Caption = 'Calculate';
                ApplicationArea = All;
                Image = Calculate;
                ToolTip = 'Calculates the amount from the current inputs.';
                trigger OnAction()
                var
                    Calculation: Codeunit "SBC Calculation";
                begin
                    Amount := Calculation.CalculateAmount(Quantity, UnitPrice);
                end;
            }
        }
    }
    trigger OnOpenPage()
    begin
        Quantity := 2;
        UnitPrice := 150;
    end;
    var
        Quantity: Decimal;
        UnitPrice: Decimal;
        Amount: Decimal;
}

ดาวน์โหลด StartBCExercise.Page.al

ดูชุดโค้ดและ README ทั้งหมด

ปัญหาพบบ่อย

เรียก procedure จาก Page ไม่ได้
ตรวจชื่อ codeunit/procedure การประกาศ local และ dependency ที่ Package พบ
ไม่พบหน้าฝึกใน Tell Me
ตรวจว่า publish แล้ว และ page มี UsageCategory/ApplicationArea รวมถึงสิทธิ์ผู้ใช้สำหรับ object ใหม่
คัดลอกแล้ว syntax error
ใช้ไฟล์ดาวน์โหลดโดยตรง ตรวจอักขระ quote/semicolon และอย่าวาง codeunit ซ้อนอยู่ใน page object

เอกสารอ้างอิงทางการ

อ่านประกอบและตรวจชื่อเมนู/ข้อจำกัดของเวอร์ชันที่คุณใช้ เอกสารเดิมตรวจ 22 ตุลาคม 2569; เอกสารติดตั้งและพื้นฐาน Developer ที่เพิ่มตรวจ 4 พฤศจิกายน 2569