ScReportDM.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. {*******************************************************************************
  2. 单元名称: ScReportDM.pas
  3. 单元说明: 报表数据源
  4. 备注:ItemKind: 预清单1,清清单2,图纸工程量3,用于排序、过滤。
  5. 创建一张临时表,所有报表数据都从这张临时表用SQL语句查得。
  6. 表1:分项工程量清单:全部数据,预算项目节、清单子目号、图纸工程量。
  7. 表2-1:工程项目清单:汇总项目的软件上部分看到的预、清(即不含图)。
  8. 表2-2:工程项目清单(带细目):汇总项目的分项工程量清单。即先汇总生成另外一个项目,再分项工程量清单。
  9. 表3-1:工程量清单:清单子目号级清单汇总,不含图纸工程量(即去掉预部分,只要清部分,且汇总)。
  10. 表3-2:工程量清单(带细目):清单子目号级清单汇总,含图纸工程量。
  11. 其中,表2-1、表2-2,已经脱离了自身,操作另外一个项目。
  12. 作者时间: Chenshilong, 2011-01-07 18:20:56
  13. *******************************************************************************}
  14. unit ScReportDM;
  15. interface
  16. uses
  17. SysUtils, Classes, DB, ADODB, DBClient;
  18. type
  19. TReportData = class(TDataModule)
  20. cdsProjData: TClientDataSet;
  21. aqSQL: TADOQuery;
  22. cdsProjDataBuildProjectID: TIntegerField;
  23. cdsProjDataBuildProjectName: TWideStringField;
  24. cdsProjDataProjectLocation: TWideStringField;
  25. cdsProjDataBuildUnit: TWideStringField;
  26. cdsProjDataAuthorUnit: TWideStringField;
  27. cdsProjDataBidder: TWideStringField;
  28. cdsProjDataAuthor: TWideStringField;
  29. cdsProjDataAuthorCertificate: TWideStringField;
  30. cdsProjDataAuditor: TWideStringField;
  31. cdsProjDataAuditorCertificate: TWideStringField;
  32. cdsProjDataBudgetProjectName: TWideStringField;
  33. cdsProjDataEditRange: TWideStringField;
  34. cdsProjDataEditDate: TDateTimeField;
  35. cdsProjDataMachineBBFeeRate: TFloatField;
  36. cdsProjDataFZFeeRate: TFloatField;
  37. cdsProjDataIsCalcGYFeeRate: TBooleanField;
  38. cdsProjDataRoadLength: TFloatField;
  39. cdsProjDataAvgMaintMonth: TFloatField;
  40. cdsProjDataRoadClass: TIntegerField;
  41. cdsProjDataIsNew: TBooleanField;
  42. cdsProjDataLandForm: TIntegerField;
  43. cdsProjDataDJZG: TFloatField;
  44. cdsProjDataYJZG: TFloatField;
  45. cdsProjDataNightZG: TFloatField;
  46. cdsProjDataRaiseRateByYear: TFloatField;
  47. cdsProjDataRaiseYear: TFloatField;
  48. cdsProjDataBuildManageFeeFile: TIntegerField;
  49. private
  50. FProject: TObject;
  51. FFirstGetData: Boolean;
  52. FConnection: TADOConnection;
  53. procedure SetProject(const Value: TObject);
  54. function GetReportPath: string;
  55. // procedure CreateReportTempTab;
  56. public
  57. { Public declarations }
  58. // function GetReportData(AReportName: string): Boolean;
  59. constructor Create(AOwner: TComponent); override;
  60. procedure RefreshData;
  61. property Project: TObject read FProject write SetProject;
  62. property ReportPath: string read GetReportPath;
  63. property FirstGetData: Boolean read FFirstGetData write FFirstGetData;
  64. property Connection: TADOConnection read FConnection write FConnection;
  65. end;
  66. implementation
  67. uses ScProjectManager, Forms, DataBase, ScProgressFrm;
  68. {$R *.dfm}
  69. constructor TReportData.Create(AOwner: TComponent);
  70. begin
  71. inherited;
  72. FirstGetData := True;
  73. end;
  74. function TReportData.GetReportPath: string;
  75. begin
  76. Result := ExtractFilePath(Application.ExeName) + 'BillsEditorReports\';
  77. end;
  78. procedure TReportData.SetProject(const Value: TObject);
  79. begin
  80. FProject := Value;
  81. cdsProjData.CloneCursor(TProject(FProject).ProjPropertyDM.cdsProjData, True);
  82. FConnection := TProject(FProject).Connection;
  83. aqSQL.Connection := FConnection;
  84. end;
  85. { 速度太慢,取消临时表机制 // chenshilong, 2011-11-08
  86. procedure TReportData.CreateReportTempTab;
  87. const
  88. sName: String = 'ReportTempTab';
  89. var i: Integer;
  90. function IsExist(ATabName: string): Boolean;
  91. var vSL: TStringList;
  92. begin
  93. vSL := TStringList.Create;
  94. try
  95. FConnection.GetTableNames(vSL);
  96. if vSL.IndexOf(ATabName) < 0 then
  97. Result := False
  98. else
  99. Result := True;
  100. finally
  101. vSL.Free;
  102. end;
  103. end;
  104. begin
  105. i := 0;
  106. with TProject(FProject).BillsData do
  107. CreateProgressForm(cdsBills.RecordCount + cdsDrawingQuantity.RecordCount);
  108. try
  109. if IsExist(sName) then
  110. begin
  111. aqSQL.SQL.Clear;
  112. aqSQL.SQL.Add('Drop Table ' + sName);
  113. aqSQL.ExecSQL;
  114. end;
  115. RefreshProgressForm('正在创建临时表……');
  116. aqSQL.SQL.Clear;
  117. aqSQL.SQL.Add(Format('Create Table %s (ID Integer, SerialNo Integer, ItemKind Integer, '
  118. + 'OrderNo Integer, Code Text(255), B_Code Text(255), Name Text(255), '
  119. + 'Units Text (50), Quantity Double, UnitPrice Double, TotalPrice Double, '
  120. + 'DesignQuantity Double, DesignQuantity2 Double, '
  121. + 'MemoStr Text (255), B_CodeAlpha Text (255))', [sName]));
  122. aqSQL.ExecSQL;
  123. aqSQL.SQL.Clear;
  124. aqSQL.SQL.Add('Select * From ' + sName);
  125. aqSQL.Open;
  126. RefreshProgressForm('正在生成临时表数据:');
  127. with TProject(FProject).BillsData do
  128. begin
  129. cdsBills.First;
  130. while not cdsBills.Eof do
  131. begin
  132. aqSQL.Append;
  133. aqSQL.FieldByName('ID').AsInteger := cdsBillsID.AsInteger;
  134. aqSQL.FieldByName('SerialNo').AsInteger := cdsBillsSerialNo.AsInteger;
  135. // ItemKind: 预清单1,清清单2,图纸工程量3,用于排序、过滤
  136. if Trim(cdsBillsB_Code.AsString) <> '' then
  137. begin
  138. aqSQL.FieldByName('ItemKind').AsInteger := 2;
  139. // BCodeAlpha字段用于报表3-2:工程量清单(带细目).fr3。作用是统计后按这个字段排序
  140. aqSQL.FieldByName('B_CodeAlpha').AsString := FormatBCodeAlpha(cdsBillsB_Code.AsString);
  141. end
  142. else
  143. aqSQL.FieldByName('ItemKind').AsInteger := 1;
  144. // OrderNo:排序字段,图纸工程量之间有先后排序
  145. aqSQL.FieldByName('OrderNo').AsInteger := 0;
  146. aqSQL.FieldByName('Code').AsString := cdsBillsCode.AsString;
  147. aqSQL.FieldByName('B_Code').AsString := cdsBillsB_Code.AsString;
  148. aqSQL.FieldByName('Name').AsString := cdsBillsName.AsString;
  149. aqSQL.FieldByName('Units').AsString := cdsBillsUnits.AsString;
  150. aqSQL.FieldByName('Quantity').AsCurrency := cdsBillsQuantity.AsCurrency;
  151. aqSQL.FieldByName('DesignQuantity').AsCurrency := cdsBillsDesignQuantity.AsCurrency;
  152. aqSQL.FieldByName('DesignQuantity2').AsCurrency := cdsBillsDesignQuantity2.AsCurrency;
  153. aqSQL.FieldByName('UnitPrice').AsCurrency := cdsBillsUnitPrice.AsCurrency;
  154. aqSQL.FieldByName('TotalPrice').AsCurrency := cdsBillsTotalPrice.AsCurrency;
  155. aqSQL.FieldByName('MemoStr').AsString := cdsBillsMemoStr.AsString;
  156. aqSQL.Post;
  157. Inc(i);
  158. AddProgressForm(1, '正在生成临时表数据:' + IntToStr(i));
  159. cdsBills.Next;
  160. end;
  161. cdsDrawingQuantity.First;
  162. while not cdsDrawingQuantity.Eof do
  163. begin
  164. aqSQL.Append;
  165. if cdsBillsLookup.Locate('ID', cdsDrawingQuantityBillsID.AsInteger, []) then
  166. begin
  167. // 图纸工程量的SerialNo取所属清单的SerialNo,以保证能和清单排在一起。
  168. aqSQL.FieldByName('SerialNo').AsInteger := cdsBillsLookupSerialNo.AsInteger;
  169. aqSQL.FieldByName('B_CodeAlpha').AsString := FormatBCodeAlpha(cdsBillsLookupB_Code.AsString);
  170. end;
  171. aqSQL.FieldByName('ItemKind').AsInteger := 3;
  172. aqSQL.FieldByName('OrderNo').AsInteger := cdsDrawingQuantitySerinalNo.AsInteger;
  173. aqSQL.FieldByName('Name').AsString := cdsDrawingQuantityName.AsString;
  174. aqSQL.FieldByName('Units').AsString := cdsDrawingQuantityUnits.AsString;
  175. aqSQL.FieldByName('Quantity').AsCurrency := 0;
  176. aqSQL.FieldByName('DesignQuantity').AsCurrency := cdsDrawingQuantityDQuantity1.AsCurrency;
  177. aqSQL.FieldByName('DesignQuantity2').AsCurrency := cdsDrawingQuantityDQuantity2.AsCurrency;
  178. aqSQL.Post;
  179. Inc(i);
  180. AddProgressForm(1, '正在生成临时表数据:' + IntToStr(i));
  181. cdsDrawingQuantity.Next;
  182. end;
  183. end;
  184. finally
  185. CloseProgressForm;
  186. end;
  187. end; }
  188. {
  189. function TReportData.GetReportData(AReportName: string): Boolean;
  190. var sSQL: string;
  191. procedure ExecSQL(ASQL: string);
  192. begin
  193. aqReport.Close;
  194. aqReport.SQL.Clear;
  195. aqReport.SQL.Add(ASQL);
  196. aqReport.Open;
  197. end;
  198. begin
  199. Result := False;
  200. // 这里加冒号判断是因为防止“表1-2”匹配“表1”等类似的情况
  201. // 表1:分项工程量清单.fr3, 表2-2:工程项目清单(带细目).fr3
  202. if (Pos('表1:', AReportName) > 0) or (Pos('表2-2:', AReportName) > 0) then
  203. sSQL := 'select * from ReportTempTab order by SerialNo, ItemKind, OrderNo'
  204. // 表2-1:项目工程量清单(标准).fr3
  205. else if Pos('表2-1:', AReportName) > 0 then
  206. sSQL := 'select * from ReportTempTab where ItemKind <> 3 order by SerialNo, ItemKind, OrderNo'
  207. // 表3-1:工程量清单(标准).fr3
  208. else if Pos('表3-1:', AReportName) > 0 then
  209. sSQL := 'Select B_Code, Name, Units, B_CodeAlpha, Sum(Quantity2) as Quantity, ' +
  210. 'Sum(TotalPrice2) as TotalPrice, IIF(Quantity=0, 0, TotalPrice / Quantity) as UnitPrice ' +
  211. 'from (select B_Code, Name, Units, B_CodeAlpha, ' +
  212. '0 as Quantity2, Sum(TotalPrice) as TotalPrice2 ' +
  213. 'from ReportTempTab where ItemKind = 2 ' +
  214. 'Group by B_Code, Name, Units, B_CodeAlpha ' +
  215. 'union all ' +
  216. 'select B_Code, Name, Units, B_CodeAlpha, ' +
  217. 'Sum(Quantity) as Quantity2, 0 as TotalPrice ' +
  218. 'from ReportTempTab ' +
  219. 'where ItemKind = 2 and SerialNo < (select SerialNo from ReportTempTab where ID = 2) ' +
  220. 'Group by B_Code, Name, Units, B_CodeAlpha) ' +
  221. 'Group by B_Code, Name, Units, B_CodeAlpha ' +
  222. 'Order by B_CodeAlpha, Name'
  223. // 表3-2:工程量清单(带细目).fr3
  224. // 数据库中,清单级清单用Quantity,图纸工程量用DesignQuantity,是两个互斥字段,一者有值
  225. // 则另一者必定为0。相加是为了报表显示共用一个字段。
  226. else if Pos('表3-2:', AReportName) > 0 then
  227. sSQL := 'select B_Code, Name, Units, B_CodeAlpha, ItemKind, ' +
  228. 'Sum(Quantity2) as Quantity, Sum(TotalPrice2) as TotalPrice, ' +
  229. 'IIF(Quantity=0, 0, TotalPrice / Quantity) as UnitPrice ' +
  230. 'from(select B_Code, Name, Units, B_CodeAlpha, ItemKind, ' +
  231. 'Sum(Quantity + DesignQuantity) as Quantity2, 0 as TotalPrice2 ' +
  232. 'from ReportTempTab where (B_CodeAlpha <> '''') and ' +
  233. 'SerialNo < (select SerialNo from ReportTempTab where ID = 2) ' +
  234. 'Group by B_Code, Name, Units, B_CodeAlpha, ItemKind ' +
  235. 'union all ' +
  236. 'select B_Code, Name, Units, B_CodeAlpha, ItemKind, ' +
  237. '0 as Quantity2, Sum(TotalPrice) as TotalPrice2 ' +
  238. 'from ReportTempTab where B_CodeAlpha <> ''''' +
  239. 'Group by B_Code, Name, Units, B_CodeAlpha, ItemKind) ' +
  240. 'Group by B_Code, Name, Units, B_CodeAlpha, ItemKind ' +
  241. 'Order by B_CodeAlpha, ItemKind'
  242. else
  243. // 未定义的报表,不处理
  244. Exit;
  245. ExecSQL(sSQL);
  246. Result := True;
  247. end; }
  248. procedure TReportData.RefreshData;
  249. begin
  250. with TProject(FProject) do
  251. begin
  252. BillsData.SaveSerialNo;
  253. ChangedByReport := True;
  254. // CreateReportTempTab;
  255. end;
  256. end;
  257. end.