44[ ![ ] ( https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square )] ( https://docs.devexpress.com/GeneralInformation/403183 )
55[ ![ ] ( https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square )] ( #does-this-example-address-your-development-requirementsobjectives )
66<!-- default badges end -->
7- # DevExpress VCL Reports - Store Report Layouts in a Database
87
9- This example stores a [ report layout ] ( https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout ) (XML-based template) in the BLOB field of a memory-based dataset ( [ TdxMemData ] ( https://docs.devexpress.com/VCL/dxmdaset.TdxMemData ) inherited from the [ TDataSet ] ( https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TDataSet ) class shipped with the standard VCL library).
8+ # DevExpress Reports for Delphi/C++Builder – Store Report Layouts in a Database
109
11- ## Testing the example
10+ This example application stores [ DevExpress report layouts] [ TdxReport.Layout ] in a database.
11+ The application allows users to create new layouts, modify existing layouts using the built-in Report Designer,
12+ and save layout customization to the data source.
13+
14+
15+ ## Prerequisites
16+
17+ [ DevExpress Reports Prerequisites] [ req ]
18+
19+ [ req ] : https://docs.devexpress.com/VCL/405773/ExpressCrossPlatformLibrary/vcl-backend/reports-dashboards-app-deployment#vcl-reportsdashboards-prerequisites
20+
21+
22+ ## Test the Example
23+
24+ 1 . Run the sample app and click ** New Report** .
25+ 1 . Click ** Design Report** to display the [ Report Designer] [ dx-report-designer ] dialog.
26+ 1 . Create a report layout using tools available within the UI.
27+ 1 . Click the hamburger button, select the ** Save** option, and close the dialog.
28+ 1 . Close and restart the app.
29+ Click ** Design Report** or ** Preview Report** to load the saved report in the
30+ [ Report Designer] [ dx-report-designer ] or [ Viewer] [ dx-report-viewer ] .
31+
32+ ## Implementation Details
33+
34+ The example uses a DevExpress memory-based dataset as a report layout storage: [ TdxMemData] .
35+ You can modify the application to use any other [ TDataSet] descendant instead.
36+ To review the data module implementation, see the following file: [ uData.pas] /[ uData.cpp] .
37+
38+ The instructions assume that you start with a Delphi or C++Builder project that already includes
39+ a configured data source for DevExpress Reports.
40+ To configure a report data source in your project, refer to the following tutorial:
41+ [ Create a Table Report Using the Report Wizard] [ report-wizard ] .
42+ This example project uses a SQLite sample database ([ nwind.db] ) as a report data source.
43+
44+ ### Step 1: Create a Dataset to Store Report Layout Data
45+
46+ 1 . Add a [ TdxMemData] component to the data module (` mdLayouts ` in the example).
47+ 1 . Add a [ TDataSource] component to the data module (` dsLayouts ` in the example).
48+ Assign the previously created dataset component to ` TDataSource.DataSet ` :
49+
50+ > <img src="./images/create-bind-data-source.png" style="width: 50%"
51+ alt="Object Inspector panel displaying TDataSource properties."/>
52+
53+ 1 . Open the context menu for the dataset component and select ** Field Editor…** :
54+
55+ > <img src="./images/open-context-menu.png" style="width: 50%"
56+ alt="Context menu for the TdxMemData component displaying a 'Field Editor' option."/>
57+
58+ 1 . Click ** Add…** to create a BLOB field for layout data:
59+
60+ > <img src="./images/create-layout-field.png" style="width: 50%"
61+ alt="New Field dialog adding a 'Layout' field of type ftBlob"/>
62+
63+ 1 . Click ** Add…** to create a string field for layout names:
64+
65+ > <img src="./images/create-name-field.png" style="width: 50%"
66+ alt="New Field dialog adding a 'Name' field of type ftWideString"/>
67+
68+ 1 . (* Optional* ) Preload persistent data to the dataset to make layouts available in the application upon first launch.
69+
70+ This example includes a sample report layout that displays data from the Northwind sample database.
71+ You can preload it from [ example.dat] .
72+ Open the context menu for the dataset component, select ** Persistent Editor…** , click ** Load…** , and select the file.
73+
74+ > <img src="./images/create-persistent-data.png" style="width: 50%"
75+ alt="Context menu for the TdxMemData component displaying a 'Persistent Editor' option."/>
76+
77+ Alternatively, you can use the Report Designer later to import report data from a file.
78+
79+
80+ ### Step 2: Load a Report Layout Definition
81+
82+ To load a layout definition to the [ TdxReport] component, you must specify
83+ report name ([ TdxReport.ReportName] ) and layout ([ TdxReport.Layout] ):
84+
85+ ``` pas
86+ procedure TMainForm.LoadReportNameAndLayout();
87+ begin
88+ // Ensure that the dataset has at least one record or a new record is being created:
89+ if (DataModule1.mdLayouts.RecordCount = 0) and not (DataModule1.mdLayouts.State = dsInsert) then
90+ begin
91+ ShowMessage('The database is empty');
92+ Exit;
93+ end;
94+ // Load report name and layout from the database:
95+ dxReport1.ReportName := DataModule1.mdLayoutsName.AsString;
96+ dxReport1.Layout.Assign(DataModule1.mdLayoutsLayout);
97+ end;
98+ ```
99+
100+ To load a different report, assign a new report name and layout.
101+ The assigned report replaces the current layout definition.
102+
103+
104+ ### Step 3: Display Report Designer and Viewer
105+
106+ Once you assigned a name and layout to the [ TdxReport] component,
107+ you can display [ Report Designer] [ dx-report-designer ] and [ Report Viewer] [ dx-report-viewer ] dialogs:
108+
109+ ``` pas
110+ procedure TMainForm.btnDesignClick(Sender: TObject);
111+ begin
112+ LoadReportFromLayout; // Loads a report layout definition from the database
113+ dxReport1.ShowDesigner; // Displays the Report Designer
114+ end;
115+
116+ procedure TMainForm.btnPreviewClick(Sender: TObject);
117+ begin
118+ LoadReportFromLayout; // Loads a report layout definition from the database
119+ dxReport1.ShowViewer; // Displays the Report Viewer
120+ end;
121+ ```
122+
123+
124+ ### Step 4: Store Report Layouts in a Dataset
125+
126+ When a user edits and saves a report in the Report Designer,
127+ the value of [ TdxReport.Layout] changes and an [ OnLayoutChanged] event is called.
128+ Handle this event to save layout changes to the active dataset record.
129+
130+ ``` pas
131+ procedure TMainForm.dxReport1LayoutChanged(ASender: TdxReport);
132+ begin
133+ // Start editing the active dataset record:
134+ DataModule1.mdLayouts.Edit;
135+
136+ // Save report name and layout to the database:
137+ DataModule1.mdLayoutsName.AsString := dxReport1.ReportName;
138+ DataModule1.mdLayoutsLayout.Assign(dxReport1.Layout);
139+
140+ // Finish editing and post the modified record to the database:
141+ DataModule1.mdLayouts.Post;
142+ end;
143+ ```
144+
145+
146+ ### Step 5: Persist Data between Application Sessions
147+
148+ This step is applicable only to the memory-based [ TdxMemData] datasource.
149+
150+ To save the dataset to a file and restore data on app restart,
151+ handle ` OnCreate ` and ` OnDestroy ` events of the data module:
152+
153+ ``` pas
154+ const
155+ DataFileName = 'data.dat';
156+
157+ procedure TDataModule1.DataModuleCreate(Sender: TObject);
158+ begin
159+ if FileExists(DataFileName) then
160+ mdLayouts.LoadFromBinaryFile(DataFileName)
161+ end;
162+
163+ procedure TDataModule1.DataModuleDestroy(Sender: TObject);
164+ begin
165+ if mdLayouts.RecordCount > 0 then
166+ mdLayouts.SaveToBinaryFile(DataFileName)
167+ end;
168+ ```
169+
170+
171+ ## Files to Review
172+
173+ - [ uData.pas] /[ uData.cpp] stores report layouts.
174+ - [ uMainForm.pas] /[ uMainForm.cpp] creates a [ TdxReport] , loads report layouts from the data module, and displays Report Designer/Viewer.
175+ - [ data.dat] stores the memory-based dataset state between application sessions.
176+ - [ nwind.db] contains the Northwind sample database used as a data source for report content.
12177
13- * Run the sample app and click ** New Report** to create an empty database record.
14- * Click ** Show Designer** to display the [ Report Designer] ( https://docs.devexpress.com/XtraReports/119176/web-reporting/web-end-user-report-designer ) dialog.
15- * Create a report layout using tools available within the UI.
16- * Click the hamburger button, select the ** Save** option, and close the dialog.
17- * Close the app. The [ TdxMemData] ( https://docs.devexpress.com/VCL/dxmdaset.TdxMemData ) component will store layout data between sessions.
18- * Run the sample app again. Click ** View Designer** to load the saved report layout, or ** View Report** to preview a layout-based report in the [ Report Viewer] ( https://docs.devexpress.com/XtraReports/401850/web-reporting/web-document-viewer ) dialog.
19178
20179## Documentation
21180
22- * [ TdxReport.Layout Property] ( https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout )
23- * [ TdxBackendDataSetJSONConnection Component] ( https://docs.devexpress.com/VCL/dxBackend.ConnectionString.JSON.DataSet.TdxBackendDataSetJSONConnection )
181+ - [ Introduction to VCL Reports] [ reports-intro ]
182+ - [ Tutorial: Create a table report using the Report Wizard] [ report-wizard ]
183+ - [ Use SQLite as a data source for reports (as demonstrated in the current example)] [ sqlite-data-source ]
184+ - [ Store report layouts in REPX files at design-time] [ reports-design-time-store ]
185+ - API reference:
186+ - [ TdxReport.ReportName] (internal report name that is not included in the layout)
187+ - [ TdxReport.Layout] (an XML-based layout template that can be stored in a BLOB data field)
188+ - [ TdxMemData] (a DevExpress in-memory dataset implementation)
189+ - [ TDataSet] (contains generic database connection methods)
190+ - [ TdxBackendDatabaseSQLConnection] (supplies data to reports)
191+
192+ <!-- documentation links -->
193+ [ reports-intro ] : https://docs.devexpress.com/VCL/405469/ExpressReports/vcl-reports
194+ [ report-wizard ] : https://docs.devexpress.com/VCL/405760/ExpressReports/getting-started/create-table-report-using-report-wizard
195+ [ sqlite-data-source ] : https://docs.devexpress.com/VCL/405750/ExpressCrossPlatformLibrary/vcl-backend/database-engines/vcl-backend-sqlite-support
196+ [ reports-design-time-store ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout#string-list-editor
197+ [ dx-report-viewer ] : https://docs.devexpress.com/XtraReports/401850/web-reporting/web-document-viewer
198+ [ dx-report-designer ] : https://docs.devexpress.com/XtraReports/119176/web-reporting/web-end-user-report-designer
199+
200+
201+ <!-- reference links -->
202+ [ TdxReport ] : https://docs.devexpress.com/VCL/dxReport.TdxReport
203+ [ TdxReport.Layout ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout
204+ [ TdxReport.ReportName ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ReportName
205+ [ TdxReport.ShowDesigner ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ShowDesigner
206+ [ TdxReport.ShowViewer ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ShowViewer
207+ [ TdxBackendDatabaseSQLConnection ] : https://docs.devexpress.com/VCL/dxBackend.ConnectionString.SQL.TdxBackendDatabaseSQLConnection
208+ [ TdxMemData ] : https://docs.devexpress.com/VCL/dxmdaset.TdxMemData
209+ [ OnLayoutChanged ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.OnLayoutChanged
210+
211+ <!-- external documentation links -->
212+ [ TDataSet ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TDataSet
213+ [ TDataSource ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TDataSource
214+ [ ftString ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
215+ [ ftWideString ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
216+ [ ftBlob ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
217+
218+ <!-- in-repository links -->
219+ [ uData.pas ] : ./Delphi/uData.pas
220+ [ uData.cpp ] : ./CPB/uData.cpp
221+ [ data.dat ] : ./Delphi/data.dat
222+ [ example.dat ] : ./Delphi/example.dat
223+ [ uMainForm.pas ] : ./Delphi/uMainForm.pas
224+ [ uMainForm.cpp ] : ./CPB/uMainForm.cpp
225+ [ nwind.db ] : ./Delphi/nwind.db
226+
227+
228+ ## More Examples
229+
230+ - [ Store report layouts in REPX files] [ file-example ]
231+
232+ [ file-example ] : https://github.com/DevExpress-Examples/vcl-reports-store-layout-template-file
233+
234+
24235<!-- feedback -->
25236## Does This Example Address Your Development Requirements/Objectives?
26237
@@ -29,5 +240,3 @@ This example stores a [report layout](https://docs.devexpress.com/VCL/dxReport.T
29240(you will be redirected to DevExpress.com to submit your response)
30241<!-- feedback end -->
31242
32-
33-
0 commit comments