Dynamics 365 Business Central: How to copy Links and Notes (System Parts) – Customization

Dynamics 365 Business Central

Hi, Readers.
Yesterday we briefly discussed how to export Links and Notes (System Parts) in Business Central. And today we will go further to discuss how to copy Links and Notes.

PS: There are two system parts that you can define by using the systempart() keyword: Links and Notes

System Parts:

ValueDescription
LinksAllows the user to add links to a URL or path on the record shown in the page. For example, on an Item card, a user can add a link to the supplier’s item catalog. The links will appear with the record when it is viewed. When a user chooses a link, the target file opens.
NotesAllows the user to write a note on the record shown in the page. For example, when creating a sales order, a user can add a note about the order. The note will appear with the item when it is viewed.

So, can we copy Links and Notes to another record? Yes, of course, but this also requires customization.

This time we can simply use the procedure CopyLinks() in codeunit 447 “Record Link Management”.

But please note that the procedure CopyLinks() uses the RecordRef.CopyLinks(Variant) Method method in the backend, which will copy all the links from a specified record and paste the links to the current record. All links include all Links and Notes.

RecordRef.CopyLinks(Variant) Method: Copies all the links from a particular record.

To make it easier to understand, let’s look at an example.

I created a simple Dialog page which can be opened from the Item List. In it, select the target item, click OK and all Links and Notes of the source item are copied to the target item.

Test Video:

Source Code: Github

pageextension 50101 ZYItemListExt extends "Item List"
{
    actions
    {
        addfirst(processing)
        {
            action(CopyLinksAndNotes)
            {
                Caption = 'Copy Links And Notes';
                ApplicationArea = All;
                Promoted = true;
                PromotedCategory = Process;
                PromotedIsBig = true;
                Image = Copy;
                trigger OnAction()
                var
                    CopyLinksAndNotesDialog: Page "Copy Links and Notes Dialog";
                begin
                    CopyLinksAndNotesDialog.SetItemInfo(Rec."No.", Rec.Description);
                    if CopyLinksAndNotesDialog.RunModal() = Action::OK then
                        CopyLinksAndNotesDialog.CopyLinksAndNotes();
                end;
            }
        }
    }
}

page 50100 "Copy Links and Notes Dialog"
{
    PageType = StandardDialog;
    Caption = 'Copy Links and Notes Dialog';
    layout
    {
        area(content)
        {
            field(SourceItemNo; SourceItemNo)
            {
                ApplicationArea = All;
                Caption = 'Source Item No.';
                Editable = false;
            }
            field(SourceItemDesc; SourceItemDesc)
            {
                ApplicationArea = All;
                Caption = 'Source Item Description';
                Editable = false;
            }
            field(TargetItemNo; TargetItemNo)
            {
                ApplicationArea = All;
                Caption = 'Target Item No.';
                TableRelation = Item;

                trigger OnValidate()
                var
                    Item: Record Item;
                begin
                    if Item.Get(TargetItemNo) then
                        TargetItemDesc := Item.Description;
                end;
            }
            field(TargetItemDesc; TargetItemDesc)
            {
                ApplicationArea = All;
                Caption = 'Target Item Description';
                Editable = false;
            }
        }
    }
    var
        SourceItemNo: Code[20];
        TargetItemNo: Code[20];
        SourceItemDesc: Text[100];
        TargetItemDesc: Text[100];


    procedure SetItemInfo(NewItemNo: Code[20]; NewItemDesc: Text[100])
    begin
        SourceItemNo := NewItemNo;
        SourceItemDesc := NewItemDesc;
    end;

    procedure CopyLinksAndNotes()
    var
        RecordLink: Record "Record Link";
        RecordLinkMgt: Codeunit "Record Link Management";
        SourceItem: Record Item;
        TargetItem: Record Item;
    begin
        if SourceItem.Get(SourceItemNo) then
            if TargetItem.Get(TargetItemNo) then begin
                RecordLinkMgt.CopyLinks(SourceItem, TargetItem);
            end;
    end;
}

What if we only want to copy Links, or Notes? We can insert it manually in the program.

I updated my code. (Please note that the source code is for reference only, you can improve it according to your own needs)

Added a Type option to let users choose whether to copy Link or Note.

Test Video: looks good.

Source Code: Github

pageextension 50101 ZYItemListExt extends "Item List"
{
    actions
    {
        addfirst(processing)
        {
            action(CopyLinksAndNotes)
            {
                Caption = 'Copy Links And Notes';
                ApplicationArea = All;
                Promoted = true;
                PromotedCategory = Process;
                PromotedIsBig = true;
                Image = Copy;
                trigger OnAction()
                var
                    CopyLinksAndNotesDialog: Page "Copy Links and Notes Dialog";
                begin
                    CopyLinksAndNotesDialog.SetItemInfo(Rec."No.", Rec.Description);
                    if CopyLinksAndNotesDialog.RunModal() = Action::OK then
                        CopyLinksAndNotesDialog.CopyLinksAndNotes();
                end;
            }
        }
    }
}

page 50100 "Copy Links and Notes Dialog"
{
    PageType = StandardDialog;
    Caption = 'Copy Links and Notes Dialog';
    layout
    {
        area(content)
        {
            field(SourceItemNo; SourceItemNo)
            {
                ApplicationArea = All;
                Caption = 'Source Item No.';
                Editable = false;
            }
            field(SourceItemDesc; SourceItemDesc)
            {
                ApplicationArea = All;
                Caption = 'Source Item Description';
                Editable = false;
            }
            field(TargetItemNo; TargetItemNo)
            {
                ApplicationArea = All;
                Caption = 'Target Item No.';
                TableRelation = Item;

                trigger OnValidate()
                var
                    Item: Record Item;
                begin
                    if Item.Get(TargetItemNo) then
                        TargetItemDesc := Item.Description;
                end;
            }
            field(TargetItemDesc; TargetItemDesc)
            {
                ApplicationArea = All;
                Caption = 'Target Item Description';
                Editable = false;
            }
            field(RecordLinkType; RecordLinkType)
            {
                ApplicationArea = All;
                Caption = 'Type';
            }
        }
    }
    var
        SourceItemNo: Code[20];
        TargetItemNo: Code[20];
        SourceItemDesc: Text[100];
        TargetItemDesc: Text[100];
        RecordLinkType: Option Link,Note;
        LastLinkID: Integer;


    procedure SetItemInfo(NewItemNo: Code[20]; NewItemDesc: Text[100])
    begin
        SourceItemNo := NewItemNo;
        SourceItemDesc := NewItemDesc;
    end;

    procedure CopyLinksAndNotes()
    var
        SourceRecordLink: Record "Record Link";
        TargetRecordLink: Record "Record Link";
        SourceItem: Record Item;
        TargetItem: Record Item;
    begin
        if SourceItem.Get(SourceItemNo) then
            if TargetItem.Get(TargetItemNo) then begin
                SourceRecordLink.Reset();
                SourceRecordLink.SetRange("Record ID", SourceItem.RecordId);
                SourceRecordLink.SetRange(Type, RecordLinkType);
                if SourceRecordLink.FindSet() then begin
                    LastLinkID := 0;
                    GetLastLinkID();
                    repeat
                        LastLinkID += 1;
                        TargetRecordLink.Init();
                        if RecordLinkType = RecordLinkType::Note then
                            SourceRecordLink.CalcFields(Note);
                        TargetRecordLink.Copy(SourceRecordLink);
                        TargetRecordLink."Link ID" := LastLinkID;
                        TargetRecordLink."Record ID" := TargetItem.RecordId;
                        TargetRecordLink.Insert();
                    until SourceRecordLink.Next() = 0;
                end;
            end;
    end;

    local procedure GetLastLinkID()
    var
        RecordLink: Record "Record Link";
    begin
        RecordLink.Reset();
        if RecordLink.FindLast() then
            LastLinkID := RecordLink."Link ID"
        else
            LastLinkID := 0;
    end;
}

Give it a try!!!😁

PS:
1. Links and Notes can be copied between different tables, for example, Links and Notes on Customer A can be copied to Vendor B.

2. You can find more about Add notes and links to data in MS Learn (Docs)

3. How to export Links and Notes (System Parts) – Customization

4. How to import Links and Notes (System Parts) – Customization

END

Hope this will help.

Thanks for reading.

ZHU

コメント

Copied title and URL