Browse Source

Merge branch 'master' of http://192.168.1.41:3000/MaiXinRong/Measure

builder 6 years ago
parent
commit
d599a3ffdc

+ 17 - 0
DataModules/PHPWebDm.pas

@@ -120,6 +120,7 @@ type
     function UrlGet(AUrl: string; APostParam: TStrings; var AResult: string): Integer; overload;
     function UrlGet(AUrl: string; APostParam: TStrings; var AResult: TStrings): Integer; overload;
     procedure ReadIniValues;
+    function RepalceSpecChars(AFileName: string): string;
 
     property Account: string read FAccount write SetAccount;
     property UserID: Integer read FUserID write SetUserID;
@@ -976,6 +977,22 @@ begin
   end;
 end;
 
+function TPHPWeb.RepalceSpecChars(AFileName: string): string;
+const
+  BefChar: array [0..10] of Char = ('(', ')', '[', ']', '{', '}', ':', '"', '''', ',', ';');
+  AftChar: array [0..10] of string = ('(', ')', '【', '】', '『', '』', ':', '”', '”', ',', ';');
+var
+  I: Integer;
+begin
+  AFileName := Trim(AFileName);
+  for I := low(BefChar) to High(BefChar) do
+  begin
+    if Pos(BefChar[I], AFileName) > 0 then
+      AFileName := StringReplace(AFileName, BefChar[I], AftChar[I], [rfReplaceAll]);
+  end;
+  Result := AFileName;
+end;
+
 initialization
 
 finalization

+ 84 - 0
DataModules/ReportMemoryDm/rmBGBillsGatherDm.dfm

@@ -0,0 +1,84 @@
+object rmBGBillsGatherData: TrmBGBillsGatherData
+  OldCreateOrder = False
+  Left = 864
+  Top = 318
+  Height = 150
+  Width = 215
+  object cdsBGBills: TClientDataSet
+    Active = True
+    Aggregates = <>
+    IndexFieldNames = 'TenderID;PartID;BGLCode;IndexCode'
+    Params = <>
+    Left = 48
+    Top = 40
+    Data = {
+      820100009619E0BD01000000180000001100000000000300000082010854656E
+      6465724944040001000000000006506172744944040001000000000009496E64
+      6578436F646501004A000000010005574944544802000200640006425F436F64
+      6501004A0000000100055749445448020002006400044E616D6502004A000000
+      010005574944544802000200FE0105556E69747301004A000000010005574944
+      54480200020028000550726963650800040000000000085175616E7469747908
+      000400000000000A546F74616C507269636508000400000000000B4375725175
+      616E7469747908000400000000000D437572546F74616C507269636508000400
+      000000000B5072655175616E7469747908000400000000000D507265546F7461
+      6C507269636508000400000000000B456E645175616E74697479080004000000
+      00000D456E64546F74616C507269636508000400000000000750657263656E74
+      08000400000000000742474C436F646502004A00000001000557494454480200
+      0200FE010000}
+    object cdsBGBillsTenderID: TIntegerField
+      FieldName = 'TenderID'
+    end
+    object cdsBGBillsPartID: TIntegerField
+      FieldName = 'PartID'
+    end
+    object cdsBGBillsIndexCode: TWideStringField
+      FieldName = 'IndexCode'
+      Size = 50
+    end
+    object cdsBGBillsB_Code: TWideStringField
+      FieldName = 'B_Code'
+      Size = 50
+    end
+    object cdsBGBillsName: TWideStringField
+      FieldName = 'Name'
+      Size = 255
+    end
+    object cdsBGBillsUnits: TWideStringField
+      FieldName = 'Units'
+    end
+    object cdsBGBillsPrice: TFloatField
+      FieldName = 'Price'
+    end
+    object cdsBGBillsQuantity: TFloatField
+      FieldName = 'Quantity'
+    end
+    object cdsBGBillsTotalPrice: TFloatField
+      FieldName = 'TotalPrice'
+    end
+    object cdsBGBillsCurQuantity: TFloatField
+      FieldName = 'CurQuantity'
+    end
+    object cdsBGBillsCurTotalPrice: TFloatField
+      FieldName = 'CurTotalPrice'
+    end
+    object cdsBGBillsPreQuantity: TFloatField
+      FieldName = 'PreQuantity'
+    end
+    object cdsBGBillsPreTotalPrice: TFloatField
+      FieldName = 'PreTotalPrice'
+    end
+    object cdsBGBillsEndQuantity: TFloatField
+      FieldName = 'EndQuantity'
+    end
+    object cdsBGBillsEndTotalPrice: TFloatField
+      FieldName = 'EndTotalPrice'
+    end
+    object cdsBGBillsPercent: TFloatField
+      FieldName = 'Percent'
+    end
+    object cdsBGBillsBGLCode: TWideStringField
+      FieldName = 'BGLCode'
+      Size = 255
+    end
+  end
+end

+ 676 - 0
DataModules/ReportMemoryDm/rmBGBillsGatherDm.pas

@@ -0,0 +1,676 @@
+unit rmBGBillsGatherDm;
+
+interface
+
+uses
+  SysUtils, Classes, DB, DBClient, rmSelectProjectFrm, ProjectData,
+  BillsTree, sdDB;
+
+type
+  TBGBills = class
+  private
+    FIndexCode: string;
+    FB_Code: string;
+    FName: string;
+    FUnits: string;
+    FPrice: Double;
+    FQuantity: Double;
+    FTotalPrice: Double;
+    FCurQuantity: Double;
+    FCurTotalPrice: Double;
+    FPreQuantity: Double;
+    FPreTotalPrice: Double;
+    FEndQuantity:  Double;
+    FEndTotalPrice: Double;
+    procedure SetB_Code(const Value: string);
+    function GetPercent: Double;
+  public
+    procedure Calcualte;
+
+    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 CurQuantity: Double read FCurQuantity write FCurQuantity;
+    property CurTotalPrice: Double read FCurTotalPrice;
+    property PreQuantity: Double read FPreQuantity write FPreQuantity;
+    property PreTotalPrice: Double read FPreTotalPrice;
+    property EndQuantity: Double read FEndQuantity;
+    property EndTotalPrice: Double read FEndTotalPrice;
+    property Percent: Double read GetPercent;
+  end;
+
+  TBGLData = class
+  private
+    FBGLCode: string;
+    FBGBillsList: TList;
+    function GetBGBills(AIndex: Integer): TBGBills;
+    function GetBGBillsCount: Integer;
+  public
+    constructor Create(const ACode: string);
+    destructor Destroy; override;
+
+    function AddBGBills: TBGBills;
+    function FindBGBills(const AB_Code: string): TBGBills;
+
+    procedure Calculate;
+
+    property BGLCode: string read FBGLCode;
+
+    property BGBills[AIndex: Integer]: TBGBills read GetBGBills;
+    property BGBillsCount: Integer read GetBGBillsCount;
+  end;
+
+  TTenderData = class
+  private
+    FSerialNo: Integer;
+    FID: Integer;
+    FName: String;
+    FBGLs: TList;
+
+    FTotalPrice: Double;
+    FCurTotalPrice: Double;
+    FPreTotalPrice: Double;
+    FEndTotalPrice: Double;
+
+    function GetBGLCount: Integer;
+    function GetBGLData(AIndex: Integer): TBGLData;
+    function GetPercent: Double;
+  public
+    constructor Create(ASerialNo, AID: Integer; const AName: string);
+    destructor Destroy; override;
+
+    procedure Calculate;
+    function AddBGL(const ACode: string): TBGLData;
+    function FindBGL(const ACode: string): TBGLData;
+
+    property SerialNo: Integer read FSerialNo;
+    property ID: Integer read FID;
+    property Name: string read FName;
+
+    property BGL[AIndex: Integer]: TBGLData read GetBGLData;
+    property BGLCount: Integer read GetBGLCount;
+
+    property TotalPrice: Double read FTotalPrice;
+    property CurTotalPrice: Double read FCurTotalPrice;
+    property PreTotalPrice: Double read FPreTotalPrice;
+    property EndTotalPrice: Double read FEndTotalPrice;
+    property Percent: Double read GetPercent;
+  end;
+
+  TGatherData = class
+  private
+    FTenders: TList;
+
+    FTotalPrice: Double;
+    FCurTotalPrice: Double;
+    FPreTotalPrice: Double;
+    FEndTotalPrice: Double;
+
+    function GetTender(AIndex: Integer): TTenderData;
+    function GetTenderCount: Integer;
+    function GetPercent: Double;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    function AddTender(AIndex, AID: Integer; const AName: string): TTenderData;
+    procedure Calculate;
+
+    property Tender[AIndex: Integer]: TTenderData read GetTender;
+    property TenderCount: Integer read GetTenderCount;
+
+    property TotalPrice: Double read FTotalPrice;
+    property CurTotalPrice: Double read FCurTotalPrice;
+    property PreTotalPrice: Double read FPreTotalPrice;
+    property EndTotalPrice: Double read FEndTotalPrice;
+    property Percent: Double read GetPercent;
+  end;
+
+  TrmBGBillsGatherData = class(TDataModule)
+    cdsBGBills: TClientDataSet;
+    cdsBGBillsTenderID: TIntegerField;
+    cdsBGBillsPartID: TIntegerField;
+    cdsBGBillsIndexCode: TWideStringField;
+    cdsBGBillsB_Code: TWideStringField;
+    cdsBGBillsName: TWideStringField;
+    cdsBGBillsUnits: TWideStringField;
+    cdsBGBillsPrice: TFloatField;
+    cdsBGBillsQuantity: TFloatField;
+    cdsBGBillsTotalPrice: TFloatField;
+    cdsBGBillsCurQuantity: TFloatField;
+    cdsBGBillsCurTotalPrice: TFloatField;
+    cdsBGBillsPreQuantity: TFloatField;
+    cdsBGBillsPreTotalPrice: TFloatField;
+    cdsBGBillsEndQuantity: TFloatField;
+    cdsBGBillsEndTotalPrice: TFloatField;
+    cdsBGBillsPercent: TFloatField;
+    cdsBGBillsBGLCode: TWideStringField;
+  private
+    FGatherData: TGatherData;
+    FProjectName: string;
+    FProjectData: TProjectData;
+
+    procedure BeforeGather;
+    procedure AfterGather;
+
+    procedure OpenProjectData(AProject: TSelectProject; AProjectIndex: Integer);
+    procedure FreeProjectData;
+
+    procedure GatherBGBills(ABGL: TBGLData; ABGLID: Integer);
+    procedure GatherBGL(ATenderData: TTenderData);
+    procedure GatherMeasureData(ATenderData: TTenderData);
+    procedure GatherProject(AProject: TSelectProject; AProjectIndex: Integer);
+
+    procedure CalculateGatherData;
+
+    procedure WriteData;
+  public
+    function AssignData(AProjects: TList): TDataSet;
+  end;
+
+implementation
+
+uses
+  ZhAPI, UtilMethods, DateUtils, Globals, BGLDm, mDataRecord;
+
+{$R *.dfm}
+
+{ TGatherData }
+
+function TGatherData.AddTender(AIndex, AID: Integer;
+  const AName: string): TTenderData;
+begin
+  Result := TTenderData.Create(AIndex, AID, AName);
+  FTenders.Add(Result);
+end;
+
+procedure TGatherData.Calculate;
+var
+  i: Integer;
+begin
+  FTotalPrice := 0;
+  FCurTotalPrice := 0;
+  FPreTotalPrice := 0;
+  FEndTotalPrice := 0;
+  for i := 0 to TenderCount - 1 do
+  begin
+    Tender[i].Calculate;
+    FTotalPrice := FTotalPrice + Tender[i].TotalPrice;
+    FCurTotalPrice := FCurTotalPrice + Tender[i].CurTotalPrice;
+    FPreTotalPrice := FPreTotalPrice + Tender[i].PreTotalPrice;
+    FEndTotalPrice := FEndTotalPrice + Tender[i].EndTotalPrice;
+  end;
+end;
+
+constructor TGatherData.Create;
+begin
+  FTenders := TList.Create;
+end;
+
+destructor TGatherData.Destroy;
+begin
+  ClearObjects(FTenders);
+  FTenders.Free;
+  inherited;
+end;
+
+function TGatherData.GetPercent: Double;
+begin
+  if FTotalPrice <> 0 then
+    Result := CommonRoundTo(FEndTotalPrice / FTotalPrice * 100, -2)
+  else
+    Result := 0;
+end;
+
+function TGatherData.GetTender(AIndex: Integer): TTenderData;
+begin
+  Result := TTenderData(FTenders[AIndex]);
+end;
+
+function TGatherData.GetTenderCount: Integer;
+begin
+  Result := FTenders.Count;
+end;
+
+{ TTenderData }
+
+function TTenderData.AddBGL(const ACode: string): TBGLData;
+begin
+  Result := TBGLData.Create(ACode);
+  FBGLs.Add(Result);
+end;
+
+procedure TTenderData.Calculate;
+var
+  i, j: Integer;
+  vBGL: TBGLData;
+begin
+  FTotalPrice := 0;
+  FPreTotalPrice := 0;
+  FCurTotalPrice := 0;
+  FEndTotalPrice := 0;
+  for i := 0 to BGLCount - 1 do
+  begin
+    vBGL := BGL[i];
+    vBGL.Calculate;
+    for j := 0 to vBGL.BGBillsCount - 1 do
+    begin
+      FTotalPrice := FTotalPrice + vBGL.BGBills[j].TotalPrice;
+      FCurTotalPrice := FCurTotalPrice + vBGL.BGBills[j].CurTotalPrice;
+      FPreTotalPrice := FPreTotalPrice + vBGL.BGBills[j].PreTotalPrice;
+      FEndTotalPrice := FEndTotalPrice + vBGL.BGBills[j].EndTotalPrice;
+    end;
+  end;
+end;
+
+constructor TTenderData.Create(ASerialNo, AID: Integer; const AName: string);
+begin
+  FSerialNo := ASerialNo;
+  FID := AID;
+  FName := AName;
+  FBGLs := TList.Create;
+end;
+
+destructor TTenderData.Destroy;
+begin
+  ClearObjects(FBGLs);
+  FBGLs.Free;
+  inherited;
+end;
+
+function TTenderData.FindBGL(const ACode: string): TBGLData;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to BGLCount - 1 do
+  begin
+    if (ACode = BGL[i].BGLCode) then
+    begin
+      Result := BGL[i];
+      Break;
+    end;
+  end;
+end;
+
+function TTenderData.GetBGLCount: Integer;
+begin
+  Result := FBGLs.Count;
+end;
+
+function TTenderData.GetBGLData(AIndex: Integer): TBGLData;
+begin
+  Result := TBGLData(FBGLs[AIndex]);
+end;
+
+function TTenderData.GetPercent: Double;
+begin
+  if FTotalPrice <> 0 then
+    Result := CommonRoundTo(FEndTotalPrice / FTotalPrice * 100, -2)
+  else
+    Result := 0;
+end;
+
+{ TBGLData }
+
+function TBGLData.AddBGBills: TBGBills;
+begin
+  Result := TBGBills.Create;
+  FBGBillsList.Add(Result);
+end;
+
+procedure TBGLData.Calculate;
+var
+  i: Integer;
+begin
+  for i := 0 to BGBillsCount - 1 do
+    BGBills[i].Calcualte;
+end;
+
+constructor TBGLData.Create(const ACode: string);
+begin
+  FBGLCode := ACode;
+  FBGBillsList := TList.Create;
+end;
+
+destructor TBGLData.Destroy;
+begin
+  ClearObjects(FBGBillsList);
+  FBGBillsList.Free;
+  inherited;
+end;
+
+function TBGLData.FindBGBills(const AB_Code: string): TBGBills;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to BGBillsCount - 1 do
+  begin
+    if (AB_Code = BGBills[i].B_Code) then
+    begin
+      Result := BGBills[i];
+      Break;
+    end;
+  end;
+end;
+
+function TBGLData.GetBGBills(AIndex: Integer): TBGBills;
+begin
+  Result := TBGBills(FBGBillsList[AIndex]);
+end;
+
+function TBGLData.GetBGBillsCount: Integer;
+begin
+  Result := FBGBillsList.Count;
+end;
+
+{ TrmBGBillsGatherData }
+
+procedure TrmBGBillsGatherData.AfterGather;
+begin
+  cdsBGBills.EnableControls;
+  FGatherData.Free;
+end;
+
+function TrmBGBillsGatherData.AssignData(AProjects: TList): TDataSet;
+var
+  iProject: Integer;
+  SelectProject: TSelectProject;
+begin
+  BeforeGather;
+  try
+    for iProject := 0 to AProjects.Count - 1 do
+      GatherProject(TSelectProject(AProjects.Items[iProject]), iProject);
+    CalculateGatherData;
+    WriteData;
+  finally
+    Result := cdsBGBills;
+    AfterGather;
+  end;
+end;
+
+procedure TrmBGBillsGatherData.BeforeGather;
+begin
+  FGatherData := TGatherData.Create;
+  cdsBGBills.DisableControls;
+  cdsBGBills.Active := True;
+  cdsBGBills.EmptyDataSet;
+end;
+
+procedure TrmBGBillsGatherData.CalculateGatherData;
+begin
+  FGatherData.Calculate;
+end;
+
+procedure TrmBGBillsGatherData.FreeProjectData;
+begin
+  if not Assigned(OpenProjectManager.FindProjectData(FProjectData.ProjectID)) then
+    FProjectData.Free;
+end;
+
+procedure TrmBGBillsGatherData.GatherBGBills(ABGL: TBGLData;
+  ABGLID: Integer);
+var
+  vBGBills: TBGBills;
+begin
+  with FProjectData.BGLData do
+  begin
+    cdsBGBills.Filter := 'BGID = ' + IntToStr(ABGLID);
+    cdsBGBills.Filtered := True;
+    try
+      cdsBGBills.First;
+      while not cdsBGBills.Eof do
+      begin
+        vBGBills := ABGL.AddBGBills;
+        vBGBills.B_Code := cdsBGBillsB_Code.AsString;
+        vBGBills.Name := cdsBGBillsName.AsString;
+        vBGBills.Units := cdsBGBillsUnits.AsString;
+        vBGBills.Price := cdsBGBillsPrice.AsFloat;
+        vBGBills.Quantity := cdsBGBillsQuantity.AsFloat;
+        vBGBills.TotalPrice := cdsBGBillsTotalPrice.AsFloat;
+        cdsBGBills.Next;
+      end;
+    finally
+      cdsBGBills.Filtered := False;
+    end;
+  end;
+end;
+
+procedure TrmBGBillsGatherData.GatherBGL(ATenderData: TTenderData);
+var
+  vBGL: TBGLData;
+begin
+  with FProjectData.BGLData do
+  begin
+    cdsBGL.First;
+    while not cdsBGL.Eof do
+    begin
+      vBGL := ATenderData.AddBGL(cdsBGLCode.AsString);
+      GatherBGBills(vBGL, cdsBGLID.AsInteger);
+      cdsBGL.Next;
+    end;
+  end;
+end;
+
+procedure TrmBGBillsGatherData.GatherMeasureData(ATenderData: TTenderData);
+
+  procedure GatherCur(ANode: TMeasureBillsIDTreeNode);
+  var
+    sgsCode, sgsNum: TStrings;
+    i: Integer;
+    sCode: string;
+    fNumber: Double;
+    vBGL: TBGLData;
+    vBGBills: TBGBills;
+  begin
+    sgsCode := TStringList.Create;
+    sgsNum := TStringList.Create;
+    try
+      sgsCode.Delimiter := ';';
+      sgsNum.Delimiter := ';';
+      sgsCode.DelimitedText := ANode.StageRec.QcBGLCode.AsString;
+      sgsNum.DelimitedText := ANode.StageRec.QcBGLNum.AsString;
+      for i := 0 to sgsCode.Count - 1 do
+      begin
+        sCode := sgsCode[i];
+        fNumber := StrToFloatDef(sgsNum[i], 0);
+        vBGL := ATenderData.FindBGL(sCode);
+        if Assigned(vBGL) then
+        begin
+          vBGBills := vBGL.FindBGBills(ANode.Rec.B_Code.AsString);
+          if Assigned(vBGBills) then
+            vBGBills.CurQuantity := vBGBills.CurQuantity + fNumber;
+        end;
+      end;
+    finally
+      sgsCode.Free;
+      sgsNum.Free;
+    end;
+  end;
+
+  procedure GatherPre(ANode: TMeasureBillsIDTreeNode);
+  var
+    sgsCode, sgsNum: TStrings;
+    i: Integer;
+    sCode: string;
+    fNumber: Double;
+    vBGL: TBGLData;
+    vBGBills: TBGBills;
+  begin
+    sgsCode := TStringList.Create;
+    sgsNum := TStringList.Create;
+    try
+      sgsCode.Delimiter := ';';
+      sgsNum.Delimiter := ';';
+      sgsCode.DelimitedText := ANode.StageRec.PreQcBGLCode.AsString;
+      sgsNum.DelimitedText := ANode.StageRec.PreQcBGLNum.AsString;
+      for i := 0 to sgsCode.Count - 1 do
+      begin
+        sCode := sgsCode[i];
+        fNumber := StrToFloatDef(sgsNum[i], 0);
+        vBGL := ATenderData.FindBGL(sCode);
+        if Assigned(vBGL) then
+        begin
+          vBGBills := vBGL.FindBGBills(ANode.Rec.B_Code.AsString);
+          if Assigned(vBGBills) then
+            vBGBills.PreQuantity := vBGBills.PreQuantity + fNumber;
+        end;
+      end;
+    finally
+      sgsCode.Free;
+      sgsNum.Free;
+    end;
+  end;
+
+var
+  i: Integer;
+  vNode: TMeasureBillsIDTreeNode;
+begin
+  for i := 0 to FProjectData.BillsMeasureData.BillsMeasureTree.Count - 1 do
+  begin
+    vNode := TMeasureBillsIDTreeNode(FProjectData.BillsMeasureData.BillsMeasureTree.Items[i]);
+    if (vNode.HasChildren) or (not Assigned(vNode.StageRec)) then Continue;
+
+    if (vNode.StageRec.QcBGLCode.AsString <> '') then
+      GatherCur(vNode);
+    if (vNode.StageRec.PreQcBGLCode.AsString <> '') then
+      GatherPre(vNode);
+  end;
+end;
+
+procedure TrmBGBillsGatherData.GatherProject(AProject: TSelectProject;
+  AProjectIndex: Integer);
+var
+  vTenderData: TTenderData;
+begin
+  OpenProjectData(AProject, AProjectIndex);
+  try
+    vTenderData := FGatherData.AddTender(AProjectIndex, AProject.ProjectID, FProjectName);
+    GatherBGL(vTenderData);
+    GatherMeasureData(vTenderData);
+  finally
+    FreeProjectData;
+  end;
+end;
+
+procedure TrmBGBillsGatherData.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.OpenForReport3(GetMyProjectsFilePath + Rec.ValueByName('FileName').AsString);
+  end;
+  FProjectName := Rec.ValueByName('Name').AsString;
+end;
+
+procedure TrmBGBillsGatherData.WriteData;
+
+  procedure WriteBGLData(ATenderID: Integer; ABGL: TBGLData);
+  var
+    i: Integer;
+    vBills: TBGBills;
+  begin
+    for i := 0 to ABGL.BGBillsCount - 1 do
+    begin
+      vBills := ABGL.BGBills[i];
+      cdsBGBills.Append;
+      cdsBGBillsTenderID.AsInteger := ATenderID;
+      cdsBGBillsPartID.AsInteger := 2;
+      cdsBGBillsIndexCode.AsString := vBills.IndexCode;
+      cdsBGBillsB_Code.AsString := vBills.B_Code;
+      cdsBGBillsName.AsString := vBills.Name;
+      cdsBGBillsUnits.AsString := vBills.Units;
+      cdsBGBillsPrice.AsFloat := vBills.Price;
+      cdsBGBillsQuantity.AsFloat := vBills.Quantity;
+      cdsBGBillsTotalPrice.AsFloat := vBills.TotalPrice;
+      cdsBGBillsCurQuantity.AsFloat := vBills.CurQuantity;
+      cdsBGBillsCurTotalPrice.AsFloat := vBills.CurTotalPrice;
+      cdsBGBillsPreQuantity.AsFloat := vBills.PreQuantity;
+      cdsBGBillsPreTotalPrice.AsFloat := vBills.PreTotalPrice;
+      cdsBGBillsEndQuantity.AsFloat := vBills.EndQuantity;
+      cdsBGBillsEndTotalPrice.AsFloat := vBills.EndTotalPrice;
+      cdsBGBillsPercent.AsFloat := vBills.Percent;
+      cdsBGBillsBGLCode.AsString := ABGL.BGLCode;
+      cdsBGBills.Post;
+    end;
+  end;
+
+  procedure WriteTenderData(ATender: TTenderData);
+  var
+    iBGL: Integer;
+  begin
+    cdsBGBills.Append;
+    cdsBGBillsTenderID.AsInteger := ATender.SerialNo;
+    cdsBGBillsPartID.AsInteger := 1;
+    cdsBGBillsName.AsString := ATender.Name;
+    cdsBGBills.Post;
+    for iBGL := 0 to ATender.BGLCount - 1 do
+      WriteBGLData(ATender.SerialNo, ATender.BGL[iBGL]);
+    cdsBGBills.Append;
+    cdsBGBillsTenderID.AsInteger := ATender.SerialNo;
+    cdsBGBillsPartID.AsInteger := 3;
+    cdsBGBillsName.AsString := 'С¼Æ';
+    cdsBGBillsTotalPrice.AsFloat := ATender.TotalPrice;
+    cdsBGBillsCurTotalPrice.AsFloat := ATender.CurTotalPrice;
+    cdsBGBillsPreTotalPrice.AsFloat := ATender.PreTotalPrice;
+    cdsBGBillsEndTotalPrice.AsFloat := ATender.EndTotalPrice;
+    cdsBGBillsPercent.AsFloat := ATender.Percent;
+    cdsBGBills.Post;
+  end;
+
+  procedure WriteGatherData;
+  begin 
+    cdsBGBills.Append;
+    cdsBGBillsTenderID.AsInteger := FGatherData.TenderCount + 1;
+    cdsBGBillsName.AsString := 'ºÏ¼Æ';
+    cdsBGBillsTotalPrice.AsFloat := FGatherData.TotalPrice;
+    cdsBGBillsCurTotalPrice.AsFloat := FGatherData.CurTotalPrice;
+    cdsBGBillsPreTotalPrice.AsFloat := FGatherData.PreTotalPrice;
+    cdsBGBillsEndTotalPrice.AsFloat := FGatherData.EndTotalPrice;
+    cdsBGBillsPercent.AsFloat := FGatherData.Percent;
+    cdsBGBills.Post;
+  end;
+
+var
+  i: Integer;
+begin
+  for i := 0 to FGatherData.TenderCount - 1 do
+    WriteTenderData(FGatherData.Tender[i]);
+  WriteGatherData;
+end;
+
+{ TBGBills }
+
+procedure TBGBills.Calcualte;
+begin
+  FCurTotalPrice := FCurQuantity * FPrice;
+  FPreTotalPrice := FPreQuantity * FPrice;
+  FEndQuantity := FCurQuantity + FPreQuantity;
+  FEndTotalPrice := FEndQuantity * FPrice;
+end;
+
+function TBGBills.GetPercent: Double;
+begin
+  if FTotalPrice <> 0 then
+    Result := CommonRoundTo(FEndTotalPrice / FTotalPrice * 100, -2)
+  else
+    Result := 0;
+end;
+
+procedure TBGBills.SetB_Code(const Value: string);
+begin
+  FB_Code := Value;
+  FIndexCode := B_CodeToIndexCode(FB_Code);
+end;
+
+end.

+ 128 - 0
DataModules/ReportMemoryDm/rmBillsPhaseGatherDm.dfm

@@ -0,0 +1,128 @@
+object rmBillsPhaseGatherData: TrmBillsPhaseGatherData
+  OldCreateOrder = False
+  Left = 626
+  Top = 282
+  Height = 150
+  Width = 215
+  object cdsZjtzBills: TClientDataSet
+    Active = True
+    Aggregates = <>
+    Params = <>
+    Left = 40
+    Top = 32
+    Data = {
+      850200009619E0BD01000000180000001C000000000003000000850202494404
+      0001000000000008506172656E74494404000100000000000D4E657874536962
+      6C696E674944040001000000000004436F646501004A00000001000557494454
+      48020002006400044E616D6502004A000000010005574944544802000200FE01
+      05556E69747301004A000000010005574944544802000200280009636244676E
+      51747931080004000000000009636244676E5174793208000400000000000863
+      6244676E51747901004900000001000557494454480200020032000C6362546F
+      74616C507269636508000400000000000A73736344676E517479310800040000
+      0000000A73736344676E5174793208000400000000000973736344676E517479
+      01004900000001000557494454480200020032000D737363546F74616C507269
+      636508000400000000000A73687444676E5174793108000400000000000A7368
+      7444676E5174793208000400000000000973687444676E517479010049000000
+      01000557494454480200020032000D736874546F74616C507269636508000400
+      0000000009687444676E51747931080004000000000009687444676E51747932
+      080004000000000008687444676E517479010049000000010005574944544802
+      00020032000A546F74616C5072696365080004000000000009626744676E5174
+      7931080004000000000009626744676E51747932080004000000000008626744
+      676E51747901004900000001000557494454480200020032000F456E64516354
+      6F74616C5072696365080004000000000011456E644465616C546F74616C5072
+      6963650800040000000000074D656D6F53747202004A00000001000557494454
+      4802000200FE010000}
+    object cdsZjtzBillsID: TIntegerField
+      FieldName = 'ID'
+    end
+    object cdsZjtzBillsParentID: TIntegerField
+      FieldName = 'ParentID'
+    end
+    object cdsZjtzBillsNextSiblingID: TIntegerField
+      FieldName = 'NextSiblingID'
+    end
+    object cdsZjtzBillsCode: TWideStringField
+      FieldName = 'Code'
+      Size = 50
+    end
+    object cdsZjtzBillsName: TWideStringField
+      FieldName = 'Name'
+      Size = 255
+    end
+    object cdsZjtzBillsUnits: TWideStringField
+      FieldName = 'Units'
+    end
+    object cdsZjtzBillscbDgnQty1: TFloatField
+      FieldName = 'cbDgnQty1'
+    end
+    object cdsZjtzBillscbDgnQty2: TFloatField
+      FieldName = 'cbDgnQty2'
+    end
+    object cdsZjtzBillscbDgnQty: TStringField
+      FieldName = 'cbDgnQty'
+      Size = 50
+    end
+    object cdsZjtzBillscbTotalPrice: TFloatField
+      FieldName = 'cbTotalPrice'
+    end
+    object cdsZjtzBillssscDgnQty1: TFloatField
+      FieldName = 'sscDgnQty1'
+    end
+    object cdsZjtzBillssscDgnQty2: TFloatField
+      FieldName = 'sscDgnQty2'
+    end
+    object cdsZjtzBillssscDgnQty: TStringField
+      FieldName = 'sscDgnQty'
+      Size = 50
+    end
+    object cdsZjtzBillssscTotalPrice: TFloatField
+      FieldName = 'sscTotalPrice'
+    end
+    object cdsZjtzBillsshtDgnQty1: TFloatField
+      FieldName = 'shtDgnQty1'
+    end
+    object cdsZjtzBillsshtDgnQty2: TFloatField
+      FieldName = 'shtDgnQty2'
+    end
+    object cdsZjtzBillsshtDgnQty: TStringField
+      FieldName = 'shtDgnQty'
+      Size = 50
+    end
+    object cdsZjtzBillsshtTotalPrice: TFloatField
+      FieldName = 'shtTotalPrice'
+    end
+    object cdsZjtzBillshtDgnQty1: TFloatField
+      FieldName = 'htDgnQty1'
+    end
+    object cdsZjtzBillshtDgnQty2: TFloatField
+      FieldName = 'htDgnQty2'
+    end
+    object cdsZjtzBillshtDgnQty: TStringField
+      FieldName = 'htDgnQty'
+      Size = 50
+    end
+    object cdsZjtzBillsTotalPrice: TFloatField
+      FieldName = 'TotalPrice'
+    end
+    object cdsZjtzBillsbgDgnQty1: TFloatField
+      FieldName = 'bgDgnQty1'
+    end
+    object cdsZjtzBillsbgDgnQty2: TFloatField
+      FieldName = 'bgDgnQty2'
+    end
+    object cdsZjtzBillsbgDgnQty: TStringField
+      FieldName = 'bgDgnQty'
+      Size = 50
+    end
+    object cdsZjtzBillsEndQcTotalPrice: TFloatField
+      FieldName = 'EndQcTotalPrice'
+    end
+    object cdsZjtzBillsEndDealTotalPrice: TFloatField
+      FieldName = 'EndDealTotalPrice'
+    end
+    object cdsZjtzBillsMemoStr: TWideStringField
+      FieldName = 'MemoStr'
+      Size = 255
+    end
+  end
+end

+ 350 - 0
DataModules/ReportMemoryDm/rmBillsPhaseGatherDm.pas

@@ -0,0 +1,350 @@
+unit rmBillsPhaseGatherDm;
+
+interface
+
+uses
+  SysUtils, Classes, DB, DBClient, sdDB, sdIDTree,
+  ProjectData, MCacheTree, BillsTree, mDataRecord,
+  rmSelectProjectFrm;
+
+type
+  TrmBillsPhaseGatherData = class(TDataModule)
+    cdsZjtzBills: TClientDataSet;
+    cdsZjtzBillsID: TIntegerField;
+    cdsZjtzBillsParentID: TIntegerField;
+    cdsZjtzBillsNextSiblingID: TIntegerField;
+    cdsZjtzBillsCode: TWideStringField;
+    cdsZjtzBillsName: TWideStringField;
+    cdsZjtzBillsUnits: TWideStringField;
+    cdsZjtzBillscbDgnQty1: TFloatField;
+    cdsZjtzBillscbDgnQty2: TFloatField;
+    cdsZjtzBillscbDgnQty: TStringField;
+    cdsZjtzBillscbTotalPrice: TFloatField;
+    cdsZjtzBillssscDgnQty1: TFloatField;
+    cdsZjtzBillssscDgnQty2: TFloatField;
+    cdsZjtzBillssscDgnQty: TStringField;
+    cdsZjtzBillssscTotalPrice: TFloatField;
+    cdsZjtzBillsshtDgnQty1: TFloatField;
+    cdsZjtzBillsshtDgnQty2: TFloatField;
+    cdsZjtzBillsshtDgnQty: TStringField;
+    cdsZjtzBillsshtTotalPrice: TFloatField;
+    cdsZjtzBillshtDgnQty1: TFloatField;
+    cdsZjtzBillshtDgnQty2: TFloatField;
+    cdsZjtzBillshtDgnQty: TStringField;
+    cdsZjtzBillsTotalPrice: TFloatField;
+    cdsZjtzBillsbgDgnQty1: TFloatField;
+    cdsZjtzBillsbgDgnQty2: TFloatField;
+    cdsZjtzBillsbgDgnQty: TStringField;
+    cdsZjtzBillsEndQcTotalPrice: TFloatField;
+    cdsZjtzBillsEndDealTotalPrice: TFloatField;
+    cdsZjtzBillsMemoStr: TWideStringField;
+  private
+    FCacheTree: TSpecPhaseCacheTree;
+    FProjectData: TProjectData;
+
+    function GetDgnQuantity(ANum1, ANum2: Double): string;
+
+    procedure BeforeGather;
+    procedure AfterGather;
+
+    procedure OpenProject(AProject: TSelectProject);
+    procedure FreeProject;
+
+    function AddBillsNode(ANode: TBillsIDTreeNode;
+      AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+
+    function AddSpecBillsNode(ANode: TsdIDTreeNode; AParent: TSpecPhaseCacheNode;
+      ASelectProject: TSelectProject): TSpecPhaseCacheNode;
+    function AddSpecBills(ANode: TsdIDTreeNode; AParent: TSpecPhaseCacheNode;
+      ASelectProject: TSelectProject): TSpecPhaseCacheNode;
+
+    function AddPhaseBillsNode(ANode: TsdIDTreeNode;
+      AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+    function AddPhaseBills(ANode: TsdIDTreeNode;
+      AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+
+    procedure GatherProject(AProject: TSelectProject);
+
+    procedure WriteNode(ANode: TSpecPhaseCacheNode);
+    procedure WriteData;
+  public
+    function AssignData(AProjects: TList): TDataSet;
+  end;
+
+implementation
+
+uses CacheTree, Globals, UtilMethods;
+
+{$R *.dfm}
+
+{ TrmBillsPhaseGatherData }
+
+function TrmBillsPhaseGatherData.AddBillsNode(ANode: TBillsIDTreeNode;
+  AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+var
+  Rec: TBillsRecord;
+  iGatherCompare: Integer;
+  ANextSibling: TSpecPhaseCacheNode;
+begin
+  Rec := ANode.Rec;
+
+  if Rec.B_Code.AsString <> '' then
+    iGatherCompare := ReportConfig.GclCompare
+  else
+    iGatherCompare := ReportConfig.XmjCompare;
+  case iGatherCompare of
+    // 按编号
+    0: if (Rec.Code.asString <> '') or (Rec.B_Code.asString <> '') then
+         Result := FCacheTree.FindNode(AParent, Rec.Code.AsString, Rec.B_Code.AsString)
+       else
+         Result := FCacheTree.FindNode(AParent, Rec.Name.AsString);
+    // 按名称
+    1: Result := FCacheTree.FindNode(AParent, Rec.Name.AsString);
+    // 按编号+名称
+    2: Result := FCacheTree.FindNode(AParent, Rec.Code.AsString,
+           Rec.B_Code.AsString, Rec.Name.AsString);
+  end;
+
+  if not Assigned(Result) then
+  begin
+    ANextSibling := FCacheTree.FindNextSibling(AParent,
+        Rec.Code.AsString, Rec.B_Code.AsString);
+    Result := FCacheTree.AddNode(AParent, ANextSibling);
+    Result.Code := Rec.Code.AsString;
+    Result.B_Code := Rec.B_Code.AsString;
+    Result.Name := Rec.Name.AsString;
+    Result.Units := Rec.Units.AsString;
+  end;
+end;
+
+function TrmBillsPhaseGatherData.AddPhaseBills(ANode: TsdIDTreeNode;
+  AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+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 ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit;
+  Result := AddPhaseBillsNode(ANode, AParent);
+  AddPhaseBills(ANode.FirstChild, Result);
+  AddPhaseBills(ANode.NextSibling, AParent);
+end;
+
+function TrmBillsPhaseGatherData.AddPhaseBillsNode(ANode: TsdIDTreeNode;
+  AParent: TSpecPhaseCacheNode): TSpecPhaseCacheNode;
+var
+  vNode: TMeasureBillsIDTreeNode;
+  Rec: TBillsRecord;
+  StageRec: TStageRecord;
+begin
+  vNode :=  TMeasureBillsIDTreeNode(ANode);
+  Result := AddBillsNode(vNode, AParent);
+  Rec := vNode.Rec;
+  Result.TotalPrice := Result.TotalPrice + Rec.TotalPrice.AsFloat;
+
+  Result.htDgnQty1 := Result.htDgnQty1 + Rec.DealDgnQuantity1.AsFloat;
+  Result.htDgnQty2 := Result.htDgnQty2 + Rec.DealDgnQuantity2.AsFloat;
+  Result.bgDgnQty1 := Result.bgDgnQty1 + Rec.CDgnQuantity1.AsFloat;
+  Result.bgDgnQty2 := Result.bgDgnQty2 + Rec.CDgnQuantity2.AsFloat;
+
+  StageRec := vNode.StageRec;
+  if Assigned(StageRec) then
+  begin
+    Result.EndDealTotalPrice := Result.EndDealTotalPrice + StageRec.EndDealTotalPrice.AsFloat;
+    Result.EndQcTotalPrice := Result.EndQcTotalPrice + StageRec.EndQcTotalPrice.AsFloat;
+  end;
+end;
+
+function TrmBillsPhaseGatherData.AddSpecBills(ANode: TsdIDTreeNode;
+  AParent: TSpecPhaseCacheNode; ASelectProject: TSelectProject): TSpecPhaseCacheNode;
+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 ANode.Rec.ValueByName('B_Code').AsString <> '' then Exit;
+
+  Result := AddSpecBillsNode(ANode, AParent, ASelectProject);
+  AddSpecBills(ANode.FirstChild, Result, ASelectProject);
+  AddSpecBills(ANode.NextSibling, AParent, ASelectProject);
+end;
+
+function TrmBillsPhaseGatherData.AddSpecBillsNode(ANode: TsdIDTreeNode;
+  AParent: TSpecPhaseCacheNode;
+  ASelectProject: TSelectProject): TSpecPhaseCacheNode;
+var
+  vNode: TBillsIDTreeNode;
+  Rec: TBillsRecord;
+begin
+  vNode := TBillsIDTreeNode(ANode);
+  Result := AddBillsNode(vNode, AParent);
+
+  Rec := vNode.Rec;
+  if ASelectProject.IsPD then
+  begin
+    Result.cbDgnQty1 := Rec.DgnQuantity1.AsFloat;
+    Result.cbDgnQty2 := Rec.DgnQuantity2.AsFloat;
+    Result.cbTotalPrice := Rec.TotalPrice.AsFloat;
+  end
+  else if ASelectProject.IsCddSc then
+  begin
+    Result.sscDgnQty1 := Rec.DgnQuantity1.AsFloat;
+    Result.sscDgnQty2 := Rec.DgnQuantity2.AsFloat;
+    Result.sscTotalPrice := Rec.TotalPrice.AsFloat;
+  end
+  else if ASelectProject.IsCddHt then
+  begin
+    Result.shtDgnQty1 := Rec.DgnQuantity1.AsFloat;
+    Result.shtDgnQty2 := Rec.DgnQuantity2.AsFloat;
+    Result.shtTotalPrice := Rec.TotalPrice.AsFloat;
+  end;
+end;
+
+procedure TrmBillsPhaseGatherData.AfterGather;
+begin
+  cdsZjtzBills.EnableControls;
+
+  FCacheTree.Free;
+end;
+
+function TrmBillsPhaseGatherData.AssignData(AProjects: TList): TDataSet;
+var
+  iProject: Integer;
+begin
+  BeforeGather;
+  try
+    for iProject := 0 to AProjects.Count - 1 do
+      GatherProject(AProjects[iProject]);
+    WriteData;
+  finally
+    Result := cdsZjtzBills;
+    AfterGather;
+  end;
+end;
+
+procedure TrmBillsPhaseGatherData.BeforeGather;
+begin
+  FCacheTree := TSpecPhaseCacheTree.Create;
+
+  cdsZjtzBills.DisableControls;
+  cdsZjtzBills.Active := True;
+  cdsZjtzBills.EmptyDataSet;
+end;
+
+procedure TrmBillsPhaseGatherData.FreeProject;
+begin
+  if not Assigned(OpenProjectManager.FindProjectData(FProjectData.ProjectID)) then
+    FProjectData.Free;
+end;
+
+procedure TrmBillsPhaseGatherData.GatherProject(AProject: TSelectProject);
+begin
+  OpenProject(AProject);
+  try
+    if AProject.IsPD or AProject.IsCddSc or AProject.IsCddHt then
+      AddSpecBills(FProjectData.BillsCompileData.BillsCompileTree.FirstNode, nil, AProject)
+    else
+      AddPhaseBills(FProjectData.BillsMeasureData.BillsMeasureTree.FirstNode, nil);
+  finally
+    FreeProject;
+  end;
+end;
+
+function TrmBillsPhaseGatherData.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 TrmBillsPhaseGatherData.OpenProject(AProject: TSelectProject);
+var
+  Rec: TsdDataRecord;
+begin
+  FProjectData := OpenProjectManager.FindProjectData(AProject.ProjectID);
+  if not Assigned(FProjectData) then
+  begin
+    Rec := ProjectManager.sddProjectsInfo.FindKey('idxID', AProject.ProjectID);
+    FProjectData := TProjectData.Create;
+    if AProject.IsPD or AProject.IsCddSc or AProject.IsCddHt then
+      FProjectData.OpenForReport(GetMyProjectsFilePath + Rec.ValueByName('FileName').AsString)
+    else
+      FProjectData.OpenForReport3(GetMyProjectsFilePath + Rec.ValueByName('FileName').AsString);
+  end;
+end;
+
+procedure TrmBillsPhaseGatherData.WriteData;
+begin
+  WriteNode(TSpecPhaseCacheNode(FCacheTree.FirstNode));
+end;
+
+procedure TrmBillsPhaseGatherData.WriteNode(ANode: TSpecPhaseCacheNode);
+begin
+  if not Assigned(ANode) then Exit;
+
+  cdsZjtzBills.Append;
+  cdsZjtzBillsID.AsInteger := ANode.ID;
+  cdsZjtzBillsParentID.AsInteger := ANode.ParentID;
+  cdsZjtzBillsNextSiblingID.AsInteger := ANode.NextSiblingID;
+
+  cdsZjtzBillsCode.AsString := ANode.Code;
+  cdsZjtzBillsName.AsString := ANode.Name;
+  cdsZjtzBillsUnits.AsString := ANode.Units;
+
+  cdsZjtzBillscbDgnQty1.AsFloat := ANode.cbDgnQty1;
+  cdsZjtzBillscbDgnQty2.AsFloat := ANode.cbDgnQty2;
+  cdsZjtzBillscbDgnQty.AsString := GetDgnQuantity(ANode.cbDgnQty1, ANode.cbDgnQty2);
+  cdsZjtzBillscbTotalPrice.AsFloat := ANode.cbTotalPrice;
+
+  cdsZjtzBillssscDgnQty1.AsFloat := ANode.sscDgnQty1;
+  cdsZjtzBillssscDgnQty2.AsFloat := ANode.sscDgnQty2;
+  cdsZjtzBillssscDgnQty.AsString := GetDgnQuantity(ANode.sscDgnQty1, ANode.sscDgnQty2);
+  cdsZjtzBillssscTotalPrice.AsFloat := ANode.sscTotalPrice;
+
+  cdsZjtzBillsshtDgnQty1.AsFloat := ANode.shtDgnQty1;
+  cdsZjtzBillsshtDgnQty2.AsFloat := ANode.shtDgnQty2;
+  cdsZjtzBillsshtDgnQty.AsString := GetDgnQuantity(ANode.shtDgnQty1, ANode.shtDgnQty2);
+  cdsZjtzBillsshtTotalPrice.AsFloat := ANode.shtTotalPrice;
+
+  cdsZjtzBillshtDgnQty1.AsFloat := ANode.htDgnQty1;
+  cdsZjtzBillshtDgnQty2.AsFloat := ANode.htDgnQty2;
+  cdsZjtzBillshtDgnQty.AsString := GetDgnQuantity(ANode.htDgnQty1, ANode.htDgnQty2);
+  cdsZjtzBillsTotalPrice.AsFloat := ANode.TotalPrice;
+
+  cdsZjtzBillsbgDgnQty1.AsFloat := ANode.bgDgnQty1;
+  cdsZjtzBillsbgDgnQty2.AsFloat := ANode.bgDgnQty2;
+  cdsZjtzBillsbgDgnQty.AsString := GetDgnQuantity(ANode.bgDgnQty1, ANode.bgDgnQty2);
+  cdsZjtzBillsEndQcTotalPrice.AsFloat := ANode.EndQcTotalPrice;
+  cdsZjtzBillsEndDealTotalPrice.AsFloat := ANode.EndDealTotalPrice;
+  cdsZjtzBills.Post;
+
+  WriteNode(TSpecPhaseCacheNode(ANode.FirstChild));
+  WriteNode(TSpecPhaseCacheNode(ANode.NextSibling));
+end;
+
+end.

+ 2 - 2
Dprs/CSL/Measure_Cloud.cfg

@@ -31,11 +31,11 @@
 -M
 -$M16384,1048576
 -K$00400000
--E"C:\Program Files (x86)\纵横软件\纵横结算决算计量一体化软件(云版)渭武"
+-E"C:\Program Files (x86)\纵横软件\计量支付 (单机版+云版) 1"
 -N"C:\DelphiTemp"
 -LE"c:\program files (x86)\borland\delphi7\Projects\Bpl"
 -LN"c:\program files (x86)\borland\delphi7\Projects\Bpl"
--D_mCloud;_mLoginNoPW;
+-D_mCloud;
 -w-UNSAFE_TYPE
 -w-UNSAFE_CODE
 -w-UNSAFE_CAST

+ 9 - 8
Dprs/CSL/Measure_Cloud.dof

@@ -90,13 +90,13 @@ MaxStackSize=1048576
 ImageBase=4194304
 ExeDescription=
 [Directories]
-OutputDir=C:\Program Files (x86)\纵横软件\纵横结算决算计量一体化软件(云版)渭武
+OutputDir=C:\Program Files (x86)\纵横软件\计量支付 (单机版+云版) 1
 UnitOutputDir=C:\DelphiTemp
 PackageDLLOutputDir=
 PackageDCPOutputDir=
 SearchPath=
 Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOfficeXP;ZjGridD7;DPanel;ExTree;JimComboBoxs;JimTab;PrintComRep;XPMenu_tom;ZjGridFereD7;ZjCommon;SmartDataSet;ZjGridActns
-Conditionals=_mCloud;_mLoginNoPW;
+Conditionals=_mCloud;
 DebugSourceDirs=
 UsePackages=0
 [Parameters]
@@ -137,8 +137,8 @@ ProductVersion=3.1.7
 c:\program files (x86)\borland\delphi7\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package
 [HistoryLists\hlConditionals]
 Count=4
-Item0=_mCloud;_mLoginNoPW;
-Item1=_mCloud;
+Item0=_mCloud;
+Item1=_mCloud;_mLoginNoPW;
 Item2=_mCloud;_mLoginNoPW
 Item3=_mCloud;_mDebugView
 [HistoryLists\hlUnitAliases]
@@ -149,7 +149,8 @@ Count=2
 Item0=C:\DelphiTemp
 Item1=..\..\Dcus
 [HistoryLists\hlOutputDirectorry]
-Count=3
-Item0=C:\Program Files (x86)\纵横软件\纵横结算决算计量一体化软件(云版)渭武
-Item1=D:\SmartCostExe\Measure\PWFree
-Item2=D:\SmartCostExe\Measure
+Count=4
+Item0=C:\Program Files (x86)\纵横软件\计量支付 (单机版+云版) 1
+Item1=C:\Program Files (x86)\纵横软件\纵横结算决算计量一体化软件(云版)渭武
+Item2=D:\SmartCostExe\Measure\PWFree
+Item3=D:\SmartCostExe\Measure

+ 12 - 4
Forms/UpFileManageFrame.pas

@@ -456,7 +456,7 @@ procedure TUpFileManageView.SelectUpFile;
 var vODlg: TOpenDialog;
   i, iBillID: Integer;
   vFile: TUpFile;
-  sFile, sName: string;
+  sFile, sFile2, sName, sName2: string;
   iV: Int64;
 begin
   vODlg := TOpenDialog.Create(nil);
@@ -483,14 +483,22 @@ begin
       end;
 
       sName := ExtractFileName(sFile);
+      sName2 := PHPWeb.RepalceSpecChars(sName);
+
+      sFile2 := sFile;
+      if sName2 <> sName then
+      begin
+        sFile2 := ExtractFilePath(sFile) + sName2;
+        CopyFile(PChar(sFile), PChar(sFile2), False);
+      end;
 
       vFile := Datas.Add(iBillID);
       vFile.Phase := TProjectData(FProjectData).PhaseIndex;
-      vFile.OrgFile := sFile;
+      vFile.OrgFile := sFile2;
       vFile.Category := '̨Õʸ½¼þ';
       vFile.Memo := 'Îҵı¸×¢';
-      vFile.LocalFile := Datas.Path + sName;
-      vFile.DisplayName := sName;
+      vFile.LocalFile := Datas.Path + sName2;
+      vFile.DisplayName := sName2;
       vFile.Status := ufsNeedUp;
 
       if G_IsCloud then

+ 1 - 0
Forms/rmSelectProjectFrm.dfm

@@ -105,6 +105,7 @@ object ProjectSelectForm: TProjectSelectForm
     FrozenRow = 0
     OnGetCellText = zgResultGetCellText
     OnSetCellText = zgResultSetCellText
+    Anchors = [akLeft, akTop, akRight]
   end
   object stdSelectProject: TsdGridTreeDBA
     Columns = <

+ 123 - 1
Forms/rmSelectProjectFrm.pas

@@ -12,7 +12,8 @@ type
   // 批准概算 Approved Budget
   // 多合同 Deal
   // 甘肃高管局定制 Mental1
-  TMultiSelectType = (mstCommon, mstE_PCD, mstE_A, mstDeal, mstMental1);
+  // 导则 造价台账汇总
+  TMultiSelectType = (mstCommon, mstE_PCD, mstE_A, mstDeal, mstMental1, mstZjtz);
 
   // 所选项目
   TSelectProject = class
@@ -24,6 +25,8 @@ type
     FIsCDD: Boolean;
     FIsAB: Boolean;
     FIsDeal: Boolean;
+    FIsCddSc: Boolean;
+    FIsCddHt: Boolean;
   public
     property ProjectID: Integer read FProjectID write FProjectID;
     property IsTender: Boolean read FIsTender write FIsTender;
@@ -36,6 +39,10 @@ type
     property IsAB: Boolean read FIsAB write FIsAB;
     // 多合同项目(二三部分,土地征拆、监理等)
     property IsDeal: Boolean read FIsDeal write FIsDeal;
+    // 施工图设计审查预算
+    property IsCddSc: Boolean read FIsCddSc write FIsCddSc;
+    // 施工图设计合同费用
+    property IsCddHt: Boolean read FIsCddHt write FIsCddHt;
   end;
 
   TProjectSelectForm = class(TForm)
@@ -79,10 +86,14 @@ type
     procedure SetPDProject(AProjecID: Integer);
     procedure SetCDDProject(AProjectID: Integer);
     procedure SetABProject(AProjectID: Integer);
+    procedure SetCddScProject(AProjectID: Integer);
+    procedure SetCddHtProject(AProjectID: Integer);
 
     function HasPDProject: Boolean;
     function HasCDDProject: Boolean;
     function HasABProject: Boolean;
+    function HasCddScProject: Boolean;
+    function HasCddHtProject: Boolean;
 
     procedure InitForm;
     procedure InitResultGrid;
@@ -148,6 +159,15 @@ begin
             if SelectProject.IsDeal then
               zgResult.Cells[2, zgResult.RowCount - 1].Text := 'True';
           end;
+        mstZjtz:
+          begin
+            if SelectProject.IsPD then
+              zgResult.Cells[2, zgResult.RowCount - 1].Text := 'True';
+            if SelectProject.IsCddSc then
+              zgResult.Cells[3, zgResult.RowCount - 1].Text := 'True';
+            if SelectProject.IsCddHt then
+              zgResult.Cells[4, zgResult.RowCount - 1].Text := 'True';
+          end;
       end;
     end;
   end;
@@ -184,6 +204,8 @@ begin
       iLimitProjectCount := 3
     else if FMultiSelectType = mstE_A then
       iLimitProjectCount := 2
+    else if FMultiSelectType = mstZjtz then
+      iLimitProjectCount := 4
     else
       iLimitProjectCount := 2;
   end;
@@ -196,6 +218,8 @@ begin
         ModalResult := mrOk
       else if (FMultiSelectType = mstE_A) and HasABProject then
         ModalResult := mrOk
+      else if (FMultiSelectType = mstZjtz) and HasPDProject and HasCddScProject and HasCddHtProject then
+        ModalResult := mrOk
       else if FMultiSelectType in [mstCommon, mstDeal, mstMental1] then
         ModalResult := mrOk;
     end
@@ -417,12 +441,30 @@ procedure TProjectSelectForm.InitResultGrid;
     zgResult.ColWidths[2] := 42;
   end;
 
+  procedure InitZjtzResultGrid;
+  begin
+    zgResult.ColCount := 5;
+    zgResult.RowCount := 1;
+    zgResult.Cells[1, 0].Text := '所选项目';
+    zgResult.ColWidths[1] := 200;
+    zgResult.Cells[2, 0].Text := '初步设计概算';
+    zgResult.CellClass.Cols[2] := TZjCheckBoxCell;
+    zgResult.ColWidths[2] := 47;
+    zgResult.Cells[3, 0].Text := '施工图设计审查预算';
+    zgResult.CellClass.Cols[3] := TZjCheckBoxCell;
+    zgResult.ColWidths[3] := 60;
+    zgResult.Cells[4, 0].Text := '施工图设计合同费用';
+    zgResult.CellClass.Cols[4] := TZjCheckBoxCell;
+    zgResult.ColWidths[4] := 60;
+  end;
+
 begin
   case FMultiSelectType of
     mstCommon: InitCommonResultGrid;
     mstE_PCD: InitE_PCDResultGrid;
     mstE_A: InitE_AResultGrid;
     mstDeal: InitDealResultGrid;
+    mstZjtz: InitZjtzResultGrid;
   end;
 end;
 
@@ -442,6 +484,11 @@ begin
               else Value := 'False';
       mstDeal: if SelectProject.IsDeal then Value := 'True'
                else Value := 'False';
+      mstZjtz: if ((ACoord.X = 2) and SelectProject.IsPD) or
+                  ((ACoord.X = 3) and SelectProject.IsCddSc) or
+                  ((ACoord.X = 4) and SelectProject.IsCddHt)
+               then Value := 'True'
+               else Value := 'False';
     end;
   end;
 end;
@@ -463,6 +510,13 @@ begin
             SetCDDProject(SelectProject.ProjectID);
         mstE_A: SetABProject(SelectProject.ProjectID);
         mstDeal: SelectProject.IsDeal := True;
+        mstZjtz:
+          if ACoord.X = 2 then
+            SetPDProject(SelectProject.ProjectID)
+          else if ACoord.X = 3 then
+            SetCddScProject(SelectProject.ProjectID)
+          else if ACoord.X = 4 then
+            SetCddHtProject(SelectProject.ProjectID);
       end
     else
       case FMultiSelectType of
@@ -473,6 +527,13 @@ begin
             SelectProject.IsCDD := False;
         mstE_A: SelectProject.IsAB := False;
         mstDeal: SelectProject.IsDeal := False;
+        mstZjtz:
+          if ACoord.X = 2 then
+            SelectProject.IsPD := False
+          else if ACoord.X = 3 then
+            SelectProject.IsCddSc := False
+          else if ACoord.X = 4 then
+            SelectProject.IsCddHt := False;
       end;
   end;
   zgResult.InvalidateCol(ACoord.X);
@@ -492,12 +553,15 @@ begin
     mstE_PCD: Caption := Caption + ',并勾选初步设计、施工图设计项目';
     mstE_A: Caption := Caption + ',并勾选批准概(预)算项目';
     mstDeal: Caption := Caption + ',并勾选其中的多合同项目';
+    mstZjtz: Caption := Caption + ',并勾选初步设计、施工图设计审查预算、施工图设计合同费用项目';
   end;
 
   // 甘肃高管局定制,隐藏结果表
   iWidth := GetSystemMetrics(SM_CXFRAME);
   if FMultiSelectType = mstMental1 then
     ClientWidth := 384
+  else if FMultiSelectType = mstZjtz then
+    ClientWidth := 809
   else
     ClientWidth := 729;
 end;
@@ -632,4 +696,62 @@ begin
   end;
 end;
 
+function TProjectSelectForm.HasCddHtProject: Boolean;
+var
+  i: Integer;
+  SelectProject: TSelectProject;
+begin
+  Result := False;
+  for i := 0 to FSelectProjects.Count - 1 do
+  begin
+    SelectProject := TSelectProject(FSelectProjects.Items[i]);
+    if SelectProject.IsCddHt then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+function TProjectSelectForm.HasCddScProject: Boolean;
+var
+  i: Integer;
+  SelectProject: TSelectProject;
+begin
+  Result := False;
+  for i := 0 to FSelectProjects.Count - 1 do
+  begin
+    SelectProject := TSelectProject(FSelectProjects.Items[i]);
+    if SelectProject.IsCddSc then
+    begin
+      Result := True;
+      Break;
+    end;
+  end;
+end;
+
+procedure TProjectSelectForm.SetCddHtProject(AProjectID: Integer);
+var
+  i: Integer;
+  SelectProject: TSelectProject;
+begin
+  for i := 0 to FSelectProjects.Count - 1 do
+  begin
+    SelectProject := TSelectProject(FSelectProjects.Items[i]);
+    SelectProject.IsCddHt := SelectProject.ProjectID = AProjectID;
+  end;
+end;
+
+procedure TProjectSelectForm.SetCddScProject(AProjectID: Integer);
+var
+  i: Integer;
+  SelectProject: TSelectProject;
+begin
+  for i := 0 to FSelectProjects.Count - 1 do
+  begin
+    SelectProject := TSelectProject(FSelectProjects.Items[i]);
+    SelectProject.IsCddSc := SelectProject.ProjectID = AProjectID;
+  end;
+end;
+
 end.

+ 185 - 0
Units/MCacheTree.pas

@@ -326,6 +326,75 @@ type
     procedure SaveTreeToFile(const AFileName: string);
   end;
 
+  TSpecPhaseCacheNode = class(TCacheNode)
+  private
+    FCode: string;
+    FB_Code: string;
+    FName: string;
+    FUnits: string;
+
+    FTotalPrice: Double;
+
+    FEndDealTotalPrice: Double;
+    FEndQcTotalPrice: Double;
+
+    FhtDgnQty1: Double;
+    FhtDgnQty2: Double;
+    FbgDgnQty1: Double;
+    FbgDgnQty2: Double;
+
+    FcbDgnQty1: Double;
+    FcbDgnQty2: Double;
+    FcbTotalPrice: Double;
+
+    FsscDgnQty1: Double;
+    FsscDgnQty2: Double;
+    FsscTotalPrice: Double;
+
+    FshtDgnQty1: Double;
+    FshtDgnQty2: Double;
+    FshtTotalPrice: Double;
+  public
+    property Code: string read FCode write FCode;
+    property B_Code: string read FB_Code write FB_Code;
+    property Name: string read FName write FName;
+    property Units: string read FUnits write FUnits;
+
+    property TotalPrice: Double read FTotalPrice write FTotalPrice; 
+
+    property EndDealTotalPrice: Double read FEndDealTotalPrice write FEndDealTotalPrice;
+    property EndQcTotalPrice: Double read FEndQcTotalPrice write FEndQcTotalPrice;
+
+    property htDgnQty1: Double read FhtDgnQty1 write FhtDgnQty1;
+    property htDgnQty2: Double read FhtDgnQty2 write FhtDgnQty2;
+    property bgDgnQty1: Double read FbgDgnQty1 write FbgDgnQty1;
+    property bgDgnQty2: Double read FbgDgnQty2 write FbgDgnQty2;
+
+    property cbDgnQty1: Double read FcbDgnQty1 write FcbDgnQty1;
+    property cbDgnQty2: Double read FcbDgnQty2 write FcbDgnQty2;
+    property cbTotalPrice: Double read FcbTotalPrice write FcbTotalPrice;
+    
+    property sscDgnQty1: Double read FsscDgnQty1 write FsscDgnQty1;
+    property sscDgnQty2: Double read FsscDgnQty2 write FsscDgnQty2;
+    property sscTotalPrice: Double read FsscTotalPrice write FsscTotalPrice;
+
+    property shtDgnQty1: Double read FshtDgnQty1 write FshtDgnQty1;
+    property shtDgnQty2: Double read FshtDgnQty2 write FshtDgnQty2;
+    property shtTotalPrice: Double read FshtTotalPrice write FshtTotalPrice;
+  end;
+
+  TSpecPhaseCacheTree = class(TCacheTree)
+  private 
+    function GetNewNode: TSpecPhaseCacheNode;
+  public
+    function AddNode(AParent: TCacheNode; ANextSibling: TCacheNode = nil): TSpecPhaseCacheNode;
+
+    function FindNextSibling(AParent: TCacheNode; ACode, AB_Code: string): TSpecPhaseCacheNode;
+    function FindNode(AParent: TCacheNode; ACode, AB_Code: string): TSpecPhaseCacheNode; overload;
+    function FindNode(AParent: TCacheNode; AName: string): TSpecPhaseCacheNode; overload;
+    function FindNode(AParent: TCacheNode; ACode, AB_Code, AName: string): TSpecPhaseCacheNode; overload;
+  end;
+
 implementation
 
 uses
@@ -1077,4 +1146,120 @@ begin
   end;
 end;
 
+{ TSpecPhaseCacheTree }
+
+function TSpecPhaseCacheTree.AddNode(AParent,
+  ANextSibling: TCacheNode): TSpecPhaseCacheNode;
+begin
+  Result := GetNewNode();
+  if Assigned(ANextSibling) then
+    ANextSibling.InsertPreSibling(Result)
+  else if Assigned(AParent) then
+    AParent.InsertChild(Result)
+  else
+    Root.InsertChild(Result);
+end;
+
+function TSpecPhaseCacheTree.FindNextSibling(AParent: TCacheNode; ACode,
+  AB_Code: string): TSpecPhaseCacheNode;
+var
+  Node: TSpecPhaseCacheNode;
+  sCodeID, sCodeID2, sB_CodeID, sB_CodeID2: string;
+begin
+  if Assigned(AParent) then
+    Node := TSpecPhaseCacheNode(AParent.FirstChild)
+  else
+    Node := TSpecPhaseCacheNode(Root.FirstChild);
+  Result := nil;
+  if (ACode = '') and (AB_Code = '') then Exit;
+  sCodeID := ConvertDigitCode(ACode, 3, '-');
+  sB_CodeID := ConvertDigitCode(AB_Code, 4, '-');
+  while Assigned(Node) do
+  begin
+    sCodeID2 := ConvertDigitCode(Node.Code, 3, '-');
+    sB_CodeID2 := ConvertDigitCode(Node.B_Code, 4, '-');
+    if (sCodeID <> '') and (sCodeID < sCodeID2) then
+    begin
+      Result := Node;
+      Break;
+    end
+    else if sB_CodeID < sB_CodeID2 then
+    begin
+      Result := Node;
+      Break;
+    end;
+    Node := TSpecPhaseCacheNode(Node.NextSibling);
+  end;
+end;
+
+function TSpecPhaseCacheTree.FindNode(AParent: TCacheNode; ACode,
+  AB_Code: string): TSpecPhaseCacheNode;
+var
+  Node: TSpecPhaseCacheNode;
+begin
+  if Assigned(AParent) then
+    Node := TSpecPhaseCacheNode(AParent.FirstChild)
+  else
+    Node := TSpecPhaseCacheNode(Root.FirstChild);
+  Result := nil;
+  while Assigned(Node) do
+  begin
+    if (Node.Code = ACode) and (Node.B_Code = AB_Code) then
+    begin
+      Result := Node;
+      Break;
+    end;
+    Node := TSpecPhaseCacheNode(Node.NextSibling);
+  end;
+end;
+
+function TSpecPhaseCacheTree.FindNode(AParent: TCacheNode;
+  AName: string): TSpecPhaseCacheNode;
+var
+  Node: TSpecPhaseCacheNode;
+begin
+  if Assigned(AParent) then
+    Node := TSpecPhaseCacheNode(AParent.FirstChild)
+  else
+    Node := TSpecPhaseCacheNode(Root.FirstChild);
+  Result := nil;
+  while Assigned(Node) do
+  begin
+    if SameText(Node.Name, AName) then
+    begin
+      Result := Node;
+      Break;
+    end;
+    Node := TSpecPhaseCacheNode(Node.NextSibling);
+  end;
+end;
+
+function TSpecPhaseCacheTree.FindNode(AParent: TCacheNode; ACode, AB_Code,
+  AName: string): TSpecPhaseCacheNode;
+var
+  Node: TSpecPhaseCacheNode;
+begin
+  if Assigned(AParent) then
+    Node := TSpecPhaseCacheNode(AParent.FirstChild)
+  else
+    Node := TSpecPhaseCacheNode(Root.FirstChild);
+  Result := nil;
+  while Assigned(Node) do
+  begin
+    if SameText(Node.Code, ACode) and SameText(Node.B_Code, AB_Code)
+        and SameText(Node.Name, AName) then
+    begin
+      Result := Node;
+      Break;
+    end;
+    Node := TSpecPhaseCacheNode(Node.NextSibling);
+  end;
+end;
+
+function TSpecPhaseCacheTree.GetNewNode: TSpecPhaseCacheNode;
+begin
+  Result := TSpecPhaseCacheNode.Create(Self, GetNewNodeID);
+  CacheNodes.Add(Result);
+end;
+
 end.

+ 19 - 4
Units/ReportManager.pas

@@ -8,7 +8,8 @@ uses
   rmGclBillsAuditCompareDm, rmDealInfosDm, rmXmjBGLDetailDm,
   rmOtherReport1Dm, rmGcl_XmjBillsDm, rmGclBillsPlaneDm,
   rmMentalCustomized1Dm, rmCustomized2Dm, rmHaBaiCustomizedDm,
-  rmWeiWuZjjlGatherDm, rmZhongKaiDm, rmWuJiuZqzfGatherDm,
+  rmWeiWuZjjlGatherDm, rmZhongKaiDm, rmWuJiuZqzfGatherDm, rmBGBillsGatherDm,
+  rmBillsPhaseGatherDm,
   rmTestFrm,
   ReportInteractInfo,
   Classes, ScFileArchiver, IniFiles, Graphics, DB, ProjectData,
@@ -227,6 +228,8 @@ type
     FrmWeiWuZjjlGatherData: TrmWeiWuZjjlGatherData;
     FrmZhongKaiData: TrmZhongKaiData;
     FrmWuJiuZqzfGatherData: TrmWuJiuZqzfGatherData;
+    FrmBGBillsGatherData: TrmBGBillsGatherData;
+    FrmBillsPhaseGatherData: TrmBillsPhaseGatherData;
 
     FMemoryQuery: TADOQuery;
 
@@ -235,6 +238,7 @@ type
     FProjects: TList;         // 普通汇总
     FE_PCDProjects: TList;    // 须选择初步设计,施工图设计
     FE_AProjects: TList;      // 须选择批准概算
+    FZjtzProjects: TList;     // 须选择初步设计,施工图设计审查预算,施工图设计合同费用
     FDealProjects: TList;     // 可选择多合同项目
 
     function OpenProject(ARec: TsdDataRecord): TProjectData;
@@ -667,6 +671,8 @@ begin
   FrmWeiWuZjjlGatherData := TrmWeiWuZjjlGatherData.Create(nil);
   FrmZhongKaiData := TrmZhongKaiData.Create(nil);
   FrmWuJiuZqzfGatherData := TrmWuJiuZqzfGatherData.Create(nil);
+  FrmBGBillsGatherData := TrmBGBillsGatherData.Create(nil);
+  FrmBillsPhaseGatherData := TrmBillsPhaseGatherData.Create(nil);
 
   FMemoryQuery := TADOQuery.Create(nil);
 
@@ -676,6 +682,7 @@ begin
   FE_PCDProjects := TList.Create;
   FE_AProjects := TList.Create;
   FDealProjects := TList.Create;
+  FZjtzProjects := TList.Create;
 end;
 
 destructor TMemoryReportManager.Destroy;
@@ -689,9 +696,13 @@ begin
   FE_AProjects.Free;
   ClearObjects(FDealProjects);
   FDealProjects.Free;
+  ClearObjects(FZjtzProjects);
+  FZjtzProjects.Free;
 
   FMemoryQuery.Free;
 
+  FrmBillsPhaseGatherData.Free;
+  FrmBGBillsGatherData.Free;
   FrmWuJiuZqzfGatherData.Free;
   FrmZhongKaiData.Free;
   FrmWeiWuZjjlGatherData.Free;
@@ -738,7 +749,7 @@ end;
 function TMemoryReportManager.GetMemoryDataSet(
   ADataSetID: Integer; AProjectData: TProjectData): TDataSet;
 begin
-  //ADataSetID := 59;
+  //ADataSetID := 61;
   case ADataSetID of
     1: Result := FrmGridHeaderData.AssginData(AProjectData);   // 各表表头
     2: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseGather, rmgtGather); // 工程量清单[本期完成]
@@ -759,7 +770,7 @@ begin
        // 内蒙古哈白定制表(支表2, 支表3, 支表14, 支表3-1, 支表4-1, 会签)
        52, 53, 54, 55,
        // 内蒙古306国道定制(支表2, 支表3, 支表3-1, 支表4-1)
-       57, 58:
+       57, 58, 60, 61:
        // 中开高速定制表(支表2, 支表3)
         Result := SelectProjectsAndAssignData(ADataSetID);
     14: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseDeal, rmgtGather); // 工程量清单[本期合同]
@@ -840,6 +851,7 @@ begin
     20, 36: SelectFrm.MultiSelectType := mstE_A;
     32: SelectFrm.MultiSelectType := mstDeal;
     40: SelectFrm.MultiSelectType := mstMental1;
+    61: SelectFrm.MultiSelectType := mstZjtz;
     else SelectFrm.MultiSelectType := mstCommon;
   end;
 
@@ -864,6 +876,7 @@ begin
     13, 33: Projects := FE_PCDProjects;
     20, 36: Projects := FE_AProjects;
     32: Projects := FDealProjects;
+    61: Projects := FZjtzProjects;
     else Projects := FProjects;
   end;
 
@@ -906,8 +919,10 @@ begin
       53: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3, False);
       54: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3_1, False);
       55: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt4_1, False);
-      57: Result := FrmZhongKaiData.AssignData(FTenders, zkgt2);                
+      57: Result := FrmZhongKaiData.AssignData(FTenders, zkgt2);
       58: Result := FrmZhongKaiData.AssignData(FTenders, zkgt3);
+      60: Result := FrmBGBillsGatherData.AssignData(FTenders);
+      61: Result := FrmBillsPhaseGatherData.AssignData(FTenders);
       else Result := FrmBillsGatherData.AssignData(FTenders);
     end;
   end;