Hàm Patch

Áp dụng cho: Ứng dụng canvas Ứng dụng dựa trên mô hình Power Platform CLI Luồng máy tính để bàn

Sửa đổi/tạo một hoặc nhiều bản ghi trong nguồn dữ liệu hoặc hợp nhất các bản ghi bên ngoài nguồn dữ liệu.

Sử dụng hàm Patch để sửa đổi bản ghi trong các tình huống phức tạp, chẳng hạn như khi bạn thực hiện các bản cập nhật không yêu cầu tương tác của người dùng hoặc sử dụng các biểu mẫu trải rộng trên nhiều màn hình.

Để cập nhật các thay đổi đơn giản cho bản ghi trong nguồn dữ liệu dễ dàng hơn, hãy sử dụng công cụ điều khiển Edit form (Chỉnh sửa biểu mẫu). Khi thêm công cụ điều khiển Edit form, bạn cung cấp cho người dùng một biểu mẫu để điền vào rồi lưu các thay đổi vào nguồn dữ liệu. Để biết thêm thông tin, hãy xem phần Tìm hiểu biểu mẫu dữ liệu.

Xem video sau để tìm hiểu cách sử dụng hàm Patch:

Tổng quan

Sử dụng hàm Patch để sửa đổi một hoặc nhiều bản ghi của nguồn dữ liệu. Các giá trị của những trường cụ thể được sửa đổi mà không ảnh hưởng đến các thuộc tính khác. Ví dụ: công thức sau thay đổi số điện thoại của một khách hàng tên là Contoso:

Patch( Customers, First( Filter( Customers, Name = "Contoso" ) ), { Phone: "1-212-555-1234" } )

Sử dụng hàm Patch với hàm Defaults để tạo bản ghi. Sử dụng thao tác này để xây dựng một màn hình nhằm mục đích vừa tạo vừa chỉnh sửa bản ghi. Ví dụ: công thức sau tạo bản ghi cho một khách hàng tên là Contoso:

Patch( Customers, Defaults( Customers ), { Name: "Contoso" } )

Ngay cả khi không thao tác với nguồn dữ liệu, bạn vẫn có thể sử dụng hàm Patch để hợp nhất hai hoặc nhiều bản ghi. Ví dụ: công thức sau hợp nhất hai bản ghi thành một bản xác định cả số điện thoại và vị trí của Contoso:

Patch( { Name: "Contoso", Phone: "1-212-555-1234" }, { Name: "Contoso", Location: "Midtown" } )

Mô tả

Sửa đổi hoặc tạo bản ghi trong nguồn dữ liệu

Để sử dụng hàm này với nguồn dữ liệu, hãy chỉ định nguồn dữ liệu, sau đó chỉ định bản ghi cơ sở:

  • Để sửa đổi bản ghi, bản ghi cơ sở cần phải đến từ nguồn dữ liệu. Bản ghi cơ sở có thể đã đi qua thuộc tính Items của thư viện, được đặt trong biến bối cảnh hoặc qua đường dẫn nào đó. Tuy nhiên, bạn có thể truy vết bản ghi cơ sở trở lại nguồn dữ liệu. Điều này rất quan trọng vì bản ghi sẽ bao gồm thông tin bổ sung để giúp tìm lại bản ghi để sửa đổi.
  • Để tạo bản ghi, hãy sử dụng hàm Defaults để tạo bản ghi cơ sở với các giá trị mặc định.

Sau đó, chỉ định một hoặc nhiều bản ghi thay đổi, mỗi bản ghi chứa giá trị thuộc tính mới ghi đè giá trị thuộc tính trong bản ghi cơ sở. Các bản ghi thay đổi được xử lý theo thứ tự từ đầu đến cuối danh sách đối số, với các giá trị thuộc tính sau ghi đè lên các giá trị trước đó.

Hàm Patch trả về bản ghi mà bạn đã sửa đổi hoặc tạo. Nếu bạn đã tạo một bản ghi, giá trị trả về có thể bao gồm các thuộc tính mà nguồn dữ liệu tạo tự động. Tuy nhiên, giá trị trả về không cung cấp giá trị cho các trường của bảng có liên quan.

Ví dụ: bạn sử dụng Set(MyAccount, Patch(Accounts, First(Account), 'Account Name': "Example name")); rồi dùng MyAccount.'Primary Contact'.'Full Name'. Trong trường hợp này, bạn sẽ không có được tên đầy đủ. Thay vào đó, để truy cập các trường của bảng có liên quan, hãy sử dụng tra cứu riêng biệt như:

LookUp(Accounts, Account = MyAccount.Account).'Primary Contact'.'Full Name'

Khi bạn cập nhật nguồn dữ liệu, có thể phát sinh một hoặc nhiều vấn đề. Sử dụng IfErrorIsError với giá trị trả về từ Patch để phát hiện và phản hồi lỗi, như Error Handling mô tả. Bạn cũng có thể sử dụng hàm Errors xác định và kiểm tra các vấn đề, như mô tả trong Làm việc với các nguồn dữ liệu.

Các hàm liên quan bao gồm hàm Update để thay thế toàn bộ bản ghi và hàm Collect để tạo bản ghi. DÙng hàm UpdateIf để sửa đổi các thuộc tính cụ thể của nhiều bản ghi dựa trên một điều kiện.

Sửa đổi hoặc tạo một tập hợp bản ghi trong nguồn dữ liệu

Cũng có thể dùng hàm Patch để tạo hoặc sửa đổi nhiều bản ghi bằng một lệnh gọi.

Thay vì sử dụng một bản ghi cơ sở duy nhất, bạn có thể cung cấp đối số thứ hai là một bảng các bản ghi cơ sở. Các bản ghi thay đổi cũng được cung cấp trong bảng, tương ứng với bản ghi cơ sở. Số lượng bản ghi trong mỗi bảng thay đổi phải giống với số lượng bản ghi trong bảng cơ sở.

Khi sử dụng hàm Patch theo cách này, giá trị trả về cũng là một bảng với mỗi bản ghi tương ứng với bản ghi cơ sở và các bản ghi thay đổi.

Hợp nhất các bản ghi bên ngoài nguồn dữ liệu

Chỉ định hai hoặc nhiều bản ghi mà bạn muốn hợp nhất. Các bản ghi được xử lý theo thứ tự từ đầu đến cuối danh sách đối số, với các giá trị thuộc tính sau ghi đè lên các giá trị trước đó.

Hàm Patch trả về bản ghi đã hợp nhất và không sửa đổi các đối số hoặc bản ghi trong bất kỳ nguồn dữ liệu nào.

Cú pháp

Sửa đổi hoặc tạo bản ghi trong nguồn dữ liệu

Patch( DataSource, BaseRecord, ChangeRecord1 [, ChangeRecord2, … ])

  • DataSource – Bắt buộc. Nguồn dữ liệu có chứa bản ghi mà bạn muốn sửa đổi hoặc sẽ chứa bản ghi mà bạn muốn tạo.
  • BaseRecord – Bắt buộc. Bản ghi cần sửa đổi hoặc tạo. Hàm sẽ tìm thấy và sửa đổi bản ghi nếu bản ghi này đến từ nguồn dữ liệu. Nếu kết quả của hàm Defaults được sử dụng, một bản ghi sẽ được tạo.
  • ChangeRecord – Bắt buộc. Một hoặc nhiều bản ghi có chứa các thuộc tính cần sửa đổi trong BaseRecord. Các bản ghi thay đổi được xử lý theo thứ tự từ đầu đến cuối danh sách đối số, với các giá trị thuộc tính sau ghi đè lên các giá trị trước đó.

Sửa đổi hoặc tạo một tập hợp bản ghi trong nguồn dữ liệu

Patch( DataSource, BaseRecordsTable, ChangeRecordTable1 [, ChangeRecordTable2, … ] )

  • DataSource – Bắt buộc. Nguồn dữ liệu có chứa các bản ghi mà bạn muốn sửa đổi hoặc sẽ chứa các bản ghi mà bạn muốn tạo.
  • BaseRecordTable – Bắt buộc. Một bảng chứa các bản ghi cần sửa đổi hoặc tạo. Hàm sẽ tìm thấy và sửa đổi bản ghi nếu bản ghi này đến từ nguồn dữ liệu. Nếu kết quả của hàm Defaults được sử dụng, một bản ghi sẽ được tạo.
  • ChangeRecordTable – Bắt buộc. Một hoặc nhiều bảng có một số thuộc tính nhất định cần sửa đổi cho mỗi bản ghi của BaseRecordTable. Các bản ghi thay đổi được xử lý theo thứ tự từ đầu đến cuối danh sách đối số, với các giá trị thuộc tính sau ghi đè lên các giá trị trước đó.

Hợp nhất bản ghi

Patch( Record1, Record2 [, …] )

  • Record – Bắt buộc. Ít nhất hai bản ghi bạn muốn hợp nhất. Các bản ghi được xử lý theo thứ tự từ đầu đến cuối danh sách đối số, với các giá trị thuộc tính sau ghi đè lên các giá trị trước đó.

Ví dụ

Sửa đổi hoặc tạo bản ghi (trong nguồn dữ liệu)

Trong các ví dụ sau, bạn sẽ sửa đổi hoặc tạo bản ghi trong nguồn dữ liệu có tên IceCream, chứa dữ liệu trong bảng sau và tự động tạo các giá trị trong cộtID:

Ví dụ về kem.

Công thức Description Kết quả
Patch( IceCream,
LookUp( IceCream, Flavor = "Chocolate" ), { Quantity: 400 } )
Sửa đổi một bản ghi trong nguồn dữ liệu IceCream:
  • Cột ID của bản ghi cần sửa đổi, chứa giá trị 1. (Bản ghi Chocolate có ID này.)
  • Giá trị trong cột Quantity chuyển thành 400.
{ ID: 1, Flavor: "Chocolate", Quantity: 400 }

Cột Chocolate trong nguồn dữ liệu IceCream đã được sửa đổi.
Patch( IceCream, Defaults( IceCream ), { Flavor: "Strawberry" } ) Tạo một bản ghi trong nguồn dữ liệu IceCream:
  • Các ID chứa giá trị 3, do nguồn dữ liệu tự động tạo.
  • Cột Quantity chứa 0, đây là giá trị mặc định của cột đó trong nguồn dữ liệu IceCream như hàm Defaults chỉ định.
  • Cột Flavor (Hương vị) chứa giá trị Strawberry (Dâu).
{ ID: 3, Flavor: "Strawberry", Quantity: 0 }

Cột Strawberry (Dâu) trong nguồn dữ liệu IceCream (Kem) đã được tạo.

Sau khi các công thức trước đó đã được ước tính, nguồn dữ liệu kết thúc với các giá trị sau:

Ví dụ về kem sau.

Hợp nhất các bản ghi (bên ngoài nguồn dữ liệu)

Công thức Mô tả Kết quả
Patch( { Name: "James", Score: 90 }, { Name: "Jim", Passed: true } ) Hợp nhất hai bản ghi bên ngoài nguồn dữ liệu:
  • Các giá trị trong cột Name của mỗi bản ghi không khớp. Kết quả chứa giá trị (Jim) trong bản ghi gần cuối danh sách đối số thay vì giá trị (James) trong bản ghi gần đầu danh sách đối số đó.
  • Bản ghi đầu tiên chứa cột (Score) không có trong bản ghi thứ hai. Kết quả chứa cột đó với giá trị của cột (90).
  • Bản ghi thứ hai chứa cột (Passed) không có trong bản ghi đầu tiên. Kết quả chứa cột đó với giá trị của cột (true).
{ Name: "Jim", Score: 90, Passed: true }

Sử dụng As hoặc ThisRecord

Sử dụng từ khóa As hoặc ThisRecord trong công thức tránh ngữ cảnh đánh giá không rõ ràng.

Trong ví dụ dưới đây, hãy xem xét lần tra cứu đầu tiên trong câu If. (OrderID = A[@OrderID]) dự kiến sẽ so sánh OrderId trong phạm vi tra cứu với OrderId của bộ sưu tập A trong phạm vi ForAll. Trong trường hợp này, bạn có thể muốn A[@OrderId] được giải quyết như một tham số cục bộ. Tuy nhiên, việc này hơi mơ hồ.

Power Apps hiện đang diễn giải cả bên trái OrderId và bên tay phải A[@OrderId] dưới dạng một trường trong phạm vi tra cứu. Do đó, tra cứu sẽ luôn tìm thấy hàng đầu tiên trong [dbo].[Orders1] bởi vì điều kiện luôn đúng (nghĩa là OrderId của bất kỳ hàng nào bằng chính nó.)

ClearCollect(
    A,
    Filter(
        '[dbo].[Orders1]',
        OrderId = 8888888
    )
);
ForAll(
    A,
    If(
        LookUp(
            '[dbo].[Orders1]',
            OrderId = A[@OrderId],
            "OK"
        ) = "OK",
        Patch(
            '[dbo].[Orders1]',
            LookUp(
                '[dbo].[Orders1]',
                OrderId = A[@OrderId]
            ),
            {
      OrderName: "val1"
       }
   ),
   Patch(
            '[dbo].[Orders1]',
            Defaults('[dbo].[Orders1]'),
            {
      OrderName: "val2"
       }
   )
    )
)

Sử dụng As hoặc ThisRecord

Bất cứ khi nào có thể, hãy sử dụng toán tử As hoặc ThisRecord để phân biệt phía bên trái. As được đề xuất cho tình huống trên.

Khi công thức của bạn sử dụng nhiều phạm vi với ForAll, FilterLookup trên cùng một bảng hoặc nguồn dữ liệu, có thể các tham số phạm vi có thể xung đột với cùng một trường ở nơi khác. Do đó, bạn nên sử dụng toán tử As hoặc ThisRecord để giải quyết tên trường và tránh sự mơ hồ.

Ví dụ, bạn có thể sử dụng toán tử As để phân biệt trong ví dụ dưới đây.

ClearCollect(
    A,
    Filter(
        '[dbo].[Orders1]',
        OrderId = 8888888
    )
);
ForAll(
    A,
    If(
        LookUp(
            '[dbo].[Orders1]' As B,
            B.OrderId = A[@OrderId],
            "OK"
        ) = "OK",
        Patch(
            '[dbo].[Orders1]',
            LookUp(
                '[dbo].[Orders1]' As C,
                C.OrderId = A[@OrderId]
            ),
            {
      OrderName: "val1"
       }
   ),
   Patch(
            '[dbo].[Orders1]',
            Defaults('[dbo].[Orders1]'),
            {
      OrderName: "val2"
       }
   )
    )
)

Ngoài ra, bạn có thể sử dụng ThisRecord cho cùng một mục đích.

ClearCollect(
    A,
    Filter(
        '[dbo].[Orders1]',
        OrderId = 8888888
    )
);
ForAll(
    A,
    If(
        LookUp(
            '[dbo].[Orders1]',
            ThisRecord.OrderId = A[@OrderId],
            "OK"
        ) = "OK",
        Patch(
            '[dbo].[Orders1]',
            LookUp(
                '[dbo].[Orders1]',
                ThisRecord.OrderId = A[@OrderId]
            ),
            {
      OrderName: "val1"
       }
   ),
   Patch(
            '[dbo].[Orders1]',
            Defaults('[dbo].[Orders1]'),
            {
      OrderName: "val2"
       }
   )
    )
)

Để tìm hiểu thêm về cách sử dụng toán tử AsThisRecord, hãy xem bài viết về Toán tử.