web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Small and medium business | Business Central, N...
Answered

Getting Record Links Notes from Blob into a list or API page

(1) ShareShare
ReportReport
Posted on by 11
Hi everyone,
I am posting this as a question as I couldn't figure out how to make it a blog. Regardless, there may be some improvements to be made to my solution to this so I welcome feedback.
 
Situation: We use Notes on customer ledger entries, POs, invoices, etc to record information about the transaction in question. My specific need was we track Accounts Receivable notes on overdue AR with customer notes so the whole team knows what interactions have taken place to collect old invoices. We are a small team so just needed a quick way to add notes without collections modules and all that complexity. The issue is that BC stores Notes as Blob, so you cannot get to them without custom code, to get them reportable in Power BI, or a data warehouse or any of that.
 
Task: Create a new List Page that displays these notes converted to a string so they can be read. List pages automatically come with a web service API so its highly functional.
 
Caveat: The Record Link table stores record ids as a concatenation of "Table Name" : "Primary Key(s)". I added extra functionality to parse the table name and primary key out of the Record Link to join them to other tables for reporting in our BI.
 
Here is my solution. Please let me know if it can be improved in any way:
 

 
page 50702 "RecordLinkList"
/* created this page and web service to extract the BLOB of notes from the system */
{
    PageType = List;
    SourceTable = "Record Link";
    Caption = 'Record Links and Notes';
    UsageCategory = Lists;
    ApplicationArea = all;
    Editable = false;
    layout
    {
        area(content)
        {
            repeater(Rep)
            {
                field(LinkId; Rec."Link ID")
                {
                    Caption = 'Link ID';
                }
                field(RecordId; Rec."Record ID")
                {
                    Caption = 'Record ID';
                }
                field(Company; Rec."Company")
                {
                    Caption = 'Company';
                }
                field(Type; Rec."Type")
                {
                    Caption = 'Type';
                }
                field(Description; Rec."Description")
                {
                    Caption = 'Description';
                }
                field(SourceTable; ParseRecordId(Rec."Record ID", 'Table', ':', ','))
                {
                    Caption = 'Source Table';
                }
                field(PrimaryKey; ParseRecordId(Rec."Record ID", 'Primary Key', ':', ','))
                {
                    Caption = 'Primary Key';
                }
                field(NoteText; GetNoteText())
                {
                    Caption = 'Note Text';
                }
                field(systemid; Rec."SystemId")
                {
                }
                field(systemcreatedat; Rec."SystemCreatedAt")
                {
                }
                field(systemcreatedby; Rec."SystemCreatedBy")
                {
                }
                field(systemmodifiedat; Rec."SystemModifiedAt")
                {
                }
                field(systemmodifiedby; Rec."SystemModifiedBy")
                {
                }

            }
        }
    }
    actions
    {
        area(processing)
        {
        }
    }
	
    local procedure GetNoteText(): Text[1024]
    /* get the note from using built in codeunit */
    var
        RecordLinkMgt: Codeunit "Record Link Management";
    begin
        if Rec.Type = Rec.Type::Note then begin
            Rec.CalcFields(Note); // Load the Note BLOB field
            exit(RecordLinkMgt.ReadNote(Rec))
        end;

        exit(''); // Return an empty string if no note or invalid type
    end;

    local procedure ParseRecordId(record_id: RecordId; recType: Text[20]; recordIdDelimiter: Text[1]; pkDelimiter: Text[2]): Text[250]
    // take in the record id, parse the table and the primary key(s) from it and return
    var
        formattedRecordId: Text[250];
        tableName: Text[250];
        pkName: Text[250];        
    begin
        // Convert RecordId to a readable text format
        formattedRecordId := Format(record_id);

        // Extract the table name and primary key components
        tableName := CopyStr(formattedRecordId, 1, StrPos(formattedRecordId, recordIdDelimiter) - 1);
        pkName := CopyStr(formattedRecordId, StrPos(formattedRecordId, recordIdDelimiter) + 2);

        if recType = 'Table' then begin
            // Return the table name. This is prob over complicated but w/e... may be smarter to split this procuedure into two or more functions
            exit(tableName);
        end else begin
                exit(pkName); // Return the full primary key string if no parsing is needed
        end;

        exit(pkName);
    end;

}
 
I have the same question (0)
  • Suggested answer
    YUN ZHU Profile Picture
    95,331 Super User 2025 Season 2 on at
    You can contribute your blog to the link below.
     
    In addition, creating an API page should have much better performance than Odata, especially for this kind of file access
     
    Hope this helps.
    Thanks.
    ZHU
  • Verified answer
    Khushbu Rajvi. Profile Picture
    20,275 Super User 2025 Season 2 on at
  • BR-28051246-0 Profile Picture
    11 on at
    Thanks ZHU. I first had an API page but switched it to a List page with odata as our DW pipelines were already setup to pull from that base URL. I agree with you here however.
    BTW your Dynamics Lab website has been a huge inspiration to me, thanks for all the community building you have done through it.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Small and medium business | Business Central, NAV, RMS

#1
OussamaSabbouh Profile Picture

OussamaSabbouh 3,143

#2
Jainam M. Kothari Profile Picture

Jainam M. Kothari 1,694 Super User 2025 Season 2

#3
YUN ZHU Profile Picture

YUN ZHU 1,067 Super User 2025 Season 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans