We have frequently received requests from technical support for functionality to automatically validate reports, and we are pleased to announce its inclusion in the 2026.2.0 release. The "File" menu in the report designer now features "Validate" and "Validation Rule Settings" options. This allows users not only to check reports but also to manage the set of rules, including the creation of custom ones
In this article, we'll explain how report validation works, how to set it up, how to write your own rules, and share some interesting new features.
Â
Â
Let us limit ourselves to three basic terms that will be used repeatedly in this article.
Validation is the verification of a report's correctness and compliance with specified rules without actually generating it. Validation is accomplished by sequentially applying a set of predefined rules to the report.
A rule is a separate validation function executed during report validation. The validator stores a set of rules. A rule can be enabled or disabled. Only enabled rules are executed during validation. A rule can send multiple messages during execution.
A message is a record generated by a rule during report validation. The message contains information about the detected issue, including its severity level, a text description, and a double-click response.
Â
Â
Report validation is performed by selecting the "Validate" menu item or by pressing the Shift+F9 keyboard shortcut. Additionally, report validation can be linked to saving or building the report. This can be configured in the "View-Options" menu, on the "Validation" tab.
The Automatic Validation checkbox enables automatic report validation when generating or saving a report.
The "Validation fails if severity is at least" setting determines the error level at which validation is considered unsuccessful. Possible values: "Hint", "Warning", "Error".
If you select "Warning," validation will fail if at least one warning or error is detected during validation. The default value is "Error."
The last two settings control what happens to reports that fail validation when saving or building. You can allow the action, notify the user, or deny it.
Â
Â
In the "Validation Rule Settings" menu, you can configure the set of rules applied to the report. This window looks like this:
The left list, "Default rules," contains built-in rules. The right list, "Custom rules," is intended for user-created rules tailored to specific tasks. However, this division is conditional: users can also place their own rules in the default rules list.
The checkboxes below the lists allow you to instantly select or deselect all items in a list. The "Run validation on save" checkbox enables validation to run when the rule settings window is closed by clicking OK.
During subsequent validations, only the checked rules will be applied. The lists of active rules are preserved even after closing the report designer.
Â
Â
The following rules are available by default:
Please note that the list of rules may be expanded in the future.
Â
Â
Let's try running report validation. Please note: it will be considered a failure if warnings or more serious errors appear (if you've forgotten how to do this, see the section "How to Validate Reports in the Designer").
Let 's take report 1.fr3 from the DemoCenter and start validation:
Report validation failed. The IntersectingTest rule returned five warnings. This was expected, as an empty MemoView is used to fill the background of even-numbered rows.
To see a list of warnings, you can expand the rule node. Double-clicking on the warning row allows you to select the component in the designer where the rule generated the issue. It's important to note that you can validate not only report pages, but also scripts and dialogs. The entire report is available for validation.
Â
Â
Note the validator message box. We decided to use it for other purposes, such as debug messages and displaying the report generation time.
How can this be used? In the report script, use the new function — DebugLn. Call it with a string parameter. The parameter value will appear in the Messages window along with a timestamp when the report is generated. Let's look at an example.
Open any report in "FastReport Demo", for example, 1.fr3. Create several events for the components and call DebugLn() with the event name in the event handler code. Run the report, and you'll see the following information in the Messages window:
We hope this feature helps you debug your reports more efficiently.
Â
Â
As mentioned above, you can create your own report validation rules. Let's take a closer look at how to do this. Any validation rule must inherit from one of the following classes:
TfrxValidationRule — the base class for report rules. To work with the class, you need to override the abstract Validate (AReport: TfrxReport) method.Â
TfrxValidationPageRule — a class designed for page-by-page report validation. In descendants, you must override the ValidatePage method. This method will be called for each report page.
TfrxValidationComponentRule — a class designed for element-by-element report validation. The class must override the ValidateComponent method. This method will be called to validate each report component.
To notify that a validation error has been found, the base class TfrxValidationRule provides a method.
procedure DoMessage(ASeverity: TfrxValidationSeverity; const AText: string; ADoubleClickData: TObject = nil);
The method sends a message with error information to the registered recipients. Let's consider the parameters of this method in more detail.
Let's take a closer look at the third parameter ADoubleClickData. Currently, only an instance of the TfrxDoubleClickSetSelectionData class can be sent there. This can be expanded in the future.
This class has the following fields:
For correct processing, there are 3 options for filling this object:
After sending the validation error message, the object responsible for the double click needs to be removed. To use the rule, the written class should be registered. This is done by calling the following code:
frxValidationSettings.RegisterRule(ABucket: TfrxRuleBucket; ARuleClass: TfrxValidationRuleClass; AActive: Boolean = True);
Â
The frxValidationSettings object is defined in the TfrxValidator module. It is a singleton for storing validation rules.
The call parameters are as follows:
Based on the above, let's try to formulate a report validation rule. Let's say we're creating reports for a corporation, where all text must be formatted in the corporate colors—black and red. Using other colors is considered an error. Text borders must also be black or red, and the background white. Since we are checking individual components, the TfrxValidationComponentRule class is suitable for inheritance.
Our rule class declaration looks like this:
type TCorporateRule = class(TfrxValidationComponentRule) private procedure SendMessage(AComponent: TFrxComponent; APropertyName, AText:string); public procedure ValidateComponent(AComponent: TfrxComponent); override; class function GetName: string; override; end;
You also need to override the GetName method to return the rule name. Implementation of methods:
class function TCorporateRule.GetName: string; begin Result := 'Corporate_Colors'; end; Â Â procedure TCorporateRule.SendMessage(AComponent: TFrxComponent; APropertyName: string); var LSelData: TfrxDoubleClickSetSelectionData; begin LSelData := TfrxDoubleClickSetSelectionData.Create; try LSelData.ComponentName := AComponent.Name; LSelData.PropName := APropertyName; DoMessage(vsError, AComponent.Name + ': Invalid color of property ' + APropertyName, LSelData); finally LSelData.Free; end; end; Â Â procedure TCorporateRule.ValidateComponent(AComponent: TfrxComponent); var LMemo: TfrxMemoView; function CheckColors(AValue: TColor): Boolean; begin Result := (AValue = clBlack) or (AValue = clRed) or (AValue = clWhite) or (AValue = clNone) ; end; begin if not (AComponent is TfrxMemoView) then Exit; LMemo := TfrxMemoView(AComponent); if not CheckColors(LMemo.Font.Color) then SendMessage(LMemo, 'Font.Color'); if (not CheckColors(LMemo.Frame.TopLine.Color)) and (ftTop in LMemo.Frame.Typ) then SendMessage(LMemo, 'Frame.TopLine.Color'); if not CheckColors(LMemo.Frame.BottomLine.Color) and (ftBottom in LMemo.Frame.Typ) then SendMessage(LMemo, 'Frame.BottomLine.Color'); if not CheckColors(LMemo.Frame.LeftLine.Color) and (ftLeft in LMemo.Frame.Typ) then SendMessage(LMemo, 'Frame.LeftLine.Color'); if not CheckColors(LMemo.Frame.RightLine.Color) and (ftRight in LMemo.Frame.Typ) then SendMessage(LMemo, 'Frame.RightLine.Color'); if not CheckColors(LMemo.Color) then SendMessage(LMemo, 'Color'); end;
Then we register the rule:
initialization frxValidationSettings.RegisterRule(rbCustom, TCorporateRule);
We launch our application, open the report designer, and check the list of rules.
Now let's test a report using our rule. For example, a report from the DemoCenter called 1.fr3.
The validation log shows that the rule is triggered. Double-clicking the error takes us directly to the component with the incorrect color. The relevant property is highlighted in the Object Inspector.
Â
Â
FastReport only implements report validation in the designer. However, if such validations are required in other cases, the user can implement them independently. This means that hundreds of reports can be validated with one click. This can be done as follows.
TfrxValidator. frxValidationSettings. ApplySettings(AValidator: TfrxValidator). DefaultRules and CustomRules lists with rule objects in the validator object (an example of implementation is in frxValidationSettings. ApplySettings).TfrxValidator.AddListener(const AListener: IfrxValidationListener).TfrxValidator.Validate(AReport: TfrxReport) method to check the report.This is a fairly general guide. You can find a full implementation example in the ConsoleValidate demo project.
As you can see, report validation is simple and very useful. We welcome your suggestions for new rules.