Incompatible field types across TransferFields
TransferFields copies field values between records by matching field IDs, not field names. When two tables share a field ID but define incompatible data types, the call throws a runtime error at execution time.
The fields must have the same data type for the copying to succeed (text and code are convertible, other types are not). There must be room for the actual length of the contents of the field to be copied in the field to which it is to be copied. If any one of these conditions aren’t fulfilled, a runtime error will occur.
— Record.TransferFields(var Record [, Boolean]) Method on Microsoft Learn
The compiler cannot catch this — the mismatch only surfaces when TransferFields executes. This rule performs a compile-time analysis of table schemas to detect incompatible field types before they reach production.
Example
Both tables define field ID 2, but "Sales Document" declares it as Decimal while "Posted Sales Document" declares it as Integer:
table 50100 "Sales Document"
{
fields
{
field(1; "No."; Code[20]) { }
field(2; Amount; Decimal) { }
}
}
table 50101 "Posted Sales Document"
{
fields
{
field(1; "No."; Code[20]) { }
field(2; Amount; Integer) { }
}
procedure Post(SalesDoc: Record "Sales Document")
begin
Rec.TransferFields(SalesDoc); // Incompatible field types across TransferFields [PC0020]
end;
}Align the field types so they match across both tables:
table 50100 "Sales Document"
{
fields
{
field(1; "No."; Code[20]) { }
field(2; Amount; Decimal) { }
}
}
table 50101 "Posted Sales Document"
{
fields
{
field(1; "No."; Code[20]) { }
field(2; Amount; Decimal) { }
}
procedure Post(SalesDoc: Record "Sales Document")
begin
Rec.TransferFields(SalesDoc);
end;
}When the diagnostic is reported
- Direct
TransferFieldsinvocations: the rule compares field types between the source and target tables for all shared field IDs. - Table extensions: the base application has many table pairs coupled via
TransferFields(e.g.,CustomerandContact, orPurchase HeaderandPurch. Inv. Header). When your table extensions add a field with the same ID to both sides of a known pair, the rule checks that the types match — even though your extension never callsTransferFieldsdirectly.
The following type conversions are considered safe and do not trigger the diagnostic:
| Source type | Target type |
|---|---|
| Code | Text |
| Integer | BigInteger or Decimal |
| Enum | Integer |
| Any length-based type | Same type with equal or greater length |
Exception
The three-parameter overload TransferFields(FromRecord, InitPrimaryKeyFields, SkipFieldsNotMatchingType) (available from runtime 4.2) accepts a SkipFieldsNotMatchingType parameter. When set to true, the platform skips fields with incompatible types instead of throwing a runtime error. The diagnostic is not reported when this parameter is true.
Use a pragma on the field definition when the type mismatch is intentional and you have verified it is handled:
#pragma warning disable PC0020
field(2; Amount; Integer) { }
#pragma warning restore PC0020
See also
- Record.TransferFields(var Record, Boolean, Boolean) Method on Microsoft Learn
- PC0021 — Inconsistent field names across TransferFields