📄 faq.txt
字号:
---------------- Using own functions ----------------------------------------
Q: How I can add my own function?
A: Use TfrReport.OnUserFunction event. Here is simple example:
procedure TForm1.frReport1UserFunction(const Name: String;
p1, p2, p3: Variant; var val: Variant);
begin
if AnsiCompareText('SUMTOSTR', Name) = 0 then
val := My_Convertion_Routine(frParser.Calc(p1));
end;
After this, you can use SumToStr function in any place of report
(in any expression or script).
Q: Ok, but it works only for one TfrReport component. I want to use
my function everywhere (in all TfrReport components).
A: Make OnUserFunction event handler common for all components. If you
can't do this, you should create function library:
type
TMyFunctionLibrary = class(TfrFunctionLibrary)
public
constructor Create; override;
procedure DoFunction(FNo: Integer; p1, p2, p3: Variant;
var val: Variant); override;
end;
constructor TMyFunctionLibrary.Create;
begin
inherited Create;
with List do
begin
Add('DATETOSTR');
Add('SUMTOSTR');
end;
end;
procedure TMyFunctionLibrary.DoFunction(FNo: Integer; p1, p2, p3: Variant;
var val: Variant);
begin
val := 0;
case FNo of
0: val := My_DateConvertion_Routine(frParser.Calc(p1));
1: val := My_SumConvertion_Routine(frParser.Calc(p1));
end;
end;
To register function library, call
frRegisterFunctionLibrary(TMyFunctionLibrary);
To unregister library, call
frUnRegisterFunctionLibrary(TMyFunctionLibrary);
Q: How I can add my function to function list (in expression builder)?
A: Use frAddFunctionDesc procedure (FR_Class unit):
frAddFunctionDesc(FuncLib, 'SUMTOSTR', 'My functions',
'SUMTOSTR(<Number>)/Converts number to its verbal presentation.');
Note: "/" symbol is required! It separates function syntax from its
description.
FuncLib is reference to your function library (can be nil if you don't
use function library). When function library is unregistered, all its
function will be automatically removed from function list.
---------------- Working with variables -------------------------------------
Q: How I can fill variables list (in data dictionary) programmatically?
A: All variables and categories from data dictionary stored in
TfrReport.Dictionary.Variables.
with frReport1.Dictionary do
begin
// creating category (space in category name required!)
Variables[' New category'] := '';
// creating variables
Variables['New Variable'] := 'CustomerData.Customers."CustNo"';
Variables['Another Variable'] := 'Page#';
end;
Q: I define my variable and assign string to it:
with frReport1.Dictionary do
Variables['Month'] := 'March';
But when I run report, I get an error. Why?
A: Because FastReport assumes that string values, assigned to the data
dictionary variables, are expressions which it should parse and calculate.
Use additional quotes:
with frReport1.Dictionary do
Variables['Month'] := '''' + 'March' + '''';
Or, use frVariables to transfer static data to the report.
Q: I don't want to show some datasets in data dictionary.
A: Use TfrReport.Dictionary.DisabledDatasets:
with frReport1.Dictionary do
begin
// turn of this dataset
DisabledDatasets.Add('CustomerData.Bio');
// or, turn off entire datamodule/form
DisabledDatasets.Add('CustomerData*');
end;
Q: How I can transfer data to the report?
A: There is several methods to do this. First is to use global object
frVariables (defined in FR_Class unit):
frVariables['My variable'] := 10;
This code creates new variable with 'My variable' name and value = 10.
This method is best to transfer static data to the report.
Second method is to use TfrReport.OnGetValue event. You can use this
method to transfer dynamic data, i.e. data which changes from record
to record.
procedure TForm1.frReport1GetValue(ParName: String; var ParValue: Variant);
begin
if ParName = 'MyField' then
ParValue := Table1MyField.Value;
end;
Finally, third method is to define variable from dictionary
programmatically (see previous question):
with frReport1.Dictionary do
begin
Variables['MyVariable'] := 'CustomerData.Customers."CustNo"';
Variables['Another Variable'] := '10';
end;
Q: Can I transfer data from report to the program?
A: Use frVariables object. If you write the following code in script of
any object in the report:
MyVariable := 10
In your program you can use this code to retrieve MyVariable value:
v := frVariables['MyVariable'];
---------------- Script (FastReport Pascal) ---------------------------------
Q: Does band have a script?
A: Yes, it does. Select band and press Ctrl+Enter or choose "OnBeforePrint"
property in object inspector.
Q: Does report page have a script?
A: Yes, it does too. Select page (click on empty space) and choose
"OnBeforePrint" property in object inspector. If page is dialog form,
this property called "OnActivate".
Q: I have two objects: Memo1 and Memo2. Can I call Memo2 properties and
methods from Memo1 script?
A: Yes, use comma-notation, e.g. ObjectName.PropertyName.
Q: Which object's properties can I use in script?
A: Almost all which you can see in object inspector. Font properties
accessible as Font.Name, Font.Size and etc.
---------------- Other questions --------------------------------------------
Q: How to change page order in the multi-page report?
A: Drag page tab to desired position.
Q: I want to see all fields and variables I want to insert in the report
in one list.
A: Set TfrReport.MixVariablesAndDBFields := True. All data fields and
variables now accessible in the "Insert data field" dialog.
Q: I don't want to see export options dialog.
A: Set all necessary options in the export component (e.g., TfrTextExport)
and turn off dialog by setting ShowDialog property to False.
Q: Why TotalPages variable does'nt works? It always returns 0.
A: Set Two-pass option for your report. To do this, open "Report options"
dialog in the "File" menu of the designer.
Q: I store my report in the BLOb field. When I run designer, it shows that
my report has "Untitled" name.
A: Before run designer, do this:
frReport1.FileName := 'Name of my report';
Q: Same situation. I want to define my reaction of "Open" and "Save"
buttons in designer.
A: Look at TfrDesigner component. It has necessary events: OnLoadReport and
OnSaveReport. Here is a small example:
procedure TForm1.frDesigner1LoadReport(Report: TfrReport;
var ReportName: String; var Opened: Boolean);
begin
with MyOpenDialog do
begin
Opened := ShowModal = mrOk;
if Opened then
begin
Report.LoadFromBlobField(...);
ReportName := ...;
end;
end;
end;
procedure TForm1.frDesigner1SaveReport(Report: TfrReport;
var ReportName: String; SaveAs: Boolean; var Saved: Boolean);
begin
if SaveAs then
with MySaveDialog do
begin
Saved := ShowModal = mrOk;
if Saved then
begin
Report.SaveToBlobField(...);
ReportName := ...;
end;
end
else
Report.SaveToBlobField(...);
end;
Q: In QR, I can write code like QRLabel1.Caption := 'Some text'. How can
I do this with FR?
A: FR objects is not a components (like in QR, RB). Use TfrReport.FindObject
method to find object by name:
var
t: TfrMemoView;
begin
t := TfrMemoView(frReport1.FindObject('Memo1'));
if t <> nil then
t.Memo.Text := 'FastReport';
end;
Q: I want to define own hot keys in user preview (TfrPreview component).
A: This component has Window: TForm property. Assign own event handler
to Window.OnKeyDown property.
Q: Fast Report 2.4 can not load FreeReport 2.21 files.
A: Guys from FreeR made wrong modifications. Just change the first byte in
the report file to 16h and do the following modifications in source code.
After these modifications, load the report and save it. Finally, return
back the original code.
FR_Class:
function ReadString(Stream: TStream): String;
begin
{ if frVersion >= 23 then}
Result := frReadString(Stream) {else
Result := frReadString22(Stream);}
end;
procedure ReadMemo(Stream: TStream; Memo: TStrings);
begin
{ if frVersion >= 23 then}
frReadMemo(Stream, Memo){ else
frReadMemo22(Stream, Memo);}
end;
FR_Utils:
procedure frReadMemo(Stream: TStream; l: TStrings);
var
s: String;
b: Byte;
n: Word;
begin
l.Clear;
l.Text := frReadString(Stream); exit;
Stream.Read(n, 2);
if n > 0 then
repeat
Stream.Read(n, 2);
SetLength(s, n);
Stream.Read(s[1], n);
l.Add(s);
Stream.Read(b, 1);
until b = 0
else
Stream.Read(b, 1);
end;
function frReadString(Stream: TStream): String;
var
s: String;
n: Integer;
b: Byte;
begin
Stream.Read(n, 4);
SetLength(s, n);
Stream.Read(s[1], n);
// Stream.Read(b, 1);
Result := s;
end;
Q: How to print report without preview?
A: Here is the code:
frReport1.PrepareReport;
frReport1.PrintPreparedReport('', 1, True, frAll);
or
frReport1.PrintPreparedReportDlg;
Q: I want to put a picture on my report. The only problem is that my
application is generating this picture. Is there a way to load this
picture into the report just before printing?
A: Use TfrReport.OnBeforePrint event:
if View.Name = 'Picture1' then
TfrPictureView(View).Picture.LoadFromFile(...) or
.Assign or
.everything_what_you_want
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -