Hi all,
I've created a function that opens two tables by using RecordRef variables, a source and a target table.
I attempt to copy each record in the source table into the target table by applying the same logic than the NAV build-in function TRANSFERFIELDS (unfortunately it does not exist on RecordRef variables). This means I have to simulate a field mapping based on the Field No. property.
By consequence I cannot use the RecordRef.FIELDINDEX function and instead need to use the RecordRef.FIELD...
However, in order to properly insert a record into the target table, I first need to find all the fields of the source record and store them until I can write them (altogether) into the target table.
My problem is the storage of the field values until I have them altogether in between the same loop...
How can I tell NAV that it should search for each field, try to find a correspondence, and then insert a the new record into the target table?
Thanks for helping me out on this
Variables:
DynamicTableSource : RecordRef variable
DynamicTableTarget: RecordRef variable
"Copy Table ID" : a field value of a record that contains the Table No. of the source table as integer
"Target Table ID" : a field value of a record that contains the Table No. of the target table as integer
TableField : a record variable pointing at the virtual "Field" table
DynamicFieldSource : FieldRef variable
DynamicFieldTarget : FieldRef variable
Code:
CLEAR(DynamicTableSource);
CLEAR(DynamicTableTarget);
DynamicTableSource.OPEN("Copy Table ID");
DynamicTableTarget.OPEN("Target Table ID");
DynamicTableTarget.DELETEALL;
IF DynamicTableSource.FINDSET THEN REPEAT
CLEAR(TableField);
TableField.SETRANGE(TableNo,Rec."Source Table ID");
IF TableField.FINDSET THEN REPEAT
DynamicFieldSource := TableField."No.";
CLEAR(TableField2);
TableField2.SETRANGE(TableNo,Rec."Target Table ID");
IF TableField2.FINDSET THEN REPEAT
DynamicFieldTarget := TableField2."No.";
//make sure whatever I have to do is only done if the Field No. match
IF DynamicFieldSource = DynamicFieldTarget THEN BEGIN
DynamicFieldRefSource := DynamicTableSource.FIELD(DynamicFieldSource);
DynamicFieldRefTarget := DynamicTableTarget.FIELD(DynamicFieldTarget);
DynamicFieldRefTarget.VALUE := DynamicFieldRefSource.VALUE;
//obivously, this cannot work....
DynamicTableTarget.INSERT;
END;
UNTIL TableField2.NEXT = 0;
END;
UNTIL TableField.NEXT = 0;
END;
UNTIL DynamicTableSource.NEXT=0;
END;
Comments
1. Tablefield should be filtered only for "normal" class fields
2. Tablefield2 shoul be filtered for field found in Tablefield
3. DynamicTableTarget should be inserted once, then modified in next loop
Thanks for your replies.
I tried Lubots approach and in fact can confirm, it works only if the PK consists of the first field.
However, it perfectly makes sense to filter the fields before processing.
Concerning the suggestion to simply insert the found record completely: it does not work, as I don't have the same table structure in the target as in the source table. I only want to copy the fields that match each others' field numbers, exactly as the TRANSFERFIELD function would do it.
This is the Source Table:
Field No. + Field Name
***********************
1, Code (Code 20)
2, City (Text 30)
3, Search City (Code 30)
50804, County Description (Text 30)
60327, Territory (Code 10)
60328, Territory Code ID (Code 20)
60329, City Code ID (Code 10)
60330, City Addition (Text 30)
This is the Target Table:
Field No. + Field Name
***********************
1, Code (Code 20)
2, City (Text 30)
3, Search City (Code 30)
4, Country/Region Code (Code 10)
5, County (Text 30)
50804, County Name (Text 50)
Following the logic of TRANSFERFIELDS, only the red fields are copied (as their number and their type are matching). Now, I could probably count the number of times I have looped through the fields of the source table and hard-code variables like "MatchedField1", "MatchedField2", etc. Then I would stop after I have reached the RecordRef.COUNT function result. This just doesn't seem very efficient to me and I am unsure whether it would work.
Many thanks again for sharing your thoughts.
Best regards,
Transfer all fields that should be transferred and then insert the target record.
I would start by finding the fields that can be transferred as it's the same for all records in the table. In below the numbers of the fields to be transferred are saved in a temporary Integer table
Thanks for your help. Using the integer table as a temporary variable is an useful idea.
The below part made me understand why.
Also, the modifications on filtering and testing suggested by the three of you show an effect: the codeunit runs noticeably faster.
Thanks to everyone.
BR