unit rmHaBaiCustomizedDm; // 内蒙古 哈白项目定制汇总表 严禁任何其他项目或标表调用该单元 // 包括支表2/3/14/3-1/4-1 interface uses SysUtils, Classes, DB, rmSelectProjectFrm, ProjectData, mDataRecord, BillsTree, DBClient; type TDoubleArray = array of Double; TStringArray = array of string; TGclNode = class private FB_Code: string; FIndexCode: string; FName: string; FUnits: string; FPrice: Double; FQuantity: Double; FTotalPrice: Double; FCurGatherQuantity: Double; FCurGatherTotalPrice: Double; FEndGatherQuantity: Double; FEndGatherTotalPrice: Double; FPreGatherQuantity: Double; FPreGatherTotalPrice: Double; FP_Quantity: TDoubleArray; FP_TotalPrice: TDoubleArray; FP_CurGatherQuantity: TDoubleArray; FP_CurGatherTotalPrice: TDoubleArray; FP_EndGatherQuantity: TDoubleArray; FP_EndGatherTotalPrice: TDoubleArray; procedure SetB_Code(const Value: string); function GetCurPercent: Double; function GetEndPercent: Double; public constructor Create(AProjectCount: Integer); property B_Code: string read FB_Code write SetB_Code; property IndexCode: string read FIndexCode; 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 CurGatherQuantity: Double read FCurGatherQuantity write FCurGatherQuantity; property CurGatherTotalPrice: Double read FCurGatherTotalPrice write FCurGatherTotalPrice; property EndGatherQuantity: Double read FEndGatherQuantity write FEndGatherQuantity; property EndGatherTotalPrice: Double read FEndGatherTotalPrice write FEndGatherTotalPrice; property PreGatherQuantity: Double read FPreGatherQuantity write FPreGatherQuantity; property PreGatherTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice; property P_Quantity: TDoubleArray read FP_Quantity write FP_Quantity; property P_TotalPrice: TDoubleArray read FP_TotalPrice write FP_TotalPrice; property P_CurGatherQuantity: TDoubleArray read FP_CurGatherQuantity write FP_CurGatherQuantity; property P_CurGatherTotalPrice: TDoubleArray read FP_CurGatherTotalPrice write FP_CurGatherTotalPrice; property P_EndGatherQuantity: TDoubleArray read FP_EndGatherQuantity write FP_EndGatherQuantity; property P_EndGatherTotalPrice: TDoubleArray read FP_EndGatherTotalPrice write FP_EndGatherTotalPrice; property CurPercent: Double read GetCurPercent; property EndPercent: Double read GetEndPercent; end; TGclChapter = class private FProjectCount: Integer; FGclNodes: TList; FChapterID: Integer; FChapterBegin: Integer; FChapterEnd: Integer; FChapterName: string; FName: string; FTotalPrice: Double; FCurGatherTotalPrice: Double; FEndGatherTotalPrice: Double; FPreGatherTotalPrice: Double; FP_TotalPrice: TDoubleArray; FP_CurGatherTotalPrice: TDoubleArray; FP_EndGatherTotalPrice: TDoubleArray; function GetGclNode(AIndex: Integer): TGclNode; function GetGclNodeCount: Integer; function GetCurPercent: Double; function GetEndPercent: Double; public constructor Create(AChapterID: Integer; const AName: string; AProjectCount: Integer); destructor Destroy; override; procedure AddGclNode(AGclNode: TGclNode); procedure CalculateChapter; property ChapterID: Integer read FChapterID; property ChapterBegin: Integer read FChapterBegin; property ChapterEnd: Integer read FChapterEnd; property ChapterName: string read FChapterName; property Name: string read FName; property TotalPrice: Double read FTotalPrice write FTotalPrice; property CurGatherTotalPrice: Double read FCurGatherTotalPrice write FCurGatherTotalPrice; property EndGatherTotalPrice: Double read FEndGatherTotalPrice write FEndGatherTotalPrice; property PreGatherTotalPrice: Double read FPreGatherTotalPrice write FPreGatherTotalPrice; property P_TotalPrice: TDoubleArray read FP_TotalPrice write FP_TotalPrice; property P_CurGatherTotalPrice: TDoubleArray read FP_CurGatherTotalPrice write FP_CurGatherTotalPrice; property P_EndGatherTotalPrice: TDoubleArray read FP_EndGatherTotalPrice write FP_EndGatherTotalPrice; property CurPercent: Double read GetCurPercent; property EndPercent: Double read GetEndPercent; property GclNodeCount: Integer read GetGclNodeCount; property GclNode[AIndex: Integer]: TGclNode read GetGclNode; end; TGclControl = class private FProjectCount: Integer; FProjectName: TStringArray; FGclNodes: TList; FGclChapters: TList; FGclChapterGather: TGclChapter; FOtherGcl: TGclChapter; function FindGclNode(ARec: TBillsRecord): TGclNode; function NewGclNode(ARec: TBillsRecord): TGclNode; function B_CodeToChapter(const AB_Code: string): Integer; procedure LinkGclChapter(AGclNode: TGclNode); function FindGclChapter(AChapterID: Integer): TGclChapter; procedure CalculateChapterGather; function GetGclChapterCount: Integer; function GetGclChapter(AIndex: Integer): TGclChapter; public constructor Create(AProjectCount: Integer); destructor Destroy; function AddGclNode(ANode: TBillsIDTreeNode; AProjectIndex: Integer): TGclNode; procedure Calculate; property GclChapterCount: Integer read GetGclChapterCount; property GclChapter[AIndex: Integer]: TGclChapter read GetGclChapter; property GclChapterGather: TGclChapter read FGclChapterGather; property ProjectName: TStringArray read FProjectName write FProjectName; property ProjectCount: Integer read FProjectCount; end; TPayNode = class private FName: string; FIsMinus: Boolean; FCurTotalPrice: Double; FEndTotalPrice: Double; FPreTotalPrice: Double; public property Name: string read FName write FName; property IsMinus: Boolean read FIsMinus write FisMinus; property CurTotalPrice: Double read FCurTotalPrice write FCurTotalPrice; property EndTotalPrice: Double read FEndTotalPrice write FEndTotalPrice; property PreTotalPrice: Double read FPreTotalPrice write FPreTotalPrice; end; TDealPayControl = class private FPayNodes: TList; FGatherPayNode: TPayNode; function FindPayNode(const AName: string; AIsMinus: Boolean): TPayNode; function NewPayNode(const AName: string; AIsMinus: Boolean): TPayNode; function GetPayCount: Integer; function GetPayNode(AIndex: Integer): TPayNode; public constructor Create; destructor Destroy; override; function AddPayNode(const AName: string; AIsMinus: Boolean): TPayNode; property PayCount: Integer read GetPayCount; property PayNode[AIndex: Integer]: TPayNode read GetPayNode; property GatherPayNode: TPayNode read FGatherPayNode; end; // 分别对应5张定制汇总表的编号,详见文档 THaBaiGatherType = (hbgt2, hbgt3, hbgt14, hbgt3_1, hbgt4_1); TrmHaBaiCustomizedData = class(TDataModule) cdsCustom2: TClientDataSet; cdsCustom2Chapter: TIntegerField; cdsCustom2Name: TWideStringField; cdsCustom2TotalPrice: TFloatField; cdsCustom2CTotalPrice: TFloatField; cdsCustom2GTotalPrice: TFloatField; cdsCustom2EndGatherTotalPrice: TFloatField; cdsCustom2PreGatherTotalPrice: TFloatField; cdsCustom2CurGatherTotalPrice: TFloatField; cdsCustom2Percent: TFloatField; cdsCustom3: TClientDataSet; cdsCustom3ChapterID: TIntegerField; cdsCustom3InnerPartID: TIntegerField; cdsCustom3IndexCode: TStringField; cdsCustom3B_Code: TWideStringField; cdsCustom3Name: TWideStringField; cdsCustom3Units: TWideStringField; cdsCustom3Price: TFloatField; cdsCustom3Quantity: TFloatField; cdsCustom3TotalPrice: TFloatField; cdsCustom3PreGatherQuantity: TFloatField; cdsCustom3PreGatherTotalPrice: TFloatField; cdsCustom3EndGatherQuantity: TFloatField; cdsCustom3EndGatherTotalPrice: TFloatField; cdsCustom3CurGatherQuantity: TFloatField; cdsCustom3CurGatherTotalPrice: TFloatField; cdsCustom3Percent: TFloatField; cdsCustom14: TClientDataSet; cdsCustom14IndexCode: TWideStringField; cdsCustom14B_Code: TWideStringField; cdsCustom14Name: TWideStringField; cdsCustom14Units: TWideStringField; cdsCustom14Price: TFloatField; cdsCustom14Quantity: TFloatField; cdsCustom14TotalPrice: TFloatField; cdsCustom14CertificateCode: TWideStringField; cdsCustomProj: TClientDataSet; cdsCustomProjProjectID: TIntegerField; cdsCustomProjProjectName: TWideStringField; cdsCustomProjChapterID: TIntegerField; cdsCustomProjInnerPartID: TIntegerField; cdsCustomProjIndexCode: TWideStringField; cdsCustomProjB_Code: TWideStringField; cdsCustomProjName: TWideStringField; cdsCustomProjUnits: TWideStringField; cdsCustomProjPrice: TFloatField; cdsCustomProjQuantity: TFloatField; cdsCustomProjTotalPrice: TFloatField; cdsCustomProjCurGatherQuantity: TFloatField; cdsCustomProjCurGatherTotalPrice: TFloatField; cdsCustomProjEndGatherQuantity: TFloatField; cdsCustomProjEndGatherTotalPrice: TFloatField; cdsCustomProjP_CurGatherQuantity: TFloatField; cdsCustomProjP_CurGatherTotalPrice: TFloatField; cdsCustomProjP_EndGatherQuantity: TFloatField; cdsCustomProjP_EndGatherTotalPrice: TFloatField; cdsCustomProjCurPercent: TFloatField; cdsCustomProjEndPercent: TFloatField; cdsCustomProjSerialNo: TIntegerField; private FhbGatherType: THaBaiGatherType; FProjectData: TProjectData; FProjectName: string; FGclControl: TGclControl; FDealPayControl: TDealPayControl; procedure BeforeGather(AProjectCount: Integer); procedure AfterGather; procedure OpenProjectData(AProject: TSelectProject); procedure FreeProjectData; procedure GatherProject(AProject: TSelectProject; AProjectIndex: Integer); procedure FilterGcl(AProjectIndex: Integer); procedure FilterDealPay; procedure WriteFlowData; procedure WriteReport2; procedure WriteReport3; procedure WriteReport3_1; procedure WriteReport4_1; procedure WriteData; public function AssignData(AProjects: TList; AhbGatherType: THaBaiGatherType): TDataSet; end; implementation uses UtilMethods, ZhAPI, BillsCompileDm, sdDB, Globals, Math, BillsMeasureDm, ZJJLDm; {$R *.dfm} { TrmHaBaiCustomizedData } function TrmHaBaiCustomizedData.AssignData(AProjects: TList; AhbGatherType: THaBaiGatherType): TDataSet; var iProject: Integer; begin FhbGatherType := AhbGatherType; BeforeGather(AProjects.Count); try for iProject := 0 to AProjects.Count - 1 do GatherProject(TSelectProject(AProjects.Items[iProject]), iProject); FGclControl.Calculate; WriteData; finally AfterGather; case FhbGatherType of hbgt2: Result := cdsCustom2; hbgt3: Result := cdsCustom3; hbgt14: Result := cdsCustom14; hbgt3_1, hbgt4_1: Result := cdsCustomProj; end; end; end; procedure TrmHaBaiCustomizedData.BeforeGather(AProjectCount: Integer); begin cdsCustom2.DisableControls; cdsCustom2.Active := True; cdsCustom2.EmptyDataSet; cdsCustom3.DisableControls; cdsCustom3.Active := True; cdsCustom3.EmptyDataSet; cdsCustom14.DisableControls; cdsCustom14.Active := True; cdsCustom14.EmptyDataSet; cdsCustomProj.DisableControls; cdsCustomProj.Active := True; cdsCustomProj.EmptyDataSet; FGclControl := TGclControl.Create(AProjectCount); FDealPayControl := TDealPayControl.Create; end; procedure TrmHaBaiCustomizedData.AfterGather; begin FDealPayControl.Free; FGclControl.Free; cdsCustomProj.EnableControls; cdsCustom14.EnableControls; cdsCustom3.EnableControls; cdsCustom2.EnableControls; end; procedure TrmHaBaiCustomizedData.FreeProjectData; begin if not Assigned(OpenProjectManager.FindProjectData(FProjectData.ProjectID)) then FProjectData.Free; end; procedure TrmHaBaiCustomizedData.OpenProjectData(AProject: TSelectProject); var Rec: TsdDataRecord; begin FProjectData := OpenProjectManager.FindProjectData(AProject.ProjectID); Rec := ProjectManager.sddProjectsInfo.FindKey('idxID', AProject.ProjectID); if not Assigned(FProjectData) then begin FProjectData := TProjectData.Create; FProjectData.OpenForReport3(GetMyProjectsFilePath + Rec.ValueByName('FileName').AsString); end; FProjectName := Rec.ValueByName('Name').AsString; end; procedure TrmHaBaiCustomizedData.GatherProject(AProject: TSelectProject; AProjectIndex: Integer); begin OpenProjectData(AProject); try FGclControl.ProjectName[AProjectIndex] := FProjectName; if FhbGatherType in [hbgt2, hbgt3, hbgt3_1, hbgt4_1] then FilterGcl(AProjectIndex); if FhbGatherType = hbgt2 then FilterDealPay; if FhbGatherType = hbgt14 then WriteFlowData; finally FreeProjectData; end; end; procedure TrmHaBaiCustomizedData.FilterGcl(AProjectIndex: Integer); var i: Integer; vNode: TBillsIDTreeNode; GclNode: TGclNode; begin with FProjectData.BillsMeasureData do begin for i := 0 to BillsMeasureTree.Count - 1 do begin vNode := TBillsIDTreeNode(BillsMeasureTree.Items[i]); if not vNode.HasChildren and (vNode.Rec.B_Code.AsString <> '') then GclNode := FGclControl.AddGclNode(vNode, AProjectIndex); end; end; end; procedure TrmHaBaiCustomizedData.FilterDealPay; var sCurField, sPreField, sEndField: string; procedure GatherCommonDealPayData; var iRec: Integer; Rec, StageRec: TsdDataRecord; DealPay: TPayNode; begin with FProjectData.DealPaymentData do begin for iRec := 0 to sddDealPayment.RecordCount - 1 do begin Rec := sddDealPayment.Records[iRec]; if SameText(Rec.ValueByName('Name').AsString, '本期完成计量') or SameText(Rec.ValueByName('Name').AsString, '本期应付') or SameText(Rec.ValueByName('Name').AsString, '本期实付') then Continue; StageRec := FProjectData.PhaseData.PhasePayData.PayRecord(Rec.ValueByName('ID').AsInteger); DealPay := FDealPayControl.AddPayNode(Rec.ValueByName('Name').AsString, Rec.ValueByName('IsMinus').AsBoolean); DealPay.CurTotalPrice := DealPay.CurTotalPrice + StageRec.ValueByName(sCurField).AsFloat; DealPay.PreTotalPrice := DealPay.PreTotalPrice + StageRec.ValueByName(sPreField).AsFloat; DealPay.EndTotalPrice := DealPay.EndTotalPrice + StageRec.ValueByName(sEndField).AsFloat; end; end; end; procedure GatherPayData; var Rec, StageRec: TsdDataRecord; begin Rec := FProjectData.DealPaymentData.DealPayRecord('本期应付'); StageRec := FProjectData.PhaseData.PhasePayData.PayRecord(Rec.ValueByName('ID').AsInteger); with FDealPayControl.GatherPayNode do begin CurTotalPrice := CurTotalPrice + StageRec.ValueByName(sCurField).AsFloat; PreTotalPrice := PreTotalPrice + StageRec.ValueByName(sPreField).AsFloat; EndTotalPrice := EndTotalPrice + StageRec.ValueByName(sEndField).AsFloat; end; end; begin sCurField := 'TotalPrice' + IntToStr(FProjectData.PhaseData.AuditCount); sPreField := 'PreTotalPrice' + IntToStr(FProjectData.PhaseData.AuditCount); sEndField := 'EndTotalPrice' + IntToStr(FProjectData.PhaseData.AuditCount); GatherCommonDealPayData; GatherPayData; end; procedure TrmHaBaiCustomizedData.WriteData; begin case FhbGatherType of hbgt2: WriteReport2; hbgt3: WriteReport3; hbgt3_1: WriteReport3_1; hbgt4_1: WriteReport4_1; end; end; procedure TrmHaBaiCustomizedData.WriteReport2; procedure WriteGclChapter(AGclChapter: TGclChapter; const AName: string = ''); begin cdsCustom2.Append; if AGclChapter.ChapterBegin > 0 then cdsCustom2Chapter.AsInteger := AGclChapter.ChapterBegin; if AName = '' then cdsCustom2Name.AsString := AGclChapter.Name else cdsCustom2Name.AsString := AName; cdsCustom2TotalPrice.AsFloat := AGclChapter.TotalPrice; cdsCustom2GTotalPrice.AsFloat := AGclChapter.TotalPrice; cdsCustom2EndGatherTotalPrice.AsFloat := AGclChapter.EndGatherTotalPrice; cdsCustom2PreGatherTotalPrice.AsFloat := AGclChapter.PreGatherTotalPrice; cdsCustom2CurGatherTotalPrice.AsFloat := AGclChapter.CurGatherTotalPrice; cdsCustom2Percent.AsFloat := AGclChapter.EndPercent; cdsCustom2.Post; end; procedure WriteBlankRecord(const AName: string); begin cdsCustom2.Append; cdsCustom2Name.AsString := AName; cdsCustom2.Post; end; procedure WritePayNode(APayNode: TPayNode; const AName: string = ''); begin cdsCustom2.Append; if AName = '' then cdsCustom2Name.AsString := APayNode.Name else cdsCustom2Name.AsString := AName; cdsCustom2EndGatherTotalPrice.AsFloat := APayNode.EndTotalPrice; cdsCustom2PreGatherTotalPrice.AsFloat := APayNode.PreTotalPrice; cdsCustom2CurGatherTotalPrice.AsFloat := APayNode.CurTotalPrice; cdsCustom2.Post; end; var iIndex: Integer; begin for iIndex := 0 to FGclControl.GclChapterCount - 1 do WriteGclChapter(FGclControl.GclChapter[iIndex]); WriteGclChapter(FGclControl.GclChapterGather); WriteGclChapter(FGclControl.GclChapterGather, '小 计'); WriteBlankRecord('价格调整'); WriteBlankRecord('违约罚金'); WriteBlankRecord('迟付款利息'); WriteGclChapter(FGclControl.GclChapterGather, '合 计'); for iIndex := 0 to FDealPayControl.PayCount - 1 do WritePayNode(FDealPayControl.PayNode[iIndex]); WritePayNode(FDealPayControl.GatherPayNode, '支 付'); end; procedure TrmHaBaiCustomizedData.WriteReport3; procedure WriteChapterName(AGclChapter: TGclChapter); begin cdsCustom3.Append; cdsCustom3ChapterID.AsInteger := AGclChapter.ChapterID; cdsCustom3InnerPartID.AsInteger := 1; cdsCustom3B_Code.AsString := AGclChapter.ChapterName; cdsCustom3Name.AsString := AGclChapter.Name; cdsCustom3.Post; end; procedure WriteGclNodeData(AGclNode: TGclNode; AChapterID: Integer); begin cdsCustom3.Append; cdsCustom3ChapterID.AsInteger := AChapterID; cdsCustom3InnerPartID.AsInteger := 2; cdsCustom3IndexCode.AsString := AGclNode.IndexCode; cdsCustom3B_Code.AsString := AGclNode.B_Code; cdsCustom3Name.AsString := AGclNode.Name; cdsCustom3Units.AsString := AGclNode.Units; cdsCustom3Price.AsFloat := AGclNode.Price; cdsCustom3Quantity.AsFloat := AGclNode.Quantity; cdsCustom3TotalPrice.AsFloat := AGclNode.TotalPrice; cdsCustom3CurGatherQuantity.AsFloat := AGclNode.CurGatherQuantity; cdsCustom3CurGatherTotalPrice.AsFloat := AGclNode.CurGatherTotalPrice; cdsCustom3EndGatherQuantity.AsFloat := AGclNode.EndGatherQuantity; cdsCustom3EndGatherTotalPrice.AsFloat := AGclNode.EndGatherTotalPrice; cdsCustom3PreGatherQuantity.AsFloat := AGclNode.PreGatherQuantity; cdsCustom3PreGatherTotalPrice.AsFloat := AGclNode.PreGatherTotalPrice; cdsCustom3Percent.AsFloat := AGclNode.EndPercent; cdsCustom3.Post; end; procedure WriteChapterGather(AGclChapter: TGclChapter; const AName: string = ''); begin cdsCustom3.Append; cdsCustom3ChapterID.AsInteger := AGclChapter.ChapterID; cdsCustom3InnerPartID.AsInteger := 3; if AName = '' then cdsCustom3Name.AsString := AGclChapter.Name else cdsCustom3Name.AsString := AName; cdsCustom3TotalPrice.AsFloat := AGclChapter.TotalPrice; cdsCustom3CurGatherTotalPrice.AsFloat := AGclChapter.CurGatherTotalPrice; cdsCustom3EndGatherTotalPrice.AsFloat := AGclChapter.EndGatherTotalPrice; cdsCustom3PreGatherTotalPrice.AsFloat := AGclChapter.PreGatherTotalPrice; cdsCustom3Percent.AsFloat := AGclChapter.EndPercent; cdsCustom3.Post; end; procedure WriteGclChapterData(AGclChapter: TGclChapter); var iGcl: Integer; begin if AGclChapter.GclNodeCount = 0 then Exit; WriteChapterName(AGclChapter); for iGcl := 0 to AGclChapter.GclNodeCount - 1 do WriteGclNodeData(AGclChapter.GclNode[iGcl], AGclChapter.ChapterID); WriteChapterGather(AGclChapter, Format('%s 小计', [AGclChapter.ChapterName])); end; var iIndex: Integer; begin for iIndex := 0 to FGclControl.GclChapterCount - 1 do WriteGclChapterData(FGclControl.GclChapter[iIndex]); WriteChapterGather(FGclControl.GclChapterGather, '第100章~第900章 合计'); end; procedure TrmHaBaiCustomizedData.WriteReport3_1; var iProject, iChapter: Integer; sProjectName: string; procedure WriteChapterName(AGclChapter: TGclChapter); begin cdsCustomProj.Append; cdsCustomProjProjectID.AsInteger := iProject; cdsCustomProjProjectName.AsString := sProjectName; cdsCustomProjChapterID.AsInteger := AGclChapter.ChapterID; cdsCustomProjInnerPartID.AsInteger := 1; cdsCustomProjB_Code.AsString := AGclChapter.ChapterName; cdsCustomProjName.AsString := AGclChapter.Name; cdsCustomProj.Post; end; procedure WriteGclNodeData(AGclNode: TGclNode; AChapterID: Integer); begin cdsCustomProj.Append; cdsCustomProjProjectID.AsInteger := iProject; cdsCustomProjProjectName.AsString := sProjectName; cdsCustomProjChapterID.AsInteger := AChapterID; cdsCustomProjInnerPartID.AsInteger := 2; cdsCustomProjIndexCode.AsString := AGclNode.IndexCode; cdsCustomProjB_Code.AsString := AGclNode.B_Code; cdsCustomProjName.AsString := AGclNode.Name; cdsCustomProjUnits.AsString := AGclNode.Units; cdsCustomProjPrice.AsFloat := AGclNode.Price; cdsCustomProjQuantity.AsFloat := AGclNode.Quantity; cdsCustomProjTotalPrice.AsFloat := AGclNode.TotalPrice; cdsCustomProjCurGatherQuantity.AsFloat := AGclNode.CurGatherQuantity; cdsCustomProjCurGatherTotalPrice.AsFloat := AGclNode.CurGatherTotalPrice; cdsCustomProjEndGatherQuantity.AsFloat := AGclNode.EndGatherQuantity; cdsCustomProjEndGatherTotalPrice.AsFloat := AGclNode.EndGatherTotalPrice; cdsCustomProjP_CurGatherQuantity.AsFloat := AGclNode.P_CurGatherQuantity[iProject]; cdsCustomProjP_CurGatherTotalPrice.AsFloat := AGclNode.P_CurGatherTotalPrice[iProject]; cdsCustomProjP_EndGatherQuantity.AsFloat := AGclNode.P_EndGatherQuantity[iProject]; cdsCustomProjP_EndGatherTotalPrice.AsFloat := AGclNode.P_EndGatherTotalPrice[iProject]; cdsCustomProjCurPercent.AsFloat := AGclNode.CurPercent; cdsCustomProjEndPercent.AsFloat := AGclNode.EndPercent; cdsCustomProj.Post; end; procedure WriteChapterGather(AGclChapter: TGclChapter; const AName: string = ''); begin cdsCustomProj.Append; cdsCustomProjProjectID.AsInteger := iProject; cdsCustomProjProjectName.AsString := sProjectName; cdsCustomProjChapterID.AsInteger := AGclChapter.ChapterID; cdsCustomProjInnerPartID.AsInteger := 3; if AName = '' then cdsCustomProjName.AsString := AGclChapter.Name else cdsCustomProjName.AsString := AName; cdsCustomProjTotalPrice.AsFloat := AGclChapter.TotalPrice; cdsCustomProjCurGatherTotalPrice.AsFloat := AGclChapter.CurGatherTotalPrice; cdsCustomProjEndGatherTotalPrice.AsFloat := AGclChapter.EndGatherTotalPrice; cdsCustomProjP_CurGatherTotalPrice.AsFloat := AGclChapter.P_CurGatherTotalPrice[iProject]; cdsCustomProjP_EndGatherTotalPrice.AsFloat := AGclChapter.P_EndGatherTotalPrice[iProject]; cdsCustomProjCurPercent.AsFloat := AGclChapter.CurPercent; cdsCustomProjEndPercent.AsFloat := AGclChapter.EndPercent; cdsCustomProj.Post; end; procedure WriteGclChapterData(AGclChapter: TGclChapter); var iGcl: Integer; begin if AGclChapter.GclNodeCount = 0 then Exit; WriteChapterName(AGclChapter); for iGcl := 0 to AGclChapter.GclNodeCount - 1 do WriteGclNodeData(AGclChapter.GclNode[iGcl], AGclChapter.ChapterID); WriteChapterGather(AGclChapter, Format('%s 小计', [AGclChapter.ChapterName])); end; begin for iProject := 0 to FGclControl.ProjectCount - 1 do begin sProjectName := FGclControl.ProjectName[iProject]; for iChapter := 0 to FGclControl.GclChapterCount - 1 do WriteGclChapterData(FGclControl.GclChapter[iChapter]); WriteChapterGather(FGclControl.GclChapterGather, '第100章至第900章 合计'); end; end; procedure TrmHaBaiCustomizedData.WriteReport4_1; var iProject, iChapter, iSerial: Integer; sProjectName: string; procedure WriteGclNodeData(AGclNode: TGclNode; AChapterID: Integer); begin cdsCustomProj.Append; cdsCustomProjProjectID.AsInteger := iProject; cdsCustomProjProjectName.AsString := sProjectName; cdsCustomProjChapterID.AsInteger := AChapterID; cdsCustomProjInnerPartID.AsInteger := 2; cdsCustomProjIndexCode.AsString := AGclNode.IndexCode; cdsCustomProjB_Code.AsString := AGclNode.B_Code; cdsCustomProjName.AsString := AGclNode.Name; cdsCustomProjUnits.AsString := AGclNode.Units; cdsCustomProjPrice.AsFloat := AGclNode.Price; cdsCustomProjQuantity.AsFloat := AGclNode.Quantity; cdsCustomProjTotalPrice.AsFloat := AGclNode.TotalPrice; cdsCustomProjCurGatherQuantity.AsFloat := AGclNode.CurGatherQuantity; cdsCustomProjCurGatherTotalPrice.AsFloat := AGclNode.CurGatherTotalPrice; cdsCustomProjEndGatherQuantity.AsFloat := AGclNode.EndGatherQuantity; cdsCustomProjEndGatherTotalPrice.AsFloat := AGclNode.EndGatherTotalPrice; cdsCustomProjP_CurGatherQuantity.AsFloat := AGclNode.P_CurGatherQuantity[iProject]; cdsCustomProjP_CurGatherTotalPrice.AsFloat := AGclNode.P_CurGatherTotalPrice[iProject]; cdsCustomProjP_EndGatherQuantity.AsFloat := AGclNode.P_EndGatherQuantity[iProject]; cdsCustomProjP_EndGatherTotalPrice.AsFloat := AGclNode.P_EndGatherTotalPrice[iProject]; cdsCustomProjCurPercent.AsFloat := AGclNode.CurPercent; cdsCustomProjEndPercent.AsFloat := AGclNode.EndPercent; cdsCustomProj.Post; end; procedure WriteGclChapterData(AGclChapter: TGclChapter); var iGcl: Integer; begin if AGclChapter.GclNodeCount = 0 then Exit; for iGcl := 0 to AGclChapter.GclNodeCount - 1 do WriteGclNodeData(AGclChapter.GclNode[iGcl], AGclChapter.ChapterID); end; procedure WriteChapterGather(AGclChapter: TGclChapter; const AName: string = ''); begin cdsCustomProj.Append; cdsCustomProjProjectID.AsInteger := iProject; cdsCustomProjProjectName.AsString := sProjectName; cdsCustomProjChapterID.AsInteger := AGclChapter.ChapterID; cdsCustomProjInnerPartID.AsInteger := 3; if AName = '' then cdsCustomProjName.AsString := AGclChapter.Name else cdsCustomProjName.AsString := AName; cdsCustomProjTotalPrice.AsFloat := AGclChapter.TotalPrice; cdsCustomProjCurGatherTotalPrice.AsFloat := AGclChapter.CurGatherTotalPrice; cdsCustomProjEndGatherTotalPrice.AsFloat := AGclChapter.EndGatherTotalPrice; cdsCustomProjP_CurGatherTotalPrice.AsFloat := AGclChapter.P_CurGatherTotalPrice[iProject]; cdsCustomProjP_EndGatherTotalPrice.AsFloat := AGclChapter.P_EndGatherTotalPrice[iProject]; cdsCustomProjCurPercent.AsFloat := AGclChapter.CurPercent; cdsCustomProjEndPercent.AsFloat := AGclChapter.EndPercent; cdsCustomProj.Post; end; procedure ResortSerialNo; var iSerialNo, iProject: Integer; begin iSerialNo := 1; cdsCustomProj.First; iProject := cdsCustomProjProjectID.AsInteger; while not cdsCustomProj.Eof do begin if iProject <> cdsCustomProjProjectID.AsInteger then begin iProject := cdsCustomProjProjectID.AsInteger; iSerialNo := 1; end; cdsCustomProj.Edit; cdsCustomProjSerialNo.AsInteger := iSerialNo; cdsCustomProj.Post; Inc(iSerialNo); cdsCustomProj.Next; end; end; begin for iProject := 0 to FGclControl.ProjectCount - 1 do begin sProjectName := FGclControl.ProjectName[iProject]; for iChapter := 0 to FGclControl.GclChapterCount - 1 do WriteGclChapterData(FGclControl.GclChapter[iChapter]); WriteChapterGather(FGclControl.GclChapterGather, '第100章至第900章 合计'); end; ResortSerialNo; end; procedure TrmHaBaiCustomizedData.WriteFlowData; procedure AddNodeData(ANode: TBillsIDTreeNode); begin cdsCustom14.Append; cdsCustom14IndexCode.AsString := ANode.Rec.IndexCode.AsString; cdsCustom14B_Code.AsString := ANode.Rec.B_Code.AsString; cdsCustom14Name.AsString := ANode.Rec.Name.AsString; cdsCustom14Units.AsString := ANode.Rec.Units.AsString; cdsCustom14Price.AsFloat := ANode.Rec.Price.AsFloat; cdsCustom14Quantity.AsFloat := ANode.StageRec.GatherQuantity.AsFloat; cdsCustom14TotalPrice.AsFloat := ANode.StageRec.GatherTotalPrice.AsFloat; with FProjectData.PhaseData.ZJJLData do if cdsZJJL.Locate('BillsID', ANode.ID, []) then cdsCustom14CertificateCode.AsString := cdsZJJLCertificateCode.AsString; cdsCustom14.Post; end; var iIndex: Integer; vNode: TBillsIDTreeNode; begin for iIndex := 0 to FProjectData.BillsMeasureData.BillsMeasureTree.Count - 1 do begin vNode := TBillsIDTreeNode(FProjectData.BillsMeasureData.BillsMeasureTree.Items[iIndex]); if (not vNode.HasChildren) and (vNode.Rec.B_Code.AsString <> '') and Assigned(vNode.StageRec) and (vNode.StageRec.GatherTotalPrice.AsFloat <> 0) then AddNodeData(vNode); end; end; { TGclNode } constructor TGclNode.Create(AProjectCount: Integer); begin SetLength(FP_Quantity, AProjectCount); SetLength(FP_TotalPrice, AProjectCount); SetLength(FP_CurGatherQuantity, AProjectCount); SetLength(FP_CurGatherTotalPrice, AProjectCount); SetLength(FP_EndGatherQuantity, AProjectCount); SetLength(FP_EndGatherTotalPrice, AProjectCount); end; function TGclNode.GetCurPercent: Double; begin if TotalPrice <> 0 then Result := CurGatherTotalPrice/TotalPrice*100 else Result := 0; end; function TGclNode.GetEndPercent: Double; begin if TotalPrice <> 0 then Result := EndGatherTotalPrice/TotalPrice*100 else Result := 0; end; procedure TGclNode.SetB_Code(const Value: string); begin FB_Code := Value; FIndexCode := B_CodeToIndexCode(FB_Code); end; { TGclControl } function TGclControl.AddGclNode(ANode: TBillsIDTreeNode; AProjectIndex: Integer): TGclNode; begin Result := FindGclNode(ANode.Rec); if not Assigned(Result) then Result := NewGclNode(ANode.Rec); with ANode.Rec do begin Result.Quantity := Result.Quantity + Quantity.AsFloat; Result.TotalPrice := Result.TotalPrice + TotalPrice.AsFloat; Result.P_Quantity[AProjectIndex] := Result.P_Quantity[AProjectIndex] + Quantity.AsFloat; Result.P_TotalPrice[AProjectIndex] := Result.P_TotalPrice[AProjectIndex] + TotalPrice.AsFloat; end; if Assigned(ANode.StageRec) then with ANode.StageRec do begin Result.CurGatherQuantity := Result.CurGatherQuantity + GatherQuantity.AsFloat; Result.CurGatherTotalPrice := Result.CurGatherTotalPrice + GatherTotalPrice.AsFloat; Result.P_CurGatherQuantity[AProjectIndex] := Result.P_CurGatherQuantity[AProjectIndex] + GatherQuantity.AsFloat; Result.P_CurGatherTotalPrice[AProjectIndex] := Result.P_CurGatherTotalPrice[AProjectIndex] + GatherTotalPrice.AsFloat; Result.EndGatherQuantity := Result.EndGatherQuantity + EndGatherQuantity.AsFloat; Result.EndGatherTotalPrice := Result.EndGatherTotalPrice + EndGatherTotalPrice.AsFloat; Result.P_EndGatherQuantity[AProjectIndex] := Result.P_EndGatherQuantity[AProjectIndex] + EndGatherQuantity.AsFloat; Result.P_EndGatherTotalPrice[AProjectIndex] := Result.P_EndGatherTotalPrice[AProjectIndex] + EndGatherTotalPrice.AsFloat; Result.PreGatherQuantity := Result.PreGatherQuantity + PreGatherQuantity.AsFloat; Result.PreGatherTotalPrice := Result.PreGatherTotalPrice + PreGatherTotalPrice.AsFloat; end; end; function TGclControl.B_CodeToChapter(const AB_Code: string): Integer; var sgs: TStrings; iFirst, iSecond: Integer; begin Result := 0; sgs := TStringList.Create; try sgs.Delimiter := '-'; sgs.DelimitedText := AB_Code; iFirst := StrToIntDef(sgs.Strings[0], 0); Result := Trunc(iFirst/100); if (Result >= 90) and (Result < 100) then Result := 9; finally sgs.Free; end; end; procedure TGclControl.CalculateChapterGather; var iIndex, iProject: Integer; vGclChapter: TGclChapter; begin FGclChapterGather.TotalPrice := 0; FGclChapterGather.CurGatherTotalPrice := 0; FGclChapterGather.EndGatherTotalPrice := 0; FGclChapterGather.PreGatherTotalPrice := 0; for iProject := 0 to FProjectCount - 1 do begin FGclChapterGather.P_TotalPrice[iProject] := 0; FGclChapterGather.P_CurGatherTotalPrice[iProject] := 0; FGclChapterGather.P_EndGatherTotalPrice[iProject] := 0; end; for iIndex := 0 to FGclChapters.Count - 1 do begin vGclChapter := TGclChapter(FGclChapters.Items[iIndex]); with FGclChapterGather do begin TotalPrice := TotalPrice + vGclChapter.TotalPrice; CurGatherTotalPrice := CurGatherTotalPrice + vGclChapter.CurGatherTotalPrice; EndGatherTotalPrice := EndGatherTotalPrice + vGclChapter.EndGatherTotalPrice; PreGatherTotalPrice := PreGatherTotalPrice + vGclChapter.PreGatherTotalPrice; for iProject := 0 to FProjectCount - 1 do begin P_TotalPrice[iProject] := P_TotalPrice[iProject] + vGclChapter.P_TotalPrice[iProject]; P_CurGatherTotalPrice[iProject] := P_CurGatherTotalPrice[iProject] + vGclChapter.P_CurGatherTotalPrice[iProject]; P_EndGatherTotalPrice[iProject] := P_EndGatherTotalPrice[iProject] + vGclChapter.P_EndGatherTotalPrice[iProject]; end; end; end; end; constructor TGclControl.Create(AProjectCount: Integer); function CreateGclChapter(AChapterID: Integer; const AName: string): TGclChapter; begin Result := TGclChapter.Create(AChapterID, AName, FProjectCount); FGclChapters.Add(Result); end; begin FProjectCount := AProjectCount; SetLength(FProjectName, AProjectCount); FGclNodes := TList.Create; FGclChapters := TList.Create; CreateGclChapter(1, '总 则'); CreateGclChapter(2, '路 基'); CreateGclChapter(3, '路 面'); CreateGclChapter(4, '桥梁、涵洞工程'); CreateGclChapter(5, '隧 道'); CreateGclChapter(6, '安全设计及预埋管线'); CreateGclChapter(7, '绿化及环境保护工程'); CreateGclChapter(8, '房建工程'); CreateGclChapter(9, '机电工程'); FOtherGcl := TGclChapter.Create(19, '非标准清单', FProjectCount); FGclChapterGather := TGclChapter.Create(20, '第100章至900章合计', FProjectCount); end; destructor TGclControl.Destroy; begin FOtherGcl.Free; FGclChapterGather.Free; ClearObjects(FGclChapters); FGclChapters.Free; ClearObjects(FGclNodes); FGclNodes.Free; end; function TGclControl.FindGclNode(ARec: TBillsRecord): TGclNode; var iIndex: Integer; vGclNode: TGclNode; bSameCode, bSameName, bSameUnits, bSamePrice: Boolean; begin Result := nil; for iIndex := 0 to FGclNodes.Count - 1 do begin vGclNode := TGclNode(FGclNodes.Items[iIndex]); if (vGclNode.B_Code = ARec.B_Code.AsString) and (vGclNode.Name = ARec.Name.AsString) and (vGclNode.Units = ARec.Units.AsString) and (vGclNode.Price = ARec.Price.AsFloat) then begin Result := vGclNode; Break; end; end; end; function TGclControl.FindGclChapter(AChapterID: Integer): TGclChapter; var iIndex: Integer; vChapter: TGclChapter; begin Result := nil; for iIndex := 0 to FGclChapters.Count - 1 do begin vChapter := TGclChapter(FGclChapters.Items[iIndex]); if vChapter.ChapterID = AChapterID then begin Result := vChapter; Break; end; end; end; function TGclControl.GetGclChapter(AIndex: Integer): TGclChapter; begin Result := TGclChapter(FGclChapters.Items[AIndex]); end; function TGclControl.GetGclChapterCount: Integer; begin Result := FGclChapters.Count; end; procedure TGclControl.LinkGclChapter(AGclNode: TGclNode); var iChapterID: Integer; vChapter: TGclChapter; begin iChapterID := B_CodeToChapter(AGclNode.B_Code); vChapter := FindGclChapter(iChapterID); if Assigned(vChapter) then vChapter.AddGclNode(AGclNode) else FOtherGcl.AddGclNode(AGclNode); end; function TGclControl.NewGclNode(ARec: TBillsRecord): TGclNode; begin Result := TGclNode.Create(FProjectCount); FGclNodes.Add(Result); Result.B_Code := ARec.B_Code.AsString; Result.Name := ARec.Name.AsString; Result.Units := ARec.Units.AsString; Result.Price := ARec.Price.AsFloat; LinkGclChapter(Result); end; procedure TGclControl.Calculate; var i: Integer; begin for i := 0 to GclChapterCount - 1 do GclChapter[i].CalculateChapter; CalculateChapterGather; end; { TGclChapter } procedure TGclChapter.AddGclNode(AGclNode: TGclNode); begin FGclNodes.Add(AGclNode); end; procedure TGclChapter.CalculateChapter; var iIndex, iProject: Integer; vGclNode: TGclNode; begin FTotalPrice := 0; FCurGatherTotalPrice := 0; FEndGatherTotalPrice := 0; FPreGatherTotalPrice := 0; for iProject := 0 to FProjectCount - 1 do begin FP_TotalPrice[iProject] := 0; FP_CurGatherTotalPrice[iProject] := 0; FP_EndGatherTotalPrice[iProject] := 0; end; for iIndex := 0 to FGclNodes.Count - 1 do begin vGclNode := TGclNode(FGclNodes.Items[iIndex]); FTotalPrice := FTotalPrice + vGclNode.TotalPrice; FCurGatherTotalPrice := FCurGatherTotalPrice + vGclNode.FCurGatherTotalPrice; FEndGatherTotalPrice := FEndGatherTotalPrice + vGclNode.FEndGatherTotalPrice; FPreGatherTotalPrice := FPreGatherTotalPrice + vGclNode.FPreGatherTotalPrice; for iProject := 0 to FProjectCount - 1 do begin FP_TotalPrice[iProject] := FP_TotalPrice[iProject] + vGclNode.P_TotalPrice[iProject]; FP_CurGatherTotalPrice[iProject] := FP_CurGatherTotalPrice[iProject] + vGclNode.P_CurGatherTotalPrice[iProject]; FP_EndGatherTotalPrice[iProject] := FP_EndGatherTotalPrice[iProject] + vGclNode.P_EndGatherTotalPrice[iProject]; end; end; end; constructor TGclChapter.Create(AChapterID: Integer; const AName: string; AProjectCount: Integer); begin FGclNodes := TList.Create; FChapterID := AChapterID; if FChapterID < 19 then begin FChapterBegin := FChapterID * 100; FChapterEnd := FChapterBegin + 99; FChapterName := Format('第%d章', [FChapterBegin]); end; FName := AName; FProjectCount := AProjectCount; SetLength(FP_TotalPrice, FProjectCount); SetLength(FP_CurGatherTotalPrice, FProjectCount); SetLength(FP_EndGatherTotalPrice, FProjectCount); end; destructor TGclChapter.Destroy; begin FGclNodes.Free; inherited; end; function TGclChapter.GetCurPercent: Double; begin if TotalPrice <> 0 then Result := CurGatherTotalPrice/TotalPrice*100 else Result := 0; end; function TGclChapter.GetEndPercent: Double; begin if TotalPrice <> 0 then Result := EndGatherTotalPrice/TotalPrice*100 else Result := 0; end; function TGclChapter.GetGclNode(AIndex: Integer): TGclNode; begin Result := TGclNode(FGclNodes.Items[AIndex]); end; function TGclChapter.GetGclNodeCount: Integer; begin Result := FGclNodes.Count; end; { TDealPayControl } function TDealPayControl.AddPayNode(const AName: string; AIsMinus: Boolean): TPayNode; begin Result := FindPayNode(AName, AIsMinus); if not Assigned(Result) then Result := NewPayNode(AName, AIsMinus); end; constructor TDealPayControl.Create; begin FPayNodes := TList.Create; FGatherPayNode := TPayNode.Create; end; destructor TDealPayControl.Destroy; begin FGatherPayNode.Free; ClearObjects(FPayNodes); FPayNodes.Free; inherited; end; function TDealPayControl.FindPayNode(const AName: string; AIsMinus: Boolean): TPayNode; var iIndex: Integer; vPayNode: TPayNode; begin Result := nil; for iIndex := 0 to FPayNodes.Count -1 do begin vPayNode := TPayNode(FPayNodes.Items[iIndex]); if (vPayNode.Name = AName) and (vPayNode.IsMinus = AIsMinus) then begin Result := vPayNode; Break; end; end; end; function TDealPayControl.GetPayCount: Integer; begin Result := FPayNodes.Count; end; function TDealPayControl.GetPayNode(AIndex: Integer): TPayNode; begin Result := TPayNode(FPayNodes.Items[AIndex]); end; function TDealPayControl.NewPayNode(const AName: string; AIsMinus: Boolean): TPayNode; begin Result := TPayNode.Create; FPayNodes.Add(Result); Result.Name := AName; Result.IsMinus := AIsMinus; end; end.