Sign in Join
Wiki copytemporary

FPReport Usage/ru: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: FPReport Usage/ru

OldNewLine
1+На этой странице мы рассмотрим, как создать простой отчет в коде. В качестве отправной точки мы возьмем демонстрационный отчет dataset из демонстрационного приложения Free Pascal.
2+
3+## Владельцы и родительско-дочерняя структура
4+
5+Все элементы отчета (страницы, бэнды, элементы, доступные для печати) являются наследниками TComponent. Они организованы по принципу "родитель-потомок":
6+
7+ * Страницы являются дочерними элементами отчета
8+ * Бэнды являются дочерними элементами страницы
9+ * Элементы, доступные для печати, являются дочерними элементами бэнда.
10+
11+Владелец (как в TComponent) различных элементов не важен для структуры отчета, но если владелец является естественным родительским элементом вновь созданного компонента, то родительский элемент будет установлен автоматически.
12+
13+## Создание отчета
14+
15+Большинство классов, связанных с fpReport, определены в одном модуле, **fpreport**. Поэтому обязательно добавьте это в раздел uses.
16+```
17+uses
18+ SysUtils
19+ ,fpreport // для большинства классов отчетов FPReport
20+ ,dbf // для доступа к DBF (базе данных)
21+ ,fpreportdb // для класса TFPReportDatasetData
22+ ,fpttf // для доступа к gTTFontCache singleton
23+ {$IFDEF ExportPDF}
24+ ,fpreportpdfexport // для доступа к классу экспортера отчетов в формате PDF
25+ {$ENDIF}
26+ {$IFDEF ExportAggPas}
27+ ,fpreport_export_aggpas // для доступа к классу экспортера fpReport AggPas в fpGUI
28+ {$ENDIF}
29+ {$IFDEF ExportFPImage}
30+ ,fpreportfpimageexport // для доступа к классу FP Image exporter
31+ {$ENDIF}
32+ ;
33+```
34+
35+Все начинается с компонента отчета:
36+```
37+PaperManager.RegisterStandardSizes; // регистрация типов бумаги для fpReport
38+ rpt := TFPReport.Create(nil); // если ваш объект Application является потомком TComponent, используйте Self вместо nil.
39+ rpt.Author := 'Graeme Geldenhuys';
40+ rpt.Title := 'FPReport Demo 8 - Datasets';
41+```
42+
43+Свойства **Author** и **Title** могут использоваться в выражениях отчета.
44+
45+### Предоставление данных для отчета
46+
47+Для отображения каждого отчета необходим цикл обработки данных. Цикл обработки данных является производным от **TFPReportData** , существует несколько предопределенных циклов обработки данных.
48+
49+Один из возможных циклов обработки данных основан на наборе данных, **TFPReportDatasetData** \- определен в модуле **fpreportdb** , поэтому не забудьте добавить его в раздел uses. У него есть свойство **Dataset** , которое должно быть присвоено набору данных, предоставляющему данные для отчета. Цикл будет выполняться по всем записям в наборе данных, и все поля в наборе данных будут доступны для использования в выражениях, используемых в отчете.
50+
51+Следующий код создает компонент цикла обработки данных и назначает ему набор данных **TDBF**. Обратите внимание, что класс DBF определен в модуле **dbf**.
52+```
53+var
54+ lDataSet: TDBF;
55+ lReportData: TFPReportDatasetData;
56+ begin
57+ lReportData := TFPReportDatasetData.Create(nil); // То же, что и в предыдущем примере кода. Используйте Self
58+ lDataSet := TDBF.Create(nil); // или Nil, в зависимости от объекта Application
59+ lDataSet.TableName := 'test.dbf';
60+ lReportData.DataSet := lDataSet;
61+```
62+
63+Затем компонент **lReportData** может быть использован в структуре отчета.
64+
65+### Добавление страницы
66+
67+Для каждого отчета требуется как минимум одна страница.
68+
69+Следующая страница принадлежит отчету, поэтому она будет автоматически добавлена к страницам отчета. После создания необходимо задать размер страницы (доступен набор стандартных размеров), это делается с помощью свойства `PageSize.PaperName`. Если название известно движку global paper manager, то размеры будут установлены автоматически на основе названия.
70+```
71+p := TFPReportPage.Create(rpt);
72+ p.Orientation := poPortrait;
73+ p.PageSize.PaperName := 'A4';
74+```
75+
76+После того, как было задано название страницы, можно задать поля. Размеры указаны в миллиметрах:
77+```
78+{ поля страницы }
79+ p.Margins.Left := 30;
80+ p.Margins.Top := 20;
81+ p.Margins.Right := 30;
82+ p.Margins.Bottom := 20;
83+```
84+
85+Страница может содержать шрифт. Этот шрифт затем используется по умолчанию для всех полос на странице. Аналогично, все элементы на полосе будут использовать шрифт полосы по умолчанию. Обратите внимание, что название шрифта - это PostScript-название файла шрифтов TTF.
86+```
87+p.Font.Name := 'LiberationSans';
88+```
89+
90+Когда отчет должен быть отрисован, модуль компоновки запустит цикл обработки данных страницы и будет повторять просмотр страницы столько раз, сколько потребуется для соответствия данным.
91+
92+Следовательно, со страницей должен быть связан цикл обработки данных.
93+```
94+p.Data := lReportData;
95+```
96+
97+### Добавление бэндов на страницу
98+
99+Теперь страница должна быть заполнена каким-либо контентом. Это означает добавление нескольких полос на страницу отчета.
100+
101+Заголовок отчета будет напечатан один раз, в начале отчета:
102+```
103+TitleBand := TFPReportTitleBand.Create(p);
104+ TitleBand.Layout.Height := 40;
105+```
106+
107+Ширину полосы задавать не нужно, она рассчитывается автоматически исходя из ширины страницы, количества колонок и полей страницы.
108+
109+Сама по себе полоса не очень полезна, она служит только в качестве заполнителя для некоторых элементов, которые можно распечатать.
110+
111+Для титульной страницы мы добавим простой статический текст в качестве заголовка страницы. Весь текст (динамический или статический) должен быть добавлен с помощью компонента **TFPReportMemo** :
112+```
113+Memo := TFPReportMemo.Create(TitleBand);
114+ Memo.Layout.Left := 5;
115+ Memo.Layout.Top := 0;
116+ Memo.Layout.Width := 140;
117+ Memo.Layout.Height := 15;
118+```
119+
120+Расположение memo относительно полосы и определяет, где она будет размещена.
121+
122+Текст memo и внутреннее форматирование можно задать с помощью свойств **Text** и **TextAlignment** :
123+```
124+Memo.Text := 'Dataset Demo';
125+ Memo.TextAlignment.Vertical := tlCenter;
126+ Memo.TextAlignment.Horizontal := taCentered;
127+```
128+
129+Наконец, можно настроить шрифт и его размер:
130+```
131+Memo.UseParentFont := False;
132+ Memo.Font.Color := TFPReportColor($000080);
133+ Memo.Font.Size := 24;
134+```
135+
136+Цвет имеет значение RRGGBB (красный/зеленый/синий). Поддержка альфа-канала пока недоступна. В модуле FP Report задано несколько предопределенных значений.
137+
138+### Данные цикла
139+
140+Заголовок отчета печатается только один раз, но обычно отчет содержит бэнд, который печатается для каждой записи в цикле отчета. Для этого в отчет необходимо добавить бэнд данных (**TFPReportDataBand**):
141+```
142+DataBand := TFPReportDataBand.Create(p);
143+ DataBand.Layout.Height := 30;
144+ DataBand.Data:= lReportData;
145+```
146+
147+Этот бэнд будет повторяться для каждой записи в цикле обработки данных.
148+
149+Как отмечалось выше, любой текст должен быть напечатан с memo. Это также относится к данным из цикла обработки данных. В следующем memo будет напечатано имя поля из набора данных, дополненное буквальным текстом **"Name: "**
150+```
151+Memo := TFPReportMemo.Create(DataBand);
152+ Memo.Layout.Left := 30;
153+ Memo.Layout.Top := 0;
154+ Memo.Layout.Width := 50;
155+ Memo.Layout.Height := 5;
156+ Memo.Text := 'Name: [name]';
157+```
158+
159+### Выражения
160+
161+Динамический текст получается путем смешивания статического текста и выражений.
162+
163+Выражения - это все, что заключено в квадратные скобки **[]**.
164+
165+
166+Для вычисления данных используется механизм анализа выражений **TFPExpressionParser**.
167+
168+Это означает, что выражения во многом похожи на выражения Pascal. Выражение:
169+
170+ * Типизировано (string, integer, float, datetime)
171+ * может содержать вычисления для этих типов.
172+ * может содержать переменные отчета
173+ * может использовать поля данных из данных отчета
174+ * Может использовать любую из предопределенных функций, доступных в fpexprpars.
175+
176+#### Встроенные переменные
177+
178+Эти переменные создаются во фрипорте и всегда определены
179+
180+ * **[TODAY]**
181+ * **[AUTHOR]**
182+ * **[TITLE]**
183+
184+#### Встроенные выражения
185+
186+Это выражение создается во фрипорте и всегда предопредено
187+
188+ * **[RecNo]**
189+ * **[PageNo]** Фактический номер страницы
190+ * **[PageCount]** Максимальное количество страниц (подсказка: для работы необходимо активировать два прохода)
191+ * **[ColNo]** Фактический столбец
192+ * **[PageNoPerDesignerPage]**
193+ * **[InRepeatedGroupHeader]**
194+ * **[InIntermediateGroupFooter]**
195+ * **[IsOverflowed]**
196+ * **[IsGroupDetailPrinted]**
197+ * **[FieldIsNull]**
198+
199+### Поддержка изображений
200+
201+Если набор данных содержит большое двоичное поле с изображением, то его также можно распечатать:
202+```
203+Image := TFPReportImage.Create(DataBand);
204+ Image.Layout.Top := 0;
205+ Image.Layout.Left := 10;
206+ Image.Layout.Height := 20;
207+ Image.Layout.Width := 14.8;
208+ Image.FieldName := 'Photo';
209+ Image.Stretched := True;
210+```
211+
212+Для этого достаточно присвоить свойству FieldName значение имени поля, содержащего данные изображения.
213+
214+При желании можно также добавить фиксированное изображение:
215+```
216+Image := TFPReportImage.Create(TitleBand);
217+ Image.Layout.Left := 0;
218+ Image.Layout.Top := 0;
219+ Image.Layout.Width := 40;
220+ Image.Layout.Height := 30;
221+ Image.LoadFromFile('company-logo.png');
222+ Image.Stretched := True;
223+```
224+
225+## Запуск отчета
226+
227+Для компоновки отчета можно использовать метод RunReport:
228+```
229+{ укажите, какие каталоги следует использовать для поиска шрифтов TrueType }
230+ gTTFontCache.SearchPath.Add(cFCLReportDemosLocation + '/fonts/');
231+ gTTFontCache.BuildFontCache;
232+
233+ rpt.RunReport;
234+```
235+
236+В результате отчет будет создан в памяти.
237+
238+Он не отображается на экране и не сохраняется в файл.
239+
240+## Визуализация (или экспорт) отчета
241+
242+TO DO [поправить корректность внешней ссылки]
243+
244+Для реального просмотра отчета его необходимо отрисовать или экспортировать. Предварительный просмотр отчета также является экспортом.
245+
246+Существуют различные экспортеры:
247+
248+ * [[PDF]] экспорт
249+ * FPImage экспорт (без субпиксельного рендеринга)
250+ * Экспортер AggPas (субпиксельный рендеринг и сглаживание). Рекомендуется использовать код [AggPas](<https://github.com/graemeg/fpGUI/tree/develop/src/corelib/render/software>), содержащийся в репозитории кода [[fpGUI]].
251+ * HTML экспорт
252+ * LCL canvas экспорт, используемый в качестве основы для предварительного просмотра LCL
253+ * [[fpGUI]] canvas экспорт, используется в качестве основы для экспортера предварительного просмотра fpGUI
254+
255+Таким образом, предварительный просмотр или сохранение макета отчета - это всего лишь вопрос создания правильного экспорта и вызова метода отчета **RenderReport** :
256+```
257+RptExporter := TFPReportExportPDF.Create(nil); // как и прежде, используйте Self или Nil в зависимости от класса приложения
258+ rpt.RenderReport(RptExporter);
259+```
260+
261+## Полный пример кода
262+
263+### Требования
264+
265+Этот пример может быть скомпилирован с помощью FPC 2.6.4 или более поздней версии.
266+
267+Для компиляции этого кода вам необходимо указать следующие пути поиска модулей:
268+
269+ * /data/devel/fpc-3.1.1/src/packages/fcl-report/src/
270+ * ../../fpgui/src/fpreport
271+ * ../../fpgui/src/corelib/render/software
272+
273+Первый путь поиска - это каталог **fcl-report** из транка FPC.
274+
275+Второй путь поиска (необязательный) - это путь к экспортеру AggPas, как определено в репозитории кода [[fpGUI]].
276+
277+Третий путь поиска (необязательный) - к исходному коду библиотеки AggPas, который находится в репозитории кода fpGUI.
278+
279+Вам также необходимо убедиться, что константа **cFCLReportDemosLocation** , определенная в исходном коде, указывает на правильный каталог fcl-report/demo/, который находится в вашей собственной системе.
280+
281+### Исходный код
282+```
283+program project1;
284+
285+ {$mode objfpc}{$H+}
286+
287+ { Какой экспортер вы хотите использовать. Выберите любой из них или все. Если вы включили AggPas
288+ экспортер, не забудьте добавить дополнительные пути поиска объектов в настройки вашего проекта. }
289+ {$define ExportPDF}
290+ {$define ExportFPImage}
291+ {$define ExportAggPas}
292+
293+ uses
294+ SysUtils
295+ ,fpreport // для большинства классов FPReport
296+ ,dbf // для доступа к DBF (базе данных)
297+ ,fpreportdb // для класса TFPReportDatasetData
298+ ,fpttf // для доступа к gTTFontCache singleton
299+ {$IFDEF ExportPDF}
300+ ,fpreportpdfexport // для доступа к классу экспорта отчетов в формате PDF
301+ {$ENDIF}
302+ {$IFDEF ExportAggPas}
303+ ,fpreport_export_aggpas // для доступа к классу экспорта fpReport AggPas в fpGUI
304+ {$ENDIF}
305+ {$IFDEF ExportFPImage}
306+ ,fpreportfpimageexport // для доступа к классу FP Image exporter
307+ {$ENDIF}
308+ ;
309+
310+ const
311+ cFCLReportDemosLocation = '/data/devel/fpc-3.1.1/src/packages/fcl-report/demos/';
312+
313+ var
314+ rpt: TFPReport;
315+ lDataSet: TDBF;
316+ lReportData: TFPReportDatasetData;
317+ p: TFPReportPage;
318+ TitleBand: TFPReportTitleBand;
319+ Memo: TFPReportMemo;
320+ DataBand: TFPReportDataBand;
321+ Image: TFPReportImage;
322+ RptExporter: TFPReportExporter;
323+ begin
324+ RptExporter := nil;
325+ if not FileExists(cFCLReportDemosLocation + 'test.dbf') then
326+ begin
327+ writeln('Не удается найти файл базы данных <' + cFCLReportDemosLocation + 'test.dbf>');
328+ writeln('Пожалуйста, запустите демо набора данных fcl-report хотя бы один раз.');
329+ writeln('');
330+ exit;
331+ end;
332+
333+ // ***** Создание отчета *****
334+ PaperManager.RegisterStandardSizes;
335+ rpt:=TFPReport.Create(nil);
336+ rpt.Author := 'Graeme Geldenhuys';
337+ rpt.Title := 'FPReport Demo 8 - Datasets';
338+ try
339+ // ***** Предоставление данных для отчета *****
340+ lReportData := TFPReportDatasetData.Create(nil);
341+ lDataSet := TDBF.Create(nil);
342+ lDataSet.TableName := cFCLReportDemosLocation + 'test.dbf';
343+ lReportData.DataSet := lDataSet;
344+
345+ // ***** Добавление страницы *****
346+ p := TFPReportPage.Create(rpt);
347+ p.Orientation := poPortrait;
348+ p.PageSize.PaperName := 'A4';
349+
350+ { поля страницы }
351+ p.Margins.Left := 30;
352+ p.Margins.Top := 20;
353+ p.Margins.Right := 30;
354+ p.Margins.Bottom := 20;
355+
356+ { шрифт страницы по умолчанию }
357+ p.Font.Name := 'LiberationSans'; // это название шрифта TTF в формате PostScript
358+
359+ { назначение данных для цикла обработки данных страницы }
360+ p.Data := lReportData;
361+
362+ // ***** Добавление бэндов на страницу *****
363+ TitleBand := TFPReportTitleBand.Create(p);
364+ TitleBand.Layout.Height := 40;
365+ // TitleBand.Frame.Shape := fsRectangle;
366+ // TitleBand.Frame.BackgroundColor := clYellow;
367+
368+ Memo := TFPReportMemo.Create(TitleBand);
369+ Memo.Layout.Left := 5;
370+ Memo.Layout.Top := 0;
371+ Memo.Layout.Width := 140;
372+ Memo.Layout.Height := 15;
373+
374+ Memo.Text := 'Dataset Demo';
375+ Memo.TextAlignment.Vertical := tlCenter;
376+ Memo.TextAlignment.Horizontal := taCentered;
377+
378+ Memo.UseParentFont := False;
379+ Memo.Font.Color := TFPReportColor($000080);
380+ Memo.Font.Size := 24;
381+
382+ // ***** The loop data *****
383+ DataBand := TFPReportDataBand.Create(p);
384+ DataBand.Layout.Height := 30;
385+ DataBand.Data:= lReportData;
386+ // DataBand.Frame.Shape := fsRectangle;
387+ // DataBand.Frame.BackgroundColor := clCream;
388+
389+ Memo := TFPReportMemo.Create(DataBand);
390+ Memo.Layout.Left := 30;
391+ Memo.Layout.Top := 0;
392+ Memo.Layout.Width := 50;
393+ Memo.Layout.Height := 5;
394+ Memo.Text := 'Name: [name]';
395+
396+ // ***** Поддержка изображений *****
397+ Image := TFPReportImage.Create(DataBand);
398+ Image.Layout.Top := 0;
399+ Image.Layout.Left := 10;
400+ Image.Layout.Height := 20;
401+ Image.Layout.Width := 14.8;
402+ Image.FieldName := 'Photo';
403+ Image.Stretched := True;
404+
405+ Image := TFPReportImage.Create(TitleBand); // обратите внимание, что это изображение размещено на титульной полосе
406+ Image.Layout.Left := 0;
407+ Image.Layout.Top := 0;
408+ Image.Layout.Width := 40;
409+ Image.Layout.Height := 30;
410+ Image.LoadFromFile(cFCLReportDemosLocation + 'pictures/woman01.png');
411+ Image.Stretched := True;
412+
413+ // ***** Запуск отчета *****
414+ { укажите, какие каталоги следует использовать для поиска шрифтов TrueType }
415+ gTTFontCache.SearchPath.Add(cFCLReportDemosLocation + '/fonts/');
416+ gTTFontCache.BuildFontCache;
417+
418+ rpt.RunReport;
419+
420+ // ***** Визуализация (или экспорт) отчета *****
421+ {$IFDEF ExportPDF}
422+ if Assigned(RptExporter) then
423+ FreeAndNil(RptExporter);
424+ RptExporter := TFPReportExportPDF.Create(nil);
425+ rpt.RenderReport(RptExporter);
426+ {$ENDIF}
427+ {$IFDEF ExportAggPas}
428+ if Assigned(RptExporter) then
429+ FreeAndNil(RptExporter);
430+ RptExporter := TFPReportExportAggPas.Create(nil);
431+ TFPReportExportAggPas(RptExporter).BaseFileName := ApplicationName + '-aggpas-%.2d.png';
432+ rpt.RenderReport(RptExporter);
433+ {$ENDIF}
434+ {$IFDEF ExportFPImage}
435+ if Assigned(RptExporter) then
436+ FreeAndNil(RptExporter);
437+ RptExporter := TFPReportExportfpImage.Create(nil);
438+ TFPReportExportfpImage(RptExporter).BaseFileName := ApplicationName + '-fpimage-.png';
439+ rpt.RenderReport(RptExporter);
440+ {$ENDIF}
441+
442+ finally
443+ // Freeing all objects we used
444+ FreeAndNil(RptExporter);
445+ FreeAndNil(rpt);
446+ FreeAndNil(lReportData);
447+ FreeAndNil(lDataset);
448+ end;
449+ end.
450+```
451+
452+## Загрузка и сохранение отчета из/в файла
453+
454+Как объяснено на вводной странице [[FPReport]], класс **TFPReport** сам по себе не имеет понятия о файлах. Он знает только стример (**TFPReportStreamer**). FPC предоставляет JSON-стример **TFPReportJSONStreamer** , есть также более старый XML-стример, который в настоящее время не тестировался.
455+
456+### Загрузка и сохранение вручную
457+
458+В следующем коде показано, как использовать стример отчетов TFP в формате JSON для сохранения отчета в файл:
459+```
460+Var
461+ J : TFPReportJSONStreamer;
462+ F : TFileStream;
463+ S : TJSONStringType;
464+ begin
465+ F:=Nil;
466+ J:=TFPReportJSONStreamer.Create(Self);
467+ try
468+ FReport.WriteElement(J);
469+ F:=TFileStream.Create('txt2pdf.fpr',fmCreate);
470+ S:=J.JSON.FormatJSON();
471+ F.WriteBuffer(S[1],Length(S));
472+ finally
473+ F.Free;
474+ J.Free;
475+ end;
476+ end;
477+```
478+
479+И следующий код загружает его снова из файла:
480+```
481+procedure TPrintApplication.LoadReportDesign;
482+
483+ Var
484+ J : TFPReportJSONStreamer;
485+ F : TFileStream;
486+ O : TJSONObject;
487+
488+ begin
489+ J:=Nil;
490+ F:=TFileStream.Create('txt2pdf.fpr',fmOpenRead);
491+ try
492+ O:=GetJSON(F) as TJSONObject;
493+ J:=TFPReportJSONStreamer.Create(Self);
494+ J.JSON:=O;
495+ J.OwnsJSON:=True;
496+ FReport.ReadElement(J);
497+ finally
498+ F.Free;
499+ J.Free;
500+ end;
501+ end;
502+```
503+
504+### Самый простой способ: использовать TFPJSONReport
505+
506+Модуль _fpjsonreport_ содержит класс **TFPJSONReport**. Он объединяет стример JSON и отчет TFP и упрощает его загрузку/сохранение. Модуль _fpjsonreport_ содержит потомка **TFPJSONReport** , который выполняет все вышеперечисленное с помощью нескольких простых методов:
507+```
508+TFPJSONReport = class(TFPReport)
509+ procedure LoadFromStream(const aStream: TStream);
510+ procedure SaveToStream(const aStream: TStream);
511+ Procedure LoadFromJSON(aJSON : TJSONObject); virtual;
512+ Procedure SavetoJSON(aJSON : TJSONObject); virtual;
513+ Procedure LoadFromFile(const aFileName : String);
514+ Procedure SaveToFile(const aFileName : String);
515+ Property DataManager : TFPCustomReportDataManager;
516+ end;
517+```
518+
519+Он также может сохранять дизайн в формате JSON в файле lazarus.lfm, поэтому, если вы хотите использовать отчет, в котором информация о дизайне хранится в файле .lfm, используйте **TJSONFPReport** в lazarus.
520+
521+### Управление данными
522+
523+Класс **TFPReportDataManager** может использоваться для создания наборов данных и управления ими на основе определений, найденных в файле JSON, созданном автономным разработчиком.
524+
525+(на самом деле автономный разработчик использует **TFPReportDataManager** для управления своими данными).
526+
527+Когда вы используете **TFPJSONReport** , вы можете присвоить его свойству **DataManager** значение экземпляра **TFPReportDataManager**.
528+
529+При загрузке/сохранении данных он будет использовать диспетчер данных для добавления и/или интерпретации дополнительной информации в JSON-файле отчета для создания наборов данных.
530+
531+Если набор данных не открывается по какой-либо причине (нет подключения к базе данных или по другим причинам), свойство **LoadErrors** (типа **TStrings**) будет содержать сообщения об ошибках.
532+
533+Менеджер данных использует движок для создания необходимых наборов данных. Для этого в исполняемом файле должны быть зарегистрированы обработчики. Доступны следующие модули с обработчиками данных:
534+
535+ * **fpreportdatacsv** для поддержки CSV.
536+ * **fpreportdatadbf** для поддержки dbf.
537+ * **fpreportdatajson** для поддержки файла данных JSON.
538+ * **fpreportdatasqldb** для поддержки SQLDB.
539+
540+You must make sure to include the units for the data formats that you need in your project file. If you fail to do so, you will get errors saying that an unknown data type is used.
541+
542+Вы должны убедиться, что в вашем файле проекта указаны модули для нужных вам форматов данных. Если вы этого не сделаете, вы получите сообщение об ошибке, указывающее на то, что используется неизвестный тип данных.
543+
544+## Вернуться на главную страницу FP Report
545+
546+ * [[FPReport/ru|FPReport]]
547+
548+---
549+*From the Free Pascal wiki, page "FPReport Usage/ru", as the Internet Archive kept it on 2025-04-29, last changed on 2025-03-01. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history