I have been using Report Builder for some years, but I am getting tired of the cha-ching, cha-ching. It is a great reporting tool for "non database" reports.
I have started playing around with Fast Reports and I am utterly flustered with it. It seems a great reporting tool for databases but big question mark concerning complex "non database" reports. Their demos and help are horrible.
Wished I could show a report I am talking about. The report is a serial communications report that has operating system information which of course is single in nature. It has 4 distinct table which has installed serial ports and USB Serial Device tables. It also has a summary memo.
Has anyone successfully designed a report of the above configuration in Fast Reports? And yes, I have posted the same query with Fast Reports. Just want other opinions.
Thanks in advance.
I've extended the option provided by @jrodenhi's answer, which seems to be the proper way to do what you want (thus I've made this answer a community wiki). So here are the two options you can use (and I think there will be more of them):
The answer by @jrodenhi shows how to add report variables in code. I'll try to show here, how to define them in report designer.
In the Edit Variables window create a new category by clicking the Category button. Then you can rename the category the same way as you do e.g. for files in Windows Explorer:
Then you can declare a custom variable by clicking Variable button. You can give to the variable some meaningful name the same way as you do e.g. for files in Windows Explorer:
After this save your changes by clicking OK button:
Then you'll get back to the report designer, where you can find your just declared variables in the Data Tree pane tab Variables from where you can drag and drop the variables to the report:
After you refine all component positions and properties you can close the report designer and go back to the Delphi IDE. There you can write a handler for the OnGetValue
event of your report and if its VarName
parameter equals to your variable, change its Value
parameter to the value you want to give to the associated report component:
procedure TForm1.frxReport1GetValue(const VarName: string; var Value: Variant);
begin
if VarName = 'MyVariable' then
Value := 'This is a new value!';
end;
There is an option of direct access to report components from your Delphi code. For instance, to find a certain report component by name you can use the FindObject
method of the TfrxReport
object. Then you can follow the usual pattern of checking if the returned reference is of type of the control you want to access and if so, you can access the instance by typecasting, as usually.
For example to find a TfrxMemoView
object of name Memo1
on the frxReport1
report and modify its text you may write:
var
Component: TfrxComponent;
begin
Component := frxReport1.FindObject('Memo1');
if Component is TfrxMemoView then
TfrxMemoView(Component).Memo.Text := 'New text';
end;
Most of the reports I write are for payroll. In addition to the table based data that makes up the bulk of the report, there is usually a significant amount of singular data, such as user and employer information that is frequently most easily entered as a series of variables taken from a filter dialog that runs before the report. Once the filter has run I iterate through all of its variables and add them to the report variables. Maybe you could pick up your singular system variables and do the same.
This is my routine that runs just before I prepare a report. It not only adds variables, it also adds functions defined in Delphi that can be used in the report:
procedure TFastReportDriver.SetVariables(sVariables: String; var frxReport: TfrxReport);
var i,
iDetail: Integer;
sl: TStringList;
sVariable,
sValue: String;
begin
sl := TStringList.Create;
sl.CommaText := sVariables;
frxReport.Variables.Clear;
frxReport.Variables[' Filter'] := Null;
for i := 0 to sl.Count - 1 do begin
sVariable := sl.Names[i];
sValue := Qtd(sl.ValueFromIndex[i]);
frxReport.Variables.AddVariable('Filter', sVariable, sValue);
end;
frxReport.AddFunction('procedure CreateCheck(hPaystub, iCheckNo: Integer)');
frxReport.AddFunction('function NumberToWords(cAmount: Currency): String');
frxReport.OnUserFunction := repChecksUserFunction;
sl.Free;
end;
Then, in your code, you call frxReport.DesignReport and at run time you can drag and drop your variables onto your report:
And, if you have defined any functions like above, they show up under the functions tab.
I've had success with this method:
Use an in-memory table, such as TkbmMemTable, TdxMemTable or any in-memory table.
Link the in-memory table to the TfrDataSet.
Populate the in-memory table using usual TDataset methods and run the report.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With