unit rmFxBillsCompareDm; interface uses SysUtils, Classes, DB, DBClient, ProjectData, sdIDTree, MCacheTree; type {------------------------------------ fctCommon: 常规的分项清单审核比较模式。 fctG07: 广东标准表-台账07表,在fctCommon的基础上加一行公路基本造价汇总行。 需求有标明: 只需汇总项目节。此处不做特别处理,根据报表设置中的选项决定。 ------------------------------------} TFxCompareType = (fctCommon, fctG07); TrmFxBillsCompareData = class(TDataModule) cdsBills: TClientDataSet; cdsBillsCode: TStringField; cdsBillsB_Code: TStringField; cdsBillsName: TWideStringField; cdsBillsUnits: TWideStringField; cdsBillsSQuantity: TFloatField; cdsBillsSPrice: TFloatField; cdsBillsSTotalPrice: TFloatField; cdsBillsCQuantity: TFloatField; cdsBillsCPrice: TFloatField; cdsBillsCTotalPrice: TFloatField; cdsBillsDQuantity: TFloatField; cdsBillsDPrice: TFloatField; cdsBillsDTotalPrice: TFloatField; cdsBillsMemoStr: TStringField; cdsBillsSDgnQuantity1: TFloatField; cdsBillsSDgnQuantity2: TFloatField; cdsBillsSDgnQuantity: TStringField; cdsBillsCDgnQuantity1: TFloatField; cdsBillsCDgnQuantity2: TFloatField; cdsBillsCDgnQuantity: TStringField; cdsBillsDDgnQuantity1: TFloatField; cdsBillsDDgnQuantity2: TFloatField; cdsBillsDDgnQuantity: TStringField; cdsBillsXiangCode: TWideStringField; cdsBillsMuCode: TStringField; cdsBillsJieCode: TStringField; cdsBillsXiMuCode: TStringField; private FCacheTree: TReportCacheTree; FCompareType: TFxCompareType; function GetDgnQuantity(ANum1, ANum2: Double): string; function FilterBillsNode(ANode: TsdIDTreeNode; AParent: TReportCacheNode; AIsSource: Boolean): TReportCacheNode; procedure FilterBills(ANode: TsdIDTreeNode; AParent: TReportCacheNode; AIsSource: Boolean); procedure WriteNode(ANode: TReportCacheNode); procedure WriteGatherNodeData(const AName: string); procedure WriteBills; public function AssignData(ASProjectData, ACProjectData: TProjectData): TDataSet; property CompareType: TFxCompareType read FCompareType write FCompareType; end; implementation uses CacheTree, Globals; {$R *.dfm} { TrmFxBillsCompareData } function TrmFxBillsCompareData.AssignData(ASProjectData, ACProjectData: TProjectData): TDataSet; begin cdsBills.DisableControls; cdsBills.Active := True; cdsBills.EmptyDataSet; FCacheTree := TReportCacheTree.Create(2); try FilterBills(ASProjectData.BillsCompileData.BillsCompileTree.FirstNode, nil, True); FilterBills(ACProjectData.BillsCompileData.BillsCompileTree.FirstNode, nil, False); if CompareType = fctG07 then FCacheTree.ReCalcGatherData; WriteBills; Result := cdsBills; finally FCacheTree.Free; cdsBills.EnableControls; end; end; procedure TrmFxBillsCompareData.FilterBills(ANode: TsdIDTreeNode; AParent: TReportCacheNode; AIsSource: Boolean); var ACur: TReportCacheNode; begin if not Assigned(ANode) then Exit; // (Level从0开始取值) case ReportConfig.GatherLevel of // 项 0: if ANode.Level > 1 then Exit; // 目 1: if ANode.Level > 2 then Exit; // 节 2: if ANode.Level > 3 then Exit; // 细目 3: if ANode.Level > 4 then Exit; // 项目节 4: if ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit; end; ACur := FilterBillsNode(ANode, AParent, AIsSource); FilterBills(ANode.FirstChild, ACur, AIsSource); FilterBills(ANode.NextSibling, AParent, AIsSource); end; function TrmFxBillsCompareData.FilterBillsNode(ANode: TsdIDTreeNode; AParent: TReportCacheNode; AIsSource: Boolean): TReportCacheNode; var iGatherCompare: Integer; ANextSibling: TReportCacheNode; begin with ANode.Rec do begin if ANode.Rec.ValueByName('B_Code').AsString <> '' then iGatherCompare := ReportConfig.GclCompare else iGatherCompare := ReportConfig.XmjCompare; case iGatherCompare of // 按编号 0: if (ValueByName('Code').asString <> '') or (ValueByName('B_Code').asString <> '') then Result := FCacheTree.FindNode(AParent, ValueByName('Code').AsString, ValueByName('B_Code').AsString) else Result := FCacheTree.FindNode(AParent, ValueByName('Code').AsString, ValueByName('B_Code').AsString, ValueByName('Name').AsString); // 按名称 1: Result := FCacheTree.FindNode(AParent, ValueByName('Name').AsString); // 按编号+名称 2: Result := FCacheTree.FindNode(AParent, ValueByName('Code').AsString, ValueByName('B_Code').AsString, ValueByName('Name').AsString); end; if not Assigned(Result) then begin ANextSibling := FCacheTree.FindNextSibling(AParent, ValueByName('Code').AsString, ValueByName('B_Code').AsString); Result := FCacheTree.AddNode(AParent, ANextSibling); Result.Code := ValueByName('Code').AsString; Result.B_Code := ValueByName('B_Code').AsString; Result.Name := ValueByName('Name').AsString; Result.Units := ValueByName('Units').AsString; end; if AIsSource then begin Result.P_Quantity[0] := ValueByName('Quantity').AsFloat; Result.P_Price[0] := ValueByName('Price').AsFloat; Result.P_TotalPrice[0] := ValueByName('TotalPrice').AsFloat; Result.P_DgnQuantity1[0] := ValueByName('DgnQuantity1').AsFloat; Result.P_DgnQuantity2[0] := ValueByName('DgnQuantity2').AsFloat; end else begin Result.P_Quantity[1] := ValueByName('Quantity').AsFloat; Result.P_Price[1] := ValueByName('Price').AsFloat; Result.P_TotalPrice[1] := ValueByName('TotalPrice').AsFloat; Result.P_DgnQuantity1[1] := ValueByName('DgnQuantity1').AsFloat; Result.P_DgnQuantity2[1] := ValueByName('DgnQuantity2').AsFloat; end; end; end; function TrmFxBillsCompareData.GetDgnQuantity(ANum1, ANum2: Double): string; begin Result := ''; if ANum1 <> 0 then begin Result := FloatToStr(ANum1); if ANum2 <> 0 then Result := Result + '/' + FloatToStr(ANum2); end; end; procedure TrmFxBillsCompareData.WriteBills; begin WriteNode(TReportCacheNode(FCacheTree.FirstNode)); WriteGatherNodeData('公路基本造价'); end; procedure TrmFxBillsCompareData.WriteGatherNodeData(const AName: string); begin cdsBills.Append; cdsBillsName.AsString := AName; with FCacheTree.GatherCacheNode do begin cdsBillsSTotalPrice.AsFloat := P_TotalPrice[0]; cdsBillsCTotalPrice.AsFloat := P_TotalPrice[1]; cdsBillsDTotalPrice.AsFloat := P_TotalPrice[1] - P_TotalPrice[0]; end; cdsBills.Post; end; procedure TrmFxBillsCompareData.WriteNode(ANode: TReportCacheNode); begin if not Assigned(ANode) then Exit; cdsBills.Append; cdsBillsCode.AsString := ANode.Code; cdsBillsB_Code.AsString := ANode.B_Code; cdsBillsName.AsString := ANode.Name; cdsBillsUnits.AsString := ANode.Units; cdsBillsSQuantity.AsFloat := ANode.P_Quantity[0]; cdsBillsSPrice.AsFloat := ANode.P_Price[0]; cdsBillsSTotalPrice.AsFloat := ANode.P_TotalPrice[0]; cdsBillsSDgnQuantity1.AsFloat := ANode.P_DgnQuantity1[0]; cdsBillsSDgnQuantity2.AsFloat := ANode.P_DgnQuantity2[0]; cdsBillsSDgnQuantity.AsString := GetDgnQuantity(cdsBillsSDgnQuantity1.AsFloat, cdsBillsSDgnQuantity2.AsFloat); cdsBillsCQuantity.AsFloat := ANode.P_Quantity[1]; cdsBillsCPrice.AsFloat := ANode.P_Price[1]; cdsBillsCTotalPrice.AsFloat := ANode.P_TotalPrice[1]; cdsBillsCDgnQuantity1.AsFloat := ANode.P_DgnQuantity1[1]; cdsBillsCDgnQuantity2.AsFloat := ANode.P_DgnQuantity2[1]; cdsBillsCDgnQuantity.AsString := GetDgnQuantity(cdsBillsCDgnQuantity1.AsFloat, cdsBillsCDgnQuantity2.AsFloat); cdsBillsDQuantity.AsFloat := ANode.P_Quantity[1] - ANode.P_Quantity[0]; cdsBillsDPrice.AsFloat := ANode.P_Price[1] - ANode.P_Price[0]; cdsBillsDTotalPrice.AsFloat := ANode.P_TotalPrice[1] - ANode.P_TotalPrice[0]; cdsBillsDDgnQuantity1.AsFloat := ANode.P_DgnQuantity1[1] - ANode.P_DgnQuantity1[0]; cdsBillsDDgnQuantity2.AsFloat := ANode.P_DgnQuantity2[1] - ANode.P_DgnQuantity2[0]; cdsBillsDDgnQuantity.AsString := GetDgnQuantity(cdsBillsDDgnQuantity1.AsFloat, cdsBillsDDgnQuantity2.AsFloat); cdsBillsXiangCode.AsString := ANode.XiangCode; cdsBillsMuCode.AsString := ANode.MuCode; cdsBillsJieCode.AsString := ANode.JieCode; cdsBillsXiMuCode.AsString := ANode.XiMuCode; cdsBills.Post; WriteNode(TReportCacheNode(ANode.FirstChild)); WriteNode(TReportCacheNode(ANode.NextSibling)); end; end.