From bb41eed0c536a24a25d67e3fe105dd9d93134c7b Mon Sep 17 00:00:00 2001 From: Yahya Touil <60827484+yahyatouil-dev@users.noreply.github.com> Date: Wed, 19 Aug 2026 19:32:01 +0100 Subject: [PATCH 1/4] Add TransferFields SkipFieldsNotMatchingType guidance --- ...ds-skip-type-mismatch-can-drop-data.bad.al | 55 ++++++++++++++++++ ...s-skip-type-mismatch-can-drop-data.good.al | 56 +++++++++++++++++++ ...fields-skip-type-mismatch-can-drop-data.md | 26 +++++++++ 3 files changed, 137 insertions(+) create mode 100644 community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.bad.al create mode 100644 community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al create mode 100644 community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.bad.al b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.bad.al new file mode 100644 index 0000000..691dfd2 --- /dev/null +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.bad.al @@ -0,0 +1,55 @@ +table 50123 "Transfer Source Bad" +{ + fields + { + field(1; "Entry No."; Integer) + { + DataClassification = CustomerContent; + } + field(2; "Reference"; Code[20]) + { + DataClassification = CustomerContent; + } + } + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } + +} + +table 50124 "Transfer Target Bad" +{ + fields + { + field(1; "Entry No."; Integer) + { + DataClassification = CustomerContent; + } + field(2; "Reference"; Integer) + { + DataClassification = CustomerContent; + } + } + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } + +} + +codeunit 50492 "TransferFields Bad" +{ + procedure CopyData(Source: Record "Transfer Source Bad"; var Target: Record "Transfer Target Bad") + begin + Target.TransferFields(Source, true, true); + end; +} \ No newline at end of file diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al new file mode 100644 index 0000000..91823c6 --- /dev/null +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al @@ -0,0 +1,56 @@ +table 50121 "Transfer Source" +{ + fields + { + field(1; "Entry No."; Integer) + { + DataClassification = CustomerContent; + } + field(2; "Reference"; Code[20]) + { + DataClassification = CustomerContent; + } + } + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } + +} + +table 50122 "Transfer Target" +{ + fields + { + field(1; "Entry No."; Integer) + { + DataClassification = CustomerContent; + } + field(2; "Reference"; Integer) + { + DataClassification = CustomerContent; + } + } + + keys + { + key(PK; "Entry No.") + { + Clustered = true; + } + } + +} + +codeunit 50491 "TransferFields Good" +{ + procedure CopyData(Source: Record "Transfer Source"; var Target: Record "Transfer Target") + begin + Target."Entry No." := Source."Entry No."; + Evaluate(Target."Reference", Source."Reference"); + end; +} \ No newline at end of file diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md new file mode 100644 index 0000000..f1cbc28 --- /dev/null +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md @@ -0,0 +1,26 @@ +--- +bc-version: [all] +domain: data-modeling +keywords: [transferfields, skipfieldsnotmatchingtype, type-mismatch, field-mapping, data-transfer] +technologies: [al] +countries: [w1] +application-area: [all] +--- + +# Do not use SkipFieldsNotMatchingType to hide required TransferFields mismatches + +## Description + +`Record.TransferFields` copies values between fields with matching field numbers. Without `SkipFieldsNotMatchingType` (or with it `false`), a type mismatch between two fields in the same extension raises a runtime error at the point of transfer. Setting `SkipFieldsNotMatchingType` to `true` removes that error: the field is skipped instead, and the rest of the transfer completes normally. The caller gets no indication that a field was not copied. + +## Best Practice + +Use `TransferFields(Source)` when matching field definitions are an expected part of the table design. If source and destination fields intentionally have different types, map those fields explicitly and handle the conversion or validation in code. Use `SkipFieldsNotMatchingType = true` only when skipping incompatible fields is an intentional, documented part of the transfer contract. + +## Anti Pattern + +Using `TransferFields(Source, InitPrimaryKeyFields, true)` as a generic way to make two evolving table schemas transfer without errors, when the destination depends on every required source field being copied. A type change on either table can turn a previously transferred field into a silently skipped one without making the transfer itself fail. + +See sample: `transferfields-skip-type-mismatch-can-drop-data.good.al`. + +See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`. \ No newline at end of file From f471bdec202fa3f9815682de701e46e894d02bb9 Mon Sep 17 00:00:00 2001 From: Yahya Touil <60827484+yahyatouil-dev@users.noreply.github.com> Date: Fri, 21 Aug 2026 19:04:04 +0100 Subject: [PATCH 2/4] Update transferfields-skip-type-mismatch-can-drop-data.md --- .../transferfields-skip-type-mismatch-can-drop-data.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md index f1cbc28..a2ebeb6 100644 --- a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md @@ -1,5 +1,5 @@ --- -bc-version: [all] +bc-version: [16..] domain: data-modeling keywords: [transferfields, skipfieldsnotmatchingtype, type-mismatch, field-mapping, data-transfer] technologies: [al] @@ -15,7 +15,7 @@ application-area: [all] ## Best Practice -Use `TransferFields(Source)` when matching field definitions are an expected part of the table design. If source and destination fields intentionally have different types, map those fields explicitly and handle the conversion or validation in code. Use `SkipFieldsNotMatchingType = true` only when skipping incompatible fields is an intentional, documented part of the transfer contract. +Use `TransferFields(Source)` only when every field the destination requires, including primary key fields, is guaranteed to share a matching field number and type with the source; this form defaults `InitPrimaryKeyFields` to `true`. Fields with no matching field number, and fields whose types differ across extensions, are skipped regardless of `SkipFieldsNotMatchingType` — that parameter only governs same-extension type mismatches. If the destination depends on a field that falls into either case, map and validate it explicitly in code rather than relying on `TransferFields` to catch the gap. Use `SkipFieldsNotMatchingType = true` only when skipping same-extension type mismatches is an intentional, documented part of the transfer contract. ## Anti Pattern @@ -23,4 +23,4 @@ Using `TransferFields(Source, InitPrimaryKeyFields, true)` as a generic way to m See sample: `transferfields-skip-type-mismatch-can-drop-data.good.al`. -See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`. \ No newline at end of file +See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`. From 4a961cf9b7cfbc3e9679a51e977eece11c937cc9 Mon Sep 17 00:00:00 2001 From: Yahya Touil <60827484+yahyatouil-dev@users.noreply.github.com> Date: Fri, 21 Aug 2026 19:05:22 +0100 Subject: [PATCH 3/4] Update transferfields-skip-type-mismatch-can-drop-data.good.al --- ...transferfields-skip-type-mismatch-can-drop-data.good.al | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al index 91823c6..a0ac2a8 100644 --- a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.good.al @@ -49,8 +49,11 @@ table 50122 "Transfer Target" codeunit 50491 "TransferFields Good" { procedure CopyData(Source: Record "Transfer Source"; var Target: Record "Transfer Target") + var + ConvertedReference: Integer; begin Target."Entry No." := Source."Entry No."; - Evaluate(Target."Reference", Source."Reference"); + Evaluate(ConvertedReference, Source."Reference"); + Target.Validate("Reference", ConvertedReference); end; -} \ No newline at end of file +} From e28b07d007cac00ab6dd96e2ae4c25667ce15779 Mon Sep 17 00:00:00 2001 From: Jesper Schulz Date: Mon, 24 Aug 2026 09:51:53 +0200 Subject: [PATCH 4/4] Move good sample reference under Best Practice Aligns the article with the repo convention used by the sibling data-modeling files: the .good.al reference belongs under Best Practice and the .bad.al reference under Anti Pattern. Previously both pointers sat under Anti Pattern, leaving the good-sample reference orphaned in the wrong section. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3c998c71-f30b-40f3-b714-87fafed505d8 --- .../transferfields-skip-type-mismatch-can-drop-data.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md index a2ebeb6..7d1ea77 100644 --- a/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md +++ b/community/knowledge/data-modeling/transferfields-skip-type-mismatch-can-drop-data.md @@ -17,10 +17,10 @@ application-area: [all] Use `TransferFields(Source)` only when every field the destination requires, including primary key fields, is guaranteed to share a matching field number and type with the source; this form defaults `InitPrimaryKeyFields` to `true`. Fields with no matching field number, and fields whose types differ across extensions, are skipped regardless of `SkipFieldsNotMatchingType` — that parameter only governs same-extension type mismatches. If the destination depends on a field that falls into either case, map and validate it explicitly in code rather than relying on `TransferFields` to catch the gap. Use `SkipFieldsNotMatchingType = true` only when skipping same-extension type mismatches is an intentional, documented part of the transfer contract. +See sample: `transferfields-skip-type-mismatch-can-drop-data.good.al`. + ## Anti Pattern Using `TransferFields(Source, InitPrimaryKeyFields, true)` as a generic way to make two evolving table schemas transfer without errors, when the destination depends on every required source field being copied. A type change on either table can turn a previously transferred field into a silently skipped one without making the transfer itself fail. -See sample: `transferfields-skip-type-mismatch-can-drop-data.good.al`. - -See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`. +See sample: `transferfields-skip-type-mismatch-can-drop-data.bad.al`. \ No newline at end of file