共用方式為


Patch 函數

適用於: 畫布應用程式 Copilot Studio 桌面流程 模型導向應用程式 Power Platform CLI Dataverse 函數

修改或建立 資料來源 中的一或多筆 記錄,或合併資料來源外的記錄。

使用此功能 Patch 可在複雜情況下修改記錄,例如當您執行不需要使用者互動的更新或使用跨越多個畫面的表單時。

若要更輕鬆地更新資料來源中的記錄以進行簡單變更,請改用 Edit form 控制項。 當您新增 Edit form 控制項時,您會提供表單供使用者填寫,然後將變更儲存至資料來源。 如需詳細資訊,請參閱 了解資料表單

觀看此影片以了解如何使用該 Patch 函數:

概觀

使用此功能 Patch 來修改資料來源的一或多筆記錄。 會修改特定 欄位 值而不影響其他屬性。 例如,此公式會變更名為 Contoso 客戶的電話號碼︰

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

Patch預設值功能一起使用以建立記錄。 使用此行為組建 單一畫面控制項 建立和編輯記錄。 例如,此公式會建立名為 Contoso 客戶的記錄:

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

備註

當您使用具有預設值的資料來源記錄來修補集合時,修補作業會使用指定的修補值和資料來源中的預設值來更新集合。 patch 陳述式的 DataSource 與 Defaults 函數的 DataSource 必須相符,才能建立新記錄。

即使您沒有使用資料來源,也可以用來 Patch 合併兩筆或多筆記錄。 例如此公式會將兩筆記錄合併為一筆記錄,以識別 Contoso 的電話號碼和位置:

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

描述

修改或建立資料來源中的記錄

若要使用此函式與資料來源,請指定資料來源,然後指定基底記錄︰

  • 若要修改一筆記錄,基底記錄必須來自資料來源。 基底記錄可能已透過資源庫的 Items 屬性、放置在 內容變數中,或透過其他路徑。 但您可以將基底記錄追回資料來源。 這很重要,因為記錄包含其他資訊,可協助再次尋找記錄進行修改。
  • 若要建立記錄,請使用 Defaults 函式使用預設值建立基底記錄。

然後指定一或多筆變更記錄,其中每一筆皆包含在基底記錄中覆寫屬性值的新屬性值。 變更記錄會依引數清單開頭到結尾的順序處理,並以新的屬性值覆寫舊的屬性值。

Patch 傳回值是您修改或建立的記錄。 如果您建立記錄,傳回值可能包含資料來源自動產生的屬性。 但是,傳回值並未為相關資料表的欄位提供值。

例如,您使用 Set(MyAccount, Patch(Accounts, First(Account), 'Account Name': "Example name"));,接著使用 MyAccount.'Primary Contact'.'Full Name'。 本案例中您不能暫止完整名稱。 相反地,若要存取相關資料表的欄位,請使用獨立的查詢,例如:

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

當您更新資料來源時,可能會發生一或多個問題。 使用 IfErrorIsError 搭配傳回值 , Patch 以偵測和回應錯誤,如 錯誤處理 所述。 您也可以使用 Errors 函式識別及檢查問題,如搭配資料來源所述。

相關函式包括 Update 函式,取代整筆記錄及 Collect 函式,建立一筆記錄。 使用 UpdateIf 函式,根據條件修改多筆記錄的特定屬性。

修改或建立資料來源中的一組記錄

Patch 也可用於透過單一呼叫建立或修改多個記錄。

可在第二個引數中提供基底記錄的資料表,而不是傳遞單一基底記錄。 也會在資料表中提供變更記錄,以基底記錄對應一對一。 每個變更資料表中的記錄數目必須與基底資料表中的記錄數目相同。

以這種方式使用 Patch 時,傳回值也是一個表格,其中每筆記錄都與基本和變更記錄一對一對應。

合併資料來源外部的記錄

指定您想要合併的兩筆或多筆記錄。 記錄會依引數清單開頭到結尾的順序處理,並以新的屬性值覆寫舊的屬性值。

Patch 傳回合併的記錄,並且不會修改其引數或任何資料來源中的記錄。

語法

修改或建立資料來源中的記錄

Patch資料來源BaseRecordChangeRecord1 [、 ChangeRecord2、... ])

  • DataSource – 必要項目。 包含您想要修改之記錄或將包含您想要建立之記錄的資料來源。
  • BaseRecord –必需。 要修改或建立的記錄。 如果記錄來自資料來源,則已找到並修改記錄。 如果使用 Defaults 的結果,可建立記錄。 patch 陳述式的 DataSource 與 Defaults 函數的 DataSource 必須相符,才能建立新記錄。
  • ChangeRecords –必需。 包含要在 BaseRecord 中修改屬性的一或多筆記錄。 變更記錄會依引數清單開頭到結尾的順序處理,並以新的屬性值覆寫舊的屬性值。

修改或建立資料來源中的一組記錄

Patch資料來源BaseRecordsTableChangeRecordTable1 [、 ChangeRecordTable2、... ] )

  • DataSource – 必要項目。 包含您想要修改之記錄或將包含您想要建立之記錄的資料來源。
  • BaseRecordTable –必需。 要修改或建立的記錄資料表。 如果記錄來自資料來源,則已找到並修改記錄。 如果使用 Defaults 的結果,可建立記錄。 patch 陳述式的 DataSource 與 Defaults 函數的 DataSource 必須相符,才能建立新記錄。
  • ChangeRecordTables –必需。 包含要針對 BaseRecordTable 的每筆記錄修改屬性的一個或多個記錄資料表。 變更記錄會依引數清單開頭到結尾的順序處理,並以新的屬性值覆寫舊的屬性值。

合併記錄

Patch記錄 1記錄 2 [, ...] )

  • 記錄 - 必需。 至少兩筆您想要合併的記錄。 記錄會依引數清單開頭到結尾的順序處理,並以新的屬性值覆寫舊的屬性值。

範例

修改或建立記錄 (在資料來源中)

在這些範例中,您會修改或建立資料來源中的記錄,名為 IceCream,其中包含在此資料表中的資料,並在 ID欄位中自動產生值:

範例 icecream。

公式 描述 Result
Patch(冰淇淋,
LookUp( IceCream, flavor = “chocolate” ), { 數量: 400 } )
修改 IceCream 資料來源中的記錄︰
  • 要修改記錄的 ID 欄位包含值 1。 (Chocolate 記錄具有該 ID。)
  • Quantity 欄位值會變更為 400
{ ID:1,口味:「巧克力」,數量:400 }

IceCream 資料來源中的 Chocolate 項目已修改。
Patch( IceCream, defaults( IceCream ), { flavor: “草莓” } ) 建立 IceCream 資料來源中的記錄︰
  • ID 欄位包含資料來源自動產生的值 3
  • Quantity 欄位包含 0,是 IceCream 資料來源中該欄位的預設值,如 Defaults 函式所指定。
  • Flavor 欄位包含值 Strawberry
{ ID:3,口味:“草莓”,數量:0 }

IceCream 資料來源中的 Strawberry 項目已建立。

評估過上述公式之後,資料來源最後會顯示這些值︰

範例冰淇淋之後。

合併記錄 (資料來源外)

公式 描述 Result
Patch( { 姓名: “詹姆斯”, 得分: 90 }, { 姓名: “吉姆”, 通過: true } ) 合併資料來源外部的兩筆資料:
  • 每筆記錄的 Name 欄位值都不符合。 結果包含較接近引數清單結尾記錄中的值 (Jim),而不是較接近開始記錄中的值 (James)。
  • 第一筆記錄包含的欄位 (Score) 不存在於第二筆記錄。 結果會包含該欄位與其值 (90)。
  • 第二筆記錄包含的欄位 (Passed) 不存在於第一筆記錄。 結果會包含該欄位與其值 (true)。
{ 姓名:“Jim”,分數:90,通過:true }

使用 AsThisRecord

在公式中使用 AsThisRecord 關鍵字可避免不明確的計算上下文。

在下面的範例中,請考慮 If 陳述式中的第一個查詢。 (OrderID = A[@OrderID]) 應將 OrderId the in the lookup scope 與 OrderId the A collection in the scope 進行比較 ForAll 。 在此案例中,您可能希望將 A[@OrderId] 解析為本機參數。 但是不明確。

Power Apps 目前會將左側 OrderId 和右側 A[@OrderId] 解釋為查詢範圍中的欄位。 因此,查詢將始終會在 [dbo].[Orders1] 中尋找第一列,因為條件始終為 true(即任何列的 OrderId 值都等於自身)。

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"
       }
   )
    )
)

使用 AsThisRecord

只要有可能,請使用 As 運算子或 ThisRecord 來消除左側的歧義。 對於 上述場景,建議這樣做。

當您的公式在同一個資料來源或表格上使用具有 ForAllFilterLookup 的多個範圍時,範圍參數可能會與其他地方的同一欄位衝突。 因此,建議使用 As 運算子或 ThisRecord 來解析欄位名稱,避免混淆。

例如,您可以使用 As 運算子來消除下列範例中的歧義。

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"
       }
   )
    )
)

或者,您也可以使用 ThisRecord 來進行相同的目的。

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"
       }
   )
    )
)

若要進一步了解 As 運算子和 ThisRecord 的用法,請參閱運算子文章。