How to Split a List into Sublists of size N in Business Central
Code
The following procedure is the protagonist of the post, it allows dividing a List in this case of JsonObject into sublists of size Size.
codeunit 50800 Helper
{
local procedure SplitList(Input: List of [JsonObject]; Size: Integer): List of [List of [JsonObject]]
var
List: List of [List of [JsonObject]];
I: Integer;
Math: Codeunit Math;
begin
for I := 1 to Input.Count do begin
List.Add(Input.GetRange(I, Math.Min(Size, Input.Count + 1 - I)));
I += Size - 1;
end;
exit(List);
end;
}
To make the operation of this method a little practical and simple, I have created a small module that creates a JsonObject with all the Posted Sales Invoices, and then, through the previously shown function, I create PostedSalesInvoicePack, which would be the List of several Sublists of JsonObjects generated from the Posted Sales Invoices.
Below I share all the Helper codeunits created for the post.
codeunit 50800 Helper
{
//Method that calls GetPostedSalesInvoicePack with the Size and Max parameters.
//Max is optional, it is used to obtain a maximum of records, in case you want to bring them all, use Max = 0.
procedure Generate()
var
TempBlob: Codeunit "Temp Blob";
Confirmed, Out : Boolean;
Istream: InStream;
OStream: OutStream;
SalesInvoicesPack: List of [List of [JsonObject]];
SalesInvoicesList: List of [JsonObject];
JsonObject: JsonObject;
Max, Size, I, J : Integer;
JsonArray: JsonArray;
FileContentJson, OutText, OutputFileName : Text;
Char10: Char;
Char13: Char;
begin
Max := 0;
Size := 25;
//These characters represent a line break.
Char13 := 13;
Char10 := 10;
SalesInvoicesPack := GetPostedSalesInvoicePack(Max, Size);
foreach SalesInvoicesList in SalesInvoicesPack do begin
J += 1;
//OutText is used to create the text file to instantiate the result of the chunked list.
OutText += '[' + format(J) + ']:' + Format(Char13) + Format(Char10);
foreach JsonObject in SalesInvoicesList do begin
I += 1;
JsonArray.Add(JsonObject);
JsonArray.WriteTo(FileContentJson);
OutText += '[' + format(I) + ']:' + FileContentJson + Format(Char13) + Format(Char10);
end;
I := 0;
Clear(JsonArray);
//Here, the procedure in charge of sending the data should be consumed.
//HttpManagement.WriteinAPI(FileContentJson, URLText);
end;
//Optional: To exemplify and be able to visualize how the lists were fragmented, the SalesInvoicesPack is stored in a Text file.
OutputFileName := 'Output.txt';
TempBlob.CreateOutStream(OStream, TEXTENCODING::UTF8);
OStream.WriteText(OutText);
TempBlob.CreateInStream(Istream);
DownloadFromStream(Istream, 'Export', '', 'All Files (*.*)|*.*', OutputFileName);
end;
//Method that loops through all Posted Sales Invoices and creates the PostedSalesInvoicePack
local procedure GetPostedSalesInvoicePack(Max: Integer; Size: Integer): List of [List of [JsonObject]]
var
SalesInvoices: Record "Sales Invoice Header";
Window: Dialog;
I: Integer;
SalesInvoicesList: List of [JsonObject];
SalesInvoicesPack: List of [List of [JsonObject]];
begin
if GuiAllowed then
Window.OPEN('Sales Invoices No. #1###########\\');
SalesInvoices.Reset();
if SalesInvoices.FindSet then
repeat
if GuiAllowed then
Window.UPDATE(1, SalesInvoices."No.");
I += 1;
SalesInvoicesList.Add(SalesInvoicesToJson(SalesInvoices));
if I = Max then
break;
until SalesInvoices.Next() = 0;
if GuiAllowed then
Window.Close();
SalesInvoicesPack := SplitList(SalesInvoicesList, Size);
exit(SalesInvoicesPack);
end;
//Method that allows creating a JsonObject of each Posted Sales Invoice
local procedure SalesInvoicesToJson(var SalesInvoices: Record "Sales Invoice Header") JsonObject: JsonObject
begin
Clear(JsonObject);
SalesInvoices.CalcFields(Amount);
SalesInvoices.CalcFields("Amount Including VAT");
JsonObject.Add(SalesInvoices.FieldCaption("No."), SalesInvoices."No.");
JsonObject.Add(SalesInvoices.FieldCaption("Sell-to Customer Name"), SalesInvoices."Sell-to Customer Name");
JsonObject.Add(SalesInvoices.FieldCaption("Posting Date"), SalesInvoices."Posting Date");
JsonObject.Add(SalesInvoices.FieldCaption(Amount), SalesInvoices.Amount);
JsonObject.Add(SalesInvoices.FieldCaption("Amount Including VAT"), SalesInvoices."Amount Including VAT");
end;
//Method that allows creating a List of Lists JsonObject given a Size.
local procedure SplitList(Input: List of [JsonObject]; Size: Integer): List of [List of [JsonObject]]
var
List: List of [List of [JsonObject]];
I: Integer;
Math: Codeunit Math;
begin
for I := 1 to Input.Count do begin
List.Add(Input.GetRange(I, Math.Min(Size, Input.Count + 1 - I)));
I += Size - 1;
end;
exit(List);
end;
}
The following image is what the List of Lists looks like in the debugger.
No comments:
Post a Comment