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