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