rptmasterdetail.pp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. unit rptmasterdetail;
  2. {$mode objfpc}{$H+}
  3. {$I demos.inc}
  4. interface
  5. uses
  6. Classes,
  7. SysUtils,
  8. fpreport,
  9. udapp;
  10. type
  11. { TMasterDetailDemo }
  12. TMasterDetailDemo = class(TReportDemoApp)
  13. private
  14. FMasterData: TFPReportUserData;
  15. FDetailData: TFPReportUserData;
  16. FDetail2Data: TFPReportUserData;
  17. FMasterNo: Integer;
  18. FDetailNo: Integer;
  19. FDetail2No: Integer;
  20. procedure MasterDataFirst(Sender: TObject);
  21. procedure MasterDataGetValue(Sender: TObject; const AValueName: String; var AValue: Variant);
  22. procedure MasterDataEOF(Sender: TObject; var IsEOF: Boolean);
  23. procedure MasterDataNext(Sender: TObject);
  24. procedure DetailDataFirst(Sender: TObject);
  25. procedure DetailDataGetValue(Sender: TObject; const AValueName: string; var AValue: variant);
  26. procedure DetailDataEOF(Sender: TObject; var IsEOF: Boolean);
  27. procedure DetailDataNext(Sender: TObject);
  28. procedure Detail2DataFirst(Sender: TObject);
  29. procedure Detail2DataGetValue(Sender: TObject; const AValueName: string; var AValue: variant);
  30. procedure Detail2DataEOF(Sender: TObject; var IsEOF: Boolean);
  31. procedure Detail2DataNext(Sender: TObject);
  32. Public
  33. procedure CreateReportDesign; override;
  34. procedure MasterDataGetNames(Sender: TObject; List: TStrings);
  35. procedure DetailDataGetNames(Sender: TObject; List: TStrings);
  36. procedure Detail2DataGetNames(Sender: TObject; List: TStrings);
  37. public
  38. constructor Create(AOwner : TComponent); override;
  39. destructor Destroy; override;
  40. Class function Description : string; override;
  41. end;
  42. implementation
  43. uses
  44. fpTTF;
  45. { Our user defined data stored in arrays. }
  46. const
  47. Master: array[1..3, 1..2] of String = ( // master ID, master name
  48. ('1', 'master 1'),
  49. ('2', 'master 2'),
  50. ('3', 'master 3'));
  51. Detail: array[1..12, 1..2] of String = ( // master ID, detail name
  52. ('1', 'detail 1.1'), ('1', 'detail 1.2'), ('1', 'detail 1.3'),
  53. ('1', 'detail 1.4'), ('1', 'detail 1.5'),
  54. ('2', 'detail 2.1'), ('2', 'detail 2.2'), ('2', 'detail 2.3'),
  55. ('3', 'detail 3.1'), ('3', 'detail 3.2'), ('3', 'detail 3.3'),
  56. ('3', 'detail 3.4'));
  57. D2: array[1..4, 1..2] of String = ( // detail #1 name, detail #2 name
  58. ('detail 1.2', 'detail 1.2.1'),
  59. ('detail 1.4', 'detail 1.4.1'),
  60. ('detail 1.4', 'detail 1.4.2'),
  61. ('detail 2.2', 'detail 2.2.1'));
  62. { TMasterDetailDemo }
  63. procedure TMasterDetailDemo.MasterDataFirst(Sender: TObject);
  64. begin
  65. {$IFDEF gdebug}
  66. writeln('MasterDataFirst');
  67. {$ENDIF}
  68. FMasterNo := 1;
  69. end;
  70. procedure TMasterDetailDemo.MasterDataGetValue(Sender: TObject; const AValueName: String; var AValue: Variant);
  71. begin
  72. {$IFDEF gdebug}
  73. writeln(Format('MasterDataGetValue - %d', [FMasterData.RecNo]));
  74. {$ENDIF}
  75. if AValueName = 'mastername' then
  76. AValue := Master[FMasterNo][2];
  77. end;
  78. procedure TMasterDetailDemo.MasterDataEOF(Sender: TObject; var IsEOF: Boolean);
  79. begin
  80. {$IFDEF gdebug}
  81. writeln(Format('MasterDataEOF - %d', [FMasterData.RecNo]));
  82. {$ENDIF}
  83. IsEOF := FMasterNo > High(Master);
  84. end;
  85. procedure TMasterDetailDemo.MasterDataNext(Sender: TObject);
  86. begin
  87. Inc(FMasterNo);
  88. end;
  89. procedure TMasterDetailDemo.DetailDataFirst(Sender: TObject);
  90. begin
  91. {$IFDEF gdebug}
  92. writeln('DetailDataFirst');
  93. {$ENDIF}
  94. FDetailNo := 1;
  95. while (not FDetailData.EOF) and (Detail[FDetailNo][1] <> Master[FMasterNo][1]) do
  96. Inc(FDetailNo);
  97. end;
  98. procedure TMasterDetailDemo.DetailDataGetValue(Sender: TObject; const AValueName: string; var AValue: variant);
  99. begin
  100. {$IFDEF gdebug}
  101. writeln('DetailDataGetValue');
  102. {$ENDIF}
  103. if AValueName = 'detailname' then
  104. AValue := Detail[FDetailNo][2];
  105. end;
  106. procedure TMasterDetailDemo.DetailDataEOF(Sender: TObject; var IsEOF: Boolean);
  107. begin
  108. {$IFDEF gdebug}
  109. writeln('DetailDataEOF');
  110. {$ENDIF}
  111. IsEOF := FDetailNo > High(Detail);
  112. end;
  113. procedure TMasterDetailDemo.DetailDataNext(Sender: TObject);
  114. begin
  115. Inc(FDetailNo);
  116. while (not FDetailData.EOF) and (Detail[FDetailNo][1] <> Master[FMasterNo][1]) do
  117. Inc(FDetailNo);
  118. end;
  119. procedure TMasterDetailDemo.Detail2DataFirst(Sender: TObject);
  120. begin
  121. FDetail2No := 1;
  122. while (not FDetail2Data.EOF) and (D2[FDetail2No][1] <> Detail[FDetailNo][2]) do
  123. Inc(FDetail2No);
  124. end;
  125. procedure TMasterDetailDemo.Detail2DataGetValue(Sender: TObject; const AValueName: string; var AValue: variant);
  126. begin
  127. if AValueName = 'detail2name' then
  128. AValue := D2[FDetail2No][2]
  129. end;
  130. procedure TMasterDetailDemo.Detail2DataEOF(Sender: TObject; var IsEOF: Boolean);
  131. begin
  132. IsEOF := FDetail2No > High(D2);
  133. end;
  134. procedure TMasterDetailDemo.Detail2DataNext(Sender: TObject);
  135. begin
  136. Inc(FDetail2No);
  137. while (not FDetail2Data.EOF) and (D2[FDetail2No][1] <> Detail[FDetailNo][2]) do
  138. Inc(FDetail2No);
  139. end;
  140. procedure TMasterDetailDemo.CreateReportDesign;
  141. var
  142. p: TFPReportPage;
  143. TitleBand: TFPReportTitleBand;
  144. MasterDataBand: TFPReportDataBand;
  145. DetailDataBand: TFPReportDataBand;
  146. Detail2DataBand: TFPReportDataBand;
  147. Memo: TFPReportMemo;
  148. begin
  149. Inherited;
  150. rpt.Author := 'Graeme Geldenhuys';
  151. rpt.Title := 'FPReport Demo 10 - Master/Detail using userdata';
  152. p := TFPReportPage.Create(rpt);
  153. p.Orientation := poPortrait;
  154. p.PageSize.PaperName := 'A4';
  155. { page margins }
  156. p.Margins.Left := 30;
  157. p.Margins.Top := 20;
  158. p.Margins.Right := 30;
  159. p.Margins.Bottom := 20;
  160. p.Data := FMasterData;
  161. p.Font.Name := 'LiberationSans';
  162. TitleBand := TFPReportTitleBand.Create(p);
  163. TitleBand.Layout.Height := 20;
  164. {$ifdef ColorBands}
  165. TitleBand.Frame.Shape := fsRectangle;
  166. TitleBand.Frame.BackgroundColor := clReportTitleSummary;
  167. {$endif}
  168. Memo := TFPReportMemo.Create(TitleBand);
  169. Memo.Layout.Left := 0;
  170. Memo.Layout.Top := 0;
  171. Memo.Layout.Width := TitleBand.Layout.Width;
  172. Memo.Layout.Height := 15;
  173. Memo.UseParentFont := False;
  174. Memo.Font.Name := 'LiberationSans-Bold';
  175. Memo.Font.Size := 18;
  176. Memo.Text := 'FPReport Demo 10' + LineEnding + 'Master/Detail using userdata';
  177. Memo.TextAlignment.Vertical := tlCenter;
  178. Memo.TextAlignment.Horizontal := taCentered;
  179. MasterDataBand := TFPReportDataBand.Create(p);
  180. MasterDataBand.Layout.Height := 8;
  181. {$ifdef ColorBands}
  182. MasterDataBand.Frame.Shape := fsRectangle;
  183. MasterDataBand.Frame.BackgroundColor := clDataBand;
  184. {$endif}
  185. Memo := TFPReportMemo.Create(MasterDataBand);
  186. Memo.Layout.Left := 5;
  187. Memo.Layout.Top := 0;
  188. Memo.Layout.Width := 50;
  189. Memo.Layout.Height := 5;
  190. Memo.Text := '[mastername]';
  191. Memo.TextAlignment.Vertical := tlCenter;
  192. Memo.Frame.Shape := fsRectangle;
  193. Memo.Frame.BackgroundColor := clLtGray;
  194. DetailDataBand := TFPReportDataBand.Create(p);
  195. DetailDataBand.Layout.Height := 8;
  196. DetailDataBand.Data := FDetailData;
  197. {$ifdef ColorBands}
  198. DetailDataBand.Frame.Shape := fsRectangle;
  199. DetailDataBand.Frame.BackgroundColor := clChildBand;
  200. {$endif}
  201. { associate with Master band }
  202. DetailDataBand.MasterBand := MasterDataBand;
  203. Memo := TFPReportMemo.Create(DetailDataBand);
  204. Memo.Layout.Left := 15;
  205. Memo.Layout.Top := 0;
  206. Memo.Layout.Width := 40;
  207. Memo.Layout.Height := 5;
  208. Memo.Text := '[detailname]';
  209. Memo.TextAlignment.Vertical := tlCenter;
  210. Memo.Frame.Shape := fsRectangle;
  211. Memo.Frame.Color := clBlack;
  212. Detail2DataBand := TFPReportDataBand.Create(p);
  213. Detail2DataBand.Layout.Height := 8;
  214. Detail2DataBand.Data := FDetail2Data;
  215. {$ifdef ColorBands}
  216. Detail2DataBand.Frame.Shape := fsRectangle;
  217. Detail2DataBand.Frame.BackgroundColor := TFPReportColor($FFFFA9);
  218. {$endif}
  219. { associate with Master band }
  220. Detail2DataBand.MasterBand := DetailDataBand;
  221. Memo := TFPReportMemo.Create(Detail2DataBand);
  222. Memo.Layout.Left := 30;
  223. Memo.Layout.Top := 0;
  224. Memo.Layout.Width := 40;
  225. Memo.Layout.Height := 5;
  226. Memo.Text := '[detail2name]';
  227. Memo.TextAlignment.Vertical := tlCenter;
  228. Memo.Frame.Shape := fsRectangle;
  229. Memo.Frame.Color := clNavy;
  230. end;
  231. procedure TMasterDetailDemo.MasterDataGetNames(Sender: TObject; List: TStrings);
  232. begin
  233. List.Add('mastername');
  234. end;
  235. procedure TMasterDetailDemo.DetailDataGetNames(Sender: TObject; List: TStrings);
  236. begin
  237. List.Add('detailname');
  238. end;
  239. procedure TMasterDetailDemo.Detail2DataGetNames(Sender: TObject; List: TStrings);
  240. begin
  241. List.Add('detail2name');
  242. end;
  243. constructor TMasterDetailDemo.Create(AOwner : TComponent);
  244. begin
  245. Inherited;
  246. FMasterData := TFPReportUserData.Create(nil);
  247. FMasterData.OnGetValue := @MasterDataGetValue;
  248. FMasterData.OnGetEOF := @MasterDataEOF;
  249. FMasterData.OnFirst := @MasterDataFirst;
  250. FMasterData.OnNext := @MasterDataNext;
  251. FMasterData.OnGetNames := @MasterDataGetNames;
  252. FDetailData := TFPReportUserData.Create(nil);
  253. FDetailData.OnGetValue := @DetailDataGetValue;
  254. FDetailData.OnGetEOF := @DetailDataEOF;
  255. FDetailData.OnFirst := @DetailDataFirst;
  256. FDetailData.OnNext := @DetailDataNext;
  257. FDetailData.OnGetNames := @DetailDataGetNames;
  258. FDetail2Data := TFPReportUserData.Create(nil);
  259. FDetail2Data.OnGetValue := @Detail2DataGetValue;
  260. FDetail2Data.OnGetEOF := @Detail2DataEOF;
  261. FDetail2Data.OnFirst := @Detail2DataFirst;
  262. FDetail2Data.OnNext := @Detail2DataNext;
  263. FDetail2Data.OnGetNames := @Detail2DataGetNames;
  264. end;
  265. destructor TMasterDetailDemo.Destroy;
  266. begin
  267. FreeAndNil(FMasterData);
  268. FreeAndNil(FDetailData);
  269. FreeAndNil(FDetail2Data);
  270. inherited Destroy;
  271. end;
  272. class function TMasterDetailDemo.Description: string;
  273. begin
  274. Result:='Demo of Master/Detail data loop support';
  275. end;
  276. end.