
unit rmBillsGatherDm;

interface

uses
  SysUtils, Classes, DB, DBClient, MCacheTree, ProjectData,
  sdDB, sdIDTree, rmCacheData, rmSelectProjectFrm;

type
  {---------------------------------
    bgtFx: 分项汇总模式，按树结构汇总所选项目，汇总后结果写入cdsFxBills
    bgtXmj: 项目节汇总模式，按树结构汇总所选项目的项目节节点，汇总后结果写入cdsFxBills
    bgtGcl: 工程量清单汇总模式，汇总后结果写入cdsGclBills
    bgtMultiXmj: bgtXmj模式的扩展，汇总展示多项目数据模式，与bgtXmj的差异在于记录了每个项目的数据，而不是单纯累加
                 汇总结果写入cdsProjectBills
    bgtEstimate: 决算02表，bgtXmj模式的扩展，
                 分别汇总前两个项目的0号台账为初步设计、施工图设计，其后为所有项目按bgtXmj方式汇总。
                 汇总结果写入cdsEstimateBills
    bgtEstimate1: 决算02表（部颁格式），bgtXmj模式的扩展，
                  汇总第一个项目的0号台账为批准的概(预)算，其后为所有项目按bgtXmj方式汇总。汇总结果写入cdsEstimateBills
    bgtFinal07: 决算07表，bgtGcl模式的扩展，汇总暂时多项目数据及合计数据模式
                与bgtGcl的差异在于，记录了每个项目的数据，且汇总了某些固定id节点的数据在最后。汇总结果写入cdsProjectGclBills
    bgtFinal08: 决算08表，bgtXmj的特殊情况，仅汇总第二部分下的所有项目节节点，而非全部项目节。汇总结果写入cdsFxBills
    bgtFinal09: 决算09表，bgtXmj的特殊情况，汇总第三部分及气候所有项目节节点，而非全部项目节。汇总结果写入cdsFxBills
    bgtFinal11: 决算11表，与bgtFinal07极度相似，仅汇总固定id节点的数据处不同。汇总结果写入cdsProjectGclBills
    bgtFinal12: 决算12表，流水式写入每个项目的变更令数据。汇总结果写入cdsBGLFlow
    bgtFinal16: 决算16表，bgtMultiXmj的基础上增加了工程量清单数据，且仅汇总计日工部分(固定id40)。汇总结果写入cdsProjectBills
    bgtFinal17: 决算17表，bgtFx的特殊情况，仅汇总收尾工程部分(固定id47)，汇总结果写入cdsFxBills
    bgtFinal18: 决算18表，bgtFx的特殊情况，仅汇总报废工程部分(固定id48)，汇总结果吸入cdsFxBills
    bgtFinal19: 决算19表，bgtFinal07和bgtFinal11中去除后面的固定id节点数据，汇总结果写入cdsProjectGclBills
    bgtG_Final06_1: 粤竣06-1表，bgtEstimate的特殊情况，仅汇总土地(固定id21)，且汇总初步设计、施工图设计
                    可理解为bgtEstimate扩展为Fx，然后再限制为汇总固定id下的数据，汇总后的结果写入cdsEstimateBills
    bgtG_Final04: 粤竣04表，在bgtXmj的基础上增加了设计数量、经济指标等数据，且增加了一行公路基本造价汇总行
  ----------------------------------}
  TbgType = (bgtFx, bgtXmj, bgtGcl, bgtMultiXmj, bgtEstimate,
    bgtEstimate1, bgtFinal07, bgtFinal08, bgtFinal09, bgtFinal11,
    bgtFinal12, bgtFinal16, bgtFinal17, bgtFinal18, bgtFinal19,
    bgtG_Final06_1, bgtG_Final04);

  TrmBillsGatherData = class(TDataModule)
    // 决算04, 05[竣04]
    cdsFxBills: TClientDataSet;
    cdsFxBillsXiangCode: TStringField;
    cdsFxBillsMuCode: TStringField;
    cdsFxBillsJieCode: TStringField;
    cdsFxBillsXiMuCode: TStringField;
    cdsFxBillsCode: TStringField;
    cdsFxBillsB_Code: TStringField;
    cdsFxBillsName: TWideStringField;
    cdsFxBillsUnits: TWideStringField;
    cdsFxBillsAddDealQuantity: TFloatField;
    cdsFxBillsAddDealTotalPrice: TFloatField;
    cdsFxBillsAddQcQuantity: TFloatField;
    cdsFxBillsAddPcQuantity: TFloatField;
    cdsFxBillsAddQcTotalPrice: TFloatField;
    cdsFxBillsAddPcTotalPrice: TFloatField;
    cdsFxBillsPrice: TFloatField;
    cdsFxBillsAddGatherQuantity: TFloatField;
    cdsFxBillsAddGatherTotalPrice: TFloatField;
    cdsFxBillsMemoStr: TWideStringField;
    cdsFxBillsPercent: TFloatField;
    cdsFxBillsQuantity: TFloatField;
    cdsFxBillsTotalPrice: TFloatField;
    cdsFxBillsDgnQuantity1: TFloatField;
    cdsFxBillsDgnQuantity2: TFloatField;
    cdsFxBillsDgnQuantity: TStringField;
    cdsFxBillsDgnPrice1: TFloatField;
    cdsFxBillsDgnPrice2: TFloatField;
    cdsFxBillsDgnPrice: TStringField;
    cdsFxBillsRatioPercent: TFloatField;
    cdsFxBillsAddRatioPercent: TFloatField;
    cdsFxBillsDealDgnQuantity1: TFloatField;
    cdsFxBillsDealDgnQuantity2: TFloatField;
    cdsFxBillsDealDgnQuantity: TStringField;
    cdsFxBillsDealDgnPrice1: TFloatField;
    cdsFxBillsDealDgnPrice2: TFloatField;
    cdsFxBillsDealDgnPrice: TStringField;
    cdsFxBillsCDgnQuantity1: TFloatField;
    cdsFxBillsCDgnQuantity2: TFloatField;
    cdsFxBillsCDgnQuantity: TStringField;
    cdsFxBillsCDgnPrice1: TFloatField;
    cdsFxBillsCDgnPrice2: TFloatField;
    cdsFxBillsCDgnPrice: TStringField;
    cdsFxBillsFinalDgnQuantity1: TFloatField;
    cdsFxBillsFinalDgnQuantity2: TFloatField;
    cdsFxBillsFinalDgnQuantity: TStringField;
    cdsFxBillsFinalDgnPrice1: TFloatField;
    cdsFxBillsFinalDgnPrice2: TFloatField;
    cdsFxBillsFinalDgnPrice: TStringField;
    // 决算05-2
    cdsGclBills: TClientDataSet;
    cdsGclBillsB_Code: TStringField;
    cdsGclBillsIndexCode: TStringField;
    cdsGclBillsName: TWideStringField;
    cdsGclBillsUnits: TWideStringField;
    cdsGclBillsPrice: TFloatField;
    cdsGclBillsAddDealQuantity: TFloatField;
    cdsGclBillsAddDealTotalPrice: TFloatField;
    cdsGclBillsAddQcQuantity: TFloatField;
    cdsGclBillsAddQcTotalPrice: TFloatField;
    cdsGclBillsAddPcQuantity: TFloatField;
    cdsGclBillsAddPcTotalPrice: TFloatField;
    cdsGclBillsAddGatherQuantity: TFloatField;
    cdsGclBillsAddGatherTotalPrice: TFloatField;
    cdsGclBillsPrecent: TFloatField;
    cdsGclBillsMemoStr: TWideStringField;
    // 决算04-1, 决算部颁12
    cdsProjectBills: TClientDataSet;
    cdsProjectBillsXiangCode: TStringField;
    cdsProjectBillsMuCode: TStringField;
    cdsProjectBillsJieCode: TStringField;
    cdsProjectBillsXiMuCode: TStringField;
    cdsProjectBillsCode: TStringField;
    cdsProjectBillsName: TWideStringField;
    cdsProjectBillsUnits: TWideStringField;
    cdsProjectBillsQuantity: TFloatField;
    cdsProjectBillsProjectID: TIntegerField;
    cdsProjectBillsTotalPrice: TFloatField;
    cdsProjectBillsP_Quantity: TFloatField;
    cdsProjectBillsP_TotalPrice: TFloatField;
    cdsProjectBillsEcoIndex: TFloatField;
    cdsProjectBillsPercent: TFloatField;
    cdsProjectBillsMemoStr: TWideStringField;
    cdsProjectBillsProjectName: TWideStringField;
    cdsProjectBillsSerialNo: TIntegerField;
    cdsProjectBillsB_Code: TStringField;
    cdsProjectBillsP_Price: TFloatField;
    // 决算02
    cdsEstimateBills: TClientDataSet;
    cdsEstimateBillsXiangCode: TStringField;
    cdsEstimateBillsMuCode: TStringField;
    cdsEstimateBillsJieCode: TStringField;
    cdsEstimateBillsXiMuCode: TStringField;
    cdsEstimateBillsCode: TStringField;
    cdsEstimateBillsName: TWideStringField;
    cdsEstimateBillsUnits: TWideStringField;
    cdsEstimateBillsPDQuantity: TFloatField;
    cdsEstimateBillsPDTotalPrice: TFloatField;
    cdsEstimateBillsCDDQuantity: TFloatField;
    cdsEstimateBillsCDDTotalPrice: TFloatField;
    cdsEstimateBillsAddDealQuantity: TFloatField;
    cdsEstimateBillsAddDealTotalPrice: TFloatField;
    cdsEstimateBillsAddCQuantity: TFloatField;
    cdsEstimateBillsAddCTotalPrice: TFloatField;
    cdsEstimateBillsAddGatherQuantity: TFloatField;
    cdsEstimateBillsAddGatherTotalPrice: TFloatField;
    cdsEstimateBillsQuantityAdjust: TFloatField;
    cdsEstimateBillsTotalPriceAdjust: TFloatField;
    cdsEstimateBillsMemoStr: TWideStringField;
    cdsEstimateBillsABQuantity: TFloatField;               // 批准概算 - 数量
    cdsEstimateBillsABTotalPrice: TFloatField;             // 批准概算 - 金额
    cdsEstimateBillsQuantity: TFloatField;                 // 0号台账 - 数量
    cdsEstimateBillsTotalPrice: TFloatField;               // 0号台账 - 金额
    cdsEstimateBillsQuantityCompare1: TFloatField;         // 数量比较 - (台账-批准)/批准
    cdsEstimateBillsTotalPriceCompare1: TFloatField;       // 金额比较 - (台账-批准)/批准
    cdsEstimateBillsQuantityCompare2: TFloatField;         // 数量比较 - (决算-批准)/批准
    cdsEstimateBillsQuantityCompare3: TFloatField;         // 金额比较 - (决算-批准)/批准
    cdsEstimateBillsTotalPriceCompare2: TFloatField;       // 数量比较 - (决算-合同)/合同
    cdsEstimateBillsTotalPriceCompare3: TFloatField;       // 金额比较 - (决算-合同)/合同
    cdsEstimateBillsPDDgnQuantity: TStringField;
    cdsEstimateBillsPDDgnQuantity1: TFloatField;
    cdsEstimateBillsPDDgnQuantity2: TFloatField;
    cdsEstimateBillsCDDDgnQuantity: TStringField;
    cdsEstimateBillsCDDDgnQuantity1: TFloatField;
    cdsEstimateBillsCDDDgnQuantity2: TFloatField;
    cdsEstimateBillsDealDgnQuantity: TStringField;
    cdsEstimateBillsDealDgnQuantity1: TFloatField;
    cdsEstimateBillsDealDgnQuantity2: TFloatField;
    cdsEstimateBillsCDgnQuantity: TStringField;
    cdsEstimateBillsCDgnQuantity1: TFloatField;
    cdsEstimateBillsCDgnQuantity2: TFloatField;
    cdsEstimateBillsGatherDgnQuantity: TStringField;
    cdsEstimateBillsGatherDgnQuantity1: TFloatField;
    cdsEstimateBillsGatherDgnQuantity2: TFloatField;
    cdsEstimateBillsABDgnQuantity: TStringField;
    cdsEstimateBillsABDgnQuantity1: TFloatField;
    cdsEstimateBillsABDgnQuantity2: TFloatField;
    cdsEstimateBillsDgnQuantity: TStringField;
    cdsEstimateBillsDgnQuantity1: TFloatField;
    cdsEstimateBillsDgnQuantity2: TFloatField;
    cdsEstimateBillsDgnQuantityCompare1: TStringField;
    cdsEstimateBillsDgnQuantityCompare2: TStringField;
    cdsEstimateBillsDgnQuantityCompare3: TStringField;
    cdsEstimateBillsDgnQuantity1Compare1: TFloatField;
    cdsEstimateBillsDgnQuantity2Compare1: TFloatField;
    cdsEstimateBillsDgnQuantity1Compare2: TFloatField;
    cdsEstimateBillsDgnQuantity1Compare3: TFloatField;
    cdsEstimateBillsDgnQuantity2Compare2: TFloatField;
    cdsEstimateBillsDgnQuantity2Compare3: TFloatField;
    cdsEstimateBillsB_Code: TStringField;
    cdsEstimateBillsPrice: TFloatField;
    cdsEstimateBillsPDDgnPrice: TFloatField;
    cdsEstimateBillsCDDDgnPrice: TFloatField;
    cdsEstimateBillsABDgnPrice: TFloatField;
    cdsEstimateBillsFinalDgnQty: TStringField;
    cdsEstimateBillsFinalDgnQty1: TFloatField;
    cdsEstimateBillsFinalDgnQty2: TFloatField;
    // 决算部颁07, 11
    cdsProjectGclBills: TClientDataSet;
    cdsProjectGclBillsProjectID: TIntegerField;
    cdsProjectGclBillsProjectName: TWideStringField;
    cdsProjectGclBillsB_Code: TStringField;
    cdsProjectGclBillsIndexCode: TStringField;
    cdsProjectGclBillsName: TWideStringField;
    cdsProjectGclBillsUnits: TWideStringField;
    cdsProjectGclBillsQuantity: TFloatField;
    cdsProjectGclBillsPrice: TFloatField;
    cdsProjectGclBillsTotalPrice: TFloatField;
    cdsProjectGclBillsP_Price: TFloatField;
    cdsProjectGclBillsP_Quantity: TFloatField;
    cdsProjectGclBillsP_TotalPrice: TFloatField;
    cdsProjectGclBillsSerialNo: TIntegerField;
    cdsProjectGclBillsP_AddGatherQuantity: TFloatField;
    cdsProjectGclBillsP_AddGatherTotalPrice: TFloatField;
    cdsProjectGclBillsAddGatherQuantity: TFloatField;
    cdsProjectGclBillsAddGatherTotalPrice: TFloatField;
    // 决算部颁12
    cdsBGLFlow: TClientDataSet;
    cdsBGLFlowMergeBGLCode: TWideStringField;
    cdsBGLFlowBGLName: TWideStringField;
    cdsBGLFlowApprovalCode: TWideStringField;
    cdsBGLFlowSuggestion: TWideStringField;
    cdsBGLFlowBGReason: TWideStringField;
    cdsBGLFlowB_Code: TStringField;
    cdsBGLFlowName: TWideStringField;
    cdsBGLFlowUnits: TWideStringField;
    cdsBGLFlowQuantity: TFloatField;
    cdsBGLFlowPrice: TFloatField;
    cdsBGLFlowTotalPrice: TFloatField;
    cdsBGLFlowBGTotalPrice: TFloatField;
  private
    FCacheTree: TReportCacheTree;
    FGclList: TGclGatherList;
    FFixedIDList: TFixedIDBillsList;
    FProjectData: TProjectData;
    FProjectName: string;
    FGatherType: TbgType;
    FSerialNo: Integer;

    procedure OpenProjectData(AProject: TSelectProject; AProjectIndex: Integer);
    procedure FreeProjectData;

    function GetDgnQuantity(ANum1, ANum2: Double): string;
    function GetDgnPrice(ATotalPrice, ADgnQuantity: Double): Double;
    function GetCompare(ANum1, ANum2: Double): Double;

    {汇总树结构}
    function AddBillsNode(ANode: TsdIDTreeNode; AParent:
      TReportCacheNode; AProjectIndex: Integer;
      ASelectProject: TSelectProject): TReportCacheNode;
    // 递归模式（当前节点、子节点、后兄弟节点）
    procedure AddBills(ANode: TsdIDTreeNode; AParent: TReportCacheNode;
      AProjectIndex: Integer; ASelectProject: TSelectProject);
    // 遍历模式（当前节点、子节点）
    procedure AddBillsList(ANode: TsdIDTreeNode; AParent: TReportCacheNode;
      AProjectIndex: Integer; ASelectProject: TSelectProject);
    {汇总工程量清单}
    procedure FilterBillsNode(ANode: TsdIDTreeNode; AProjectIndex: Integer);
    procedure FilterBills(ANode: TsdIDTreeNode; AProjectIndex: Integer);
    {汇总固定ID项}
    procedure FilterFixedIDBills(ATree: TsdIDTree; AProjectIndex: Integer);
    procedure FilterSettlement(AProjectData: TProjectData; AProjectIndex: Integer);
    {写入流水数据}
    procedure WriteBGLFlowData(AProjectData: TProjectData);
    procedure WriteFlowData(AProjectData: TProjectData);

    procedure GatherProject(AProject: TSelectProject; AProjectIndex: Integer);
    procedure CalculateGatherData;
    procedure CalculateRatioPercent; // 计算各项费用所占比例，金额/总造价

    procedure WriteGatherCacheNode(const AGatherName: string);
    procedure WriteNode(ANode: TReportCacheNode);
    procedure WriteBillsData;

    procedure WriteGclNode;

    procedure WriteProjectsData;

    procedure WriteEstimateGatherNode;
    procedure WriteENodeData(ANode: TReportCacheNode);
    procedure ReWriteENodeDataAsGather(ANode: TReportCacheNode; AName: string);
    procedure WriteEstimateNode(ANode: TReportCacheNode);
    procedure WriteEstimateData;

    procedure WriteProjectsGclData;

    procedure WriteData;

    procedure BeforeGather(AProjects: TList);
    procedure AfterGather;
  public
    function AssignData(AProjects: TList): TDataSet;

    property GatherType: TbgType read FGatherType write FGatherType;
  end;

implementation

uses
  Globals, UtilMethods, Math, BGLDm;

{$R *.dfm}

{ TrmBillsGatherData }

procedure TrmBillsGatherData.AddBills(ANode: TsdIDTreeNode;
  AParent: TReportCacheNode; AProjectIndex: Integer; ASelectProject: TSelectProject);
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;
  if GatherType in [bgtXmj, bgtMultiXmj, bgtEstimate, bgtEstimate1, bgtFinal08, bgtFinal09] then
    if ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit; // 仅汇总项目节
  ACur := AddBillsNode(ANode, AParent, AProjectIndex, ASelectProject);
  AddBills(ANode.FirstChild, ACur, AProjectIndex, ASelectProject);
  AddBills(ANode.NextSibling, AParent, AProjectIndex, ASelectProject);
end;

function TrmBillsGatherData.AddBillsNode(ANode: TsdIDTreeNode;
  AParent: TReportCacheNode; AProjectIndex: Integer;
  ASelectProject: TSelectProject): 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('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 (GatherType in [bgtEstimate, bgtG_Final06_1]) and (ASelectProject.IsPD or ASelectProject.IsCDD) then
    begin
      if ASelectProject.IsPD then
      begin
        Result.PDQuantity := ValueByName('Quantity').AsFloat;
        Result.PDTotalPrice := ValueByName('TotalPrice').AsFloat;
        Result.PDDesignQuantity1 := ValueByName('DgnQuantity1').AsFloat;
        Result.PDDesignQuantity2 := ValueByName('DgnQuantity2').AsFloat;
        Result.PDDesignPrice := ValueByName('DgnPrice').AsFloat;
      end
      else if ASelectProject.IsCDD then
      begin
        Result.CDDQuantity := ValueByName('Quantity').AsFloat;
        Result.CDDTotalPrice := ValueByName('TotalPrice').AsFloat;
        Result.CDDDesignQuantity1 := ValueByName('DgnQuantity1').AsFloat;
        Result.CDDDesignQuantity2 := ValueByName('DgnQuantity2').AsFloat;
        Result.CDDDesignPrice := ValueByName('DgnPrice').AsFloat;
      end
    end
    else if (GatherType = bgtEstimate1) and ASelectProject.IsAB then
    begin
      Result.ABQuantity := ValueByName('Quantity').AsFloat;
      Result.ABTotalPrice := ValueByName('TotalPrice').AsFloat;
      Result.ABDesignQuantity1 := ValueByName('DgnQuantity1').AsFloat;
      Result.ABDesignQuantity2 := ValueByName('DgnQuantity2').AsFloat;
      Result.ABDesignPrice := ValueByName('DgnPrice').AsFloat;
    end
    else
    begin
      Result.Price := ValueByName('Price').AsFloat;

      // 汇总的经济指标只能在汇总后计算得到
      Result.Quantity := Result.Quantity + ValueByName('Quantity').AsFloat;
      Result.TotalPrice := Result.TotalPrice + ValueByName('TotalPrice').AsFloat;
      Result.DesignQuantity1 := Result.DesignQuantity1 + ValueByName('DgnQuantity1').AsFloat;
      Result.DesignQuantity2 := Result.DesignQuantity2 + ValueByName('DgnQuantity2').AsFloat;

      Result.AddDealQuantity := Result.AddDealQuantity + ValueByName('AddDealQuantity').AsFloat;
      Result.AddDealTotalPrice := Result.AddDealTotalPrice + ValueByName('AddDealTotalPrice').AsFloat;
      Result.AddQcQuantity := Result.AddQcQuantity + ValueByName('AddQcQuantity').AsFloat;
      Result.AddQcTotalPrice := Result.AddQcTotalPrice + ValueByName('AddQcTotalPrice').AsFloat;
      Result.AddPcQuantity := Result.AddPcQuantity + ValueByName('AddPcQuantity').AsFloat;
      Result.AddPcTotalPrice := Result.AddPcTotalPrice + ValueByName('AddPcTotalPrice').AsFloat;

      Result.DealDesignQuantity1 := Result.DealDesignQuantity1 + ValueByName('DealDgnQuantity1').AsFloat;
      Result.DealDesignQuantity2 := Result.DealDesignQuantity2 + ValueByName('DealDgnQuantity2').AsFloat;
      Result.CDesignQuantity1 := Result.CDesignQuantity1 + ValueByName('CDgnQuantity1').AsFloat;
      Result.CDesignQuantity2 := Result.CDesignQuantity2 + ValueByName('CDgnQuantity2').AsFloat;

      Result.P_Price[AProjectIndex] := ValueByName('Price').AsFloat;
      Result.P_Quantity[AProjectIndex] := ValueByName('AddGatherQuantity').AsFloat;
      Result.P_TotalPrice[AProjectIndex] := ValueByName('AddGatherTotalPrice').AsFloat;
    end;
  end;
end;

procedure TrmBillsGatherData.AfterGather;
begin
  cdsProjectBills.EnableControls;

  FGclList.Free;
  cdsGclBills.EnableControls;

  FCacheTree.Free;
  cdsFxBills.EnableControls;

  cdsEstimateBills.EnableControls;

  FFixedIDList.Free;
  cdsProjectGclBills.EnableControls;

  cdsBGLFlow.EnableControls;
end;

function TrmBillsGatherData.AssignData(AProjects: TList): TDataSet;
var
  iProject: Integer;
  SelectProject: TSelectProject;
begin
  BeforeGather(AProjects);
  try
    for iProject := 0 to AProjects.Count - 1 do
      GatherProject(TSelectProject(AProjects.Items[iProject]), iProject);
    CalculateGatherData;
    CalculateRatioPercent;
    WriteData;
  finally
    case GatherType of
      bgtFx, bgtXmj, bgtFinal08, bgtFinal09, bgtFinal17, bgtFinal18, bgtG_Final04:
        Result := cdsFxBills;
      bgtGcl: Result := cdsGclBills;
      bgtMultiXmj, bgtFinal16: Result := cdsProjectBills;
      bgtEstimate, bgtEstimate1, bgtG_Final06_1: Result := cdsEstimateBills;
      bgtFinal07, bgtFinal11, bgtFinal19: Result := cdsProjectGclBills;
      bgtFinal12: Result := cdsBGLFlow;
    end;
    AfterGather;
  end;
end;

procedure TrmBillsGatherData.BeforeGather(AProjects: TList);
begin
  cdsFxBills.DisableControls;
  cdsFxBills.Active := True;
  cdsFxBills.EmptyDataSet;
  FCacheTree := TReportCacheTree.Create(AProjects.Count);

  cdsGclBills.DisableControls;
  cdsGclBills.Active := True;
  cdsGclBills.EmptyDataSet;
  if GatherType in [bgtFinal07, bgtFinal11, bgtFinal19] then
    FGclList := TGclGatherList.Create(AProjects.Count, False)
  else
    FGclList := TGclGatherList.Create(AProjects.Count);

  cdsProjectBills.DisableControls;
  cdsProjectBills.Active := True;
  cdsProjectBills.EmptyDataSet;

  cdsEstimateBills.DisableControls;
  cdsEstimateBills.Active := True;
  cdsEstimateBills.EmptyDataSet;

  cdsProjectGclBills.DisableControls;
  cdsProjectGclBills.Active := True;
  cdsProjectGclBills.EmptyDataSet;
  FFixedIDList := TFixedIDBillsList.Create(AProjects.Count);

  cdsBGLFlow.DisableControls;
  cdsBGLFlow.Active := True;
  cdsBGLFlow.EmptyDataSet;
end;

procedure TrmBillsGatherData.FilterBills(ANode: TsdIDTreeNode;
  AProjectIndex: Integer);
begin
  if not Assigned(ANode) then Exit;
  if (not ANode.HasChildren) and (ANode.Rec.ValueByName('B_Code').AsString <> '') then
    FilterBillsNode(ANode, AProjectIndex);
  FilterBills(ANode.FirstChild, AProjectIndex);
  FilterBills(ANode.NextSibling, AProjectIndex);
end;

procedure TrmBillsGatherData.FilterBillsNode(ANode: TsdIDTreeNode;
  AProjectIndex: Integer);

  function CanGatherNode: Boolean;
  begin
    case GatherType of
      bgtFinal11: Result := ANode.Rec.ValueByName('TotalPrice').AsFloat <> 0;
      else Result := True;
    end;
  end;

var
  GclNode: TGclGatherNode;
begin
  if not Assigned(ANode) or not CanGatherNode then Exit;

  GclNode := FGclList.GetGclGatherNode(ANode.Rec);
  with ANode.Rec do
  begin
    GclNode.Quantity := GclNode.Quantity + ValueByName('Quantity').AsFloat;
    GclNode.TotalPrice := GclNode.TotalPrice + ValueByName('TotalPrice').AsFloat;

    GclNode.AddDealQuantity := GclNode.AddDealQuantity + ValueByName('AddDealQuantity').AsFloat;
    GclNode.AddDealTotalPrice := GclNode.AddDealTotalPrice + ValueByName('AddDealTotalPrice').AsFloat;
    GclNode.AddQcQuantity := GclNode.AddQcQuantity + ValueByName('AddQcQuantity').AsFloat;
    GclNode.AddQcTotalPrice := GclNode.AddQcTotalPrice + ValueByName('AddQcTotalPrice').AsFloat;
    GclNode.AddPcQuantity := GclNode.AddPcQuantity + ValueByName('AddPcQuantity').AsFloat;
    GclNode.AddPcTotalPrice := GclNode.AddPcTotalPrice + ValueByName('AddPcTotalPrice').AsFloat;

    GclNode.P_Price[AProjectIndex] := ValueByName('Price').AsFloat;
    GclNode.P_Quantity[AProjectIndex] := GclNode.P_Quantity[AProjectIndex] + ValueByName('Quantity').AsFloat;
    GclNode.P_TotalPrice[AProjectIndex] := GclNode.P_TotalPrice[AProjectIndex] + ValueByName('TotalPrice').AsFloat;
    GclNode.P_AddGatherQuantity[AProjectIndex] :=
        GclNode.P_AddGatherQuantity[AProjectIndex] + ValueByName('AddGatherQuantity').AsFloat;
    GclNode.P_AddGatherTotalPrice[AProjectIndex] :=
        GclNode.P_AddGatherTotalPrice[AProjectIndex] + ValueByName('AddGatherTotalPrice').AsFloat;
  end;
end;

procedure TrmBillsGatherData.FreeProjectData;
begin
  if not Assigned(OpenProjectManager.FindProjectData(FProjectData.ProjectID)) then
    FProjectData.Free;
end;

procedure TrmBillsGatherData.GatherProject(AProject: TSelectProject;
  AProjectIndex: Integer);
begin
  OpenProjectData(AProject, AProjectIndex);
  try
    case GatherType of
      bgtFinal08: // 08表 取第二部分下所有项目节
        AddBills(FProjectData.BillsCompileData.BillsCompileTree.FindNode(2).FirstChild, nil, AProjectIndex, AProject);
      bgtFinal09: // 09表 取第三部分及其后所有项目节
        AddBills(FProjectData.BillsCompileData.BillsCompileTree.FindNode(3), nil, AProjectIndex, AProject);
      bgtGcl, bgtFinal07, bgtFinal11, bgtFinal19: // 汇总工程量清单
        FilterBills(FProjectData.BillsCompileData.BillsCompileTree.FirstNode, AProjectIndex);
      bgtFinal12: // 不做数据汇总，直接流水式写入数据
        WriteFlowData(FProjectData);
      bgtFinal16: // 16表 仅汇总计日工及其子节点
        AddBillsList(FProjectData.BillsCompileData.BillsCompileTree.FindNode(40), nil, AProjectIndex, AProject);
      bgtFinal17: // 17表 仅汇总收尾工程及其子节点
        AddBillsList(FProjectData.BillsCompileData.BillsCompileTree.FindNode(47), nil, AProjectIndex, AProject);
      bgtFinal18: // 18表 仅汇总报废工程及其子节点
        AddBillsList(FProjectData.BillsCompileData.BillsCompileTree.FindNode(48), nil, AProjectIndex, AProject);
      bgtG_Final06_1: // 粤竣06-1表 仅汇总土地及其子节点
        AddBillsList(FProjectData.BillsCompileData.BillsCompileTree.FindNode(21), nil, AProjectIndex, AProject);
      else // 标准汇总方式，分项清单
        AddBills(FProjectData.BillsCompileData.BillsCompileTree.FirstNode, nil, AProjectIndex, AProject)
    end;

    if GatherType in [bgtFinal07, bgtFinal11, bgtFinal19] then
      FilterFixedIDBills(FProjectData.BillsCompileData.BillsCompileTree, AProjectIndex);

    if GatherType = bgtFinal11 then
      FilterSettlement(FProjectData, AProjectIndex);
  finally
    FreeProjectData;
  end;
end;

procedure TrmBillsGatherData.OpenProjectData(AProject: TSelectProject;
  AProjectIndex: Integer);
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.OpenForReport(GetMyProjectsFilePath + Rec.ValueByName('FileName').AsString);
  end;
  FProjectName := Rec.ValueByName('Name').AsString;
  FCacheTree.ProjectName[AProjectIndex] := Rec.ValueByName('Name').AsString;
  FGclList.ProjectName[AProjectIndex] := Rec.ValueByName('Name').AsString;
end;

procedure TrmBillsGatherData.WriteData;
begin
  case GatherType of
    bgtFx, bgtXmj, bgtFinal08, bgtFinal09, bgtFinal17, bgtFinal18, bgtG_Final04:
      WriteBillsData;
    bgtGcl:
      WriteGclNode;
    bgtMultiXmj, bgtFinal16:
      WriteProjectsData;
    bgtEstimate, bgtEstimate1, bgtG_Final06_1:
      WriteEstimateData;
    bgtFinal07, bgtFinal11, bgtFinal19: // 07&11特别的，其中还写入了部分固定ID节点  !!丧心病狂的报表!!
      WriteProjectsGclData;
  end;
end;

procedure TrmBillsGatherData.WriteNode(ANode: TReportCacheNode);
begin
  if not Assigned(ANode) then Exit;
  cdsFxBills.Append;
  cdsFxBillsXiangCode.AsString := ANode.XiangCode;
  cdsFxBillsMuCode.AsString := ANode.MuCode;
  cdsFxBillsJieCode.AsString := ANode.JieCode;
  cdsFxBillsXiMuCode.AsString := ANode.XiMuCode;

  cdsFxBillsCode.AsString := ANode.Code;
  cdsFxBillsB_Code.AsString := ANode.B_Code;
  cdsFxBillsName.AsString := ANode.Name;
  cdsFxBillsUnits.AsString := ANode.Units;
  cdsFxBillsPrice.AsFloat := ANode.Price;

  cdsFxBillsAddDealQuantity.AsFloat := ANode.AddDealQuantity;
  cdsFxBillsAddDealTotalPrice.AsFloat := ANode.AddDealTotalPrice;
  cdsFxBillsAddQcQuantity.AsFloat := ANode.AddQcQuantity;
  cdsFxBillsAddQcTotalPrice.AsFloat := ANode.AddQcTotalPrice;
  cdsFxBillsAddPcQuantity.AsFloat := ANode.AddPcQuantity;
  cdsFxBillsAddPcTotalPrice.AsFloat := ANode.AddPcTotalPrice;
  cdsFxBillsAddGatherQuantity.AsFloat := ANode.AddDealQuantity + ANode.AddQcQuantity;
  cdsFxBillsAddGatherTotalPrice.AsFloat := ANode.AddDealTotalPrice +
      ANode.AddQcTotalPrice + ANode.AddPcTotalPrice;
  cdsFxBillsAddRatioPercent.AsFloat := ANode.AddRatioPercent;

  cdsFxBillsQuantity.AsFloat := ANode.Quantity;
  cdsFxBillsTotalPrice.AsFloat := ANode.TotalPrice;
  cdsFxBillsRatioPercent.AsFloat := ANode.RatioPercent;

  cdsFxBillsDgnQuantity1.AsFloat := ANode.DesignQuantity1;
  cdsFxBillsDgnQuantity2.AsFloat := ANode.DesignQuantity2;
  cdsFxBillsDgnQuantity.AsString := GetDgnQuantity(ANode.DesignQuantity1, ANode.DesignQuantity2);
  if ANode.DesignQuantity1 <> 0 then
    cdsFxBillsDgnPrice1.AsFloat := PriceRoundTo(ANode.TotalPrice/ANode.DesignQuantity1);
  if ANode.DesignQuantity2 <> 0 then
    cdsFxBillsDgnPrice2.AsFloat := PriceRoundTo(ANode.TotalPrice/ANode.DesignQuantity2);
  if cdsFxBillsDgnPrice1.AsFloat <> 0 then
    cdsFxBillsDgnPrice.AsString := GetDgnQuantity(cdsFxBillsDgnPrice1.AsFloat, cdsFxBillsDgnPrice2.AsFloat);

  cdsFxBillsDealDgnQuantity1.AsFloat := ANode.DealDesignQuantity1;
  cdsFxBillsDealDgnQuantity2.AsFloat := ANode.DealDesignQuantity2;
  cdsFxBillsDealDgnQuantity.AsString := GetDgnQuantity(ANode.DealDesignQuantity1, ANode.DesignQuantity2);
  cdsFxBillsDealDgnPrice1.AsFloat := GetDgnPrice(cdsFxBillsAddDealTotalPrice.AsFloat, cdsFxBillsDealDgnQuantity1.AsFloat);
  cdsFxBillsDealDgnPrice2.AsFloat := GetDgnPrice(cdsFxBillsAddDealTotalPrice.AsFloat, cdsFxBillsDealDgnQuantity2.AsFloat);
  cdsFxBillsDealDgnPrice.AsString := GetDgnQuantity(cdsFxBillsDealDgnPrice1.AsFloat, cdsFxBillsDealDgnPrice2.AsFloat);

  cdsFxBillsCDgnQuantity1.AsFloat := ANode.CDesignQuantity1;
  cdsFxBillsCDgnQuantity2.AsFloat := ANode.CDesignQuantity2;
  cdsFxBillsCDgnQuantity.AsString := GetDgnQuantity(ANode.CDesignQuantity1, ANode.CDesignQuantity2);
  cdsFxBillsCDgnPrice1.AsFloat := GetDgnPrice(cdsFxBillsAddQcTotalPrice.AsFloat, cdsFxBillsCDgnQuantity1.AsFloat);
  cdsFxBillsCDgnPrice2.AsFloat := GetDgnPrice(cdsFxBillsAddQcTotalPrice.AsFloat, cdsFxBillsCDgnQuantity2.AsFloat);
  cdsFxBillsCDgnPrice.AsString := GetDgnQuantity(cdsFxBillsCDgnPrice1.AsFloat, cdsFxBillsCDgnPrice2.AsFloat);

  cdsFxBillsFinalDgnQuantity1.AsFloat := ANode.DealDesignQuantity1 + ANode.CDesignQuantity1;
  cdsFxBillsFinalDgnQuantity2.AsFloat := ANode.DealDesignQuantity2 + ANode.CDesignQuantity2;
  cdsFxBillsFinalDgnQuantity.AsString := GetDgnQuantity(cdsFxBillsFinalDgnQuantity1.AsFloat, cdsFxBillsFinalDgnQuantity2.AsFloat);
  cdsFxBillsFinalDgnPrice1.AsFloat := GetDgnPrice(cdsFxBillsAddGatherTotalPrice.AsFloat, cdsFxBillsFinalDgnQuantity1.AsFloat);
  cdsFxBillsFinalDgnPrice2.AsFloat := GetDgnPrice(cdsFxBillsAddGatherTotalPrice.AsFloat, cdsFxBillsFinalDgnQuantity2.AsFloat);
  cdsFxBillsFinalDgnPrice.AsString := GetDgnQuantity(cdsFxBillsFinalDgnPrice1.AsFloat, cdsFxBillsFinalDgnPrice2.AsFloat);
  cdsFxBills.Post;
  WriteNode(TReportCacheNode(ANode.FirstChild));
  WriteNode(TReportCacheNode(ANode.NextSibling));
end;

procedure TrmBillsGatherData.WriteGclNode;
var
  i: Integer;
  GclNode: TGclGatherNode;
begin
  for i := 0 to FGclList.Count - 1 do
  begin
    GclNode := FGclList.Node[i];
    cdsGclBills.Append;
    cdsGclBillsB_Code.AsString := GclNode.B_Code;
    cdsGclBillsIndexCode.AsString := GclNode.IndexCode;
    cdsGclBillsName.AsString := GclNode.Name;
    cdsGclBillsUnits.AsString := GclNode.Units;
    cdsGclBillsPrice.AsFloat := GclNode.Price;
    cdsGclBillsAddDealQuantity.AsFloat := GclNode.AddDealQuantity;
    cdsGclBillsAddDealTotalPrice.AsFloat := GclNode.AddDealTotalPrice;
    cdsGclBillsAddQcQuantity.AsFloat := GclNode.AddQcQuantity;
    cdsGclBillsAddQcTotalPrice.AsFloat := GclNode.AddQcTotalPrice;
    cdsGclBillsAddPcQuantity.AsFloat := GclNode.AddPcQuantity;
    cdsGclBillsAddPcTotalPrice.AsFloat := GclNode.AddPcTotalPrice;
    cdsGclBillsAddGatherQuantity.AsFloat := GclNode.AddDealQuantity + GclNode.AddQcQuantity;
    cdsGclBillsAddDealTotalPrice.AsFloat := GclNode.AddDealTotalPrice +
        GclNode.AddQcTotalPrice + GclNode.AddPcTotalPrice;
    cdsGclBillsPrecent.AsFloat := 0;
    cdsGclBillsMemoStr.AsString := '';
    cdsGclBills.Post;
  end;
end;

procedure TrmBillsGatherData.WriteProjectsData;

  procedure WriteProjectData(ANode: TReportCacheNode; AProjectIndex: Integer);
  begin
    if not Assigned(ANode) then Exit;
    cdsProjectBills.Append;
    cdsProjectBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectBillsProjectName.AsString := FCacheTree.ProjectName[AProjectIndex];
    cdsProjectBillsXiangCode.AsString := ANode.XiangCode;
    cdsProjectBillsMuCode.AsString := ANode.MuCode;
    cdsProjectBillsJieCode.AsString := ANode.JieCode;
    cdsProjectBillsXiMuCode.AsString := ANode.XiMuCode;
    cdsProjectBillsCode.AsString := ANode.Code;
    cdsProjectBillsB_Code.AsString := ANode.B_Code;
    cdsProjectBillsName.AsString := ANode.Name;
    cdsProjectBillsUnits.AsString := ANode.Units;
    // 此处数量与金额特指所有项目的累计完成数量与金额汇总。
    cdsProjectBillsQuantity.AsFloat := ANode.AddDealQuantity + ANode.AddQcQuantity;
    cdsProjectBillsTotalPrice.AsFloat := ANode.AddDealTotalPrice + ANode.AddQcTotalPrice + ANode.AddPcTotalPrice;
    cdsProjectBillsP_Quantity.AsFloat := ANode.P_Quantity[AProjectIndex];
    cdsProjectBillsP_TotalPrice.AsFloat := ANode.P_TotalPrice[AProjectIndex];
    cdsProjectBillsP_Price.AsFloat := ANode.P_Price[AProjectIndex];
    cdsProjectBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectBills.Post;
    Inc(FSerialNo);
    WriteProjectData(TReportCacheNode(ANode.FirstChild), AProjectIndex);
    WriteProjectData(TReportCacheNode(ANode.NextSibling), AProjectIndex);
  end;

  procedure WriteProjectGatherData(AProjectIndex: Integer);
  begin
    cdsProjectBills.Append;
    cdsProjectBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectBillsProjectName.AsString := FCacheTree.ProjectName[AProjectIndex];
    cdsProjectBillsName.AsString := '金额合计';
    with FCacheTree.GatherCacheNode do
    begin
      cdsProjectBillsTotalPrice.AsFloat := AddDealTotalPrice + AddQcTotalPrice + AddPcTotalPrice;
      cdsProjectBillsP_TotalPrice.AsFloat := P_TotalPrice[AProjectIndex];
    end;
    cdsProjectBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectBills.Post;
    Inc(FSerialNo);

    cdsProjectBills.Append;
    cdsProjectBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectBillsProjectName.AsString := FCacheTree.ProjectName[AProjectIndex];
    cdsProjectBillsName.AsString := Format('金额总计：%f', [FCacheTree.GatherCacheNode.GatherP_TotalPrice]);
    cdsProjectBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectBills.Post;
    Inc(FSerialNo);
  end;

var
  i: Integer;
begin
  for i := 0 to FCacheTree.ProjectCount - 1 do
  begin
    FSerialNo := 0;
    WriteProjectData(TReportCacheNode(FCacheTree.FirstNode), i);
    if GatherType = bgtFinal16 then
      WriteProjectGatherData(i);
  end;
end;

procedure TrmBillsGatherData.WriteEstimateNode(ANode: TReportCacheNode);
begin
  if not Assigned(ANode) then Exit;
  WriteENodeData(ANode);
  WriteEstimateNode(TReportCacheNode(ANode.FirstChild));
  WriteEstimateNode(TReportCacheNode(ANode.NextSibling));
end;

procedure TrmBillsGatherData.FilterFixedIDBills(ATree: TsdIDTree;
  AProjectIndex: Integer);
var
  iIndex: Integer;
  stnNode: TsdIDTreeNode;
  FixedIDNode: TFixedIDBillsNode;
begin
  for iIndex := 0 to ATree.Count - 1 do
  begin
    stnNode := ATree.Items[iIndex];
    if stnNode.ID >= 100 then Continue;
    FixedIDNode := FFixedIDList.GetFixedIDBillsNode(stnNode.ID);

    FixedIDNode.TotalPrice := FixedIDNode.TotalPrice
      + stnNode.Rec.ValueByName('TotalPrice').AsFloat;
    FixedIDNode.TotalPrice :=
      + stnNode.Rec.ValueByName('TotalPrice').AsFloat;

    FixedIDNode.AddGatherTotalPrice := FixedIDNode.AddGatherTotalPrice
      + stnNode.Rec.ValueByName('AddGatherTotalPrice').AsFloat;
    FixedIDNode.P_AddGatherTotalPrice[AProjectIndex] :=
      stnNode.Rec.ValueByName('AddGatherTotalPrice').AsFloat;
  end;
end;

procedure TrmBillsGatherData.WriteProjectsGclData;

  procedure WriteProjectGclData(AProjectIndex: Integer);
  var
    i: Integer;
    GclNode: TGclGatherNode;
  begin
    for i := 0 to FGclList.Count - 1 do
    begin
      GclNode := FGclList.Node[i];
      cdsProjectGclBills.Append;
      cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
      cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
      cdsProjectGclBillsB_Code.AsString := GclNode.B_Code;
      cdsProjectGclBillsIndexCode.AsString := GclNode.IndexCode;
      cdsProjectGclBillsName.AsString := GclNode.Name;
      cdsProjectGclBillsUnits.AsString := GclNode.Units;
      cdsProjectGclBillsQuantity.AsFloat := GclNode.Quantity;
      cdsProjectGclBillsTotalPrice.AsFloat := GclNode.TotalPrice;
      // Price须填写合计平均单价
      if cdsProjectGclBillsQuantity.AsFloat <> 0 then
        cdsProjectGclBillsPrice.AsFloat := cdsProjectGclBillsTotalPrice.AsFloat/cdsProjectGclBillsQuantity.AsFloat;
      cdsProjectGclBillsP_Price.AsFloat := GclNode.P_Price[AProjectIndex];
      cdsProjectGclBillsP_Quantity.AsFloat := GclNode.P_Quantity[AProjectIndex];
      cdsProjectGclBillsP_TotalPrice.AsFloat := GclNode.P_TotalPrice[AProjectIndex];
      cdsProjectGclBillsP_AddGatherQuantity.AsFloat := GclNode.P_AddGatherQuantity[AProjectIndex];
      cdsProjectGclBillsP_AddGatherTotalPrice.AsFloat := GclNode.P_AddGatherTotalPrice[AProjectIndex];
      cdsProjectGclBillsAddGatherQuantity.AsFloat := GclNode.AddDealQuantity + GclNode.AddQcQuantity;
      cdsProjectGclBillsAddGatherTotalPrice.AsFloat := GclNode.AddDealTotalPrice
          + GclNode.AddQcTotalPrice + GclNode.AddPcTotalPrice;
      cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
      cdsProjectGclBills.Post;
    end;
    Inc(FSerialNo);
  end;

  procedure WriteGatherNodeData(AProjectIndex: Integer);
  begin
    cdsProjectGclBills.Append;
    cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
    case GatherType of
      bgtFinal07: cdsProjectGclBillsName.AsString := '小计';
      bgtFinal11: cdsProjectGclBillsName.AsString := '第100章至900章清单合计';
      bgtFinal19: cdsProjectGclBillsName.AsString := '合计';
    end;
    cdsProjectGclBillsTotalPrice.AsFloat := FGclList.GatherNode.TotalPrice;
    cdsProjectGclBillsP_TotalPrice.AsFloat := FGclList.GatherNode.P_TotalPrice[AProjectIndex];
    cdsProjectGclBillsAddGatherTotalPrice.AsFloat := FGclList.GatherNode.AddDealTotalPrice
        + FGclList.GatherNode.AddQcTotalPrice + FGclList.GatherNode.AddPcTotalPrice;
    cdsProjectGclBillsP_AddGatherTotalPrice.AsFloat := FGclList.GatherNode.P_AddGatherTotalPrice[AProjectIndex];
    cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectGclBills.Post;
    Inc(FSerialNo);
  end;

  procedure WriteFixedIDData(AProjectIndex: Integer; ANode: TFixedIDBillsNode; const AName: string);
  begin
    cdsProjectGclBills.Append;
    cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
    cdsProjectGclBillsName.AsString := AName;
    if Assigned(ANode) then
    begin
      cdsProjectGclBillsTotalPrice.AsFloat := ANode.TotalPrice;
      cdsProjectGclBillsP_TotalPrice.AsFloat := ANode.P_TotalPrice[AProjectIndex];
      cdsProjectGclBillsAddGatherTotalPrice.AsFloat := ANode.AddGatherTotalPrice;
      cdsProjectGclBillsP_AddGatherTotalPrice.AsFloat := ANode.P_AddGatherTotalPrice[AProjectIndex];
    end;
    cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectGclBills.Post;
  end;

  procedure WriteFixedIDBillsData07(AProjectIndex: Integer);
  var
    fTotalPrice, fP_TotalPrice, fAddGatherTotalPrice, fP_AddGatherTotalPrice: Double;
    Node54, Node45, Node40, Node51: TFixedIDBillsNode;
  begin
    fTotalPrice := FGclList.GatherNode.TotalPrice;
    fP_TotalPrice := FGclList.GatherNode.P_TotalPrice[AProjectIndex];
    fAddGatherTotalPrice := FGclList.GatherNode.AddDealTotalPrice
        + FGclList.GatherNode.AddQcTotalPrice + FGclList.GatherNode.AddPcTotalPrice;
    fP_AddGatherTotalPrice := FGclList.GatherNode.P_AddGatherTotalPrice[AProjectIndex];
    // 变更引起调整合计 全部取0
    cdsProjectGclBills.Append;
    cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
    cdsProjectGclBillsName.AsString := '变更引起调整合计';
    cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectGclBills.Post;
    Inc(FSerialNo);
    // 工程项目调价合计
    Node54 := FFixedIDList.FixedIDBillsNode(54);
    WriteFixedIDData(AProjectIndex, Node54, '工程项目调价合计');
    if Assigned(Node54) then
    begin
      fTotalPrice := fTotalPrice + Node54.TotalPrice;
      fP_TotalPrice := fP_TotalPrice + Node54.P_TotalPrice[AProjectIndex];
      fAddGatherTotalPrice := fAddGatherTotalPrice + Node54.AddGatherTotalPrice;
      fP_AddGatherTotalPrice := fP_AddGatherTotalPrice + Node54.P_AddGatherTotalPrice[AProjectIndex];
    end;
    // 工程项目索赔合计
    Node45 := FFixedIDList.FixedIDBillsNode(45);
    WriteFixedIDData(AProjectIndex, Node45, '工程项目索赔合计');
    if Assigned(Node45) then
    begin
      fTotalPrice := fTotalPrice + Node45.TotalPrice;
      fP_TotalPrice := fP_TotalPrice + Node45.P_TotalPrice[AProjectIndex];
      fAddGatherTotalPrice := fAddGatherTotalPrice + Node45.AddGatherTotalPrice;
      fP_AddGatherTotalPrice := fP_AddGatherTotalPrice + Node45.P_AddGatherTotalPrice[AProjectIndex];
    end;
    // 计日工支出合计
    Node40 := FFixedIDList.FixedIDBillsNode(40);
    WriteFixedIDData(AProjectIndex, Node40, '计日工支出合计');
    if Assigned(Node40) then
    begin
      fTotalPrice := fTotalPrice + Node40.TotalPrice;
      fP_TotalPrice := fP_TotalPrice + Node40.P_TotalPrice[AProjectIndex];
      fAddGatherTotalPrice := fAddGatherTotalPrice + Node40.AddGatherTotalPrice;
      fP_AddGatherTotalPrice := fP_AddGatherTotalPrice + Node40.P_AddGatherTotalPrice[AProjectIndex];
    end;
    // 金额合计
    cdsProjectGclBills.Append;
    cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
    cdsProjectGclBillsName.AsString := '金额合计';
    cdsProjectGclBillsTotalPrice.AsFloat := fTotalPrice;
    cdsProjectGclBillsP_TotalPrice.AsFloat := fP_TotalPrice;
    cdsProjectGclBillsAddGatherTotalPrice.AsFloat := fAddGatherTotalPrice;
    cdsProjectGclBillsP_AddGatherTotalPrice.AsFloat := fP_AddGatherTotalPrice;
    cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectGclBills.Post;
    Inc(FSerialNo);
    // 设备费
    Node51 := FFixedIDList.FixedIDBillsNode(51);
    WriteFixedIDData(AProjectIndex, Node51, '设备费');
  end;

  procedure WriteFixedIDBillsData11(AProjectIndex: Integer);
  var
    fTotalPrice, fP_TotalPrice, fAddGatherTotalPrice, fP_AddGatherTotalPrice: Double;
    Node19, Node40, NodeTotal: TFixedIDBillsNode;
  begin
    fTotalPrice := FGclList.GatherNode.TotalPrice;
    fP_TotalPrice := FGclList.GatherNode.P_TotalPrice[AProjectIndex];
    fAddGatherTotalPrice := FGclList.GatherNode.AddDealTotalPrice
        + FGclList.GatherNode.AddQcTotalPrice + FGclList.GatherNode.AddPcTotalPrice;
    fP_AddGatherTotalPrice := FGclList.GatherNode.P_AddGatherTotalPrice[AProjectIndex];
    // 计日工合计
    Node40 := FFixedIDList.FixedIDBillsNode(40);
    WriteFixedIDData(AProjectIndex, Node40, '计日工合计');
    if Assigned(Node40) then
    begin
      fTotalPrice := fTotalPrice + Node40.TotalPrice;
      fP_TotalPrice := fP_TotalPrice + Node40.P_TotalPrice[AProjectIndex];
      fAddGatherTotalPrice := fTotalPrice + Node40.AddGatherTotalPrice;
      fP_AddGatherTotalPrice := fP_TotalPrice + Node40.P_AddGatherTotalPrice[AProjectIndex];
    end;
    // 暂列金额合计
    Node19 := FFixedIDList.FixedIDBillsNode(19);
    WriteFixedIDData(AProjectIndex, Node19, '暂列金额合计');
    if Assigned(Node19) then
    begin
      fTotalPrice := fTotalPrice + Node19.TotalPrice;
      fP_TotalPrice := fP_TotalPrice + Node19.P_TotalPrice[AProjectIndex];
      fAddGatherTotalPrice := fTotalPrice + Node19.AddGatherTotalPrice;
      fP_AddGatherTotalPrice := fP_TotalPrice + Node19.P_AddGatherTotalPrice[AProjectIndex];
    end;
    // 其他类别费用合计&金额合计
    NodeTotal := FFixedIDList.FixedIDBillsNode(-1);
    // 其他类别费用 = 金额合计 - 第100章至900章合计 - 计日工合计 - 暂列金额合计
    if Assigned(NodeTotal) then
    begin
      fTotalPrice := NodeTotal.TotalPrice - fTotalPrice;
      fP_TotalPrice := NodeTotal.P_TotalPrice[AProjectIndex] - fP_TotalPrice;
      fAddGatherTotalPrice := NodeTotal.AddGatherTotalPrice - fAddGatherTotalPrice;
      fP_AddGatherTotalPrice := NodeTotal.P_AddGatherTotalPrice[AProjectIndex] - fP_AddGatherTotalPrice;
    end;
    cdsProjectGclBills.Append;
    cdsProjectGclBillsProjectID.AsInteger := AProjectIndex;
    cdsProjectGclBillsProjectName.AsString := FGclList.ProjectName[AProjectIndex];
    cdsProjectGclBillsName.AsString := '其他类别费用合计';
    cdsProjectGclBillsTotalPrice.AsFloat := fTotalPrice;
    cdsProjectGclBillsP_TotalPrice.AsFloat := fP_TotalPrice;
    cdsProjectGclBillsAddGatherTotalPrice.AsFloat := fAddGatherTotalPrice;
    cdsProjectGclBillsP_AddGatherTotalPrice.AsFloat := fP_AddGatherTotalPrice;
    cdsProjectGclBillsSerialNo.AsInteger := FSerialNo;
    cdsProjectGclBills.Post;
    Inc(FSerialNo);
    WriteFixedIDData(AProjectIndex, NodeTotal, '金额合计');
  end;

var
  iProject: Integer;
begin
  for iProject := 0 to FGclList.ProjectCount - 1 do
  begin
    FSerialNo := 0;
    WriteProjectGclData(iProject);
    WriteGatherNodeData(iProject);
    case GatherType of
      bgtFinal07: WriteFixedIDBillsData07(iProject);
      bgtFinal11: WriteFixedIDBillsData11(iProject);
    end;
  end;
end;

procedure TrmBillsGatherData.FilterSettlement(AProjectData: TProjectData;
  AProjectIndex: Integer);
var
  FixedIDNode: TFixedIDBillsNode;
begin
  // -1表示项目结算价
  FixedIDNode := FFixedIDList.GetFixedIDBillsNode(-1);
  FixedIDNode.TotalPrice := FixedIDNode.TotalPrice + AProjectData.BillsData.Settlement[0];
  FixedIDNode.P_TotalPrice[AProjectIndex] := AProjectData.BillsData.Settlement[0];
  FixedIDNode.AddGatherTotalPrice := FixedIDNode.AddGatherTotalPrice
    + AProjectData.BillsData.Settlement[4];
  FixedIDNode.P_AddGatherTotalPrice[AProjectIndex] :=
    AProjectData.BillsData.Settlement[4];
end;

procedure TrmBillsGatherData.WriteFlowData(AProjectData: TProjectData);
begin
  case GatherType of
    bgtFinal12: WriteBGLFlowData(AProjectData);
  end;
end;

procedure TrmBillsGatherData.WriteBGLFlowData(AProjectData: TProjectData);

  procedure WriteBGLData(ABGLID: Integer);
  begin
    with AProjectData.BGLData do
    begin
      cdsBGBills.Filter := 'BGID = ' + IntToStr(ABGLID);
      cdsBGBills.Filtered := True;
      try
        if cdsBGBills.RecordCount = 0 then
        begin
          cdsBGLFlow.Append;
          cdsBGLFlowMergeBGLCode.AsString := cdsBGLCode.AsString;
          cdsBGLFlowBGLName.AsString := cdsBGLName.AsString;
          cdsBGLFlowApprovalCode.AsString := cdsBGLApprovalCode.AsString;
          cdsBGLFlowSuggestion.AsString := '同意';
          cdsBGLFlowBGReason.AsString := cdsBGLPos_Reason.AsString;
          cdsBGLFlowBGTotalPrice.AsFloat := cdsBGLTotalPrice.AsFloat;
          cdsBGLFlow.Post;
          Exit;
        end;

        cdsBGBills.First;
        while not cdsBGBills.Eof do
        begin
          cdsBGLFlow.Append;
          cdsBGLFlowMergeBGLCode.AsString := cdsBGLCode.AsString;
          cdsBGLFlowBGLName.AsString := cdsBGLName.AsString;
          cdsBGLFlowApprovalCode.AsString := cdsBGLApprovalCode.AsString;
          cdsBGLFlowSuggestion.AsString := '同意';
          cdsBGLFlowBGReason.AsString := cdsBGLPos_Reason.AsString;
          cdsBGLFlowBGTotalPrice.AsFloat := cdsBGLTotalPrice.AsFloat;
          cdsBGLFlowB_Code.AsString := cdsBGBillsB_Code.AsString;
          cdsBGLFlowName.AsString := cdsBGBillsName.AsString;
          cdsBGLFlowUnits.AsString := cdsBGBillsUnits.AsString;
          cdsBGLFlowQuantity.AsFloat := cdsBGBillsQuantity.AsFloat;
          cdsBGLFlowPrice.AsFloat := cdsBGBillsPrice.AsFloat;
          cdsBGLFlowTotalPrice.AsFloat := cdsBGBillsTotalPrice.AsFloat;
          cdsBGLFlow.Post;
          cdsBGBills.Next;
        end;
      finally
        cdsBGBills.Filtered := False;
      end;
    end;
  end;

begin
  cdsBGLFlow.Append;
  cdsBGLFlowMergeBGLCode.AsString := AProjectData.ProjProperties.DealIndex;
  cdsBGLFlow.Post;

  with AProjectData.BGLData do
  begin
    cdsBGL.First;
    while not cdsBGL.Eof do
    begin
      WriteBGLData(cdsBGLID.AsInteger);
      cdsBGL.Next;
    end;
  end;
end;

procedure TrmBillsGatherData.AddBillsList(ANode: TsdIDTreeNode;
  AParent: TReportCacheNode; AProjectIndex: Integer;
  ASelectProject: TSelectProject);
var
  ACur: TReportCacheNode;
begin
  if not Assigned(ANode) then Exit;
  // 按设置的层次汇总
  case ReportConfig.GatherLevel of
    // 项
    0: if ANode.Level > 2 then Exit;
    // 目
    1: if ANode.Level > 3 then Exit;
    // 节
    2: if ANode.Level > 4 then Exit;
    // 细目
    3: if ANode.Level > 5 then Exit;
    // 项目节
    4: if ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit;
  end;
  if GatherType in [bgtXmj, bgtMultiXmj, bgtEstimate, bgtEstimate1] then
    if ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit;
  ACur := AddBillsNode(ANode, AParent, AProjectIndex, ASelectProject);
  AddBills(ANode.FirstChild, ACur, AProjectIndex, ASelectProject);
end;

procedure TrmBillsGatherData.WriteGatherCacheNode(const AGatherName: string);
begin
  cdsFxBills.Append;
  cdsFxBillsName.AsString := AGatherName;
  with FCacheTree.GatherCacheNode do
  begin
    cdsFxBillsAddDealTotalPrice.AsFloat := AddDealTotalPrice;
    cdsFxBillsAddQcTotalPrice.AsFloat := AddQcTotalPrice;
    cdsFxBillsAddPcTotalPrice.AsFloat := AddPcTotalPrice;
    cdsFxBillsAddGatherTotalPrice.AsFloat := AddDealTotalPrice +
        AddQcTotalPrice + AddPcTotalPrice;
    cdsFxBillsTotalPrice.AsFloat := TotalPrice;
  end;
  cdsFxBills.Post;
end;

procedure TrmBillsGatherData.CalculateGatherData;
begin
  if GatherType in [bgtFinal08, bgtFinal16, bgtEstimate, bgtEstimate1, bgtG_Final04] then
    FCacheTree.ReCalcGatherData;
  if GatherType in [bgtFinal07, bgtFinal11, bgtFinal19] then
    FGclList.ReCalcualteGatherNode;
end;

procedure TrmBillsGatherData.WriteBillsData;
begin
  WriteNode(TReportCacheNode(FCacheTree.FirstNode));
  case GatherType of
    bgtFinal08: WriteGatherCacheNode('金额合计');
    bgtG_Final04: WriteGatherCacheNode('公路基本造价');
  end;
end;

procedure TrmBillsGatherData.WriteEstimateGatherNode;
begin
  cdsEstimateBills.Append;
  cdsEstimateBillsName.AsString := '公路基本造价';
  with FCacheTree.GatherCacheNode do
  begin
    cdsEstimateBillsTotalPrice.AsFloat := TotalPrice;
    cdsEstimateBillsAddDealTotalPrice.AsFloat := AddDealTotalPrice;
    cdsEstimateBillsAddCTotalPrice.AsFloat := AddQcTotalPrice + AddPcTotalPrice;
    cdsEstimateBillsAddGatherTotalPrice.AsFloat :=
        cdsEstimateBillsAddDealTotalPrice.AsFloat + cdsEstimateBillsAddCTotalPrice.AsFloat;
    cdsEstimateBillsTotalPriceAdjust.AsFloat :=
        cdsEstimateBillsAddGatherTotalPrice.AsFloat - cdsEstimateBillsPDTotalPrice.AsFloat;

    cdsEstimateBillsPDTotalPrice.AsFloat := PDTotalPrice;
    cdsEstimateBillsCDDTotalPrice.AsFloat := CDDTotalPrice;
    cdsEstimateBillsABTotalPrice.AsFloat := ABTotalPrice;

    cdsEstimateBillsTotalPriceCompare1.AsFloat := GetCompare(ABTotalPrice, TotalPrice);
    cdsEstimateBillsTotalPriceCompare2.AsFloat :=
        GetCompare(ABTotalPrice, cdsEstimateBillsAddGatherTotalPrice.AsFloat);
    cdsEstimateBillsTotalPriceCompare3.AsFloat :=
        GetCompare(TotalPrice, cdsEstimateBillsAddGatherTotalPrice.AsFloat);
  end;
  cdsEstimateBills.Post;
end;

procedure TrmBillsGatherData.WriteEstimateData;
begin
  WriteEstimateNode(TReportCacheNode(FCacheTree.FirstNode));
  if GatherType = bgtG_Final06_1 then
    ReWriteENodeDataAsGather(TReportCacheNode(FCacheTree.FirstNode), '土地征用及拆迁补偿费用合计');
  if GatherType in [bgtEstimate, bgtEstimate1] then
    WriteEstimateGatherNode;
end;

function TrmBillsGatherData.GetCompare(ANum1, ANum2: Double): Double;
begin
  Result := 0;
  if ANum1 <> 0 then
    Result := (ANum2 - ANum1)/ANum1*100;
end;

procedure TrmBillsGatherData.WriteENodeData(ANode: TReportCacheNode);
begin
  cdsEstimateBills.Append;
  cdsEstimateBillsXiangCode.AsString := ANode.XiangCode;
  cdsEstimateBillsMuCode.AsString := ANode.MuCode;
  cdsEstimateBillsJieCode.AsString := ANode.JieCode;
  cdsEstimateBillsXiMuCode.AsString := ANode.XiMuCode;

  cdsEstimateBillsCode.AsString := ANode.Code;
  cdsEstimateBillsB_Code.AsString := ANode.B_Code;
  cdsEstimateBillsName.AsString := ANode.Name;
  cdsEstimateBillsUnits.AsString := ANode.Units;
  cdsEstimateBillsPrice.AsFloat := ANode.Price;

  cdsEstimateBillsQuantity.AsFloat := ANode.Quantity;
  cdsEstimateBillsTotalPrice.AsFloat := ANode.TotalPrice;
  cdsEstimateBillsDgnQuantity1.AsFloat := ANode.DesignQuantity1;
  cdsEstimateBillsDgnQuantity2.AsFloat := ANode.DesignQuantity2;
  cdsEstimateBillsDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsDgnQuantity1.AsFloat, cdsEstimateBillsDgnQuantity2.AsFloat);

  cdsEstimateBillsAddDealQuantity.AsFloat := ANode.AddDealQuantity;
  cdsEstimateBillsAddDealTotalPrice.AsFloat := ANode.AddDealTotalPrice;
  cdsEstimateBillsAddCQuantity.AsFloat := ANode.AddQcQuantity;
  cdsEstimateBillsAddCTotalPrice.AsFloat := ANode.AddQcTotalPrice + ANode.AddPcTotalPrice;
  cdsEstimateBillsAddGatherQuantity.AsFloat :=
      cdsEstimateBillsAddDealQuantity.AsFloat + cdsEstimateBillsAddCQuantity.AsFloat;
  cdsEstimateBillsAddGatherTotalPrice.AsFloat :=
      cdsEstimateBillsAddDealTotalPrice.AsFloat + cdsEstimateBillsAddCTotalPrice.AsFloat;
  cdsEstimateBillsQuantityAdjust.AsFloat :=
      cdsEstimateBillsAddGatherQuantity.AsFloat - cdsEstimateBillsPDQuantity.AsFloat;
  cdsEstimateBillsTotalPriceAdjust.AsFloat :=
      cdsEstimateBillsAddGatherTotalPrice.AsFloat - cdsEstimateBillsPDTotalPrice.AsFloat;

  cdsEstimateBillsDealDgnQuantity1.AsFloat := ANode.DealDesignQuantity1;
  cdsEstimateBillsDealDgnQuantity2.AsFloat := ANode.DealDesignQuantity2;
  cdsEstimateBillsDealDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsDealDgnQuantity1.AsFloat, cdsEstimateBillsDealDgnQuantity2.AsFloat);
  cdsEstimateBillsCDgnQuantity1.AsFloat := ANode.CDesignQuantity1;
  cdsEstimateBillsCDgnQuantity2.AsFloat := ANode.CDesignQuantity2;
  cdsEstimateBillsCDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsCDgnQuantity1.AsFloat, cdsEstimateBillsCDgnQuantity2.AsFloat);
  cdsEstimateBillsGatherDgnQuantity1.AsFloat :=
      cdsEstimateBillsDealDgnQuantity1.AsFloat + cdsEstimateBillsCDgnQuantity1.AsFloat;
  cdsEstimateBillsGatherDgnQuantity2.AsFloat :=
      cdsEstimateBillsDealDgnQuantity2.AsFloat + cdsEstimateBillsCDgnQuantity2.AsFloat;;
  cdsEstimateBillsGatherDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsGatherDgnQuantity1.AsFloat, cdsEstimateBillsGatherDgnQuantity2.AsFloat);
  cdsEstimateBillsFinalDgnQty1.AsFloat := cdsEstimateBillsDgnQuantity1.AsFloat + cdsEstimateBillsCDgnQuantity1.AsFloat;
  cdsEstimateBillsFinalDgnQty2.AsFloat := cdsEstimateBillsDgnQuantity2.AsFloat + cdsEstimateBillsCDgnQuantity2.AsFloat;
  cdsEstimateBillsFinalDgnQty.AsString := GetDgnQuantity(
      cdsEstimateBillsFinalDgnQty1.AsFloat, cdsEstimateBillsFinalDgnQty2.AsFloat);

  cdsEstimateBillsPDQuantity.AsFloat := ANode.PDQuantity;
  cdsEstimateBillsPDTotalPrice.AsFloat := ANode.PDTotalPrice;
  cdsEstimateBillsPDDgnQuantity1.AsFloat := ANode.PDDesignQuantity1;
  cdsEstimateBillsPDDgnQuantity2.AsFloat := ANode.PDDesignQuantity2;
  cdsEstimateBillsPDDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsPDDgnQuantity1.AsFloat, cdsEstimateBillsPDDgnQuantity2.AsFloat);
  cdsEstimateBillsPDDgnPrice.AsFloat := ANode.PDDesignPrice;

  cdsEstimateBillsCDDQuantity.AsFloat := ANode.CDDQuantity;
  cdsEstimateBillsCDDTotalPrice.AsFloat := ANode.CDDTotalPrice;
  cdsEstimateBillsCDDDgnQuantity1.AsFloat := ANode.CDDDesignQuantity1;
  cdsEstimateBillsCDDDgnQuantity2.AsFloat := ANode.CDDDesignQuantity2;
  cdsEstimateBillsCDDDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsCDDDgnQuantity1.AsFloat, cdsEstimateBillsCDDDgnQuantity2.AsFloat);
  cdsEstimateBillsCDDDgnPrice.AsFloat := ANode.CDDDesignPrice;

  cdsEstimateBillsABQuantity.AsFloat := ANode.ABQuantity;
  cdsEstimateBillsABTotalPrice.AsFloat := ANode.ABTotalPrice;
  cdsEstimateBillsABDgnQuantity1.AsFloat := ANode.ABDesignQuantity1;
  cdsEstimateBillsABDgnQuantity2.AsFloat := ANode.ABDesignQuantity2;
  cdsEstimateBillsABDgnQuantity.AsString :=
      GetDgnQuantity(cdsEstimateBillsABDgnQuantity1.AsFloat, cdsEstimateBillsABDgnQuantity2.AsFloat);
  cdsEstimateBillsABDgnPrice.AsFloat := ANode.ABDesignPrice;    

  cdsEstimateBillsQuantityCompare1.AsFloat := GetCompare(ANode.ABQuantity, ANode.Quantity);
  cdsEstimateBillsTotalPriceCompare1.AsFloat := GetCompare(ANode.ABTotalPrice, ANode.TotalPrice);
  cdsEstimateBillsDgnQuantity1Compare1.AsFloat := GetCompare(
      cdsEstimateBillsABDgnQuantity1.AsFloat, cdsEstimateBillsDgnQuantity1.AsFloat);
  cdsEstimateBillsDgnQuantity2Compare1.AsFloat := GetCompare(
      cdsEstimateBillsABDgnQuantity2.AsFloat, cdsEstimateBillsDgnQuantity2.AsFloat);
  cdsEstimateBillsDgnQuantityCompare1.AsString := GetDgnQuantity(
      cdsEstimateBillsDgnQuantity1Compare1.AsFloat, cdsEstimateBillsDgnQuantity2Compare1.AsFloat);

  cdsEstimateBillsQuantityCompare2.AsFloat :=
      GetCompare(ANode.ABQuantity, cdsEstimateBillsAddGatherQuantity.AsFloat);
  cdsEstimateBillsTotalPriceCompare2.AsFloat :=
      GetCompare(ANode.ABTotalPrice, cdsEstimateBillsAddGatherTotalPrice.AsFloat);
  cdsEstimateBillsDgnQuantity1Compare2.AsFloat := GetCompare(
      cdsEstimateBillsABDgnQuantity1.AsFloat, cdsEstimateBillsGatherDgnQuantity1.AsFloat);
  cdsEstimateBillsDgnQuantity2Compare2.AsFloat := GetCompare(
      cdsEstimateBillsABDgnQuantity2.AsFloat, cdsEstimateBillsGatherDgnQuantity2.AsFloat);
  cdsEstimateBillsDgnQuantityCompare2.AsString := GetDgnQuantity(
      cdsEstimateBillsDgnQuantity1Compare2.AsFloat, cdsEstimateBillsDgnQuantity2Compare2.AsFloat);

  cdsEstimateBillsQuantityCompare3.AsFloat :=
      GetCompare(ANode.Quantity, cdsEstimateBillsAddGatherQuantity.AsFloat);
  cdsEstimateBillsTotalPriceCompare3.AsFloat :=
      GetCompare(ANode.TotalPrice, cdsEstimateBillsAddGatherTotalPrice.AsFloat);
  cdsEstimateBillsDgnQuantity1Compare3.AsFloat := GetCompare(
      cdsEstimateBillsDgnQuantity1.AsFloat, cdsEstimateBillsGatherDgnQuantity1.AsFloat);
  cdsEstimateBillsDgnQuantity2Compare3.AsFloat := GetCompare(
      cdsEstimateBillsDgnQuantity2.AsFloat, cdsEstimateBillsGatherDgnQuantity2.AsFloat);
  cdsEstimateBillsDgnQuantityCompare3.AsString := GetDgnQuantity(
      cdsEstimateBillsDgnQuantity1Compare3.AsFloat, cdsEstimateBillsDgnQuantity2Compare3.AsFloat);
  cdsEstimateBills.Post;
end;

procedure TrmBillsGatherData.ReWriteENodeDataAsGather(
  ANode: TReportCacheNode; AName: string);
begin
  WriteENodeData(ANode);
  cdsEstimateBills.Edit;
  cdsEstimateBillsXiangCode.AsString := '';
  cdsEstimateBillsMuCode.AsString := '';
  cdsEstimateBillsJieCode.AsString := '';
  cdsEstimateBillsXiMuCode.AsString := '';
  cdsEstimateBillsCode.AsString := '';
  cdsEstimateBillsName.AsString := AName;
  cdsEstimateBillsUnits.AsString := '';
  cdsEstimateBills.Post;
end;

function TrmBillsGatherData.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 TrmBillsGatherData.CalculateRatioPercent;
begin
  if GatherType = bgtG_Final04 then
    FCacheTree.ReCalcGatherData;
end;

function TrmBillsGatherData.GetDgnPrice(ATotalPrice,
  ADgnQuantity: Double): Double;
begin
  if ADgnQuantity <> 0 then
    Result := PriceRoundTo(ATotalPrice/ADgnQuantity)
  else
    Result := 0;
end;

end.
