Dynamics 365 Business Central: Using TextBuilder Data Type to export data to a text file

Dynamics 365 Business Central

Hi, Readers.
Today I would like to talk about TextBuilder Data Type and how to use it to export data to a text file in Business Central.

First let’s look at MS Docs.

TextBuilder Data Type: Represents a lighweight wrapper for the .Net implementation of StringBuilder.

The following methods are available on instances of the TextBuilder data type.

Method nameDescription
Append(Text)Appends a copy of the specified string to this TextBuilder instance.
AppendLine([Text])Appends a copy of the specified string followed by the default line terminator to the end of the current TextBuilder object. If this parameter is omitted, only the line terminator will be appended.
Capacity([Integer])Gets or sets the maximum number of characters that can be contained in the memory allocated by the current instance.
Clear()Removes all characters from the current TextBuilder instance.
EnsureCapacity(Integer)Ensures that the capacity of this TextBuilder instance is at least the specified value.
Insert(Integer, Text)Inserts a string into this TextBuilder instance at the specified character position.
Length([Integer])Gets or sets the length of this TextBuilder instance.
MaxCapacity()Gets the maximum capacity of this TextBuilder instance.
Remove(Integer, Integer)Removes the specified range of characters from this TextBuilder instance.
Replace(Text, Text)Replaces all occurrences of a specified string in this TextBuilder instance with another specified string.
Replace(Text, Text, Integer, Integer)Replaces, within a substring of this instance, all occurrences of a specified string in this TextBuilder instance with another specified string.
ToText()Converts the value of this TextBuilder instance to a Text.
ToText(Integer, Integer)Converts the value of a substring of this TextBuilder instance to a Text.

Remark:
The TextBuilder data type is one-based indexed, that is, the indexing begins with 1.

The Text Data Type is a value type, such that every time you use a method on it, you create a new string object in memory. This requires a new allocation of space. In situations where you need to perform repeated modifications to a string, the overhead associated with creating a Text Data Type can be costly.

The TextBuilder data type is a reference type, which holds a pointer elsewhere in memory. For performance reasons, we recommend you to use it when you want to modify a string without creating a new object. For example, using TextBuilder data type can boost performance when concatenating many strings together in a loop.

TextBuilder Data Type – Business Central | Microsoft Docs

Next, let’s see how to use it. I have prepared some examples.

1. Using TextBuilder.AppendLine([Text]) Method: Appends a copy of the specified string followed by the default line terminator to the end of the current TextBuilder object.

Example01:

Text file:

Test Video:

Source Code:

pageextension 50101 CustomerLedgerEntriesExt extends "Customer Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(ExportToExt)
            {
                Caption = 'Export to Text';
                ApplicationArea = All;
                PromotedCategory = Process;
                Promoted = true;
                Image = Export;

                trigger OnAction()
                var
                    TempBlob: Codeunit "Temp Blob";
                    InS: InStream;
                    OutS: OutStream;
                    FileName: Text;
                    TxtBuilder: TextBuilder;
                begin
                    FileName := 'TestFile_' + UserId + '_' + Format(CurrentDateTime) + '.txt';
                    TxtBuilder.AppendLine('This is the first line.');
                    TxtBuilder.AppendLine();
                    TxtBuilder.AppendLine('This is the third line.');
                    TxtBuilder.AppendLine();
                    TxtBuilder.AppendLine();
                    TxtBuilder.AppendLine('This is the sixth line.');
                    TxtBuilder.AppendLine('END');
                    TempBlob.CreateOutStream(OutS);
                    OutS.WriteText(TxtBuilder.ToText());
                    TempBlob.CreateInStream(InS);
                    DownloadFromStream(InS, '', '', '', FileName);
                end;
            }
        }
    }
}

As Microsoft mentioned in Docs, using TextBuilder data type can boost performance when concatenating many strings together in a loop.

Example02: Export one million lines to a text file.

A 37MB text file was created in almost 1 second.

Test Video:

Source Code:

pageextension 50101 CustomerLedgerEntriesExt extends "Customer Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(ExportToExt)
            {
                Caption = 'Export to Text';
                ApplicationArea = All;
                PromotedCategory = Process;
                Promoted = true;
                Image = Export;

                trigger OnAction()
                var
                    TempBlob: Codeunit "Temp Blob";
                    InS: InStream;
                    OutS: OutStream;
                    FileName: Text;
                    TxtBuilder: TextBuilder;
                    Lines: Integer;
                begin
                    FileName := 'TestFile_' + UserId + '_' + Format(CurrentDateTime) + '.txt';
                    TxtBuilder.AppendLine('Start time: ' + Format(Time));
                    for Lines := 1 to 1000000 do
                        TxtBuilder.AppendLine(StrSubstNo('This is %1 line in the text file.', Lines));
                    TxtBuilder.AppendLine('End time: ' + Format(Time));
                    TempBlob.CreateOutStream(OutS);
                    OutS.WriteText(TxtBuilder.ToText());
                    TempBlob.CreateInStream(InS);
                    DownloadFromStream(InS, '', '', '', FileName);
                end;
            }
        }
    }
}

So TextBuilder.AppendLine([Text]) Method can be used to export a simple list.

Example03: Export all lines from Customer Ledger Entries, containing columns Posting Date, Document Type, Document No., Customer No. and Amount(LCY). Assume that the separator is a comma.

Text file:

Test Video:

Source Code:

pageextension 50101 CustomerLedgerEntriesExt extends "Customer Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(ExportToExt)
            {
                Caption = 'Export to Text';
                ApplicationArea = All;
                PromotedCategory = Process;
                Promoted = true;
                Image = Export;

                trigger OnAction()
                var
                    TempBlob: Codeunit "Temp Blob";
                    InS: InStream;
                    OutS: OutStream;
                    FileName: Text;
                    TxtBuilder: TextBuilder;
                    CustLedgerEntry: Record "Cust. Ledger Entry";
                begin
                    FileName := 'TestFile_' + UserId + '_' + Format(CurrentDateTime) + '.txt';
                    TxtBuilder.AppendLine('Posting Date' + ',' + 'Document Type' + ',' + 'Document No.' + ',' + 'Customer No.' + ',' + 'Amount(LCY)');
                    CustLedgerEntry.Reset();
                    CustLedgerEntry.SetAutoCalcFields("Amount (LCY)");
                    if CustLedgerEntry.FindSet() then
                        repeat
                            TxtBuilder.AppendLine(Format(CustLedgerEntry."Posting Date") + ',' + Format(CustLedgerEntry."Document Type") + ',' +
                                                     CustLedgerEntry."Document No." + ',' + CustLedgerEntry."Customer No." + ',' +
                                                        Format(CustLedgerEntry."Amount (LCY)"));
                        until CustLedgerEntry.Next() = 0;
                    TempBlob.CreateOutStream(OutS);
                    OutS.WriteText(TxtBuilder.ToText());
                    TempBlob.CreateInStream(InS);
                    DownloadFromStream(InS, '', '', '', FileName);
                end;
            }
        }
    }
}

2. Using TextBuilder.Append(Text) Method: Appends a copy of the specified string to this TextBuilder instance.

Different from TextBuilder.AppendLine([Text]) Method, it has default line terminator. All added text is displayed on one line.

If there is no text to append, an error will be prompted.

Let’s see what happens when we replace AppendLine in Example01 with Append.

Text file:

Source Code:

pageextension 50101 CustomerLedgerEntriesExt extends "Customer Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(ExportToExt)
            {
                Caption = 'Export to Text';
                ApplicationArea = All;
                PromotedCategory = Process;
                Promoted = true;
                Image = Export;
                trigger OnAction()
                var
                    TempBlob: Codeunit "Temp Blob";
                    InS: InStream;
                    OutS: OutStream;
                    FileName: Text;
                    TxtBuilder: TextBuilder;
                begin
                    FileName := 'TestFile_' + UserId + '_' + Format(CurrentDateTime) + '.txt';
                    TxtBuilder.Append('This is the first line.');
                    TxtBuilder.Append(' ');
                    TxtBuilder.Append('This is the third line.');
                    TxtBuilder.Append(' ');
                    TxtBuilder.Append(' ');
                    TxtBuilder.Append('This is the sixth line.');
                    TxtBuilder.Append('END');
                    TempBlob.CreateOutStream(OutS);
                    OutS.WriteText(TxtBuilder.ToText());
                    TempBlob.CreateInStream(InS);
                    DownloadFromStream(InS, '', '', '', FileName);
                end;
            }
        }
    }
}

So if you want to export data via TextBuilder Data Type, this should be more useful when exporting card data, or selected data.

For example:

Text file:

Test Video:

Source Code:

pageextension 50101 CustomerLedgerEntriesExt extends "Customer Ledger Entries"
{
    actions
    {
        addfirst(processing)
        {
            action(ExportToExt)
            {
                Caption = 'Export to Text';
                ApplicationArea = All;
                PromotedCategory = Process;
                Promoted = true;
                Image = Export;

                trigger OnAction()
                var
                    TempBlob: Codeunit "Temp Blob";
                    InS: InStream;
                    OutS: OutStream;
                    FileName: Text;
                    TxtBuilder: TextBuilder;
                    CustLedgerEntry: Record "Cust. Ledger Entry";
                begin
                    FileName := 'TestFile_' + UserId + '_' + Format(CurrentDateTime) + '.txt';
                    TxtBuilder.AppendLine('Posting Date' + ',' + 'Document Type' + ',' + 'Document No.' + ',' + 'Customer No.' + ',' + 'Amount(LCY)');
                    CustLedgerEntry.Reset();
                    CurrPage.SetSelectionFilter(CustLedgerEntry);
                    if CustLedgerEntry.FindFirst() then begin
                        CustLedgerEntry.CalcFields("Amount (LCY)");
                        TxtBuilder.Append(Format(CustLedgerEntry."Posting Date"));
                        TxtBuilder.Append(',');
                        TxtBuilder.Append(Format(CustLedgerEntry."Document Type"));
                        TxtBuilder.Append(',');
                        TxtBuilder.Append(CustLedgerEntry."Document No.");
                        TxtBuilder.Append(',');
                        TxtBuilder.Append(CustLedgerEntry."Customer No.");
                        TxtBuilder.Append(',');
                        TxtBuilder.Append(Format(CustLedgerEntry."Amount (LCY)"));
                    end;
                    TempBlob.CreateOutStream(OutS);
                    OutS.WriteText(TxtBuilder.ToText());
                    TempBlob.CreateInStream(InS);
                    DownloadFromStream(InS, '', '', '', FileName);
                end;
            }
        }
    }
}

Isn’t it handy? Give it a try!!!😁

In this post, I mainly shared how to use TextBuilder Data Type to generate text values and export them to a Text file. As for the other methods, I will explain them in other post when I have a chance.

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL