BusinessCentral.LinterCop
BusinessCentral.LinterCop copied to clipboard
LC0044 - TransferFields issue when going from small to larger text or code field
When using transferfields on different sized fields this warning will appear.
However, in my situation the transferfields is done from a Code[3] to a Code[10] and only in a DataUpgrade situation. Unfortunately, this causes warnings where there is no real issue. The transfer is done from small to larger field.
It would be great if the check would be smarter by either:
- check if transferfields is from smaller to larger field
- ignore check in DataUpgrade situations (replacing a table with new version where the field(s) are larger)
I've looked into this, but unfortunately it's challenging to support this.
The rule currently only gathers set of tables without the direction between them. It will also be challenging to find all the possible directions in the BaseApp and keeping them up-to-date.
An (fictional) example "Sales Header" to "Sales Invoice Header" seems straight forward, but what if you create a Corrective Creditnota from a Posted Sales Invoice, then also to flow the other way around needs to work.
Next to the challenge of mapping the direction, I believe also other possible issues could occur. For example in the case of a PTE that want to do a TransferFields from "Sales Invoice Header" to "Sales Header" would then break if a field on the "Sales Invoice Header" would have a larger field then the "Sales Header".
So with this I'm unsure if loosing up this rule is the right approach.
I understand your concern. However, in my example I've also said TransferFields was only used in a DataUpgrade codeunit.
If this was to be excluded, that would be great. The thing is I have to include quite a few locations with a pragma directive which makes the code less readable.
- New table/field
- Obsolete table/field (State=Removed)
- TransferFields in DataUpgrade codeunit
If there a specific scenario's where we can suppress the rule, that would be great. Can you share an example or a small project for me to better understand the circumstances of the different scenario's your referencing?
Thank you for providing an small project, this is very helpful.
Unfortunately there isn't a direct property 'DataUpgrade' available, but indeed we could determine whether this is the case with the status of the Source table with ObsoleteState = Removed;
and the .TransferFields
inside a codeunit with Subtype = Upgrade;
.
Maybe I can try to see if we can exclude tables with the property ObsoleteState = Removed;
when the .TransferFields
inside a codeunit with Subtype = Upgrade;
. There is a possible downside on this and could cause an error during the upgrade of an extension in the case we've overlooked an incompatible transfer (something like from Code[20] to Code[10]). So I'm between a Rock and a Hard Place on this. I understand the false positive, where disabling the rule completely is also not the best solution here I believe.
Just thinking out loud here; Is using the DataTransfer Data Type a viable solution for this? This provides more control and options for an Data Upgrade.
codeunit 50100 DataUpgrade
{
Access = Internal;
InherentPermissions = X;
Subtype = Upgrade;
var
wgCduUpgradeTag: Codeunit "Upgrade Tag";
trigger OnUpgradePerCompany()
begin
UpgradeFieldLength();
end;
local procedure UpgradeFieldLength()
var
ObsoletedTable: Record ObsoletedTable;
NewTable: Record NewTable;
TableDataTransfer: DataTransfer;
UpgradeTagLbl: Label 'UPGRADETAG-LC0044-DATAUPGRADE', Locked = true;
begin
if wgCduUpgradeTag.HasUpgradeTag(UpgradeTagLbl) then
exit;
TableDataTransfer.SetTables(Database::ObsoletedTable, Database::NewTable);
TableDataTransfer.AddFieldValue(ObsoletedTable.FieldNo(Code), NewTable.FieldNo(Code));
TableDataTransfer.AddFieldValue(ObsoletedTable.FieldNo(Description), NewTable.FieldNo(Description));
TableDataTransfer.AddJoin(ObsoletedTable.FieldNo(Code), NewTable.FieldNo(Code));
TableDataTransfer.CopyRows();
Clear(TableDataTransfer);
ObsoletedTable.DeleteAll(false);
wgCduUpgradeTag.SetUpgradeTag(UpgradeTagLbl);
end;
}