local procedure TestListAssignment()
var i: Integer; ListNumberOne: List of [Integer]; ListNumberTwo: List of [Integer]; begin for i := 1 to 20 do ListNumberOne.Add(i); ListNumberTwo := ListNumberOne; ListNumberTwo.Add(21); Message('List1 count: %1\List2 count: %2', ListNumberOne.Count(), ListNumberTwo.Count()); endlocal procedure TestListShallowCopy()
var
i: Integer;
ListNumberOne: List of [Integer];
ListNumberTwo: List of [Integer];
begin
for i := 1 to 20 do
ListNumberOne.Add(i);
ListNumberTwo := ListNumberOne.GetRange(1, ListNumberOne.Count());
ListNumberTwo.Add(21);
Message('List1 count: %1\List2 count: %2', ListNumberOne.Count(), ListNumberTwo.Count());
end;
In the case of nested lists, we must use deep copy:
local procedure TestNestedListShallowCopy()
var
ListNumberOne: List of [List of [Integer]];
ListNumberTwo: List of [List of [Integer]];
NestedList: List of [Integer];
i: Integer;
k: Integer;
begin
//ListNumberOne will contain 25 NestedList, Nested list contain numbers from 6 to 10 (5 in total)
for k := 6 to 10 do begin
NestedList.Add(k);
for i := 1 to 5 do
ListNumberOne.Add(NestedList);
end;
//Shallow copy ListNumberOne to ListNumberTwo
ListNumberTwo := ListNumberOne.GetRange(1, ListNumberOne.Count());
//Additional number to Nested List will be displayed in ListNumberOne and ListNumberTwo as well
NestedList.Add(11);
//Result is 6 and 6 (6..11), because nested list is updated in previous step (we just check first nested list by index 1)
Message('NestedList1 count: %1\NestedList2 count: %2',
ListNumberOne.Get(1).Count(),
ListNumberTwo.Get(1).Count());
end;
local procedure TestNestedListDeepCopy()
var
ListNumberOne: List of [List of [Integer]];
ListNumberTwo: List of [List of [Integer]];
NestedList: List of [Integer];
i: Integer;
k: Integer;
begin
//ListNumberOne will contain 25 NestedList, Nested list contain numbers from 6 to 10 (5 in total)
for k := 6 to 10 do begin
NestedList.Add(k);
for i := 1 to 5 do
ListNumberOne.Add(NestedList);
end;
//Deep copy ListNumberOne to ListNumberTwo
foreach NestedList in ListNumberOne do
ListNumberTwo.Add(NestedList.GetRange(1, NestedList.Count()));
//Additional number to Nested List will be displayed in ListNumberOne only
NestedList.Add(11);
//Result is 6 and 5 because ListNumberTwo contain a new copy of nested list (it was same reference in shallow copy)
Message('NestedList1 count: %1\NestedList2 count: %2',
ListNumberOne.Get(1).Count(),
ListNumberTwo.Get(1).Count());
end;
How can we use a list? For example, we need to collect all unique Customer No. values from Sales Orders. Then the code might look something like this:
local procedure CollectUniqueCustomerNoFromSalesOrder()
var
SalesHeader: Record "Sales Header";
ListOfCustomerNo: List of [Code[20]];
CustomerNo: Code[20];
begin
SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Order);
if SalesHeader.FindSet() then
repeat
//Collect unique entries
if not ListOfCustomerNo.Contains(SalesHeader."Sell-to Customer No.") then
ListOfCustomerNo.Add(SalesHeader."Sell-to Customer No.");
until SalesHeader.Next() = 0;
//Read and show each enique Customer No.
foreach CustomerNo in ListOfCustomerNo do
message(CustomerNo);
end;
local procedure CollectSalesInvoiceDocNoLineNoDict()
var
SalesHeader: Record "Sales Header";
SalesLine: Record "Sales Line";
SalesInvoiceDocNoLineNoDict: Dictionary of [Code[20], List of [Integer]];
ListOfLineNo: List of [Integer];
LineNo: Integer;
ResultTxt: TextBuilder;
DocumentNo: Code[20];
begin
SalesHeader.SetRange("Document Type", SalesHeader."Document Type"::Invoice);
if SalesHeader.FindSet() then
repeat
//Clear list of Line No. for each new Sales Invoice
Clear(ListOfLineNo);
SalesLine.SetRange("Document Type", SalesHeader."Document Type");
SalesLine.SetRange("Document No.", SalesHeader."No.");
if SalesLine.FindSet() then
repeat
//Collect Line No. of current Sales Invoice
ListOfLineNo.Add(SalesLine."Line No.");
until SalesLine.Next() = 0;
//Add DocumentNo with list of Line No. to dictionary
SalesInvoiceDocNoLineNoDict.Add(SalesHeader."No.", ListOfLineNo);
until SalesHeader.Next() = 0;
//Read result and save it to text
foreach DocumentNo in SalesInvoiceDocNoLineNoDict.Keys() do begin
SalesInvoiceDocNoLineNoDict.Get(DocumentNo, ListOfLineNo);
ResultTxt.AppendLine(DocumentNo);
foreach LineNo in ListOfLineNo do
ResultTxt.AppendLine(Format(LineNo));
ResultTxt.AppendLine();
end;
Message(ResultTxt.ToText());
end;
local procedure GroupPOCustItemDict()
var
PurchaseHeader: Record "Purchase Header";
PurchaseLine: Record "Purchase Line";
POCustItemDict: Dictionary of [Code[20], Dictionary of [Code[20], List of [Code[20]]]];
DocumentNoItemNoDict: Dictionary of [Code[20], List of [Code[20]]];
PrevDocumentNoItemNoDict: Dictionary of [Code[20], List of [Code[20]]];
PrevDocNo: Code[20];
ListOfItemNo: list of [Code[20]];
VendorNo: Code[20];
DocumentNo: Code[20];
ItemNo: Code[20];
ResultTxt: TextBuilder;
begin
PurchaseHeader.SetCurrentKey("Buy-from Vendor No.", "No.");
PurchaseHeader.SetRange("Document Type", PurchaseHeader."Document Type"::Order);
if PurchaseHeader.FindSet() then
repeat
Clear(ListOfItemNo);
PurchaseLine.SetRange("Document Type", PurchaseHeader."Document Type");
PurchaseLine.SetRange("Document No.", PurchaseHeader."No.");
PurchaseLine.SetRange(Type, PurchaseLine.Type::Item);
if PurchaseLine.FindSet() then
repeat
//Collect Item Nos. of current Purchase Document
ListOfItemNo.Add(PurchaseLine."No.");
until PurchaseLine.Next() = 0;
//Store current DocumentNo with list of document items
Clear(DocumentNoItemNoDict);
DocumentNoItemNoDict.Add(PurchaseHeader."No.", ListOfItemNo);
//Check if current vendor group is exist
if not POCustItemDict.ContainsKey(PurchaseHeader."Buy-from Vendor No.") then
//Add new Vendor group with DocumentNo -> Item Nos. dictionary
POCustItemDict.Add(PurchaseHeader."Buy-from Vendor No.", DocumentNoItemNoDict)
else begin
//Get previous DocumentNo -> Item Nos. dictionary
POCustItemDict.Get(PurchaseHeader."Buy-from Vendor No.", PrevDocumentNoItemNoDict);
//Read previous dictionary and add entries to current DocumentNo -> ItemNos dictionary
foreach PrevDocNo in PrevDocumentNoItemNoDict.Keys() do
DocumentNoItemNoDict.Add(PrevDocNo, PrevDocumentNoItemNoDict.Values().Get(1));
//Set total dictionary to current Vendor group
POCustItemDict.Set(PurchaseHeader."Buy-from Vendor No.", DocumentNoItemNoDict);
end;
until PurchaseHeader.Next() = 0;
//Read result and save it to text
foreach VendorNo in POCustItemDict.Keys() do begin
ResultTxt.AppendLine(StrSubstNo('%1:%2', PurchaseHeader."Buy-from Vendor No.", VendorNo));
POCustItemDict.Get(VendorNo, DocumentNoItemNoDict);
foreach DocumentNo in DocumentNoItemNoDict.Keys() do begin
ResultTxt.AppendLine(StrSubstNo('--%1:%2', PurchaseHeader.FieldCaption("No."), DocumentNo));
DocumentNoItemNoDict.Get(DocumentNo, ListOfItemNo);
foreach ItemNo in ListOfItemNo do
ResultTxt.AppendLine(StrSubstNo('----%1:%2', PurchaseLine.FieldCaption("No."), ItemNo));
end;
ResultTxt.AppendLine();
end;
Message(ResultTxt.ToText());
end;
No comments:
Post a Comment