123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- unit tpGatherTree;
- // 实际上可以使用mCacheTree中的ReportCacheTree
- // 但此处的树节点更多,使用的清单数据不多,为了便于理解,故重写
- interface
- uses
- Classes, CacheTree, mDataRecord, ZhAPI, sdDB, sdIDTree;
- type
- TtpGatherTreeNode = class(TCacheNode)
- private
- FCode: string;
- FB_Code: string;
- FName: string;
- FUnits: string;
- FPrice: Double;
- FQuantity: Double;
- FTotalPrice: Double;
- FDgnQuantity1: Double;
- FDgnQuantity2: Double;
- FRelaPeg: Boolean;
- FParted: Boolean;
- FDrawingCode: string;
- public
- property Code: string read FCode write FCode;
- property B_Code: string read FB_Code write FB_Code;
- property Name: string read FName write FName;
- property Units: string read FUnits write FUnits;
- property Price: Double read FPrice write FPrice;
- property Quantity: Double read FQuantity write FQuantity;
- property TotalPrice: Double read FTotalPrice write FTotalPrice;
- property DgnQuantity1: Double read FDgnQuantity1 write FDgnQuantity1;
- property DgnQuantity2: Double read FDgnQuantity2 write FDgnQuantity2;
- // 节点为桩号/节点的父项为桩号/节点的子项全为桩号
- property RelaPeg: Boolean read FRelaPeg write FRelaPeg;
- property Parted: Boolean read FParted write FParted;
- property DrawingCode: string read FDrawingCode write FDrawingCode;
- end;
- TtpGatherTree = class(TCacheTree)
- private
- function SamePrice(APrice1, APrice2: Double): Boolean;
- function GetParentParted(ANode: TtpGatherTreeNode): Boolean;
- procedure CheckNodeParted(ANode: TtpGatherTreeNode);
- function GetParentRelaPeg(ANode: TtpGatherTreeNode): Boolean;
- procedure CheckNodeRelaPeg(ANode: TtpGatherTreeNode);
- protected
- function GetNewNode: TCacheNode; override;
- public
- function FindNode(AParent: TtpGatherTreeNode; ARec: TBillsRecord): TtpGatherTreeNode;
- function FindNextSibling(AParent: TtpGatherTreeNode; ARec: TBillsRecord): TtpGatherTreeNode;
- function AddNode(AParent: TCacheNode; ANextSibling: TCacheNode = nil): TtpGatherTreeNode;
- procedure CalculateAllParent;
- procedure WriteData(ADataSet: TsdDataSet);
- procedure CheckRelaPeg;
- procedure CheckParted;
- end;
- implementation
- uses SysUtils;
- { TtpGatherTree }
- function TtpGatherTree.AddNode(AParent,
- ANextSibling: TCacheNode): TtpGatherTreeNode;
- begin
- Result := TtpGatherTreeNode(GetNewNode);
- if Assigned(ANextSibling) then
- ANextSibling.InsertPreSibling(Result)
- else if Assigned(AParent) then
- AParent.InsertChild(Result)
- else
- Root.InsertChild(Result);
- end;
- procedure TtpGatherTree.CalculateAllParent;
- function GatherChildren(ANode: TtpGatherTreeNode): Double;
- var
- vChild: TtpGatherTreeNode;
- begin
- Result := 0;
- if not Assigned(ANode) then Exit;
- vChild := TtpGatherTreeNode(ANode.FirstChild);
- while Assigned(vChild) do
- begin
- Result := Result + vChild.TotalPrice;
- vChild := TtpGatherTreeNode(vChild.NextSibling);
- end;
- end;
- procedure CalculateParent(ANode: TtpGatherTreeNode);
- begin
- if not Assigned(ANode) or not Assigned(ANode.FirstChild) then Exit;
- CalculateParent(TtpGatherTreeNode(ANode.FirstChild));
- ANode.TotalPrice := GatherChildren(ANode);
- CalculateParent(TtpGatherTreeNode(ANode.NextSibling));
- end;
- begin
- CalculateParent(TtpGatherTreeNode(Root.FirstChild));
- end;
- procedure TtpGatherTree.CheckNodeParted(ANode: TtpGatherTreeNode);
- begin
- if not Assigned(ANode) then Exit;
- if Assigned(ANode.FirstChild) then
- begin
- CheckNodeParted(TtpGatherTreeNode(ANode.FirstChild));
- ANode.Parted := GetParentParted(ANode);
- end;
- CheckNodeParted(TtpGatherTreeNode(ANode.NextSibling));
- end;
- procedure TtpGatherTree.CheckNodeRelaPeg(ANode: TtpGatherTreeNode);
- begin
- if not Assigned(ANode) then Exit;
- if Assigned(ANode.FirstChild) then
- begin
- CheckNodeRelaPeg(TtpGatherTreeNode(ANode.FirstChild));
- ANode.RelaPeg := GetParentRelaPeg(ANode);
- end;
- CheckNodeRelaPeg(TtpGatherTreeNode(ANode.NextSibling));
- end;
- procedure TtpGatherTree.CheckParted;
- begin
- CheckNodeParted(TtpGatherTreeNode(Root.FirstChild));
- end;
- procedure TtpGatherTree.CheckRelaPeg;
- begin
- CheckNodeRelaPeg(TtpGatherTreeNode(Root.FirstChild));
- end;
- function TtpGatherTree.FindNextSibling(AParent: TtpGatherTreeNode;
- ARec: TBillsRecord): TtpGatherTreeNode;
- var
- vNode: TtpGatherTreeNode;
- sCodeID, sCodeID2, sB_CodeID, sB_CodeID2: string;
- begin
- if Assigned(AParent) then
- vNode := TtpGatherTreeNode(AParent.FirstChild)
- else
- vNode := TtpGatherTreeNode(Root.FirstChild);
- Result := nil;
- if (ARec.Code.AsString = '') and (ARec.B_Code.AsString = '') then Exit;
- sCodeID := ConvertDigitCode(ARec.Code.AsString, 3, '-');
- sB_CodeID := ConvertDigitCode(ARec.B_Code.AsString, 4, '-');
- while Assigned(vNode) do
- begin
- sCodeID2 := ConvertDigitCode(vNode.Code, 3, '-');
- sB_CodeID2 := ConvertDigitCode(vNode.B_Code, 4, '-');
- if sCodeID < sCodeID2 then
- begin
- Result := vNode;
- Break;
- end
- else if sB_CodeID < sB_CodeID2 then
- begin
- Result := vNode;
- Break;
- end;
- vNode := TtpGatherTreeNode(vNode.NextSibling);
- end;
- end;
- function TtpGatherTree.FindNode(AParent: TtpGatherTreeNode; ARec: TBillsRecord): TtpGatherTreeNode;
- var
- vNode: TtpGatherTreeNode;
- begin
- if Assigned(AParent) then
- vNode := TtpGatherTreeNode(AParent.FirstChild)
- else
- vNode := TtpGatherTreeNode(Root.FirstChild);
- while Assigned(vNode) do
- begin
- if SameText(vNode.Code, ARec.Code.AsString) and
- SameText(vNode.B_Code, ARec.B_Code.AsString) and
- SameText(vNode.Name, ARec.Name.AsString) and
- SameText(vNode.Units, ARec.Units.AsString) and
- SamePrice(vNode.Price, ARec.Price.AsFloat) then
- begin
- Result := vNode;
- Break;
- end;
- vNode := TtpGatherTreeNode(vNode.NextSibling);
- end;
- end;
- function TtpGatherTree.GetNewNode: TCacheNode;
- begin
- Result := TtpGatherTreeNode.Create(Self, GetNewNodeID);
- CacheNodes.Add(Result);
- end;
- function TtpGatherTree.GetParentParted(ANode: TtpGatherTreeNode): Boolean;
- var
- i: Integer;
- vChild: TtpGatherTreeNode;
- begin
- if Assigned(ANode.FirstChild) then
- begin
- Result := True;
- vChild := TtpGatherTreeNode(ANode.FirstChild);
- while Assigned(vChild) and Result do
- begin
- Result := Result and vChild.Parted;
- vChild := TtpGatherTreeNode(vChild.NextSibling);
- end;
- end
- else
- Result := ANode.Parted;
- end;
- function TtpGatherTree.GetParentRelaPeg(ANode: TtpGatherTreeNode): Boolean;
- var
- i: Integer;
- vChild: TtpGatherTreeNode;
- begin
- if Assigned(ANode.FirstChild) then
- begin
- Result := True;
- vChild := TtpGatherTreeNode(ANode.FirstChild);
- while Assigned(vChild) and Result do
- begin
- Result := Result and vChild.RelaPeg;
- vChild := TtpGatherTreeNode(vChild.NextSibling);
- end;
- end
- else
- Result := ANode.RelaPeg;
- end;
- function TtpGatherTree.SamePrice(APrice1, APrice2: Double): Boolean;
- begin
- Result := (APrice1 - APrice2) < 0.001;
- end;
- procedure TtpGatherTree.WriteData(ADataSet: TsdDataSet);
- procedure BeforeWrite;
- begin
- ADataSet.DisableControls;
- ADataSet.BeginUpdate;
- ADataSet.DeleteAll;
- end;
- procedure AfterWrite;
- begin
- ADataSet.EndUpdate;
- ADataSet.EnableControls;
- end;
- var
- i: Integer;
- vNode: TtpGatherTreeNode;
- Rec: TsdDataRecord;
- begin
- BeforeWrite;
- try
- for i := 0 to CacheNodes.Count - 1 do
- begin
- vNode := TtpGatherTreeNode(CacheNodes.Items[i]);
- Rec := ADataSet.Add;
- Rec.ValueByName('ID').AsInteger := vNode.ID;
- Rec.ValueByName('ParentID').AsInteger := vNode.ParentID;
- Rec.ValueByName('NextSiblingID').AsInteger := vNode.NextSiblingID;
- Rec.ValueByName('Code').AsString := vNode.Code;
- Rec.ValueByName('B_Code').AsString := vNode.B_Code;
- Rec.ValueByName('Name').AsString := vNode.Name;
- Rec.ValueByName('Units').AsString := vNode.Units;
- Rec.ValueByName('Price').AsFloat := vNode.Price;
- Rec.ValueByName('Quantity').AsFloat := vNode.Quantity;
- Rec.ValueByName('TotalPrice').AsFloat := vNode.TotalPrice;
- Rec.ValueByName('DgnQuantity1').AsFloat := vNode.DgnQuantity1;
- Rec.ValueByName('DgnQuantity2').AsFloat := vNode.DgnQuantity2;
- Rec.ValueByName('DrawingCode').AsString := vNode.DrawingCode;
- end;
- finally
- AfterWrite;
- end;
- end;
- end.
|