ZJJLDm.pas 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. unit ZJJLDm;
  2. interface
  3. uses
  4. ZjGrid, MeasureGatherZJJL,
  5. SysUtils, Classes, DB, DBClient, ADODB, sdIDTree, sdDB, Provider,
  6. Windows, BillsTree, sdProvider, Variants;
  7. type
  8. TZJJLType = (ztFx, ztGcl, ztGclGather);
  9. TRefreshDetailGridEvent = procedure of Object;
  10. TZJJLNode = class
  11. private
  12. FBillsID: Integer;
  13. FCode: string;
  14. FCertificateCode: string;
  15. FBillsCode: string;
  16. FFormulaMemo: string;
  17. FRelaFile: string;
  18. FType: Integer;
  19. end;
  20. TZJJLInfoRec = Record
  21. FBFXName: string;
  22. PegName: string;
  23. BeginPeg: string;
  24. EndPeg: string;
  25. BGLCode: string;
  26. DrawingCode: string;
  27. UnitName: string;
  28. end;
  29. TZJJLData = class(TDataModule)
  30. sdpZJJL: TsdADOProvider;
  31. sddZJJL: TsdDataSet;
  32. sdvZJJL: TsdDataView;
  33. sdpHistory: TsdADOProvider;
  34. sddHistory: TsdDataSet;
  35. sdpZJJLDetail: TsdADOProvider;
  36. sddZJJLDetail: TsdDataSet;
  37. procedure sdvZJJLBeforeValueChange(AValue: TsdValue;
  38. const NewValue: Variant; var Allow: Boolean);
  39. procedure sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord);
  40. procedure sdvZJJLCurrentChanged(ARecord: TsdDataRecord);
  41. private
  42. FPhaseData: TObject;
  43. FCanModified: Boolean;
  44. FNewID: Integer;
  45. FOrgDataList: TList;
  46. FRefreshDetailGrid: TRefreshDetailGridEvent;
  47. function GetNewCode(ANewID: Integer): string;
  48. procedure GenerateZJJLNode(ANode: TsdIDTreeNode; AType: Integer);
  49. function CheckLastXmj(AID: Integer): Boolean;
  50. function CheckBGExist(ANode: TsdIDTreeNode): Boolean;
  51. function CheckMeasureExist(ANode: TsdIDTreeNode): Boolean;
  52. procedure GenerateLastXmj(ANode: TsdIDTreeNode);
  53. procedure GenerateNode(ANode: TsdIDTreeNode);
  54. function CheckLeafNodeMeasureExist(AID: Integer): Boolean;
  55. procedure GenerateLeafNode(ANode: TsdIDTreeNode);
  56. procedure GenerateNodeByB_Code(ANode: TsdIDTreeNode);
  57. procedure DeleteAll;
  58. procedure RestoreOrgData;
  59. procedure DeleteHistory(ABillsID, AType: Integer);
  60. procedure DeleteGatherHistory(ARecord: TsdDataRecord);
  61. procedure DetailGridCellCanEdit(Sender: TObject; const ACoord: TPoint;
  62. var Allow: Boolean);
  63. procedure DetailGridCellTextChanged(Sender: TObject; Col, Row: Integer);
  64. function GetFieldStrDef(ANode: TsdIDTreeNode; const AFieldName, ADef: string): string;
  65. function GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode;
  66. function GetBGLCode(ANode: TsdIDTreeNode): string;
  67. // 取树结构的第ALevel层节点的名称(level从0开始)
  68. function GetNameByLevel(ANode: TsdIDTreeNode; ALevel: Integer): string;
  69. function GetFBFXName(ANode, APegNode: TsdIDTreeNode): string;
  70. function GetPegName(ANode: TsdIDTreeNode): string;
  71. function GetInfoRecByCode_2(ABillsID: Integer): TZJJLInfoRec;
  72. function GetInfoRecByB_Code_2(ABillsID: Integer): TZJJLInfoRec;
  73. function GetInfoRec_2(ABillsID, AType: Integer): TZJJLInfoRec;
  74. function GetNewHistoryID: Integer;
  75. procedure SetHistory(const AFieldName, AValue: string; AZJJL_Rec: TsdDataRecord);
  76. // 向父项检测,直至提取到图册号为止
  77. function GetDrawingCode(ANode: TsdIDTreeNode): string;
  78. procedure CheckZjjlVerison;
  79. function GetMainBillsTree: TsdIDTree;
  80. public
  81. constructor Create(APhaseData: TObject);
  82. destructor Destroy; override;
  83. procedure Open(AConnection: TADOConnection);
  84. procedure Save;
  85. procedure GenerateAll;
  86. procedure GenerateAllByB_Code;
  87. procedure GenerateAllByB_CodeGather;
  88. procedure AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid);
  89. function GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec;
  90. function GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec;
  91. function GetInfoRec(ABillsID, AType: Integer): TZJJLInfoRec;
  92. function GetZJJLCalcData(ARec: TsdDataRecord; const AFileName: string): Double;
  93. procedure LocateBills;
  94. function FindZJJLRecord(ABillsID: Integer): TsdDataRecord;
  95. property PhaseData: TObject read FPhaseData;
  96. property MainBillsTree: TsdIDTree read GetMainBillsTree;
  97. property CanModified: Boolean read FCanModified write FCanModified;
  98. property RefreshDetailGrid: TRefreshDetailGridEvent read FRefreshDetailGrid write FRefreshDetailGrid;
  99. end;
  100. implementation
  101. uses
  102. PhaseData, ProjectData, BillsDm, UtilMethods, ProjectProperty, ZhAPI,
  103. BillsCompileDm, BillsMeasureDm, mPegFilter, Math;
  104. {$R *.dfm}
  105. { TZJJLData }
  106. constructor TZJJLData.Create(APhaseData: TObject);
  107. begin
  108. inherited Create(nil);
  109. FPhaseData := APhaseData;
  110. FOrgDataList := TList.Create;
  111. end;
  112. destructor TZJJLData.Destroy;
  113. begin
  114. ClearObjects(FOrgDataList);
  115. FOrgDataList.Free;
  116. inherited;
  117. end;
  118. function TZJJLData.GetMainBillsTree: TsdIDTree;
  119. begin
  120. with TProjectData(TPhaseData(FPhaseData).ProjectData) do
  121. Result := BillsMeasureData.BillsMeasureTree;
  122. end;
  123. procedure TZJJLData.Open(AConnection: TADOConnection);
  124. begin
  125. sdpZJJL.Connection := AConnection;
  126. sddZJJL.Open;
  127. sddZJJL.AddIndex('idxID', 'ID');
  128. sddZJJL.AddIndex('idxBillsID', 'BillsID');
  129. sdvZJJL.Open;
  130. sdpHistory.Connection := AConnection;
  131. sddHistory.Open;
  132. sddHistory.AddIndex('idxID', 'ID');
  133. sddHistory.AddIndex('idxHistory', 'BillsID;Type;FieldName');
  134. sddHistory.AddIndex('idxGatherHistory', 'BillsID;Type;B_Code;Name;Units;Price;FieldName');
  135. sdpZJJLDetail.Connection := AConnection;
  136. sddZJJLDetail.Open;
  137. sddZJJLDetail.AddIndex('idxID', 'ID');
  138. CheckZjjlVerison;
  139. end;
  140. procedure TZJJLData.Save;
  141. begin
  142. sddZJJL.Save;
  143. sddHistory.Save;
  144. sddZJJLDetail.Save;
  145. end;
  146. function TZJJLData.CheckLastXmj(AID: Integer): Boolean;
  147. var
  148. stnNode, stnChild: TsdIDTreeNode;
  149. begin
  150. stnNode := MainBillsTree.FindNode(AID);
  151. Result := stnNode.Rec.ValueByName('Code').AsString <> '';
  152. if not stnNode.HasChildren or not Result then Exit;
  153. stnChild := stnNode.FirstChild;
  154. Result := stnChild.Rec.ValueByName('B_Code').AsString <> '';
  155. end;
  156. procedure TZJJLData.AssignedCurData(ARec: TsdDataRecord; ADetailGrid: TZJGrid);
  157. var
  158. iRowIndex: Integer;
  159. begin
  160. ADetailGrid.OnCellTextChanged := nil;
  161. ADetailGrid.FixedRowCount := 0;
  162. ADetailGrid.FixedColCount := 0;
  163. ADetailGrid.ColCount := 1;
  164. ADetailGrid.RowCount := 11;
  165. ADetailGrid.DefaultColWidth := 300;
  166. for iRowIndex := 0 to ADetailGrid.RowCount - 1 do
  167. ADetailGrid[0, iRowIndex].Align := gaTopLeft;
  168. if not Assigned(ARec) then Exit;
  169. ADetailGrid.Cells[0, 0].Text := '变更令号:' + ARec.ValueByName('BGLCode').AsString;
  170. ADetailGrid.Cells[0, 1].Text := '部位:' + ARec.ValueByName('PegName').AsString;
  171. ADetailGrid.Cells[0, 2].Text := '起始桩号:' + ARec.ValueByName('BeginPeg').AsString;
  172. ADetailGrid.Cells[0, 3].Text := '终止桩号:' + ARec.ValueByName('EndPeg').AsString;
  173. ADetailGrid.Cells[0, 4].Text := '分部分项工程:' + ARec.ValueByName('FBFXName').AsString;
  174. ADetailGrid.Cells[0, 5].Text := '计量单元:' + ARec.ValueByName('UnitName').AsString;
  175. ADetailGrid.Cells[0, 6].Text := '图号:' + ARec.ValueByName('DrawingCode').AsString;
  176. ADetailGrid.Cells[0, 7].Text := '计算式说明:';
  177. ADetailGrid.Cells[0, 8].Text := ARec.ValueByName('FormulaMemo').AsString;
  178. ADetailGrid.Cells[0, 8].Align := gaTopLeft;
  179. ADetailGrid.RowHeights[8] := 57;
  180. ADetailGrid.Cells[0, 9].Text := '计算草图几何尺寸:';
  181. ADetailGrid.Cells[0, 10].Text := ARec.ValueByName('RelaFile').AsString;
  182. ADetailGrid.Cells[0, 10].Align := gaTopLeft;
  183. ADetailGrid.RowHeights[10] := 57;
  184. ADetailGrid.OnCellTextChanged := DetailGridCellTextChanged;
  185. end;
  186. procedure TZJJLData.GenerateAll;
  187. begin
  188. RestoreOrgData;
  189. FNewID := 1;
  190. DeleteAll;
  191. GenerateNode(MainBillsTree.FirstNode);
  192. TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := 1;
  193. end;
  194. procedure TZJJLData.GenerateNode(ANode: TsdIDTreeNode);
  195. begin
  196. if not Assigned(ANode) then Exit;
  197. if CheckLastXmj(ANode.ID) then
  198. GenerateLastXmj(ANode)
  199. else
  200. GenerateNode(ANode.FirstChild);
  201. GenerateNode(ANode.NextSibling);
  202. end;
  203. procedure TZJJLData.GenerateLastXmj(ANode: TsdIDTreeNode);
  204. begin
  205. if CheckMeasureExist(ANode) then
  206. GenerateZJJLNode(ANode, 0);
  207. end;
  208. function TZJJLData.CheckBGExist(ANode: TsdIDTreeNode): Boolean;
  209. function CheckBGLExist(AID: Integer): Boolean;
  210. var
  211. StageRec: TsdDataRecord;
  212. begin
  213. StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID);
  214. Result := Assigned(StageRec) and
  215. ((StageRec.ValueByName('QcBGLCode').AsString <> '')
  216. or (StageRec.ValueByName('PcBGLCode').AsString <> ''));
  217. end;
  218. var
  219. iChild: Integer;
  220. begin
  221. Result := False;
  222. if not Assigned(ANode) then Exit;
  223. if ANode.HasChildren then
  224. begin
  225. for iChild := 0 to ANode.ChildCount - 1 do
  226. begin
  227. Result := Result or CheckBGExist(ANode.ChildNodes[iChild]);
  228. if Result then Break;
  229. end;
  230. end
  231. else
  232. Result := CheckBGLExist(ANode.ID);
  233. end;
  234. procedure TZJJLData.DeleteAll;
  235. begin
  236. sddZJJL.DeleteAll;
  237. sddZJJLDetail.DeleteAll;
  238. end;
  239. procedure TZJJLData.RestoreOrgData;
  240. function CreateNodeData(ARec: TsdDataRecord): TZJJLNode;
  241. begin
  242. Result := TZJJLNode.Create;
  243. Result.FBillsID := ARec.ValueByName('BillsID').AsInteger;
  244. Result.FCode := ARec.ValueByName('Code').AsString;
  245. Result.FCertificateCode := ARec.ValueByName('CertificateCode').AsString;
  246. Result.FBillsCode := ARec.ValueByName('BillsCode').AsString;
  247. Result.FFormulaMemo := ARec.ValueByName('FormulaMemo').AsString;
  248. Result.FRelaFile := ARec.ValueByName('RelaFile').AsString;
  249. Result.FType := ARec.ValueByName('Type').AsInteger;
  250. end;
  251. var
  252. i: Integer;
  253. vRec: TsdDataRecord;
  254. begin
  255. FOrgDataList.Clear;
  256. for i := 0 to sddZJJL.RecordCount - 1 do
  257. begin
  258. vRec := sddZJJL.Records[i];
  259. FOrgDataList.Add(CreateNodeData(vRec));
  260. end;
  261. end;
  262. function TZJJLData.CheckMeasureExist(ANode: TsdIDTreeNode): Boolean;
  263. function CheckStageCompleteData(AID: Integer): Boolean;
  264. var
  265. StageRec: TsdDataRecord;
  266. begin
  267. StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID);
  268. Result := Assigned(StageRec) and
  269. ((StageRec.ValueByName('GatherQuantity').AsFloat <> 0)
  270. or (StageRec.ValueByName('GatherTotalPrice').AsFloat <> 0));
  271. end;
  272. var
  273. iChild: Integer;
  274. begin
  275. Result := False;
  276. if not Assigned(ANode) then Exit;
  277. if ANode.HasChildren then
  278. begin
  279. for iChild := 0 to ANode.ChildCount - 1 do
  280. begin
  281. Result := Result or CheckMeasureExist(ANode.ChildNodes[iChild]);
  282. if Result then Break;
  283. end;
  284. end
  285. else
  286. Result := CheckStageCompleteData(ANode.ID);
  287. end;
  288. procedure TZJJLData.DetailGridCellCanEdit(Sender: TObject;
  289. const ACoord: TPoint; var Allow: Boolean);
  290. begin
  291. Allow := ((ACoord.Y = 6) or (ACoord.Y = 8)) and
  292. not TPhaseData(FPhaseData).StageDataReadOnly;
  293. end;
  294. function TZJJLData.GetInfoRecByCode(ABillsID: Integer): TZJJLInfoRec;
  295. var
  296. vPeg, vNode: TsdIDTreeNode;
  297. begin
  298. vNode := MainBillsTree.FindNode(ABillsID);
  299. vPeg := GetPegNode(vNode);
  300. Result.BGLCode := GetBGLCode(vNode);
  301. Result.PegName := GetFieldStrDef(vPeg, 'Name', '');
  302. Result.FBFXName := GetFBFXName(vNode, vPeg);
  303. Result.UnitName := GetFieldStrDef(vNode, 'Name', '');
  304. Result.DrawingCode := GetDrawingCode(vNode);
  305. end;
  306. procedure TZJJLData.DetailGridCellTextChanged(Sender: TObject; Col,
  307. Row: Integer);
  308. var
  309. Rec: TsdDataRecord;
  310. begin
  311. Rec := sdvZJJL.Current;
  312. if not Assigned(Rec) then Exit;
  313. if (Row = 8) then
  314. Rec.ValueByName('FormulaMemo').AsString := TZJGrid(Sender).Cells[Col, Row].Text
  315. else if (Row = 10) then
  316. Rec.ValueByName('RelaFile').AsString := TZJGrid(Sender).Cells[Col, Row].Text;
  317. end;
  318. procedure TZJJLData.GenerateAllByB_Code;
  319. begin
  320. RestoreOrgData;
  321. FNewID := 1;
  322. DeleteAll;
  323. GenerateNodeByB_Code(MainBillsTree.FirstNode);
  324. TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := 1;
  325. end;
  326. procedure TZJJLData.GenerateNodeByB_Code(ANode: TsdIDTreeNode);
  327. begin
  328. if not Assigned(ANode) then Exit;
  329. if ANode.HasChildren then
  330. GenerateNodeByB_Code(ANode.FirstChild)
  331. else
  332. GenerateLeafNode(ANode);
  333. GenerateNodeByB_Code(ANode.NextSibling);
  334. end;
  335. procedure TZJJLData.GenerateLeafNode(ANode: TsdIDTreeNode);
  336. begin
  337. if (ANode.Rec.ValueByName('B_Code').AsString <> '') and
  338. CheckLeafNodeMeasureExist(ANode.ID) then
  339. GenerateZJJLNode(ANode, 1);
  340. end;
  341. procedure TZJJLData.GenerateZJJLNode(ANode: TsdIDTreeNode;
  342. AType: Integer);
  343. function GetOrgZJJLNode(ABillsID: Integer): TZJJLNode;
  344. var
  345. iIndex: Integer;
  346. begin
  347. Result := nil;
  348. for iIndex := 0 to FOrgDataList.Count - 1 do
  349. // 7/30新增了一个“总量控制”模式,Type字段控制。真的是要疯掉了。
  350. if (TZJJLNode(FOrgDataList.Items[iIndex]).FBillsID = ABillsID)
  351. and (TZJJLNode(FOrgDataList.Items[iIndex]).FType = AType) then
  352. begin
  353. Result := TZJJLNode(FOrgDataList.Items[iIndex]);
  354. Break;
  355. end;
  356. end;
  357. function GetFieldValue(const AFieldName, ADefaultValue: string): string;
  358. var
  359. HistoryRec: TsdDataRecord;
  360. begin
  361. HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([ANode.ID, AType, AFieldName]));
  362. if Assigned(HistoryRec) then
  363. Result := HistoryRec.ValueByName('FieldValue').AsString
  364. else
  365. Result := ADefaultValue;
  366. end;
  367. var
  368. ZJJLNode: TZJJLNode;
  369. vInfoRec: TZJJLInfoRec;
  370. Rec: TsdDataRecord;
  371. begin
  372. Rec := sddZJJL.Add;
  373. Rec.ValueByName('ID').AsInteger := FNewID;
  374. Rec.ValueByName('BillsID').AsInteger := ANode.ID;
  375. Rec.ValueByName('Type').AsInteger := AType;
  376. if AType = Ord(ztFx) then
  377. Rec.ValueByName('BillsCode').AsString := ANode.Rec.ValueByName('Code').AsString
  378. else if AType = Ord(ztGcl) then
  379. Rec.ValueByName('BillsCode').AsString := ANode.Rec.ValueByName('B_Code').AsString;
  380. Rec.ValueByName('Code').AsString := GetFieldValue('Code', GetNewCode(FNewID));
  381. Rec.ValueByName('CertificateCode').AsString := GetFieldValue('CertificateCode', '');
  382. Rec.ValueByName('FormulaMemo').AsString := GetFieldValue('FormulaMemo', '');
  383. Rec.ValueByName('RelaFile').AsString := GetFieldValue('RelaFile', '');
  384. vInfoRec := GetInfoRec_2(ANode.ID, AType);
  385. Rec.ValueByName('BGLCode').AsString := GetFieldValue('BGLCode', vInfoRec.BGLCode);
  386. Rec.ValueByName('PegName').AsString := GetFieldValue('PegName', vInfoRec.PegName);
  387. Rec.ValueByName('BeginPeg').AsString := GetFieldValue('BeginPeg', vInfoRec.BeginPeg);
  388. Rec.ValueByName('EndPeg').AsString := GetFieldValue('EndPeg', vInfoRec.EndPeg);
  389. Rec.ValueByName('FBFXName').AsString := GetFieldValue('FBFXName', vInfoRec.FBFXName);
  390. Rec.ValueByName('UnitName').AsString := GetFieldValue('UnitName', vInfoRec.UnitName);
  391. Rec.ValueByName('DrawingCode').AsString := GetFieldValue('DrawingCode', vInfoRec.DrawingCode);
  392. Rec := sddZJJLDetail.Add;
  393. Rec.ValueByName('ID').AsInteger := FNewID;
  394. Rec.ValueByName('BillsID').AsInteger := ANode.ID;
  395. Inc(FNewID);
  396. end;
  397. function TZJJLData.GetInfoRecByB_Code(ABillsID: Integer): TZJJLInfoRec;
  398. var
  399. vNode: TsdIDTreeNode;
  400. begin
  401. vNode := MainBillsTree.FindNode(ABillsID);
  402. Result.BGLCode := GetBGLCode(vNode);
  403. if Assigned(vNode.Parent) then
  404. Result.PegName := vNode.Parent.Rec.ValueByName('Name').AsString;
  405. Result.FBFXName := '';
  406. Result.UnitName := vNode.Rec.ValueByName('Name').AsString;
  407. Result.DrawingCode := GetDrawingCode(vNode);
  408. end;
  409. function TZJJLData.GetInfoRec(ABillsID, AType: Integer): TZJJLInfoRec;
  410. begin
  411. if AType = 0 then
  412. Result := GetInfoRecByCode(ABillsID)
  413. else if AType = 1 then
  414. Result := GetInfoRecByB_Code(ABillsID);
  415. end;
  416. procedure TZJJLData.LocateBills;
  417. var
  418. Rec: TsdDataRecord;
  419. begin
  420. with TProjectData(TPhaseData(FPhaseData).ProjectData) do
  421. begin
  422. Rec := BillsData.sddBills.FindKey('idxID', sdvZJJL.Current.ValueByName('BillsID').AsInteger);
  423. BillsMeasureData.sdvBillsMeasure.LocateInControl(Rec);
  424. end;
  425. end;
  426. function TZJJLData.GetDrawingCode(ANode: TsdIDTreeNode): string;
  427. var
  428. vNode: TBillsIDTreeNode;
  429. begin
  430. Result := '';
  431. vNode := TBillsIDTreeNode(ANode);
  432. while (Result = '') and Assigned(vNode) do
  433. begin
  434. if Assigned(vNode.Rec) then
  435. Result := vNode.Rec.DrawingCode.AsString;
  436. vNode := TBillsIDTreeNode(vNode.Parent);
  437. end;
  438. end;
  439. procedure TZJJLData.CheckZjjlVerison;
  440. procedure LoadVersion0Info;
  441. var
  442. i: Integer;
  443. Rec: TsdDataRecord;
  444. ZJJLInfoRec: TZJJLInfoRec;
  445. begin
  446. for i := 0 to sddZJJL.RecordCount - 1 do
  447. begin
  448. Rec := sddZJJL.Records[i];
  449. ZJJLInfoRec := GetInfoRec(Rec.ValueByName('BillsID').AsInteger, Rec.ValueByName('Type').AsInteger);
  450. Rec.ValueByName('BGLCode').AsString := ZJJLInfoRec.BGLCode;
  451. Rec.ValueByName('PegName').AsString := ZJJLInfoRec.PegName;
  452. Rec.ValueByName('FBFXName').AsString := ZJJLInfoRec.FBFXName;
  453. Rec.ValueByName('UnitName').AsString := ZJJLInfoRec.UnitName;
  454. Rec.ValueByName('DrawingCode').AsString := ZJJLInfoRec.DrawingCode;
  455. end;
  456. end;
  457. procedure LoadVersion0History;
  458. var
  459. i, j, iNewID: Integer;
  460. Rec: TsdDataRecord;
  461. begin
  462. for i := 0 to sddZJJL.RecordCount - 1 do
  463. begin
  464. Rec := sddZJJL.Records[i];
  465. if Rec.ValueByName('CertificateCode').AsString <> '' then
  466. SetHistory('CertificateCode', Rec.ValueByName('CertificateCode').AsString, Rec);
  467. if Rec.ValueByName('FormulaMemo').AsString <> '' then
  468. SetHistory('FormulaMemo', Rec.ValueByName('FormulaMemo').AsString, Rec);
  469. if Rec.ValueByName('RelaFile').AsString <> '' then
  470. SetHistory('RelaFile', Rec.ValueByName('RelaFile').AsString, Rec);
  471. end;
  472. end;
  473. begin
  474. if TPhaseData(PhaseData).PhaseProperty.ZjjlVersion = 0 then
  475. begin
  476. TPhaseData(PhaseData).PhaseProperty.ZJJLPreText := TProjectData(TPhaseData(PhaseData).ProjectData).ProjProperties.ZJJLPreText;
  477. LoadVersion0Info;
  478. LoadVersion0History;
  479. end;
  480. end;
  481. function TZJJLData.GetInfoRec_2(ABillsID, AType: Integer): TZJJLInfoRec;
  482. begin
  483. if AType = 0 then
  484. Result := GetInfoRecByCode_2(ABillsID)
  485. else if AType = 1 then
  486. Result := GetInfoRecByB_Code_2(ABillsID);
  487. end;
  488. function TZJJLData.GetInfoRecByB_Code_2(ABillsID: Integer): TZJJLInfoRec;
  489. var
  490. vNode: TsdIDTreeNode;
  491. sPeg: string;
  492. vPegFilter: TPegStrFilter;
  493. begin
  494. vNode := MainBillsTree.FindNode(ABillsID);
  495. sPeg := GetPegName(vNode);
  496. Result.BGLCode := GetBGLCode(vNode);
  497. if Assigned(vNode.Parent) then
  498. Result.PegName := vNode.Parent.Rec.ValueByName('Name').AsString;
  499. if sPeg <> '' then
  500. begin
  501. vPegFilter := TPegStrFilter.Create;
  502. vPegFilter.PegStr := sPeg;
  503. Result.BeginPeg := vPegFilter.BeginPeg;
  504. Result.EndPeg := vPegFilter.EndPeg;
  505. vPegFilter.Free;
  506. end;
  507. Result.UnitName := vNode.Rec.ValueByName('Name').AsString;
  508. Result.DrawingCode := GetDrawingCode(vNode);
  509. end;
  510. function TZJJLData.GetInfoRecByCode_2(ABillsID: Integer): TZJJLInfoRec;
  511. var
  512. vPeg, vNode: TsdIDTreeNode;
  513. vPegFilter: TPegStrFilter;
  514. begin
  515. vNode := MainBillsTree.FindNode(ABillsID);
  516. vPeg := GetPegNode(vNode);
  517. Result.BGLCode := GetBGLCode(vNode);
  518. Result.PegName := GetFieldStrDef(vPeg, 'Name', '');
  519. if Result.PegName <> '' then
  520. begin
  521. vPegFilter := TPegStrFilter.Create;
  522. vPegFilter.PegStr := Result.PegName;
  523. Result.BeginPeg := vPegFilter.BeginPeg;
  524. Result.EndPeg := vPegFilter.EndPeg;
  525. vPegFilter.Free;
  526. end;
  527. Result.FBFXName := GetFBFXName(vNode, vPeg);
  528. Result.UnitName := GetFieldStrDef(vNode, 'Name', '');
  529. Result.DrawingCode := GetDrawingCode(vNode);
  530. end;
  531. function TZJJLData.GetBGLCode(ANode: TsdIDTreeNode): string;
  532. begin
  533. with TProjectData(TPhaseData(FPhaseData).ProjectData) do
  534. Result := BillsMeasureData.GatherRelaBGL(ANode);
  535. end;
  536. function TZJJLData.GetPegName(ANode: TsdIDTreeNode): string;
  537. var
  538. vPeg: TsdIDTreeNode;
  539. begin
  540. vPeg := GetPegNode(ANode);
  541. Result := GetFieldStrDef(vPeg, 'Name', '');
  542. end;
  543. function TZJJLData.GetFieldStrDef(ANode: TsdIDTreeNode; const AFieldName,
  544. ADef: string): string;
  545. begin
  546. if Assigned(ANode) then
  547. Result := ANode.Rec.ValueByName(AFieldName).AsString
  548. else
  549. Result := '';
  550. end;
  551. function TZJJLData.GetPegNode(ANode: TsdIDTreeNode): TsdIDTreeNode;
  552. begin
  553. Result := nil;
  554. if not Assigned(ANode) then Exit;
  555. if CheckPeg(ANode.Rec.ValueByName('Name').AsString) then
  556. Result := ANode
  557. else
  558. Result := GetPegNode(ANode.Parent);
  559. end;
  560. function TZJJLData.GetFBFXName(ANode, APegNode: TsdIDTreeNode): string;
  561. var
  562. vCurNode: TsdIDTreeNode;
  563. begin
  564. Result := '';
  565. if not Assigned(ANode) then Exit;
  566. // 如果计量单元节点的名称为桩号(转化为判断计量单元节点与桩号节点为同一个)
  567. if not Assigned(APegNode) or (ANode.ID = APegNode.ID) then
  568. begin
  569. // 取树结构的第三、四层节点的名称
  570. Result := GetNameByLevel(ANode, 2);
  571. if (Result <> '') and (GetNameByLevel(ANode, 3) <> '') then
  572. Result := Result + ',';
  573. Result := Result + GetNameByLevel(ANode, 3);
  574. end
  575. // 否则,合并[桩号节点的子节点]至[计量单元节点的父节点]的名称
  576. else
  577. begin
  578. vCurNode := ANode.Parent;
  579. // 转化为判断层次,层次大于[桩号节点的子节点]的层次
  580. while vCurNode.Level > APegNode.Level do
  581. begin
  582. Result := vCurNode.Rec.ValueByName('Name').AsString + ',' + Result;
  583. vCurNode := vCurNode.Parent;
  584. end;
  585. end;
  586. end;
  587. function TZJJLData.GetNameByLevel(ANode: TsdIDTreeNode;
  588. ALevel: Integer): string;
  589. begin
  590. Result := '';
  591. if not Assigned(ANode) then Exit;
  592. if ANode.Level = ALevel then
  593. Result := ANode.Rec.ValueByName('Name').AsString
  594. else if ANode.Level > ALevel then
  595. Result := GetNameByLevel(ANode.Parent, ALevel);
  596. end;
  597. procedure TZJJLData.SetHistory(const AFieldName, AValue: string;
  598. AZJJL_Rec: TsdDataRecord);
  599. var
  600. HistoryRec: TsdDataRecord;
  601. begin
  602. if AZJJL_Rec.ValueByName('Type').AsInteger <> Integer(ztGclGather) then
  603. HistoryRec := sddHistory.FindKey('idxHistory', VarArrayOf([AZJJL_Rec.ValueByName('BillsID').AsInteger,
  604. AZJJL_Rec.ValueByName('Type').AsInteger, AFieldName]))
  605. else
  606. HistoryRec := sddHistory.FindKey('idxGatherHistory', VarArrayOf([AZJJL_Rec.ValueByName('GatherBillsID').AsInteger,
  607. AZJJL_Rec.ValueByName('Type').AsInteger, AZJJL_Rec.ValueByName('B_Code').AsString,
  608. AZJJL_Rec.ValueByName('Name').AsString, AZJJL_Rec.ValueByName('Units').AsString,
  609. AZJJL_Rec.ValueByName('Price').AsFloat, AFieldName]));
  610. if not Assigned(HistoryRec) then
  611. begin
  612. HistoryRec := sddHistory.Add;
  613. HistoryRec.ValueByName('ID').AsInteger := GetNewHistoryID;
  614. if AZJJL_Rec.ValueByName('Type').AsInteger <> Integer(ztGclGather) then
  615. HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('BillsID').AsInteger
  616. else
  617. HistoryRec.ValueByName('BillsID').AsInteger := AZJJL_Rec.ValueByName('GatherBillsID').AsInteger;
  618. HistoryRec.ValueByName('Type').AsInteger := AZJJL_Rec.ValueByName('Type').AsInteger;
  619. HistoryRec.ValueByName('FieldName').AsString := AFieldName;
  620. HistoryRec.ValueByName('B_Code').AsString := AZJJL_Rec.ValueByName('B_Code').AsString;
  621. HistoryRec.ValueByName('Name').AsString := AZJJL_Rec.ValueByName('Name').AsString;
  622. HistoryRec.ValueByName('Units').AsString := AZJJL_Rec.ValueByName('Units').AsString;
  623. HistoryRec.ValueByName('Price').AsFloat := AZJJL_Rec.ValueByName('Price').AsFloat;
  624. end;
  625. HistoryRec.ValueByName('FieldValue').AsString := AValue;
  626. end;
  627. function TZJJLData.GetNewHistoryID: Integer;
  628. var
  629. idx: TsdIndex;
  630. begin
  631. idx := sddHistory.FindIndex('idxID');
  632. if idx.RecordCount = 0 then
  633. Result := 1
  634. else
  635. Result := idx.Records[idx.RecordCount - 1].ValueByName('ID').AsInteger + 1;
  636. end;
  637. procedure TZJJLData.sdvZJJLBeforeValueChange(AValue: TsdValue;
  638. const NewValue: Variant; var Allow: Boolean);
  639. function CheckFieldNeedHistory(const AFieldName: string): Boolean;
  640. begin
  641. Result := SameText(AFieldName, 'Code') or
  642. SameText(AFieldName, 'CertificateCode') or
  643. SameText(AFieldName, 'BGLCode') or
  644. SameText(AFieldName, 'PegName') or
  645. SameText(AFieldName, 'BeginPeg') or
  646. SameText(AFieldName, 'EndPeg') or
  647. SameText(AFieldName, 'FBFXName') or
  648. SameText(AFieldName, 'UnitName') or
  649. SameText(AFieldName, 'DrawingCode') or
  650. SameText(AFieldName, 'FormulaMemo') or
  651. SameText(AFieldName, 'RelaFile');
  652. end;
  653. var
  654. sNewValue: string;
  655. begin
  656. if CheckFieldNeedHistory(AValue.FieldName) and not TPhaseData(FPhaseData).StageDataReadOnly then
  657. begin
  658. sNewValue := VarToStrDef(NewValue, '');
  659. if sNewValue <> AValue.AsString then
  660. SetHistory(AValue.FieldName, sNewValue, AValue.Owner);
  661. end;
  662. end;
  663. procedure TZJJLData.sdvZJJLAfterDeleteRecord(ARecord: TsdDataRecord);
  664. begin
  665. if ARecord.ValueByName('Type').AsInteger <> Integer(ztGclGather) then
  666. DeleteHistory(ARecord.ValueByName('BillsID').AsInteger, ARecord.ValueByName('Type').AsInteger)
  667. else
  668. DeleteGatherHistory(ARecord);
  669. end;
  670. procedure TZJJLData.DeleteHistory(ABillsID, AType: Integer);
  671. var
  672. i: Integer;
  673. Rec: TsdDataRecord;
  674. begin
  675. i := 0;
  676. while (i < sddHistory.RecordCount) do
  677. begin
  678. Rec := sddHistory.Records[i];
  679. if (ABillsID = Rec.ValueByName('BillsID').AsInteger) and
  680. (AType = Rec.ValueByName('Type').AsInteger) then
  681. sddHistory.Remove(Rec)
  682. else
  683. Inc(i);
  684. end;
  685. end;
  686. procedure TZJJLData.GenerateAllByB_CodeGather;
  687. procedure GenerateZJJLGather(AManager: TmgZJJLManager; ANode: TBillsIDTreeNode);
  688. var
  689. iChild: Integer;
  690. vChild: TBillsIDTreeNode;
  691. begin
  692. if ANode.HasChildren then
  693. begin
  694. iChild := 0;
  695. vChild := TBillsIDTreeNode(ANode.NextNode);
  696. while iChild < ANode.PosterityCount do
  697. begin
  698. if not vChild.HasChildren and CheckLeafNodeMeasureExist(vChild.ID) then
  699. AManager.AddZJJLAndDetail(vChild, ANode);
  700. vChild := TBillsIDTreeNode(vChild.NextNode);
  701. Inc(iChild);
  702. end;
  703. end
  704. else if CheckLeafNodeMeasureExist(ANode.ID) then
  705. AManager.AddZJJLAndDetail(ANode, ANode);
  706. end;
  707. procedure GenerateZJJLGatherByNode(AManager: TmgZJJLManager; ANode: TsdIDTreeNode);
  708. begin
  709. if not Assigned(ANode) then Exit;
  710. if ANode.HasChildren and not TBillsIDTreeNode(ANode).Rec.IsGatherZJJL.AsBoolean then
  711. GenerateZJJLGatherByNode(AManager, ANode.FirstChild)
  712. else
  713. GenerateZJJLGather(AManager, TBillsIDTreeNode(ANode));
  714. GenerateZJJLGatherByNode(AManager, ANode.NextSibling);
  715. end;
  716. function GetFieldValue(AZJJL: TmgZJJL; const AFieldName, ADefaultValue: string): string;
  717. var
  718. HistoryRec: TsdDataRecord;
  719. begin
  720. HistoryRec := sddHistory.FindKey('idxGatherHistory', VarArrayOf([AZJJL.GatherNode.ID, Integer(ztGclGather), AZJJL.B_Code, AZJJL.Name, AZJJL.Units, AZJJL.Price, AFieldName]));
  721. if Assigned(HistoryRec) then
  722. Result := HistoryRec.ValueByName('FieldValue').AsString
  723. else
  724. Result := ADefaultValue;
  725. end;
  726. procedure SaveGatherData(AManager: TmgZJJLManager);
  727. var
  728. i, j: Integer;
  729. vZJJL: TmgZJJL;
  730. Rec: TsdDataRecord;
  731. begin
  732. for i := 0 to AManager.ZJJLCount - 1 do
  733. begin
  734. vZJJL := AManager.ZJJL[i];
  735. Rec := sddZJJL.Add;
  736. Rec.ValueByName('ID').AsInteger := i + 1;
  737. Rec.ValueByName('BillsID').AsInteger := vZJJL.Detail[0].RelaNode.ID;
  738. Rec.ValueByName('Type').AsInteger := Integer(ztGclGather);
  739. Rec.ValueByName('GatherBillsID').AsInteger := vZJJL.GatherNode.ID;
  740. Rec.ValueByName('BillsCode').AsString := vZJJL.B_Code;
  741. Rec.ValueByName('B_Code').AsString := vZJJL.B_Code;
  742. Rec.ValueByName('Name').AsString := vZJJL.Name;
  743. Rec.ValueByName('Units').AsString := vZJJL.Units;
  744. Rec.ValueByName('Price').AsFloat := vZJJL.Price;
  745. Rec.ValueByName('Code').AsString := GetFieldValue(vZJJL, 'Code', GetNewCode(i+1));
  746. Rec.ValueByName('CertificateCode').AsString := GetFieldValue(vZJJL, 'CertificateCode', '');
  747. Rec.ValueByName('FormulaMemo').AsString := GetFieldValue(vZJJL, 'FormulaMemo', '');
  748. Rec.ValueByName('RelaFile').AsString := GetFieldValue(vZJJL, 'RelaFile', '');
  749. Rec.ValueByName('BGLCode').AsString := GetFieldValue(vZJJL, 'BGLCode', vZJJL.BGLCode);
  750. Rec.ValueByName('PegName').AsString := GetFieldValue(vZJJL, 'PegName', '');
  751. Rec.ValueByName('BeginPeg').AsString := GetFieldValue(vZJJL, 'BeginPeg', vZJJL.BeginPeg);
  752. Rec.ValueByName('EndPeg').AsString := GetFieldValue(vZJJL, 'EndPeg', vZJJL.EndPeg);
  753. Rec.ValueByName('FBFXName').AsString := GetFieldValue(vZJJL, 'FBFXName', vZJJL.GatherNode.Rec.Name.AsString);
  754. Rec.ValueByName('UnitName').AsString := GetFieldValue(vZJJL, 'UnitName', '');
  755. Rec.ValueByName('DrawingCode').AsString := GetFieldValue(vZJJL, 'DrawingCode', vZJJL.DrawingCode);
  756. for j := 0 to vZJJL.DetailCount - 1 do
  757. begin
  758. Rec := sddZJJLDetail.Add;
  759. Rec.ValueByName('ID').AsInteger := i + 1;
  760. Rec.ValueByName('BillsID').AsInteger := vZJJL.Detail[j].RelaNode.ID;
  761. end;
  762. end;
  763. end;
  764. var
  765. vManager: TmgZJJLManager;
  766. begin
  767. vManager := TmgZJJLManager.Create;
  768. try
  769. DeleteAll;
  770. GenerateZJJLGatherByNode(vManager, MainBillsTree.FirstNode);
  771. SaveGatherData(vManager);
  772. TPhaseData(FPhaseData).PhaseProperty.ZjjlVersion := Integer(ztGclGather);
  773. finally
  774. vManager.Free;
  775. end;
  776. end;
  777. function TZJJLData.CheckLeafNodeMeasureExist(AID: Integer): Boolean;
  778. var
  779. StageRec: TsdDataRecord;
  780. begin
  781. StageRec := TPhaseData(FPhaseData).StageData.StageRecord(AID);
  782. Result := Assigned(StageRec) and
  783. ((StageRec.ValueByName('GatherQuantity').AsFloat <> 0)
  784. or (StageRec.ValueByName('GatherTotalPrice').AsFloat <> 0));
  785. end;
  786. function TZJJLData.GetNewCode(ANewID: Integer): string;
  787. begin
  788. with TProjectData(TPhaseData(FPhaseData).ProjectData) do
  789. begin
  790. Result := ProjProperties.ZJJLPreText;
  791. if (Result <> '') and (Result[Length(Result)] <> '-') then
  792. Result := Result + '-';
  793. Result := Result + Format('%d-%d', [PhaseIndex, ANewID]);
  794. end;
  795. end;
  796. function TZJJLData.FindZJJLRecord(ABillsID: Integer): TsdDataRecord;
  797. var
  798. ADetailRec: TsdDataRecord;
  799. begin
  800. if sddZJJLDetail.RecordCount > 0 then
  801. begin
  802. ADetailRec := sddZJJLDetail.Locate('BillsID', ABillsID);
  803. if Assigned(ADetailRec) then
  804. Result := sddZJJL.FindKey('idxID', ADetailRec.ValueByName('ID').AsInteger)
  805. else
  806. Result := nil;
  807. end
  808. else
  809. Result := sddZJJL.Locate('BillsID', ABillsID);
  810. end;
  811. procedure TZJJLData.DeleteGatherHistory(ARecord: TsdDataRecord);
  812. var
  813. i: Integer;
  814. Rec: TsdDataRecord;
  815. begin
  816. i := 0;
  817. while (i < sddHistory.RecordCount) do
  818. begin
  819. Rec := sddHistory.Records[i];
  820. if (ARecord.ValueByName('GatherBillsID').AsInteger = Rec.ValueByName('BillsID').AsInteger) and
  821. (ARecord.ValueByName('Type').AsInteger = Rec.ValueByName('Type').AsInteger) and
  822. (ARecord.ValueByName('B_Code').AsString = Rec.ValueByName('B_Code').AsString) and
  823. (ARecord.ValueByName('Name').AsString = Rec.ValueByName('Name').AsString) and
  824. (ARecord.ValueByName('Units').AsString = Rec.ValueByName('Units').AsString) and
  825. (Abs(ARecord.ValueByName('Price').AsFloat - Rec.ValueByName('Price').AsFloat) < 0.00001) then
  826. sddHistory.Remove(Rec)
  827. else
  828. Inc(i);
  829. end;
  830. end;
  831. procedure TZJJLData.sdvZJJLCurrentChanged(ARecord: TsdDataRecord);
  832. begin
  833. if Assigned(FRefreshDetailGrid) then
  834. FRefreshDetailGrid;
  835. end;
  836. function TZJJLData.GetZJJLCalcData(ARec: TsdDataRecord;
  837. const AFileName: string): Double;
  838. var
  839. vIdx: TsdIndex;
  840. iBegin, iEnd, i: Integer;
  841. vRec, vStageRec: TsdDataRecord;
  842. begin
  843. Result := 0;
  844. vIdx := sddZJJLDetail.FindIndex('idxID');
  845. iBegin := vIdx.FindKeyIndex(ARec.ValueByName('ID').AsInteger);
  846. iEnd := vIdx.FindKeyLastIndex(ARec.ValueByName('ID').AsInteger);
  847. if iBegin <> -1 then
  848. begin
  849. for i := iBegin to iEnd do
  850. begin
  851. vRec := vIdx.Records[i];
  852. vStageRec := TPhaseData(FPhaseData).StageData.StageRecord(vRec.ValueByName('BillsID').AsInteger);
  853. if Assigned(vStageRec) then
  854. Result := QuantityRoundTo(Result + vStageRec.ValueByName(AFileName).AsFloat);
  855. end;
  856. end;
  857. end;
  858. end.