Hello,
I have an issue with Report.AddTable method. Implicit datatable detection is not working as expected (or I am doing something wrong).
See bellow the code used to fill my lists (fetching data from a dataset and feeding my lists).
In my case, Docs object is created once, and Docs[0].Records list will have at minimum 2 records.
I'm always getting Report.GetDataTables.Count = 1 ('Documents' table but no 'Records' table).
Report.Run will raise an exception telling me the Records range is failling because Records datatble doesn't exists.
How can I solve this ?
procedure TDataModule2.AddNewRecord(aDocs: TDocuments; aRecordType: TRecordType; aDataset: TDataSet);
var
RecIdx: Integer;
begin
aDocs.Records.Add(TRecords.Create);
RecIdx := aDocs.Records.Count - 1;
case aRecordType of
TRecordType.MasterRecord:
begin
if UpperCase(Trim(aDocs.DocumentType)) = 'INVOICE' then
aDocs.Records[RecIdx].DebitCredit := 'C'
else
aDocs.Records[RecIdx].DebitCredit := 'D';
aDocs.Records[RecIdx].Name := aDataset['Description'];
aDocs.Records[RecIdx].RecordType := '1;3;6';
aDocs.Records[RecIdx].AD5 := aDataset['Vendor_Analytical_ID_AD5'];
end;
TRecordType.DetailRecord:
begin
if UpperCase(Trim(aDocs.DocumentType)) = 'INVOICE' then
aDocs.Records[RecIdx].DebitCredit := 'D'
else
aDocs.Records[RecIdx].DebitCredit := 'C';
aDocs.Records[RecIdx].Name := aDataset['Description_Line'];
aDocs.Records[RecIdx].RecordType := '3;6';
aDocs.Records[RecIdx].AD4 := aDataset['Project_Number_AD4'];
aDocs.Records[RecIdx].AD6 := aDataset['Tax_Code_AD6'];
aDocs.Records[RecIdx].AD9 := aDataset['Misc_Analytical_Number_AD9'];
end;
end;
aDocs.Records[RecIdx].Account := aDataset['Amount_Due'];
aDocs.Records[RecIdx].Name := aDataset['Description'];
aDocs.Records[RecIdx].TransactionAmount := aDataset['Amount_Due'];
aDocs.Records[RecIdx].DebitCredit := aDataset['DC'];
aDocs.Records[RecIdx].TransactionCurrencyCode := aDataset['Currency'];
aDocs.Records[RecIdx].Description := aDataset['Description'];
aDocs.Records[RecIdx].TransactionDate := aDataset['Issue_Date'];
aDocs.Records[RecIdx].DueDate := aDataset.FieldByName('Due_Date').AsDateTime;
end;
procedure TDataModule2.actExportSelectedRecordExecute(Sender: TObject);
var
Bookmkt: TBookmark;
Docs: TObjectList<TDocuments>;
DocIdx: integer;
Report: TFlexCelReport;
begin
FdInvoiceSelected.EmptyDataSet;
Bookmkt := FdInvoices.GetBookmark;
FdInvoices.DisableControls;
Docs := TObjectList<TDocuments>.Create;
Report := TFlexCelReport.Create(true);
try
FdInvoices.Filter := 'Customer_ID=' + quotedstr(FdInvoices['Customer_ID']) + ' AND Invoice_Number=' + quotedstr(FdInvoices['Invoice_Number']) + ' AND Vendor_ID=' + quotedstr(FdInvoices['Vendor_ID']);
FdInvoices.Filtered := true;
FdInvoices.first;
Docs.Add(TDocuments.Create);
DocIdx := Docs.Count - 1;
Docs[DocIdx].BusinessUnit := FdInvoices['Customer_ID'];
Docs[DocIdx].Ledger := 'A';
Docs[DocIdx].LAAVersion := '';
Docs[DocIdx].JournalSource := 'AK';
Docs[DocIdx].JournalType := 'FACT';
Docs[DocIdx].Period := '0012024';
Docs[DocIdx].TransactionReference := FdInvoices['Invoice_Number'];
Docs[DocIdx].DocumentType := FdInvoices['Invoice_Type'];
//Adding Master record
AddNewRecord(Docs[DocIdx], TRecordType.MasterRecord, FdInvoices);
while not FdInvoices.Eof do
begin
//Adding Detail record
AddNewRecord(Docs[DocIdx], TRecordType.DetailRecord, FdInvoices);
FdInvoices.next;
end;
Report.AddTable<TDocuments>('Documents', Docs);
Report.Run(TPath.Combine(GetDataPath, 'Q&A_Template.xlsx', false), TPath.Combine(GetDataPath,'Q&A.xlsx', false));
finally
FdInvoices.Filtered := false;
FdInvoices.Filter := '';
FdInvoices.GotoBookmark(Bookmkt);
FdInvoices.enableControls;
Docs.free;
Report.Free;
end;
end;
Classes used to populate XLReport
unit Unit3;
interface
uses
Generics.Collections;
type
TRecordType = (MasterRecord,DetailRecord);
type
//We can use classes or records as data sources
TRecords = class
private
FAccount: string;
FAD1: string;
FAD2: string;
FAD3: string;
FAD4: string;
FAD5: string;
FAD6: string;
FAD7: string;
FAD8: string;
FAD9: string;
FAssetCode: Integer;
FAssetIndicator: String;
FDebitCredit: String;
FDescription: string;
FDueDate: TDate;
FName: string;
FRecordType: string;
FTransactionAmount: Double;
FTransactionCurrencyCode: string;
FTransactionDate: TDate;
public
property Account: string read FAccount write FAccount;
property AD1: string read FAD1 write FAD1;
property AD2: string read FAD2 write FAD2;
property AD3: string read FAD3 write FAD3;
property AD4: string read FAD4 write FAD4;
property AD5: string read FAD5 write FAD5;
property AD6: string read FAD6 write FAD6;
property AD7: string read FAD7 write FAD7;
property AD8: string read FAD8 write FAD8;
property AD9: string read FAD9 write FAD9;
property AssetCode: Integer read FAssetCode write FAssetCode;
property AssetIndicator: String read FAssetIndicator write FAssetIndicator;
property DebitCredit: String read FDebitCredit write FDebitCredit;
property Description: string read FDescription write FDescription;
property DueDate: TDate read FDueDate write FDueDate;
property Name: string read FName write FName;
property RecordType: string read FRecordType write FRecordType;
property TransactionAmount: Double read FTransactionAmount write
FTransactionAmount;
property TransactionCurrencyCode: string read FTransactionCurrencyCode write
FTransactionCurrencyCode;
property TransactionDate: TDate read FTransactionDate write FTransactionDate;
end;
TDocuments = class
private
FRecords: TObjectList<TRecords>;
FBusinessUnit: string;
FDocumentType: string;
FJournalSource: string;
FJournalType: string;
FLedger: string;
FLAAVersion: string;
FPeriod: string;
FTransactionReference: string;
public
constructor Create;
destructor Destroy; override;
property Records: TObjectList<TRecords> read FRecords;
property BusinessUnit: string read FBusinessUnit write FBusinessUnit;
property DocumentType: string read FDocumentType write FDocumentType;
property JournalSource: string read FJournalSource write FJournalSource;
property JournalType: string read FJournalType write FJournalType;
property Ledger: string read FLedger write FLedger;
property LAAVersion: string read FLAAVersion write FLAAVersion;
property Period: string read FPeriod write FPeriod;
property TransactionReference: string read FTransactionReference write FTransactionReference;
end;
implementation
{ TDocuments }
constructor TDocuments.Create;
begin
FRecords := TObjectList<TRecords>.Create;
end;
destructor TDocuments.Destroy;
begin
Records.Free;
inherited;
end;
end.