ScBillsTree.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. unit ScBillsTree;
  2. interface
  3. uses
  4. ZjIDTree, Classes, DB, ConstMethodUnit,
  5. ConstVarUnit, ConstTypeUnit, DBClient;
  6. const
  7. idFirstSection = 1;
  8. idSecondSection = 2;
  9. idThreeSection = 3;
  10. // 第一二三部分费用合计
  11. idAggregate123 = 4;
  12. idPricePerKM = 8;
  13. // 概(预)算总金额
  14. idBugetTotalPrice = 5;
  15. // 公路基本造价
  16. idProjectTotalPrice = 6;
  17. type
  18. {BillsTree}
  19. TScBillsItem = class(TZjIDTreeNode)
  20. private
  21. FSCode: string;
  22. FSBCode: string;
  23. FSName: string;
  24. // 是否是预定义项,即系统预设的项目,而不是用户输入的,且不允许删除
  25. FIsPreDefine: Boolean;
  26. FSelected: Boolean;
  27. FBills: TObject;
  28. FUnits: string;
  29. FQuantity: Double; // 需要用到Null值
  30. FDesignQuantity: Double;
  31. FDesignQuantity2: Double;
  32. FIsRepeat: Boolean; // 是否是重复行
  33. FIsSuperscale: Boolean;
  34. FUserModified: Boolean;
  35. FErrorHint: string;
  36. FDeductGrade: Currency;
  37. FLostPreSiblingCount: Integer;
  38. FLostChildrenCount: Integer;
  39. FStandardGrade: Currency;
  40. FLostNextSiblingCount: Integer;
  41. FIsIgNore: Boolean;
  42. FNameErrorFlag: Integer;
  43. FUnitsErrorFlag: Integer;
  44. FRightName: String;
  45. FRightUnits: String;
  46. FIsAccQuantity: Boolean;
  47. function GetLastBudgetParent: TScBillsItem;
  48. function GetBillCategory: TBillCategory;
  49. function GetNeed: Boolean;
  50. function GetTotalPrice(AIsTender: Boolean): Currency;
  51. function GetChapterID: Integer;
  52. function GetCode: string;
  53. procedure SetSelected(const Value: Boolean);
  54. public
  55. constructor Create(AOwner: TZjIDTree); override;
  56. function CanUpLevel: Boolean; override;
  57. function CanDownLevel: Boolean; override;
  58. function CanUpMove: Boolean; override;
  59. function CanDownMove: Boolean; override;
  60. function HasDrawingQuantity: Boolean;
  61. procedure SyncSelected(aValue: Boolean);
  62. function IsInheritFrom(AID: Integer): Boolean;
  63. property Bills: TObject read FBills write FBills;
  64. property IsPreDefine: Boolean read FIsPreDefine;
  65. property ChapterID: Integer read GetChapterID;
  66. // property Code: string read GetCode;
  67. property TotalPrice[AIsTender: Boolean]: Currency read GetTotalPrice;
  68. property Selected: Boolean read FSelected write SetSelected;
  69. property SBillCode: string read FSCode write FSCode;
  70. property SBillBCode: string read FSBCode write FSBCode;
  71. property SBillName: string read FSName write FSName;
  72. property Code: string read FSCode write FSCode;
  73. property B_Code: string read FSBCode write FSBCode;
  74. property Name: string read FSName write FSName;
  75. property Units: string read FUnits write FUnits;
  76. property Quantity: Double read FQuantity write FQuantity;
  77. property DesignQuantity: Double read FDesignQuantity write FDesignQuantity;
  78. property DesignQuantity2: Double read FDesignQuantity2 write FDesignQuantity2;
  79. property UserModified: Boolean read FUserModified write FUserModified;
  80. property ErrorHint: string read FErrorHint write FErrorHint;
  81. property DeductGrade: Currency read FDeductGrade write FDeductGrade;
  82. property IsSuperscale: Boolean read FIsSuperscale write FIsSuperscale;
  83. property LostPreSiblingCount: Integer read FLostPreSiblingCount write FLostPreSiblingCount;
  84. property LostChildrenCount: Integer read FLostChildrenCount write FLostChildrenCount;
  85. property LostNextSiblingCount: Integer read FLostNextSiblingCount write FLostNextSiblingCount;
  86. property StandardGrade: Currency read FStandardGrade write FStandardGrade;
  87. property IsIgNore: Boolean read FIsIgNore write FIsIgNore;
  88. property NameErrorFlag: Integer read FNameErrorFlag write FNameErrorFlag;
  89. property UnitsErrorFlag: Integer read FUnitsErrorFlag write FUnitsErrorFlag;
  90. property RightName: string read FRightName write FRightName;
  91. property RightUnits: string read FRightUnits write FRightUnits;
  92. property LastBudgetParent: TScBillsItem read GetLastBudgetParent;
  93. property Category: TBillCategory read GetBillCategory;
  94. property IsRepeat: Boolean read FIsRepeat write FIsRepeat;
  95. property NeedSearchInStdLib: Boolean read GetNeed;
  96. // Modified By MaiXinRong 2012-03-21 是否填父项量
  97. property IsAccQuantity: Boolean read FIsAccQuantity write FIsAccQuantity;
  98. end;
  99. TScBillsTree = class(TZjIDTree)
  100. private
  101. FBills: TObject;
  102. FShowError: Boolean;
  103. FInternalEvent: TInternalEvent;
  104. function GetBillsItem(ID: Integer): TScBillsItem;
  105. function GetItems(AIndex: Integer): TScBillsItem;
  106. protected
  107. function CreateItem: TScIDTreeNode; override;
  108. procedure LoadItem(AItem: TScIDTreeNode); override;
  109. procedure InitDBRecord; override;
  110. public
  111. function AddBillsItem(AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; overload;
  112. function AddBillsItem(AID, AParentID, ANextSiblingID: TScTreeNodeID): TScBillsItem; overload;
  113. function Add(AParentID, ANextSiblingID: TScTreeNodeID): TScIDTreeNode; override;
  114. function CanAdd(AParentID, ANextSiblingID: TScTreeNodeID): Boolean; override;
  115. function CanDelete(ANode: TScIDTreeNode): Boolean; override;
  116. function DeleteNode(ANode: TScIDTreeNode): Boolean; override;
  117. property BillsItem[ID: Integer]: TScBillsItem read GetBillsItem; default;
  118. property Items[AIndex: Integer]: TScBillsItem read GetItems;
  119. property Bills: TObject read FBills write FBills;
  120. property ShowError: Boolean read FShowError write FShowError;
  121. {Events}
  122. property InternalEvent: TInternalEvent read FInternalEvent write FInternalEvent;
  123. function FindNode(AID: TZjTreeNodeID): TScBillsItem;
  124. end;
  125. {stdBillsTree}
  126. TStdBillNode = class (TZjIDTreeNode)
  127. private
  128. FCode: string;
  129. FBCode: string;
  130. FName: string;
  131. FUnits: string;
  132. FNotes: string;
  133. FFee: string;
  134. FStaticID: Integer;
  135. FExpr: string;
  136. FGradeType: Integer;
  137. function GetStringValue(AIdx: Integer): string;
  138. procedure SetStringValue(AIdx: Integer; Value: string);
  139. function GetLastBudgetParent: TStdBillNode;
  140. function GetHasYsxmjChild: Boolean;
  141. public
  142. function TopestAncestor(AList: TList): TStdBillNode;
  143. property Code: string index 0 read GetStringValue write SetStringValue;
  144. property BCode: string index 1 read GetStringValue write SetStringValue;
  145. property Name: string index 2 read GetStringValue write SetStringValue;
  146. property Units: string index 3 read GetStringValue write SetStringValue;
  147. property Notes: string index 4 read GetStringValue write SetStringValue;
  148. property Fee: string index 5 read GetStringValue write SetStringValue;
  149. property Exprs: string index 6 read GetStringValue write SetStringValue;
  150. property GradeType: Integer read FGradeType write FGradeType;
  151. property StaticID: Integer read FStaticID write FStaticID;
  152. property LastBudgetParent: TStdBillNode read GetLastBudgetParent;
  153. property HasYsxmjChild: Boolean read GetHasYsxmjChild;
  154. end;
  155. TStdBillsTree = class (TZjIDTree)
  156. protected
  157. function CreateItem: TScIDTreeNode; override;
  158. procedure LoadItem(AItem: TScIDTreeNode); override;
  159. public
  160. {-------------------------------------------------------------------------------
  161. 方法: FindNode
  162. 描述: ABItem:要查找的最终清单
  163. ALostBItem:没有找到的那一层清单
  164. ALostStdPaItem:ALostBItem在标准项目表中对应的标准项的父标准项。
  165. 它的父标准项一定存在于标准项目表(即ALostStdPaItem一定存在)。
  166. 当某清单搜不到时立即返回该清单,不再往下搜索。
  167. 如:搜索1-1/1-1-2/1-1-2-9/301-1/301-1-5,在1-1-2-9时出错了,则:
  168. ABItem: 301-1-5 ALostBItem: 1-1-2-9 ALostStdPaItem: 1-1-2
  169. 作者: Chenshilong, 2010-12-15 17:48:38
  170. -------------------------------------------------------------------------------}
  171. function FindNode(ABItem: TScBillsItem; var ALostBItem: TScBillsItem;
  172. var ALostStdPaItem: TStdBillNode): TStdBillNode; overload;
  173. function FindNode(ACode, AB_Code: string): TStdBillNode; overload;
  174. end;
  175. { XMJ }
  176. TXMJBillsItem = class(TScBillsItem)
  177. public
  178. function CanUpLevel: Boolean; override;
  179. function CanDownLevel: Boolean; override;
  180. end;
  181. TXMJBillsTree = class(TScBillsTree)
  182. protected
  183. function CreateItem: TScIDTreeNode; override;
  184. end;
  185. { Merge }
  186. TAdditionalItem = class(TZjIDTreeNode)
  187. private
  188. FCode: string;
  189. FB_Code: string;
  190. FName: string;
  191. FUnits: string;
  192. FOwnerName: string;
  193. FMemoStr: string;
  194. FQuantity: Double;
  195. FQuantity2: Double;
  196. FUnitPrice: Currency;
  197. FTotalPrice: Currency;
  198. FDesignQuantity: Currency;
  199. FDesignQuantity2: Currency;
  200. FDesignPrice: Currency;
  201. public
  202. property Code: string read FCode write FCode;
  203. property B_Code: string read FB_Code write FB_Code;
  204. property Name: string read FName write FName;
  205. property Units: string read FUnits write FUnits;
  206. property MemoStr: string read FMemoStr write FMemoStr;
  207. property OwnerName: string read FOwnerName write FOwnerName;
  208. property Quantity: Double read FQuantity write FQuantity;
  209. property Quantity2: Double read FQuantity2 write FQuantity2;
  210. property UnitPrice: Currency read FUnitPrice write FUnitPrice;
  211. property TotalPrice: Currency read FTotalPrice write FTotalPrice;
  212. property DesignQuantity: Currency read FDesignQuantity write FDesignQuantity;
  213. property DesignQuantity2: Currency read FDesignQuantity2 write FDesignQuantity2;
  214. property DesignPrice: Currency read FDesignPrice write FDesignPrice;
  215. end;
  216. TAdditinalTree = class(TScBillsTree)
  217. protected
  218. function CreateItem: TScIDTreeNode; override;
  219. procedure LoadItem(AItem: TScIDTreeNode); override;
  220. procedure InitDBRecord; override;
  221. end;
  222. implementation
  223. uses DataBase, SysUtils, Variants;
  224. { TScBillsItem }
  225. function TScBillsItem.CanDownLevel: Boolean;
  226. begin
  227. Result := inherited CanDownLevel
  228. // and not TDMDataBase(Bills).HasDrawingQuantity(PrevSiblingID)
  229. and not IsPreDefine; // 不是预定义项
  230. end;
  231. function TScBillsItem.CanDownMove: Boolean;
  232. begin
  233. Result := inherited CanDownMove and not IsPreDefine;
  234. end;
  235. function TScBillsItem.CanUpLevel: Boolean;
  236. begin
  237. Result := not IsPreDefine
  238. and ((Level > 1) or not IsInheritFrom(idFirstSection)) // 第一部分的项目Level必须大于1才能升级,其它部分不限制
  239. and inherited CanUpLevel;
  240. {and (
  241. { (NextSibling = nil)
  242. or (
  243. (HasChildren and not HasDrawingQuantity)
  244. )
  245. ); }
  246. // 说明: 当该项目不是预定义项,Levle>1并且满足一下条件时可以升级
  247. { 1: 没有后续兄弟节点的时候,可以升级
  248. 2: 有后续兄弟节点时,必须没有定额和自定义的金额(即:用户直接输入金额或计算式),
  249. 判断没有自定义金额的方法是: TotalPrice = 0 并且 没有子项。
  250. }
  251. { if not Result and TScBillsTree(Owner).FShowError then
  252. begin
  253. if HasDrawingQuantity then
  254. MessageWarning(0, '该项目下面有图纸工程量,不能升级');
  255. end; }
  256. end;
  257. function TScBillsItem.CanUpMove: Boolean;
  258. begin
  259. Result := inherited CanUpMove and not IsPreDefine;
  260. end;
  261. constructor TScBillsItem.Create(AOwner: TZjIDTree);
  262. begin
  263. inherited Create(AOwner);
  264. // FSelected := False;
  265. Bills := TScBillsTree(AOwner).Bills;
  266. end;
  267. function TScBillsItem.GetBillCategory: TBillCategory;
  268. begin
  269. Result := BillCategory(FSCode, FSBCode);
  270. end;
  271. function TScBillsItem.GetChapterID: Integer;
  272. var
  273. Node: TScIDTreeNode;
  274. begin
  275. Node := Self;
  276. while Node.Parent <> nil do
  277. begin
  278. if Node.Parent.ID in [idFirstSection, idSecondSection, idThreeSection] then
  279. begin
  280. Result := Node.ID;
  281. Exit;
  282. end;
  283. Node := Node.Parent;
  284. end;
  285. Result := ID;
  286. end;
  287. function TScBillsItem.GetCode: string;
  288. begin
  289. Result := VarToStr(Owner.DataSet.Lookup(SID, ID, sCode));
  290. end;
  291. function TScBillsItem.GetLastBudgetParent: TScBillsItem;
  292. var vItem: TScBillsItem;
  293. begin
  294. Result := nil;
  295. vItem := Self;
  296. while Assigned(vItem) do
  297. begin
  298. vItem := TScBillsItem(vItem.Parent);
  299. if (Trim(vItem.Code) <> '') and (Trim(vItem.B_Code) = '') then
  300. begin
  301. Result := vItem;
  302. Break;
  303. end;
  304. end;
  305. end;
  306. function TScBillsItem.GetNeed: Boolean;
  307. begin
  308. Result := not (IsRepeat or IsSuperscale);
  309. end;
  310. function TScBillsItem.GetTotalPrice(AIsTender: Boolean): Currency;
  311. const
  312. sResult: array[Boolean] of string = (STotalPrice, STenderTotalPrice);
  313. begin
  314. Result := ScVarToCurrency(TDMDataBase(Bills).cdsBills.Lookup(SID, ID, sResult[AIsTender]));
  315. end;
  316. function TScBillsItem.HasDrawingQuantity: Boolean;
  317. begin
  318. Result := TDMDataBase(Bills).HasDrawingQuantity(ID);
  319. end;
  320. function TScBillsItem.IsInheritFrom(AID: Integer): Boolean;
  321. var
  322. vAncestor: TScBillsItem;
  323. vItem: TScBillsItem;
  324. begin
  325. Result := False;
  326. vAncestor := TScBillsTree(Owner).BillsItem[AID];
  327. if vAncestor = nil then Exit;
  328. vItem := Self;
  329. while (vItem <> nil) and (vItem <> vAncestor) do
  330. vItem := TScBillsItem(vItem.Parent);
  331. Result := vItem = vAncestor;
  332. end;
  333. procedure TScBillsItem.SetSelected(const Value: Boolean);
  334. begin
  335. FSelected := Value;
  336. TDMDataBase(Bills).ModifySelected(ID, FSelected);
  337. end;
  338. procedure TScBillsItem.SyncSelected(aValue: Boolean);
  339. begin
  340. FSelected := aValue;
  341. end;
  342. { TScBillsTree }
  343. function TScBillsTree.Add(AParentID,
  344. ANextSiblingID: TScTreeNodeID): TScIDTreeNode;
  345. begin
  346. FShowError := True;
  347. try
  348. if (Selected <> nil) and (Selected.Level = 0) then
  349. begin
  350. if (Selected.ID in [idAggregate123, idBugetTotalPrice, idPricePerKM]) then
  351. Result := inherited Add(Selected.ParentID, Selected.NextSiblingID)
  352. else
  353. Result := inherited Add(Selected.ID, -1);
  354. end
  355. else
  356. Result := inherited Add(AParentID, ANextSiblingID);
  357. finally
  358. FShowError := False;
  359. end;
  360. end;
  361. function TScBillsTree.AddBillsItem(AParentID,
  362. ANextSiblingID: TScTreeNodeID): TScBillsItem;
  363. begin
  364. Result := TScBillsItem(Add(AParentID, ANextSiblingID));
  365. end;
  366. function TScBillsTree.AddBillsItem(AID, AParentID,
  367. ANextSiblingID: TScTreeNodeID): TScBillsItem;
  368. begin
  369. if not (Assigned(DataSet) and DataSet.Active){Active} then
  370. raise Exception.Create('无法在一个关闭的数据集上执行该操作');
  371. Result := nil;
  372. if CanAdd(AParentID, ANextSiblingID) then
  373. begin
  374. DataSet.Insert;
  375. ParentField.AsInteger := AParentID;
  376. NextSiblingField.AsInteger := ANextSiblingID;
  377. InitDBRecord;
  378. KeyField.AsInteger := AID;
  379. DataSet.Post;
  380. Result := TScBillsItem(inherited Add(KeyField.AsInteger, AParentID, ANextSiblingID));
  381. end;
  382. end;
  383. function TScBillsTree.CanAdd(AParentID,
  384. ANextSiblingID: TScTreeNodeID): Boolean;
  385. var
  386. ParentNode: TScBillsItem;
  387. begin
  388. ParentNode := BillsItem[AParentID];
  389. Result :=
  390. (ParentNode = nil)
  391. or not ParentNode.IsPreDefine
  392. or not(AParentID in [idAggregate123, idBugetTotalPrice, idProjectTotalPrice,
  393. idPricePerKM]);
  394. if not Result and FShowError then
  395. MessageWarning(0, ' 该项目下面不能添加子项 ');
  396. if ParentNode = nil then Exit;
  397. { if Result then
  398. begin
  399. Result := not TDMDataBase(Bills).HasDrawingQuantity(AParentID);
  400. if not Result and FShowError then
  401. MessageWarning(0, ' 父项下面图纸工程量,如果要添加子项,请先删除该项目下面的图纸工程量');
  402. end; }
  403. if Result then
  404. begin
  405. Result := (ParentNode.TotalPrice[False] = 0) or ParentNode.HasChildren; // 父项不能有用户直接输入的金额或计算公式
  406. if not Result and FShowError then
  407. MessageWarning(0, ' 父项有用户直接输入的金额或者计算公式,如果要添加子项,请先删除该项目的金额或计算公式 ');
  408. end;
  409. end;
  410. function TScBillsTree.CanDelete(ANode: TScIDTreeNode): Boolean;
  411. var
  412. IsPreDefine: Boolean;
  413. begin
  414. Result := False;
  415. if (ANode <> nil) and TDMDataBase(FBills).cdsBills.FindKey([ANode.ID]) then
  416. begin
  417. // 预定义项
  418. IsPreDefine := TDMDataBase(FBills).cdsBills.FieldByName('IsPreDefine').AsBoolean;
  419. if not IsPreDefine then // IsPreDefine字段值为空或False
  420. begin
  421. Result := True;
  422. if FShowError then
  423. begin
  424. // 固定ID清单项
  425. if (not TDMDataBase(FBills).cdsOrgBillsIsPreDefine.Value) and (TDMDataBase(FBills).cdsBillsID.value < 100) then
  426. Result := MessageQuest('提醒:清单[' + TDMDataBase(FBills).cdsBillsName.AsString +']是固定ID清单,删除后可以从右侧的清单范本中重新添加,'
  427. + #10#13 + '添加后其ID值不变。但若通过手工录入的方式添加则不具有此功能。确认要继续吗?', '确认删除');
  428. // 有子清单
  429. if TScBillsItem(ANode).HasChildren then
  430. Result := MessageQuest('确认要删除该清单项及其下面的所有子项吗?', '确认删除')
  431. // 没有子清单,但有定额或数量单价类
  432. else if TDMDataBase(FBills).HasDrawingQuantity(TScBillsItem(ANode).ID) then
  433. Result := MessageQuest('该清单项下有图纸工程量,确认要删除该清单项吗?', '确认删除');
  434. end;
  435. end
  436. // IsPreDefine字段值为True时不能删。
  437. else if FShowError then
  438. MessageWarning(0, '该项是预定义项,不能被删除 ');
  439. end;
  440. end;
  441. function TScBillsTree.CreateItem: TScIDTreeNode;
  442. begin
  443. Result := TScBillsItem.Create(Self);
  444. end;
  445. function TScBillsTree.DeleteNode(ANode: TScIDTreeNode): Boolean;
  446. begin
  447. FShowError := True;
  448. try
  449. Result := inherited DeleteNode(ANode);
  450. finally
  451. FShowError := False;
  452. end;
  453. end;
  454. function TScBillsTree.FindNode(AID: TZjTreeNodeID): TScBillsItem;
  455. begin
  456. Result := TScBillsItem(inherited FindNode(AID));
  457. end;
  458. function TScBillsTree.GetBillsItem(ID: Integer): TScBillsItem;
  459. begin
  460. Result := TScBillsItem(FindNode(ID));
  461. end;
  462. function TScBillsTree.GetItems(AIndex: Integer): TScBillsItem;
  463. begin
  464. Result := TScBillsItem(inherited Items[AIndex]);
  465. end;
  466. procedure TScBillsTree.InitDBRecord;
  467. begin
  468. if Assigned(FInternalEvent) then FInternalEvent;
  469. end;
  470. procedure TScBillsTree.LoadItem(AItem: TScIDTreeNode);
  471. begin
  472. inherited;
  473. with TScBillsItem(AItem) do
  474. begin
  475. FIsPreDefine := DataSet.FieldByName('IsPreDefine').AsBoolean;
  476. FSCode := DataSet.FieldByName(sCode).AsString;
  477. FSBCode := DataSet.FieldByName(sB_Code).AsString;
  478. FSName := DataSet.FieldByName(sName).AsString;
  479. FSelected := DataSet.FieldByName('Selected').AsBoolean;
  480. FUnits := DataSet.FieldByName('Units').AsString;
  481. FQuantity := DataSet.FieldByName('Quantity').AsFloat;
  482. FDesignQuantity := DataSet.FieldByName('DesignQuantity').AsFloat;
  483. FDesignQuantity2 := DataSet.FieldByName('DesignQuantity2').AsFloat;
  484. FIsSuperscale := DataSet.FieldByName('IsSuperscale').AsBoolean;
  485. FUserModified := DataSet.FieldByName('UserModified').AsBoolean;
  486. FIsIgNore := DataSet.FieldByName('IsIgNore').AsBoolean;
  487. FErrorHint := DataSet.FieldByName('ErrorHint').AsString;
  488. FDeductGrade := DataSet.FieldByName('DeductGrade').AsCurrency;
  489. FStandardGrade := DataSet.FieldByName('StandardGrade').AsCurrency;
  490. FLostPreSiblingCount := DataSet.FieldByName('LostPreSiblingCount').AsInteger;
  491. FLostChildrenCount := DataSet.FieldByName('LostChildrenCount').AsInteger;
  492. FLostNextSiblingCount := DataSet.FieldByName('LostNextSiblingCount').AsInteger;
  493. FNameErrorFlag := DataSet.FieldByName('NameErrorFlag').AsInteger;
  494. FUnitsErrorFlag := DataSet.FieldByName('UnitsErrorFlag').AsInteger;
  495. FRightName := DataSet.FieldByName('RightName').AsString;
  496. FRightUnits := DataSet.FieldByName('RightUnits').AsString;
  497. FIsAccQuantity := DataSet.FieldByName('IsAccQuantity').AsBoolean;
  498. end;
  499. end;
  500. { TStdBillNode }
  501. function TStdBillNode.GetHasYsxmjChild: Boolean;
  502. var i: Integer;
  503. vItem: TStdBillNode;
  504. begin
  505. Result := False;
  506. for i := 0 to ChildCount - 1 do
  507. begin
  508. vItem := TStdBillNode(Self.ChildNodes[i]);
  509. if vItem.Code <> '' then
  510. begin
  511. Result := True;
  512. Break;
  513. end;
  514. end;
  515. end;
  516. function TStdBillNode.GetLastBudgetParent: TStdBillNode;
  517. var vNode: TStdBillNode;
  518. begin
  519. Result := nil;
  520. vNode := Self;
  521. while Assigned(vNode) do
  522. begin
  523. vNode := TStdBillNode(vNode.Parent);
  524. if (vNode.FCode <> '') and (vNode.FBCode = '') then
  525. begin
  526. Result := vNode;
  527. Break;
  528. end;
  529. end;
  530. end;
  531. function TStdBillNode.GetStringValue(AIdx: Integer): string;
  532. begin
  533. case AIdx of
  534. 0: Result := FCode;
  535. 1: Result := FBCode;
  536. 2: Result := FName;
  537. 3: Result := FUnits;
  538. 4: Result := FNotes;
  539. 5: Result := FFee;
  540. 6: Result := FExpr;
  541. end;
  542. end;
  543. procedure TStdBillNode.SetStringValue(AIdx: Integer; Value: string);
  544. begin
  545. case AIdx of
  546. 0: FCode := Value;
  547. 1: FBCode := Value;
  548. 2: FName := Value;
  549. 3: FUnits := Value;
  550. 4: FNotes := Value;
  551. 5: FFee := Value;
  552. 6: FExpr := Value;
  553. end;
  554. end;
  555. function TStdBillNode.TopestAncestor(AList: TList): TStdBillNode;
  556. var
  557. vNode: TZjIDTreeNode;
  558. begin
  559. vNode := Self;
  560. while Assigned(vNode.Parent) do
  561. begin
  562. AList.Add(vNode.Parent);
  563. vNode := vNode.Parent;
  564. end;
  565. Result := TStdBillNode(vNode);
  566. end;
  567. { TStdBillsTree }
  568. function TStdBillsTree.CreateItem: TScIDTreeNode;
  569. begin
  570. Result := TStdBillNode.Create(Self);
  571. end;
  572. function TStdBillsTree.FindNode(ABItem: TScBillsItem; var ALostBItem: TScBillsItem;
  573. var ALostStdPaItem: TStdBillNode): TStdBillNode;
  574. var BGPaList: TList;
  575. vBPaItem: TScBillsItem;
  576. vStdItem, vStdItemChild: TStdBillNode;
  577. i, j: Integer;
  578. bFinded: Boolean;
  579. // 获取父结点列表,包括自身
  580. procedure GetBGParents;
  581. begin
  582. vBPaItem := ABItem;
  583. while Assigned(vBPaItem) do
  584. begin
  585. BGPaList.Add(vBPaItem);
  586. vBPaItem := TScBillsItem(vBPaItem.Parent);
  587. end;
  588. end;
  589. begin
  590. Result := nil;
  591. // 从标准项目表第一结点开始(1 第一部分 建筑安装工程费)
  592. vStdItem := TStdBillNode(Self.Items[0]);
  593. if ABItem.ID = 1 then
  594. begin
  595. Result := vStdItem;
  596. Exit;
  597. end;
  598. try
  599. BGPaList := TList.Create;
  600. GetBGParents;
  601. // 从次顶层父结点开始(如1-1),逐层往下搜索
  602. for i := BGPaList.Count - 2 downto 0 do
  603. begin
  604. vBPaItem := TScBillsItem(BGPaList[i]);
  605. bFinded := False;
  606. for j := 0 to vStdItem.ChildCount - 1 do
  607. begin
  608. vStdItemChild := TStdBillNode(vStdItem.ChildNodes[j]);
  609. if (vBPaItem.Code = vStdItemChild.Code) and (vBPaItem.FSBCode = vStdItemChild.FBCode) then
  610. begin
  611. vStdItem := vStdItemChild;
  612. if vBPaItem = ABItem then
  613. begin
  614. Result := vStdItem;
  615. Exit;
  616. end;
  617. bFinded := True;
  618. Break;
  619. end;
  620. end;
  621. if not bFinded then
  622. begin
  623. ALostBItem := vBPaItem;
  624. ALostStdPaItem := vStdItem;
  625. end;
  626. end;
  627. finally
  628. BGPaList.Free;
  629. end;
  630. end;
  631. function TStdBillsTree.FindNode(ACode, AB_Code: string): TStdBillNode;
  632. var i: Integer;
  633. vNode: TStdBillNode;
  634. begin
  635. Result := nil;
  636. for i := 0 to Count - 1 do
  637. begin
  638. vNode := TStdBillNode(Items[i]);
  639. if SameText(vNode.Code, ACode) and SameText(vNode.BCode, AB_Code) then
  640. begin
  641. Result := vNode;
  642. Break;
  643. end;
  644. end;
  645. end;
  646. procedure TStdBillsTree.LoadItem(AItem: TScIDTreeNode);
  647. begin
  648. with TStdBillNode(AItem) do
  649. begin
  650. Code := DataSet.FieldByName('Code').AsString;
  651. BCode := DataSet.FieldByName('B_Code').AsString;
  652. Name := DataSet.FieldByName('Name').AsString;
  653. Units := DataSet.FieldByName('Unit').AsString;
  654. Exprs := DataSet.FieldByName('Expr').AsString;
  655. if DataSet.FieldByName('StaticID').IsNull then
  656. StaticID := -1
  657. else
  658. StaticID := DataSet.FieldByName('StaticID').AsInteger;
  659. end;
  660. end;
  661. { TXMJBillsItem }
  662. function TXMJBillsItem.CanDownLevel: Boolean;
  663. begin
  664. Result := False;
  665. end;
  666. function TXMJBillsItem.CanUpLevel: Boolean;
  667. begin
  668. Result := False;
  669. end;
  670. { TXMJBillsTree }
  671. function TXMJBillsTree.CreateItem: TScIDTreeNode;
  672. begin
  673. Result := TXMJBillsItem.Create(Self);
  674. end;
  675. { TMergeTree }
  676. function TAdditinalTree.CreateItem: TScIDTreeNode;
  677. begin
  678. Result := TAdditionalItem.Create(Self);
  679. end;
  680. procedure TAdditinalTree.InitDBRecord;
  681. begin
  682. end;
  683. procedure TAdditinalTree.LoadItem(AItem: TScIDTreeNode);
  684. begin
  685. with TAdditionalItem(AItem) do
  686. begin
  687. FCode := DataSet.FieldByName(sCode).AsString;
  688. FB_Code := DataSet.FieldByName(sB_Code).AsString;
  689. FName := DataSet.FieldByName(sName).AsString;
  690. FUnits := DataSet.FieldByName(sUnits).AsString;
  691. FMemoStr := DataSet.FieldByName(sMemoStr).AsString;
  692. FOwnerName := DataSet.FieldByName(sOwnerName).AsString;
  693. FQuantity := DataSet.FieldByName(sQuantity).AsFloat;
  694. FQuantity2 := DataSet.FieldByName(sQuantity2).AsFloat;
  695. FUnitPrice := DataSet.FieldByName(sUnitPrice).AsCurrency;
  696. FTotalPrice := DataSet.FieldByName(STotalPrice).AsCurrency;
  697. FDesignQuantity := DataSet.FieldByName(sDesignQuantity).AsCurrency;
  698. FDesignQuantity2 := DataSet.FieldByName(sDesignQuantity2).AsCurrency;
  699. FDesignPrice := DataSet.FieldByName(sDesignPrice).AsCurrency;
  700. end;
  701. end;
  702. end.