unit rmBGLExecutionDm; interface uses SysUtils, Classes, ProjectData, DB, DBClient, sdIDTree, sdDB; type TGclNode = class private FQuantity: Double; FTotalPrice: Double; FPrice: Double; FUnits: string; FName: string; FB_Code: string; public 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; end; TXmjNode = class private FCode: string; FName: string; FUnits: string; FGclList: TList; public constructor Create; destructor Destroy; override; function AddGclNode(AB_Code: string): TGclNode; property Code: string read FCode write FCode; property Name: string read FName write FName; property Units: string read FUnits write FUnits; property GclList: TList read FGclList; end; TBGLNode = class private FBGLCode: string; FXmjList: TList; public constructor Create; destructor Destroy; override; function FindXmjNode(ACode: string): TXmjNode; function AddXmjNode(ACode: string): TXmjNode; property BGLCode: string read FBGLCode write FBGLCode; property XmjList: TList read FXmjList; end; TrmBGLExecutionData = class(TDataModule) cdsBGLExecution: TClientDataSet; cdsBGLExecutionBGLCode: TWideStringField; cdsBGLExecutionCode: TStringField; cdsBGLExecutionB_Code: TStringField; cdsBGLExecutionName: TWideStringField; cdsBGLExecutionUnits: TWideStringField; cdsBGLExecutionPrice: TFloatField; cdsBGLExecutionQuantity: TFloatField; cdsBGLExecutionTotalPrice: TFloatField; private FProjectData: TProjectData; FBGLList: TList; function FindBGLNode(ABGLCode: string): TBGLNode; function AddBGLNode(ABGLCode: string): TBGLNode; procedure FilterGclBills(ANode: TsdIDTreeNode); procedure FilterBills(ANode: TsdIDTreeNode); procedure WriteData; public function AssignData(AProjectData: TProjectData): TDataSet; end; implementation uses ZhAPI, UtilMethods, PhaseData, BillsCompileDm; {$R *.dfm} { TrmBGLExecutionData } function TrmBGLExecutionData.AddBGLNode(ABGLCode: string): TBGLNode; var Node: TBGLNode; i, iIndex: Integer; begin // 新增 Result := TBGLNode.Create; Result.BGLCode := ABGLCode; // List中根据顺序新增 iIndex := FBGLList.Count; for i := 0 to FBGLList.Count - 1 do begin Node := TBGLNode(FBGLList.Items[i]); if ABGLCode < Node.BGLCode then begin iIndex := i; Break; end; end; FBGLList.Insert(iIndex, Result); end; function TrmBGLExecutionData.AssignData( AProjectData: TProjectData): TDataSet; begin cdsBGLExecution.DisableControls; cdsBGLExecution.Active := True; cdsBGLExecution.EmptyDataSet; FBGLList := TList.Create; try FProjectData := AProjectData; FilterBills(AProjectData.BillsMeasureData.BillsMeasureTree.FirstNode); WriteData; Result := cdsBGLExecution; finally ClearObjects(FBGLList); FBGLList.Free; cdsBGLExecution.EnableControls; end; end; procedure TrmBGLExecutionData.FilterBills(ANode: TsdIDTreeNode); begin if not Assigned(ANode) then Exit; if not ANode.HasChildren then FilterGclBills(ANode); FilterBills(ANode.FirstChild); FilterBills(ANode.NextSibling); end; procedure TrmBGLExecutionData.FilterGclBills(ANode: TsdIDTreeNode); procedure AddBGLData(ABGLCode, ABGLNum: string); var BGLNode: TBGLNode; XmjNode: TXmjNode; GclNode: TGclNode; LeafXmjParent: TsdIDTreeNode; begin // BGL BGLNode := FindBGLNode(ABGLCode); if not Assigned(BGLNode) then BGLNode := AddBGLNode(ABGLCode); // Xmj with FProjectData.BillsCompileData do LeafXmjParent := BillsCompileTree.FindNode(GetLeafXmjParentID(ANode.ID)); XmjNode := BGLNode.FindXmjNode(LeafXmjParent.Rec.ValueByName('Code').AsString); if not Assigned(XmjNode) then XmjNode := BGLNode.AddXmjNode(LeafXmjParent.Rec.ValueByName('Code').AsString); XmjNode.Name := LeafXmjParent.Rec.ValueByName('Name').AsString; XmjNode.Units := LeafXmjParent.Rec.ValueByName('Units').AsString; // Gcl GclNode := XmjNode.AddGclNode(ANode.Rec.ValueByName('B_Code').AsString); GclNode.Name := ANode.Rec.ValueByName('Name').AsString; GclNode.FUnits := ANode.Rec.ValueByName('Units').AsString; GclNode.Price := ANode.Rec.ValueByName('Price').AsFloat; GclNode.Quantity := StrToFloatDef(ABGLNum, 0); GclNode.TotalPrice := GclNode.Quantity * GclNode.Price; end; var StageRec: TsdDataRecord; sgsCode, sgsNum: TStringList; i: Integer; begin StageRec := FProjectData.PhaseData.StageData.StageRecord(ANode.ID); if (ANode.Rec.ValueByName('B_Code').AsString = '') or (not Assigned(StageRec)) or (StageRec.ValueByName('QcBGLCode').AsString = '') then Exit; sgsCode := TStringList.Create; sgsNum := TStringList.Create; try sgsCode.Delimiter := ';'; sgsCode.DelimitedText := StageRec.ValueByName('QcBGLCode').AsString; sgsNum.Delimiter := ';'; sgsNum.DelimitedText := StageRec.ValueByName('QcBGLNum').AsString; for i := 0 to sgsCode.Count - 1 do AddBGLData(sgsCode[i], sgsNum[i]); finally sgsNum.Free; sgsCode.Free; end; end; function TrmBGLExecutionData.FindBGLNode(ABGLCode: string): TBGLNode; var iBGL: Integer; BGLNode: TBGLNode; begin Result := nil; for iBGL := 0 to FBGLList.Count - 1 do begin BGLNode := TBGLNode(FBGLList.Items[iBGL]); if SameText(BGLNode.BGLCode, ABGLCode) then begin Result := BGLNode; Break; end; end; end; procedure TrmBGLExecutionData.WriteData; procedure WriteGclData(AXmjNode: TXmjNode); var iGcl: Integer; GclNode: TGclNode; begin for iGcl := 0 to AXmjNode.GclList.Count - 1 do begin GclNode := TGclNode(AXmjNode.GclList.Items[iGcl]); cdsBGLExecution.Append; cdsBGLExecutionB_Code.AsString := GclNode.B_Code; cdsBGLExecutionName.AsString := GclNode.Name; cdsBGLExecutionUnits.AsString := GclNode.Units; cdsBGLExecutionPrice.AsFloat := GclNode.Price; cdsBGLExecutionQuantity.AsFloat := GclNode.Quantity; cdsBGLExecutionTotalPrice.AsFloat := GclNode.TotalPrice; cdsBGLExecution.Post; end; end; procedure WriteXmjData(ABGLNode: TBGLNode); var iXmj: Integer; XmjNode: TXmjNode; begin for iXmj := 0 to ABGLNode.XmjList.Count - 1 do begin XmjNode := TXmjNode(ABGLNode.XmjList.Items[iXmj]); cdsBGLExecution.Append; cdsBGLExecutionCode.AsString := XmjNode.Code; cdsBGLExecutionName.AsString := XmjNode.Name; cdsBGLExecutionUnits.AsString := XmjNode.Units; cdsBGLExecution.Post; WriteGclData(XmjNode); end; end; var iBGL: Integer; BGLNode: TBGLNode; begin for iBGL := 0 to FBGLList.Count - 1 do begin BGLNode := TBGLNode(FBGLList.Items[iBGL]); cdsBGLExecution.Append; cdsBGLExecutionBGLCode.AsString := BGLNode.BGLCode; cdsBGLExecution.Post; WriteXmjData(BGLNode); end; end; { TXmjNode } function TXmjNode.AddGclNode(AB_Code: string): TGclNode; var Node: TGclNode; i, iIndex: Integer; sB_Code1, sB_Code2: string; begin // 新增 Result := TGclNode.Create; Result.B_Code := AB_Code; // List中根据顺序新增 iIndex := FGclList.Count; sB_Code1 := B_CodeToIndexCode(AB_Code); for i := 0 to FGclList.Count - 1 do begin Node := TGclNode(FGclList.Items[i]); sB_Code2 := B_CodeToIndexCode(Node.B_Code); if sB_Code1 < sB_Code2 then begin iIndex := i; Break; end; end; FGclList.Insert(iIndex, Result); end; constructor TXmjNode.Create; begin FGclList := TList.Create; end; destructor TXmjNode.Destroy; begin ClearObjects(FGclList); FGclList.Free; inherited; end; { TBGLNode } function TBGLNode.AddXmjNode(ACode: string): TXmjNode; var Node: TXmjNode; i, iIndex: Integer; sCode1, sCode2: string; begin // 新增 Result := TXmjNode.Create; Result.Code := ACode; // List中根据顺序新增 iIndex := FXmjList.Count; sCode1 := ConvertDigitCode(ACode, 3); for i := 0 to FXmjList.Count - 1 do begin Node := TXmjNode(FXmjList.Items[i]); sCode2 := ConvertDigitCode(Node.Code, 3); if sCode1 < sCode2 then begin iIndex := i; Break; end; end; FXmjList.Insert(iIndex, Result); end; constructor TBGLNode.Create; begin FXmjList := TList.Create; end; destructor TBGLNode.Destroy; begin ClearObjects(FXmjList); FXmjList.Free; inherited; end; function TBGLNode.FindXmjNode(ACode: string): TXmjNode; var iXmj: Integer; XmjNode: TXmjNode; begin Result := nil; for iXmj := 0 to FXmjList.Count - 1 do begin XmjNode := TXmjNode(FXmjList.Items[iXmj]); if SameText(XmjNode.Code, ACode) then begin Result := XmjNode; Break; end; end; end; end.