Hi, Readers.
Today I would like to talk about how to copy Item Picture from one company to another via AL. I saw this interesting question on the Business Central forum before, so I wanted to briefly discuss it in this post.
My simulation requirement this time is to add a new action to the Item Picture (346) page, click on it to open the Company List, select the target company, then open the Item List within that company, select the Item and copy the current picture to that company’s item.
The key method this time is Record.ChangeCompany([Text]) Method.
Record.ChangeCompany([Text]) Method: Redirects references to table data from one company to another.
We’ve discussed similar content before.
More details:
1. Dynamics 365 Business Central: How to redirects references to table data from one company to another (ChangeCompany Method)
2. Dynamics 365 Business Central: Collect data from different companies and Drilldown into the data of another company
For simple understanding, I also created some sample data.
My Company:
My Company 01:
My Company 02:
My Company 03:
First, let us try the first half of the requirement, select target item from other companies.
Great.
Test video:
Source code:
pageextension 50112 ItemPictureExt extends "Item Picture"
{
actions
{
addafter(ExportFile)
{
action(CopyToOtherCompany)
{
ApplicationArea = All;
Caption = 'Copy to other company';
Image = Copy;
trigger OnAction()
var
CompanyRec: Record Company;
Item: Record Item;
begin
CompanyRec.Reset();
if Page.RunModal(Page::Companies, CompanyRec) = ACTION::LookupOK then begin
Item.Reset();
Item.ChangeCompany(CompanyRec.Name);
if Page.RunModal(Page::"Item List", Item) = ACTION::LookupOK then begin
Message(Item.Description);
end;
end;
end;
}
}
}
}
Next copy the current item picture.
Test video:
Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)
pageextension 50112 ItemPictureExt extends "Item Picture"
{
actions
{
addafter(ExportFile)
{
action(CopyToOtherCompany)
{
ApplicationArea = All;
Caption = 'Copy to other company';
Image = Copy;
trigger OnAction()
var
CompanyRec: Record Company;
Item: Record Item;
ItemTenantMedia: Record "Tenant Media";
InStr: InStream;
FileName: Text;
begin
FileName := '';
CompanyRec.Reset();
if Page.RunModal(Page::Companies, CompanyRec) = ACTION::LookupOK then begin
Item.Reset();
Item.ChangeCompany(CompanyRec.Name);
if Page.RunModal(Page::"Item List", Item) = ACTION::LookupOK then
if Rec.Picture.Count > 0 then begin
ItemTenantMedia.Get(Rec.Picture.Item(1));
ItemTenantMedia.CalcFields(Content);
ItemTenantMedia.Content.CreateInStream(InStr, TextEncoding::UTF8);
FileName := Item.Description + '.png';
Item.Picture.ImportStream(InStr, FileName);
Item.Modify(true);
Message('Item picture copied to company ' + CompanyRec.Name + ' Item No. ' + Item."No.");
end;
end;
end;
}
}
}
}
In the above method, we export the picture to InStream from selected item, and then import it into the new item. There is actually another way to deal with it.
MediaSet.Insert(Guid) Method: Adds a media object that already exists in the database to a MediaSet of a record.
However, both the Tenant Media table and the Tenant Media Set table contain the Company Name field. When we insert the GUID, we also need to clear the Company Name in these two tables. (It’s a bit like user permission management)
Note that modifying these two tables requires additional permissions.
For example, the following method can also achieve the same result.
Source code: Github (Please note that the source code is for reference only, you can improve it according to your own needs)
pageextension 50112 ItemPictureExt extends "Item Picture"
{
actions
{
addafter(ExportFile)
{
action(CopyToOtherCompany)
{
ApplicationArea = All;
Caption = 'Copy to other company';
Image = Copy;
trigger OnAction()
var
CompanyRec: Record Company;
Item: Record Item;
ClearItemTenantMedia: Codeunit ClearItemTenantMedia;
begin
CompanyRec.Reset();
if Page.RunModal(Page::Companies, CompanyRec) = ACTION::LookupOK then begin
Item.Reset();
Item.ChangeCompany(CompanyRec.Name);
if Page.RunModal(Page::"Item List", Item) = ACTION::LookupOK then
if Rec.Picture.Count > 0 then begin
Item.Picture.Insert(Rec.Picture.Item(1));
Item.Modify(true);
ClearItemTenantMedia.DeleteCompanyName(Rec.Picture.MediaId, Rec.Picture.Item(1));
Message('Item picture copied to company ' + CompanyRec.Name + ' Item No. ' + Item."No.");
end;
end;
end;
}
}
}
}
codeunit 50112 ClearItemTenantMedia
{
Permissions = TableData "Tenant Media" = rimd,
TableData "Tenant Media Set" = rimd;
procedure DeleteCompanyName(PictureID: Guid; MediaId: Guid)
var
ItemTenantMedia: Record "Tenant Media";
ItemTenantMediaSet: Record "Tenant Media Set";
begin
if ItemTenantMedia.Get(MediaId) then begin
ItemTenantMedia."Company Name" := '';
ItemTenantMedia.Modify();
end;
if ItemTenantMediaSet.Get(PictureID, MediaId) then begin
ItemTenantMediaSet."Company Name" := '';
ItemTenantMediaSet.Modify();
end;
end;
}
Okay, not only Item Picture can be copied to other companies, data in other tables can also be moved using this method. In Business Central 2023 wave 1 (BC22), Microsoft also released the function of master data synchronization. More details: Business Central 2023 wave 1 (BC22) new features: Set up and sync master data across companies (Master data management)
However, please note that using Record.ChangeCompany([Text]) Method will have the following risks.
Even if you run the ChangeCompany method, triggers still run in the current company, not in the company that you specified in the ChangeCompany method.
So please fully test before deploying to a production environment. Give it a try!!!😁
END
Hope this will help.
Thanks for reading.
ZHU
コメント