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 and save report layouts, modify existing layouts, and open layouts in Report Designer/Viewer.
12+
13+
14+ ## Prerequisites
15+
16+ [ DevExpress Reports Prerequisites] [ req ]
17+
18+ [ req ] : https://docs.devexpress.com/VCL/405773/ExpressCrossPlatformLibrary/vcl-backend/reports-dashboards-app-deployment#vcl-reportsdashboards-prerequisites
19+
20+
21+ ## Test the Example
22+
23+ - Run the sample app and click ** New Report** to create an empty database record.
24+ - Click ** Show Designer** to display the [ Report Designer] [ dx-report-designer ] dialog.
25+ - Create a report layout using tools available within the UI.
26+ - Click the hamburger button, select the ** Save** option, and close the dialog.
27+ - Close the app. The [ TdxMemData] component will store layout data in the [ data.dat] file between sessions.
28+ - Run the sample app again. Click ** View Designer** to load the saved report layout,
29+ or ** View Report** to preview a layout-based report in the [ Report Viewer] [ dx-report-viewer ] dialog.
30+
31+ ## Implementation Details
32+
33+ Follow the instructions in this example to store report layouts in a database of your choice,
34+ using the corresponding ` TDataSet ` descendant.
35+
36+ The example uses a memory-based dataset
37+ ([ TdxMemData] from the DevExpress library, inherited from [ TDataSet] , shipped with the standard VCL library).
38+ Applications in this example isolate data components in separate data modules: [ uData.pas] (Delphi) and [ uData.cpp] (C++Builder).
39+
40+ The instructions assume that you start with a Delphi or C++Builder project that has
41+ a configured data source for DevExpress Reports.
42+ To configure a report data source in your project, refer to the following tutorial: [ Create a Table Report Using the Report Wizard] [ report-wizard ] .
43+ This example uses a SQLite sample database ([ nwind.db] ) as a report data source.
44+
45+ ### Step 1: Create a Dataset to Store Report Layout Data
46+
47+ Follow these steps to create a memory-based dataset to store report layout data:
48+
49+ 1 . Create a [ TdxMemData] component on a form (` mdLayouts ` in the example).
50+ 2 . Create a [ TDataSource] component on a form (` dsLayouts ` in the example).
51+ Assign the ` TDataSource.DataSet ` value to the previously created dataset component:
52+
53+ > <img src =" ./images/create-bind-data-source.png " style =" width : 50% " alt =" " />
54+
55+ 3 . Open the context menu of the dataset component and select ** Field Editor…** :
56+
57+ > <img src =" ./images/open-context-menu.png " style =" width : 50% " alt =" " />
58+
59+ 4 . Click ** Add…** to create a BLOB field for layout data:
60+
61+ > <img src =" ./images/create-layout-field.png " style =" width : 50% " alt =" " />
62+
63+ 5 . Click ** Add…** to create a string field for layout name:
64+
65+ > <img src =" ./images/create-name-field.png " style =" width : 50% " alt =" " />
66+
67+ 6 . (* Optional* ) Preload persistent data to the dataset make layouts available in the application upon first launch.
68+ Open the context menu of the dataset component, select ** Persistent Editor…** , click ** Load…** and select a DAT file.
69+
70+ > <img src =" ./images/create-persistent-data.png " style =" width : 50% " alt =" " />
71+
72+ This example has an example report layout designed to use data from the Northwind sample database.
73+ You can preload it from [ example.dat] .
74+
75+ Alternatively, you can use the Report Designer in further steps to import report data from files or raw string data.
76+
77+
78+ ### Step 2: Supply Layout Data to TdxReport
79+
80+ Supply the [ TdxReport] component with two values:
81+ report name ([ TdxReport.ReportName] ) and layout ([ TdxReport.Layout] ):
82+
83+ ``` pas
84+ procedure TMainForm.LoadReportNameAndLayout();
85+ begin
86+ if (DataModule1.mdLayouts.RecordCount = 0) and not (DataModule1.mdLayouts.State = dsInsert) then
87+ begin
88+ ShowMessage('The database is empty');
89+ Exit;
90+ end;
91+ // Load the report name from the database
92+ dxReport1.ReportName := DataModule1.mdLayoutsName.AsString;
93+ // Load the report layout from the database
94+ dxReport1.Layout.Assign(DataModule1.mdLayoutsLayout);
95+ end;
96+ ```
97+
98+ To load a different report, assign a new report name and layout.
99+ No cleanup is required between reports.
100+
101+ <!--
102+ 1. Assign report name and layout when application starts.
103+ 2. Assign report name and layout when user selects a different grid row.
104+ 3. (Optional) Change report name when user edits it in the grid view.
105+ -->
106+
107+
108+ ### Step 3: Display Report Designer and Viewer
109+
110+ Once you have assigned name and layout to the [ TdxReport] component,
111+ you can display the Report Designer and Viewer components:
112+
113+ ``` pas
114+ procedure TMainForm.btnDesignClick(Sender: TObject);
115+ begin
116+ // Display the Report Designer
117+ dxReport1.ShowDesigner;
118+ end;
119+
120+ procedure TMainForm.btnPreviewClick(Sender: TObject);
121+ begin
122+ // Display the Report Viewer
123+ dxReport1.ShowViewer;
124+ end;
125+ ```
126+
127+ ### Step 4: Store Report Layout Data in the Dataset
128+
129+ When a user edits and saves a report in the Report Designer,
130+ the value of [ TdxReport.Layout] changes and an [ OnLayoutChanged] event is called.
131+ Handle this event to store the updated layout in the active dataset record.
132+
133+ ``` pas
134+ procedure TMainForm.dxReport1LayoutChanged(ASender: TdxReport);
135+ begin
136+ // Start editing the active dataset record
137+ DataModule1.mdLayouts.Edit;
138+ // Save the report name
139+ DataModule1.mdLayoutsName.AsString := dxReport1.ReportName;
140+ // Save the report layout
141+ DataModule1.mdLayoutsLayout.Assign(dxReport1.Layout);
142+ // Finish editing and write a modified record
143+ DataModule1.mdLayouts.Post;
144+ end;
145+ ```
146+
147+ ### Step 6: Persist the Database State Between Application Sessions
148+
149+ This step is specific to the memory-based [ TdxMemData] datasource.
150+
151+ To persist the database state when user closes the application
152+ and restore the state when user restarts the application,
153+ handle the ` Create ` and ` Destroy ` events of the data module:
154+
155+ ``` pas
156+ const
157+ DataFileName = 'data.dat';
158+
159+ procedure TDataModule1.DataModuleCreate(Sender: TObject);
160+ begin
161+ if FileExists(DataFileName) then
162+ mdLayouts.LoadFromBinaryFile(DataFileName)
163+ end;
164+
165+ procedure TDataModule1.DataModuleDestroy(Sender: TObject);
166+ begin
167+ if mdLayouts.RecordCount > 0 then
168+ mdLayouts.SaveToBinaryFile(DataFileName)
169+ end;
170+ ```
171+
172+
173+ ## Files to Review
174+
175+ - [ uData.pas] (Delphi) and [ uData.cpp] (C++Builder) read and store layout data in a database represented by an in-memory storage component.
176+ - [ uMainForm.pas] (Delphi) and [ uMainForm.cpp] (C++Builder) supply layout data from the data module to [ TdxReport] and display Report Designer and Viewer.
177+ - [ data.dat] persists the memory-based dataset between application sessions.
178+ - [ nwind.db] contains the Northwind sample database used as a data source for report content.
12179
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.
19180
20181## Documentation
21182
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 )
183+ - [ Introduction to VCL Reports] [ reports-intro ]
184+ - [ Tutorial: Create a table report using the Report Wizard] [ report-wizard ]
185+ - [ Use SQLite as a data source for reports (as demonstrated in the current example)] [ sqlite-data-source ]
186+ - [ Store report layouts in REPX files at design-time] [ reports-design-time-store ]
187+ - API reference:
188+ - [ TdxReport.ReportName] (internal report name that is not included in the layout)
189+ - [ TdxReport.Layout] (an XML-based layout template that can be stored in the BLOB field of a database)
190+ - [ TdxMemData] (used to store report layout data in application runtime and between sessions)
191+ - [ TDataSet] (ancestor of the ` TdxMemData ` , contains generic database connection methods)
192+ - [ TdxBackendDatabaseSQLConnection] (used to supply data to reports)
193+
194+ <!-- documentation links -->
195+ [ reports-intro ] : https://docs.devexpress.com/VCL/405469/ExpressReports/vcl-reports
196+ [ report-wizard ] : https://docs.devexpress.com/VCL/405760/ExpressReports/getting-started/create-table-report-using-report-wizard
197+ [ sqlite-data-source ] : https://docs.devexpress.com/VCL/405750/ExpressCrossPlatformLibrary/vcl-backend/database-engines/vcl-backend-sqlite-support
198+ [ reports-design-time-store ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout#string-list-editor
199+ [ dx-report-viewer ] : https://docs.devexpress.com/XtraReports/401850/web-reporting/web-document-viewer
200+ [ dx-report-designer ] : https://docs.devexpress.com/XtraReports/119176/web-reporting/web-end-user-report-designer
201+
202+
203+ <!-- reference links -->
204+ [ TdxReport ] : https://docs.devexpress.com/VCL/dxReport.TdxReport
205+ [ TdxReport.Layout ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.Layout
206+ [ TdxReport.ReportName ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ReportName
207+ [ TdxReport.ShowDesigner ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ShowDesigner
208+ [ TdxReport.ShowViewer ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.ShowViewer
209+ [ TdxBackendDatabaseSQLConnection ] : https://docs.devexpress.com/VCL/dxBackend.ConnectionString.SQL.TdxBackendDatabaseSQLConnection
210+ [ TdxMemData ] : https://docs.devexpress.com/VCL/dxmdaset.TdxMemData
211+ [ OnLayoutChanged ] : https://docs.devexpress.com/VCL/dxReport.TdxReport.OnLayoutChanged
212+
213+ <!-- external documentation links -->
214+ [ TDataSet ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TDataSet
215+ [ TDataSource ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TDataSource
216+ [ ftString ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
217+ [ ftWideString ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
218+ [ ftBlob ] : https://docwiki.embarcadero.com/Libraries/Athens/en/Data.DB.TFieldType
219+
220+ <!-- in-repository links -->
221+ [ uData.pas ] : ./Delphi/uData.pas
222+ [ uData.cpp ] : ./CPB/uData.cpp
223+ [ data.dat ] : ./Delphi/data.dat
224+ [ example.dat ] : ./Delphi/example.dat
225+ [ uMainForm.pas ] : ./Delphi/uMainForm.pas
226+ [ uMainForm.cpp ] : ./CPB/uMainForm.cpp
227+ [ nwind.db ] : ./Delphi/nwind.db
228+
229+
230+ ## More Examples
231+
232+ - [ Store report layouts in REPX files] [ file-example ]
233+
234+ [ file-example ] : https://github.com/DevExpress-Examples/vcl-reports-store-layout-template-file
235+
236+
24237<!-- feedback -->
25238## Does This Example Address Your Development Requirements/Objectives?
26239
@@ -29,5 +242,3 @@ This example stores a [report layout](https://docs.devexpress.com/VCL/dxReport.T
29242(you will be redirected to DevExpress.com to submit your response)
30243<!-- feedback end -->
31244
32-
33-
0 commit comments