Hi, Readers.
Today I would like to talk about a question I was asked recently, how to add/display file size on Attached Documents and Doc. Attachment List Factbox.
And on most list pages, cards, and documents, you can attach files on the Attachments tab of the FactBox pane. The number in the tab title indicates how many attached files exist for the card or document. For example, on the Customer List page:
So starting from Business Central 2024 wave 2 (BC25), we have two pages to manage attachments.
Doc. Attachment List Factbox (1178, ListPart):
Document Attachment Details (1173, List):
As you might know, only the file name, File Extension, User and other information are displayed here, but not the file size. Can we add it? Yes, it can be done. But before we do that, let’s first understand the storage structure of attachments.
Attachments are saved using the Media type.
table 1173 “Document Attachment” -> “Document Reference ID”:
The actual file content is stored in Content field (Blob data type) of table 2000000184 “Tenant Media”.
table 2000000184 “Tenant Media” -> Content:
PS: Using the Media or MediaSet data type provides better performance than using a BLOB data type and is more flexible in its design. With a BLOB data type, each time the media is rendered in the client, it’s retrieved from the SQL database server, which requires extra bandwidth and affects performance. With the Media and MediaSet data types, the client uses media ID to cache the media data, which in turn improves the response time for rendering the media in the user interface. More details: Working With Media on Records
Let’s look at a simple example.
We can get the unique identifier of a media object on a record through Media.MediaId() Method.
Then you can find the specified file in table 2000000184 “Tenant Media” by Media ID.
PS: Dynamics 365 Business Central: Quick run table (Standard feature and Customization)
But since table 2000000184 “Tenant Media” is a system table, we cannot expand it.
The system or virtual table ‘Tenant Media’ cannot be extended. AL AL0525
So here are two custom methods. I personally recommend the first one.
PS: Dynamics 365 Business Central: Format File Size as KB or MB in AL
1. Add a new real field to the Document Attachment (1173) table. When inserting data, also save the size of the attachment. (Only valid for newly added attachments)
Add a new field:
Add the logic to save the file size, this time we use the OnBeforeSaveAttachment event.
Test:
Source Code: GitHub (Please note that the source code is for reference only, you can improve it according to your own needs)
tableextension 50112 DocumentAttachmentExt extends "Document Attachment"
{
fields
{
field(50100; FileSizeTxt; Text[100])
{
Caption = 'File Size';
Editable = false;
DataClassification = CustomerContent;
}
}
}
pageextension 50112 DocumentAttachmentDetailsExt extends "Document Attachment Details"
{
layout
{
addafter("File Type")
{
field(FileSizeTxt; Rec.FileSizeTxt)
{
ApplicationArea = All;
Caption = 'File Size';
Editable = false;
ToolTip = 'The size of the file in KB or MB';
}
}
}
}
pageextension 50113 DocAttachmentListFactboxExt extends "Doc. Attachment List Factbox"
{
layout
{
addafter("File Extension")
{
field(FileSizeTxt; Rec.FileSizeTxt)
{
ApplicationArea = All;
Caption = 'File Size';
Editable = false;
ToolTip = 'The size of the file in KB or MB';
}
}
}
}
codeunit 50112 AttachmentHandler
{
[EventSubscriber(ObjectType::Table, Database::"Document Attachment", OnBeforeSaveAttachment, '', false, false)]
local procedure OnBeforeSaveAttachment(var DocumentAttachment: Record "Document Attachment"; var RecRef: RecordRef; var FileName: Text; var TempBlob: Codeunit "Temp Blob")
begin
DocumentAttachment.FileSizeTxt := FormatFileSize(TempBlob.Length());
end;
var
FileSizeTxt: Label '%1 %2', Comment = '%1 = File Size, %2 = Unit of measurement', Locked = true;
local procedure FormatFileSize(SizeInBytes: Integer): Text
var
FileSizeConverted: Decimal;
FileSizeUnit: Text;
begin
FileSizeConverted := SizeInBytes / 1024; // The smallest size we show is KB
if FileSizeConverted < 1024 then
FileSizeUnit := 'KB'
else begin
FileSizeConverted := FileSizeConverted / 1024; // The largest size we show is MB
FileSizeUnit := 'MB'
end;
exit(StrSubstNo(FileSizeTxt, Round(FileSizeConverted, 0.01, '>'), FileSizeUnit));
end;
}
2. Add a variable to display the file size. The performance is not as good as the first method, but it is also effective for the attached files that have been added.
Test: There is a strange situation here. The size of the Content field (Blob data type) of table 2000000184 “Tenant Media” is smaller than that obtained during upload.
Source Code: GitHub (Please note that the source code is for reference only, you can improve it according to your own needs)
pageextension 50112 DocumentAttachmentDetailsExt extends "Document Attachment Details"
{
layout
{
addafter("File Type")
{
field(FileSizeTxt; FileSizeTxt)
{
ApplicationArea = All;
Caption = 'File Size';
Editable = false;
ToolTip = 'The size of the file in KB or MB';
}
}
}
var
FileSizeTxt: Text;
AttachmentHandler: Codeunit AttachmentHandler;
trigger OnAfterGetRecord()
var
TenantMedia: Record "Tenant Media";
begin
FileSizeTxt := '';
if TenantMedia.Get(Rec."Document Reference ID".MediaId) then
FileSizeTxt := AttachmentHandler.FormatFileSize(TenantMedia.Content.Length);
end;
}
pageextension 50113 DocAttachmentListFactboxExt extends "Doc. Attachment List Factbox"
{
layout
{
addafter("File Extension")
{
field(FileSizeTxt; FileSizeTxt)
{
ApplicationArea = All;
Caption = 'File Size';
Editable = false;
ToolTip = 'The size of the file in KB or MB';
}
}
}
var
FileSizeTxt: Text;
AttachmentHandler: Codeunit AttachmentHandler;
trigger OnAfterGetRecord()
var
TenantMedia: Record "Tenant Media";
begin
FileSizeTxt := '';
if TenantMedia.Get(Rec."Document Reference ID".MediaId) then
FileSizeTxt := AttachmentHandler.FormatFileSize(TenantMedia.Content.Length);
end;
}
codeunit 50112 AttachmentHandler
{
var
FileSizeTxt: Label '%1 %2', Comment = '%1 = File Size, %2 = Unit of measurement', Locked = true;
procedure FormatFileSize(SizeInBytes: Integer): Text
var
FileSizeConverted: Decimal;
FileSizeUnit: Text;
begin
FileSizeConverted := SizeInBytes / 1024; // The smallest size we show is KB
if FileSizeConverted < 1024 then
FileSizeUnit := 'KB'
else begin
FileSizeConverted := FileSizeConverted / 1024; // The largest size we show is MB
FileSizeUnit := 'MB'
end;
exit(StrSubstNo(FileSizeTxt, Round(FileSizeConverted, 0.01, '>'), FileSizeUnit));
end;
}
Very simple, give it a try!!!😁
PS:
1. Dynamics 365 Business Central: How to limit max file size for uploading attachment (Customization)
2. Dynamics 365 Business Central: Conversion between Blob data type and Media/MediaSet data type
END
Hope this will help.
Thanks for reading.
ZHU
コメント