Welcome Dynamics 365 BC Lovers,
In this article, I will explain how to attach a document on Custom Tables. To achieve this I will create a custom table called Student and different pages to display student's records and its attached document.
As attachment is a very new functionality in D365 Business Central, by using the “Document Attachment – 1173” table we can create our page from where user can attach any document to any table record, even by extending the “Document Attachment” table we can introduce new fields to store other related information for attached documents.
Demonstration Video:
My custom table schema for students:
table 80004 Students
{
DataClassification = ToBeClassified;
fields
{
field(1; "Entry No."; Integer)
{
DataClassification = ToBeClassified;
AutoIncrement = true;
}
field(2; "ID"; Code[20])
{
DataClassification = ToBeClassified;
}
field(3; Name; Text[250])
{
DataClassification = ToBeClassified;
}
}
keys
{
key(Key1; ID)
{
Clustered = true;
}
}
}
As my student table is ready, now let’s create a list page for document attachment using Table – 1173 “Document Attachment” from this page we can attach documents for student records.
// From below page you can upload new file or download uploaded files
page 80004 "Student's Attachment Page"
{
PageType = List;
SourceTable = "Document Attachment";
SourceTableView = order(descending);
RefreshOnActivate = true;
layout
{
area(Content)
{
repeater(Group)
{
field("File Name"; "File Name")
{
ApplicationArea = All;
Editable = false;
// Logic for import/export the file when user click on the filename
trigger OnDrillDown()
var
FromRecRef: RecordRef;
FileName: Text;
cu_FileManagement: Codeunit "File Management";
TempBlob: Record TempBlob;
ImportTxt: Label 'Attach a document.';
FileDialogTxt: Label 'Tab Attachments (%1)|%1';
FilterTxt: Label '*.jpg;*.jpeg;*.bmp;*.png;*.gif;*.tiff;*.tif;*.pdf;*.docx;*.doc;*.xlsx;*.xls;*.pptx;*.ppt;*.msg;*.xml;*.*';
begin
StudentRecs.SetRange(ID, Rec."No.");
if StudentRecs.FindFirst() then;
FromRecRef.GetTable(StudentRecs);
;
if Rec."Document Reference ID".HasValue then
ExportFile(true)
else begin
FileName := cu_FileManagement.BLOBImportWithFilter(TempBlob, ImportTxt, FileName, STRSUBSTNO(FileDialogTxt, FilterTxt), FilterTxt);
// Now Call SaveAttachment method to save the selected file
importFileAsAttachment(FromRecRef, FileName, TempBlob, StudentRecs.ID); // Change 3
CurrPage.Update(false);
end;
end;
}
field("File Type"; "File Type")
{
ApplicationArea = All;
Editable = false;
}
field("File Extension"; "File Extension")
{
ApplicationArea = All;
Editable = false;
}
field(User; User)
{
ApplicationArea = All;
Editable = false;
}
field("Attached Date"; "Attached Date")
{
ApplicationArea = All;
Editable = false;
}
}
}
}
trigger OnOpenPage()
begin
//Message('Any pop-up for the user.');
end;
trigger OnNewRecord(BelowxRec: Boolean)
var
begin
// Any default values when attachment list page shown
Rec."File Name" := SelectFileText;
//Rec."Document Type" := Rec."Document Type"::Order;
end;
// Method: Export attached documents
procedure ExportFile(ShowFileDialog: Boolean): Text
var
FullFileName: Text;
TempBlob: Record TempBlob;
DocOutStream: OutStream;
cu_FileManagement: Codeunit "File Management";
begin
if Rec.ID = 0 then
exit;
// Ensure document has value in DB
if not Rec."Document Reference ID".HasValue then
exit;
// Get Complete File name including it's extension
FullFileName := Rec."File Name" + '.' + Rec."File Extension";
// Now use Tempblob to export this file
TempBlob.Blob.CreateOutStream(DocOutStream);
Rec."Document Reference ID".ExportStream(DocOutStream);
// export the file
exit(cu_FileManagement.BLOBExport(TempBlob, FullFileName, ShowFileDialog));
end;
// Method: Attach a document
procedure importFileAsAttachment(RecRef: RecordRef; FileName: Text; TempBlob: Record TempBlob; StudentID: Code[20])
var
IncomingFileName2: Text;
DocStream2: Instream;
EmptyFileNameErr: Label 'No content';
FileManagement: Codeunit "File Management";
NoDocumentAttachedErr: Label 'No document attached';
FieldRef: FieldRef;
LineNo: Integer;
Rec_Document: Record "Document Attachment";
Rec_Attachment: Record "Document Attachment";
begin
IF FileName = '' THEN
ERROR(EmptyFileNameErr);
// Validate file/media is not empty
IF NOT TempBlob.Blob.HasValue THEN
ERROR(EmptyFileNameErr);
IncomingFileName2 := FileName;
Clear(Rec_Attachment);
Rec_Attachment.Reset();
Rec_Attachment.INIT;
Rec_Attachment.VALIDATE("File Extension", FileManagement.GetExtension(IncomingFileName2));
Rec_Attachment.VALIDATE("File Name", COPYSTR(FileManagement.GetFileNameWithoutExtension(IncomingFileName2), 1, MAXSTRLEN(Rec."File Name")));
// My Custom Field Codes
/*
Rec_Attachment.Validate("You custom field name", ValueForCustomField);
*/
Rec_Attachment.VALIDATE("Table ID", RecRef.NUMBER);
Rec_Attachment.Validate("No.", StudentRecs.ID); // Give your table field by which you are attaching documents [table unique field]
TempBlob.Blob.CREATEINSTREAM(DocStream2);
Rec_Attachment."Document Reference ID".IMPORTSTREAM(DocStream2, '', IncomingFileName2);
IF NOT Rec_Attachment."Document Reference ID".HASVALUE THEN
ERROR(NoDocumentAttachedErr);
CASE RecRef.NUMBER OF
DATABASE::Students: // Give your table name here for which you are attaching a document
BEGIN
//FieldRef := RecRef.FIELD(1);
FieldRef := RecRef.FIELD(2); // Give your field No.
// Question: Why 2 Here? [Answer: Because I am using ID field of student table and field id for this field is 3 in my Student table]
Clear(Rec_Document);
Rec_Document.SetRange("Table ID", RecRef.Number);
Rec_Document.SetRange("No.", StudentRecs.ID); // YOur custom table field name
IF Rec_Document.FindLast() then begin
Rec_Attachment.Validate("Line No.", Rec_Document."Line No." + 1000);
end
else begin
Rec_Attachment.Validate("Line No.", 1000);
end;
END;
END;
Rec_Attachment.INSERT(TRUE);
end;
var
StudentRecs: Record Students;
SelectFileText: Label 'Select File... Developed by Tabrez';
}
As our document attachment page is ready from where we can attach new documents or download any attached documents, let’s create a factbox that will show the number of documents attached to any student record, or by clicking on the document count in this factbox we can attach new documents to the student record.
// Below Page will shown in the Factbox of the list page when no. of file count will show to user
page 80005 "Student's Attachment Factbox"
{
PageType = CardPart;
SourceTable = Students;
layout
{
area(Content)
{
field(Attachments; NoOfAttachments)
{
ApplicationArea = All;
Editable = false;
Caption = 'No. of Attached Documents';
trigger OnDrillDown()
var
Recs_DocAtch: Record "Document Attachment";
begin
Clear(Page_StudentAttachment);
Clear(Recs_DocAtch);
Recs_DocAtch.Reset();
Recs_DocAtch.SetRange("No.", Rec.ID);
if Recs_DocAtch.FindFirst() then;
Page_StudentAttachment.SetRecord(Recs_DocAtch);
Page_StudentAttachment.SetTableView(Recs_DocAtch);
Page_StudentAttachment.RunModal();
Clear(Rec_DocumentAttachment);
Clear(NoOfAttachments);
Rec_DocumentAttachment.Reset();
Rec_DocumentAttachment.SetRange("No.", Rec.ID);
if Rec_DocumentAttachment.FindSet() then
NoOfAttachments := Rec_DocumentAttachment.Count;
end;
}
}
}
trigger OnAfterGetRecord()
begin
Clear(NoOfAttachments);
Clear(Rec_DocumentAttachment);
Rec_DocumentAttachment.Reset();
Rec_DocumentAttachment.SetRange("No.", Rec.ID);
if Rec_DocumentAttachment.FindSet() then
NoOfAttachments := Rec_DocumentAttachment.Count;
end;
var
NoOfAttachments: Integer;
Rec_DocumentAttachment: Record "Document Attachment";
Page_StudentAttachment: Page "Student's Attachment Page"; // Your Page Name Here
}
As of now we are ready to create our final page where we can see the list of students record and their no. of attached documents in the factbox.
page 80006 Students
{
Caption = 'Student Document Management - Demo';
PageType = List;
ApplicationArea = All;
UsageCategory = Administration;
SourceTable = Students;
layout
{
area(Content)
{
repeater(GroupName)
{
field("Entry No."; "Entry No.")
{
ApplicationArea = All;
}
field(ID; ID)
{
ApplicationArea = All;
}
field(Name; Name)
{
ApplicationArea = All;
}
}
}
area(FactBoxes)
{
part("Student's Attachment Factbox"; "Student's Attachment Factbox")
{
ApplicationArea = All;
SubPageLink = ID = field(ID);
SubPageView = order(descending);
}
}
}
}
Output:
I hope you understand how we can attach documents to any record of any custom table in Dynamics 365 Business Central.
Stay Tuned!
Comments