適用於: 畫布應用程式
Copilot Studio
桌面流程
模型導向應用程式
Power Platform CLI
Dataverse 函數
修改或建立 資料來源 中的一或多筆 記錄,或合併資料來源外的記錄。
使用此功能 Patch 可在複雜情況下修改記錄,例如當您執行不需要使用者互動的更新或使用跨越多個畫面的表單時。
若要更輕鬆地更新資料來源中的記錄以進行簡單變更,請改用 Edit form 控制項。 當您新增 Edit form 控制項時,您會提供表單供使用者填寫,然後將變更儲存至資料來源。 如需詳細資訊,請參閱 了解資料表單。
觀看此影片以了解如何使用該 Patch 函數:
Overview
使用此功能 Patch 來修改資料來源的一或多筆記錄。 它更新特定 欄位 的值,而不影響其他屬性。 例如,此公式會變更名為 Contoso 客戶的電話號碼︰
Patch( Customers, LookUp( Customers, Name = "Contoso" ), { Phone: "1-212-555-1234" } )
與Patch預設值功能一起使用以建立記錄。 使用此行為組建 單一畫面控制項 建立和編輯記錄。 例如,此公式會建立名為 Contoso 客戶的記錄:
Patch( Customers, Defaults( Customers ), { Name: "Contoso" } )
Note
當你使用來自資料來源的預設值紀錄來修補集合時,修補操作會同時更新該集合,並更新指定的補丁值與資料來源的預設值。 修補語句的資料來源與 Defaults 函式的資料來源必須相符才能建立新紀錄。
即使您沒有使用資料來源,也可以用來 Patch 合併兩筆或多筆記錄。 例如此公式會將兩筆記錄合併為一筆記錄,以識別 Contoso 的電話號碼和位置:
Patch( { Name: "Contoso", Phone: "1-212-555-1234" }, { Name: "Contoso", Location: "Midtown" } )
Description
修改或建立資料來源中的記錄
若要使用此函式與資料來源,請指定資料來源,然後指定基底記錄︰
- 要修改記錄,基礎記錄必須來自資料來源。 你可以透過畫廊的 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'
當您更新資料來源時,可能會發生一或多個問題。 使用 IfError 和 IsError 搭配傳回值 , Patch 以偵測和回應錯誤,如 錯誤處理 所述。 您也可以使用 Errors 函式識別及檢查問題,如搭配資料來源所述。
相關函式包括 Update 函式,取代整筆記錄及 Collect 函式,建立一筆記錄。 使用 UpdateIf 函式,根據條件修改多筆記錄的特定屬性。
修改或建立資料來源中的一組記錄
你也可以用 Patch 一次呼叫建立或修改多筆紀錄。
不要只傳遞單一基底記錄,而是在第二個參數中提供基底記錄的表格。 也提供變更紀錄,與基礎記錄一對一對應。 每個變更資料表中的記錄數目必須與基底資料表中的記錄數目相同。
當你用這種方式使用 Patch 時,回傳值也會變成一個表格,每個記錄都與基礎和變更記錄一一對應。
合併資料來源外部的記錄
指定您想要合併的兩筆或多筆記錄。 該函式依照參數清單開始到結束的順序處理記錄,後續屬性值會覆蓋先前的值。
Patch 傳回合併的記錄,並且不會修改其引數或任何資料來源中的記錄。
Syntax
修改或建立資料來源中的記錄
Patch( 資料來源、 BaseRecord、 ChangeRecord1 [、 ChangeRecord2、... ])
- DataSource – 必要項目。 包含您想要修改之記錄或將包含您想要建立之記錄的資料來源。
- BaseRecord –必需。 要修改或建立的記錄。 如果紀錄來自資料來源,函式會尋找並修改該紀錄。 若使用 Defaults 的結果,函式會建立一個紀錄。 patch 陳述式的 DataSource 與 Defaults 函數的 DataSource 必須相符,才能建立新記錄。
- ChangeRecords –必需。 包含要在 BaseRecord 中修改屬性的一或多筆記錄。 該函式依照參數清單開始到結束的順序處理變更記錄,後續屬性值會覆蓋先前的值。
修改或建立資料來源中的一組記錄
Patch( 資料來源、 BaseRecordsTable、 ChangeRecordTable1 [、 ChangeRecordTable2、... ] )
- DataSource – 必要項目。 包含您想要修改之記錄或將包含您想要建立之記錄的資料來源。
- BaseRecordTable –必需。 要修改或建立的記錄資料表。 如果紀錄來自資料來源,函式會尋找並修改該紀錄。 若使用 Defaults 的結果,函式會建立一個紀錄。 patch 陳述式的 DataSource 與 Defaults 函數的 DataSource 必須相符,才能建立新記錄。
- ChangeRecordTables –必需。 包含要針對 BaseRecordTable 的每筆記錄修改屬性的一個或多個記錄資料表。 該函式依照參數清單開始到結束的順序處理變更記錄,後續屬性值會覆蓋先前的值。
Merge records
Patch( 記錄 1、 記錄 2 [, ...] )
- 記錄 - 必需。 至少兩筆您想要合併的記錄。 該函式依序從參數清單開始到結束處理記錄,後續屬性值會覆蓋先前的值。
Examples
修改或建立記錄 (在資料來源中)
在這些範例中,你會修改或建立一個名為 IceCream 的資料來源紀錄。 資料來源包含此 表格 中的資料,並自動產生 ID欄位的值:
要建立這個資料來源的記憶體版本,讓你可以嘗試以下範例,請評估這個公式:
ClearCollect( IceCream,
{ ID: 1, Flavor: "Chocolate", Quantity: 100 },
{ ID: 2, Flavor: "Vanilla", Quantity: 200 }
)
| Formula | Description | Result |
|---|---|---|
|
Patch(冰淇淋, LookUp( IceCream, flavor = “chocolate” ), { 數量: 400 } ) |
修改 IceCream 資料來源中的記錄︰
|
{ ID:1,口味:「巧克力」,數量:400 } IceCream 資料來源中的巧克力條目有修改。 |
| Patch( IceCream, defaults( IceCream ), { flavor: “草莓” } ) | 建立 IceCream 資料來源中的記錄︰
|
{ ID:3,口味:“草莓”,數量:0 } IceCream 資料來源中的 Strawberry 條目會被建立。 |
在前述公式評估完畢後,資料來源以以下數值結束:
合併記錄 (資料來源外)
| Formula | Description | Result |
|---|---|---|
| Patch( { 姓名: “詹姆斯”, 得分: 90 }, { 姓名: “吉姆”, 通過: true } ) | 合併資料來源外部的兩筆資料:
|
{ 姓名:“Jim”,分數:90,通過:true } |
修改或建立一組記錄(在資料來源中)
當你使用 Patch 表格而非單一記錄時,可以在一次呼叫中建立或修改多個記錄。 回傳值是一個與輸入資料表一對一對應的記錄表。
此範例同時更新 IceCream 資料來源中多種口味的數量:
Patch(
IceCream,
Table(
{ ID: 1, Flavor: "Chocolate", Quantity: 150 },
{ ID: 2, Flavor: "Vanilla", Quantity: 200 }
),
Table(
{ Quantity: 300 },
{ Quantity: 400 }
)
)
結果是一個包含更新紀錄的表格: { ID: 1, Flavor: "Chocolate", Quantity: 300 } 和 { ID: 2, Flavor: "Vanilla", Quantity: 400 }。
此範例使用 Defaults 建立多個新紀錄:
Patch(
IceCream,
Table( Defaults( IceCream ), Defaults( IceCream ) ),
Table(
{ Flavor: "Mint", Quantity: 60 },
{ Flavor: "Peach", Quantity: 80 }
)
)
Note
當你使用 Patch 表格時,每個變更表的記錄數量必須與基礎表格的記錄數量相符。 否則會發生錯誤。
要在修改多筆紀錄時偵測錯誤,請使用 IfError。
IfError 是首選機制,且可在 Power Fx 主機間運作:
IfError(
Patch(
IceCream,
baseRecords,
changeRecords
),
Notify( "Some records failed to update: " & FirstError.Message, NotificationType.Error )
)
Patch 與 Dataverse 欄位類型相符
以下範例特別適用於Microsoft Dataverse資料來源。 記錄形狀會依資料來源而異(例如 SharePoint 和 SQL Server 格式不同)。
選擇欄: 要設定 Choice 欄位,請直接使用 enum 值。 此範例在帳戶資料表上設置狀態選擇欄位:
Patch(
Accounts,
LookUp( Accounts, 'Account Name' = "Contoso" ),
{ 'Status': 'Status (Accounts)'.Active }
)
查詢專欄: 要設定查找欄位,請提供一個包含相關資料表主鍵的紀錄。 此範例設定了帳戶紀錄的主要聯絡人查詢:
Patch(
Accounts,
LookUp( Accounts, 'Account Name' = "Contoso" ),
{ 'Primary Contact': LookUp( Contacts, 'Full Name' = "John Smith" ) }
)
Note
這些欄位類型的範例是 Dataverse 專屬的。 其他資料來源,如 SharePoint 或 SQL Server,可能需要對相似欄位類型使用不同的記錄格式。 請參考你特定資料來源的文件以取得正確的格式。
在 使用 Patch
函 Patch 式本身不受 委派 限制,因為它是寫入資料來源,而非查詢。 然而,當公式中記錄選擇部分(如 Filter、LookUp 或 ForAll)查詢超出資料來源委派限制時,委派警告可能會出現Patch。
當你在包含 Patch的公式中看到委派警告時,請檢查該警告是否適用於資料檢索函數,而非 Patch 自身。 欲了解更多委派資訊,請參閱 「了解 canvas 應用程式中的委派」。
函數常見 Patch 錯誤
使用此功能 Patch 時,可能因資料來源連線、權限或資料衝突而發生錯誤。 使用 IfError 和 IsError 來偵測錯誤並適當回應。
「使用 Patch 功能時出現網路錯誤」:此錯誤通常表示應用程式無法存取資料來源。 常見原因包括網路連線中斷、資料來源暫時無法使用,或現有使用者權限不足。 將通話包裝 Patch 成 IfError ,以向使用者提供有意義的訊息。
「伺服器變更存在衝突」:此錯誤發生在其他使用者或程序在應用程式讀取記錄並寫入變更之間修改同一記錄時。 透過呼叫 Refresh 函式來刷新資料來源並重試操作。
權限錯誤:若使用者沒有權限在資料來源中建立或修改紀錄,呼叫 Patch 將失敗。 使用 IfError 來捕捉與權限相關的錯誤並引導使用者。
關於一般錯誤處理模式,請參見錯誤處理。
使用 As 或 ThisRecord
在公式中使用 As 或 ThisRecord 關鍵字,以避免評估語境模糊。
以下範例中,考慮陳述中的If第一個Lookup。
(OrderID = A[@OrderID])預期將 在範圍內AOrderIdForAll與 在範圍內的 集合 進行比較。OrderIdLookup 在這種情況下,你很可能想 A[@OrderId] 將 解析為一個局部參數。 但這很模糊。
Power Apps目前將左側OrderId與右側A[@OrderId]解釋為Lookup範圍中的一個場。 因此, Lookup 總是找到 中 [dbo].[Orders1] 的第一列,因為條件總是成立(即任一列的 都 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"
}
)
)
)
使用 As 或 ThisRecord
盡可能使用 As 運算子或 ThisRecord 關鍵字來辨識左側。 如 前述情境所建議的。
當你的公式在同一資料來源或資料表上使用多個作用ForAll域時,FilterLookup作用域參數可能會與其他欄位發生衝突。 因此,請使用 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 的使用,請參閱 Operators 條目。