浏览代码

1. 新增“分包标段汇总(工程量清单)”功能

MaiXinRong 6 年之前
父节点
当前提交
489d9d17bd

+ 105 - 0
SubTenderGatherGcl/stgGatherControlGcl.pas

@@ -0,0 +1,105 @@
+unit stgGatherControlGcl;
+
+interface
+
+uses
+  Classes, stgGatherGclCacheData, stgGatherGclDm, stgGclResultFrm,
+  stgGclGather;
+
+type
+  TstgGatherControlGcl = class
+  private
+    FProjects: TList;
+
+    FGatherGclCacheData: TstgGatherGclCacheData;
+    FGatherGclData: TstgGatherGclData;
+
+    FHintPosition: Integer;
+
+    procedure LoadHint(const ATenderName: string);
+
+    procedure GatherSubTenderFiles;
+    procedure SaveGatherResult;
+    procedure ShowGatherResult;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Gather;
+
+    property Projects: TList read FProjects;
+  end;
+
+implementation
+
+uses
+  ProgressHintFrm, SysUtils;
+
+{ TstgGatherControl }
+
+constructor TstgGatherControlGcl.Create;
+begin
+  FProjects := TList.Create;
+  FGatherGclCacheData := TstgGatherGclCacheData.Create;
+  FGatherGclData := TstgGatherGclData.Create(nil);
+end;
+
+destructor TstgGatherControlGcl.Destroy;
+begin
+  FGatherGclData.Free;
+  FGatherGclCacheData.Free;
+  FProjects.Free;
+  inherited;
+end;
+
+procedure TstgGatherControlGcl.Gather;
+begin
+  FHintPosition := 0;
+  ShowProgressHint('正在准备数据...', FProjects.Count + 1);
+  GatherSubTenderFiles;
+  UpdateProgressHint('正在检查汇总结果...');
+  UpdateProgressPosition(FProjects.Count + 1);
+  SaveGatherResult;
+  CloseProgressHint;
+  ShowGatherResult;
+end;
+
+procedure TstgGatherControlGcl.GatherSubTenderFiles;
+var
+  vGather: TstgSubTenderFileGatherGcl;
+begin
+  vGather := TstgSubTenderFileGatherGcl.Create;
+  try
+    vGather.LoadHint := LoadHint;
+    vGather.GatherTo(FGatherGclCacheData, FProjects);
+  finally
+    vGather.Free;
+  end;
+end;
+
+procedure TstgGatherControlGcl.LoadHint(const ATenderName: string);
+begin
+  Inc(FHintPosition);
+  UpdateProgressHint(Format('正在汇总分包标段"%s"...', [ATenderName]));
+  UpdateProgressPosition(FHintPosition);
+end;
+
+procedure TstgGatherControlGcl.SaveGatherResult;
+begin
+  FGatherGclData.LoadGatherData(FGatherGclCacheData);
+end;
+
+procedure TstgGatherControlGcl.ShowGatherResult;
+var
+  Form: TstgGclResultForm;
+begin
+  Form := TstgGclResultForm.Create(nil);
+  try
+    Form.SetGatherData(FGatherGclData);
+    Form.ShowModal;
+  finally
+    Form.Free;
+  end;
+end;
+
+end.

+ 442 - 0
SubTenderGatherGcl/stgGatherGclCacheData.pas

@@ -0,0 +1,442 @@
+unit stgGatherGclCacheData;
+
+interface
+
+uses
+  CacheTree, SysUtils, BillsTree, Classes, sdDB, mDataRecord;
+
+type
+  TstgGclStageData = class
+  private
+    FDealQuantity: Double;
+    FDealTotalPrice: Double;
+    FQcQuantity: Double;
+    FQcTotalPrice: Double;
+    FQcBGLCode: string;
+    FQcBGLNum: string;
+
+    procedure AddBGLCodeAndNum(ACode, ANum: string);
+  public
+    procedure ClearData;
+    procedure AddStageData(AStageData: TstgGclStageData);
+    procedure AssignedData(AStageRecord: TStageRecord);
+
+    property DealQuantity: Double read FDealQuantity;
+    property DealTotalPrice: Double read FDealTotalPrice;
+    property QcQuantity: Double read FQcQuantity;
+    property QcTotalPrice: Double read FQcTotalPrice;
+    property QcBGLCode: string read FQcBGLCode;
+    property QcBGLNum: string read FQcBGLNum;
+  end;
+
+  TstgGclSubTenderDetailData = class
+  private
+    FSerialNo: Integer;
+    FLeafXmjCode: string;
+    FDetailStage: TstgGclStageData;
+  public
+    constructor Create(ANode: TMeasureBillsIDTreeNode);
+    destructor Destroy; override;
+
+    property SerialNo: Integer read FSerialNo;
+    property LeafXmjCode: string read FLeafXmjCode;
+    property DetailStage: TstgGclStageData read FDetailStage;
+  end;
+
+  TstgGclSubTenderStageData = class
+  private
+    FSubTenderID: Integer;
+    FGather: TstgGclStageData;
+    FDetails: TList;
+    function GetDetail(AIndex: Integer): TstgGclSubTenderDetailData;
+    function GetDetailCount: Integer;
+  public
+    constructor Create(ASubTenderID: Integer);
+    destructor Destroy; override;
+
+    function AddDetail(ANode: TMeasureBillsIDTreeNode): TstgGclSubTenderDetailData;
+
+    procedure CalculateGather;
+
+    property SubTenderID: Integer read FSubTenderID;
+    property Gather: TstgGclStageData read FGather;
+    property DetailCount: Integer read GetDetailCount;
+    property Detail[AIndex: Integer]: TstgGclSubTenderDetailData read GetDetail;
+  end;
+
+  TstgGatherGcl = class
+  private
+    FID: Integer;
+    FB_Code: string;
+    FName: string;
+    FUnits: string;
+    FPrice: Double;
+
+    FGather: TstgGclStageData;
+    FSubTenders: TList;
+    function GetIsGclBills: Boolean;
+    function GetSubTender(AIndex: Integer): TstgGclSubTenderStageData;
+    function GetSubTenderCount: Integer;
+  public
+    constructor Create(AID: Integer; ARec: TBillsRecord);
+    destructor Destroy; override;
+
+    function FindSubTender(ASubTenderID: Integer): TstgGclSubTenderStageData;
+    function SafeSubTender(ASubTenderID: Integer): TstgGclSubTenderStageData;
+
+    procedure CalculateGather;
+
+    property ID: Integer read FID;
+    property B_Code: string read FB_Code;
+    property Name: string read FName;
+    property Units: string read FUnits;
+    property Price: Double read FPrice;
+
+    property SubTenderCount: Integer read GetSubTenderCount;
+    property SubTender[AIndex: Integer]: TstgGclSubTenderStageData read GetSubTender;
+
+    property Gather: TstgGclStageData read FGather;
+  end;
+
+  TstgGatherGclSubTender = class
+  private
+    FID: Integer;
+    FRec: TsdDataRecord;
+  public
+    constructor Create(ARec: TsdDataRecord);
+
+    property ID: Integer read FID;
+    property Rec: TsdDataRecord read FRec;
+  end;
+
+  TstgGatherGclCacheData = class
+  private
+    FGatherGcls: TList;
+    FSubTenders: TList;
+
+    function GetSubTenderCount: Integer;
+    function GetSubTender(AIndex: Integer): TstgGatherGclSubTender;
+    function GetGatherGcl(AIndex: Integer): TstgGatherGcl;
+    function GetGatherGclCount: Integer;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    function FindSubTender(AID: Integer): TstgGatherGclSubTender;
+    function AddSubTender(ARec: TsdDataRecord): TstgGatherGclSubTender;
+
+    function FindGatherGcl(ARec: TBillsRecord): TstgGatherGcl;
+    function AddGatherGcl(ARec: TBillsRecord): TstgGatherGcl;
+
+    procedure CalculateAll;
+
+    property SubTenderCount: Integer read GetSubTenderCount;
+    property SubTender[AIndex: Integer]: TstgGatherGclSubTender read GetSubTender;
+
+    property GatherGclCount: Integer read GetGatherGclCount;
+    property GatherGcl[AIndex: Integer]: TstgGatherGcl read GetGatherGcl;
+  end;
+
+implementation
+
+uses
+  ZhAPI, UtilMethods, Math;
+
+{ TstgGatherGcl }
+
+procedure TstgGatherGcl.CalculateGather;
+var
+  i: Integer;
+  vSubTender: TstgGclSubTenderDetailData;
+begin
+  FGather.ClearData;
+  for i := 0 to FSubTenders.Count - 1 do
+  begin
+    SubTender[i].CalculateGather;
+    FGather.AddStageData(SubTender[i].Gather);
+  end;
+end;
+
+constructor TstgGatherGcl.Create(AID: Integer; ARec: TBillsRecord);
+begin
+  FSubTenders := TList.Create;
+  FGather := TstgGclStageData.Create;
+     
+  FID := AID;
+  FB_Code := ARec.B_Code.AsString;
+  FName := ARec.Name.AsString;
+  FUnits := ARec.Units.AsString;
+  FPrice := ARec.Price.AsFloat;
+end;
+
+destructor TstgGatherGcl.Destroy;
+begin
+  FGather.Free;
+  ClearObjects(FSubTenders);
+  FSubTenders.Free;
+  inherited;
+end;
+
+function TstgGatherGcl.FindSubTender(
+  ASubTenderID: Integer): TstgGclSubTenderStageData;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to FSubTenders.Count - 1 do
+  begin
+    if ASubTenderID = SubTender[i].SubTenderID then
+    begin
+      Result := SubTender[i];
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherGcl.GetIsGclBills: Boolean;
+begin
+  Result := FB_Code <> '';
+end;
+
+function TstgGatherGcl.GetSubTender(
+  AIndex: Integer): TstgGclSubTenderStageData;
+begin
+  Result := TstgGclSubTenderStageData(FSubTenders.Items[AIndex]);
+end;
+
+function TstgGatherGcl.GetSubTenderCount: Integer;
+begin
+  Result := FSubTenders.Count;
+end;
+
+function TstgGatherGcl.SafeSubTender(
+  ASubTenderID: Integer): TstgGclSubTenderStageData;
+begin
+  Result := FindSubTender(ASubTenderID);
+  if not Assigned(Result) then
+  begin
+    Result := TstgGclSubTenderStageData.Create(ASubTenderID);
+    FSubTenders.Add(Result);
+  end;
+end;
+
+{ TstgGatherGclCacheData }
+
+function TstgGatherGclCacheData.AddGatherGcl(
+  ARec: TBillsRecord): TstgGatherGcl;
+begin
+  Result := FindGatherGcl(ARec);
+  if not Assigned(Result) then
+  begin
+    Result := TstgGatherGcl.Create(GatherGclCount + 1, ARec);
+    FGatherGcls.Add(Result);
+  end;
+end;
+
+function TstgGatherGclCacheData.AddSubTender(
+  ARec: TsdDataRecord): TstgGatherGclSubTender;
+begin
+  Result := FindSubTender(ARec.ValueByName('ID').AsInteger);
+  if not Assigned(Result) then
+  begin
+    Result := TstgGatherGclSubTender.Create(ARec);
+    FSubTenders.Add(Result);
+  end;
+end;
+
+procedure TstgGatherGclCacheData.CalculateAll;
+var
+  i: Integer;
+  vGcl: TstgGatherGcl;
+begin
+  for i := 0 to GatherGclCount - 1 do
+  begin
+    vGcl := GatherGcl[i];
+    vGcl.CalculateGather;
+  end;
+end;
+
+constructor TstgGatherGclCacheData.Create;
+begin
+  FGatherGcls := TList.Create;
+  FSubTenders := TList.Create;
+end;
+
+destructor TstgGatherGclCacheData.Destroy;
+begin
+  ClearObjects(FSubTenders);
+  FSubTenders.Free;
+  ClearObjects(FGatherGcls);
+  FGatherGcls.Free;
+  inherited;
+end;
+
+function TstgGatherGclCacheData.FindGatherGcl(ARec: TBillsRecord): TstgGatherGcl;
+var
+  i: Integer;
+  vGcl: TstgGatherGcl;
+  bMatch: Boolean;
+begin
+  Result := nil;
+  for i := 0 to FGatherGcls.Count - 1 do
+  begin
+    vGcl := TstgGatherGcl(FGatherGcls.Items[i]);
+    bMatch := (vGcl.B_Code = ARec.B_Code.AsString) and (vGcl.Name = ARec.Name.AsString)
+      and (vGcl.Units = ARec.Units.AsString)
+      and (CommonRoundTo(vGcl.Price - ARec.Price.AsFloat, -6) = 0);
+    if bMatch then
+    begin
+      Result := vGcl;
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherGclCacheData.FindSubTender(
+  AID: Integer): TstgGatherGclSubTender;
+var
+  i: Integer;
+begin
+  Result := nil;
+  for i := 0 to SubTenderCount - 1 do
+  begin
+    if SubTender[i].ID = AID then
+    begin
+      Result := SubTender[i];
+      Break;
+    end;
+  end;
+end;
+
+function TstgGatherGclCacheData.GetGatherGcl(
+  AIndex: Integer): TstgGatherGcl;
+begin
+  Result := TstgGatherGcl(FGatherGcls.Items[AIndex]);
+end;
+
+function TstgGatherGclCacheData.GetGatherGclCount: Integer;
+begin
+  Result := FGatherGcls.Count;
+end;
+
+function TstgGatherGclCacheData.GetSubTender(AIndex: Integer): TstgGatherGclSubTender;
+begin
+  Result := TstgGatherGclSubTender(FSubTenders.Items[AIndex]);
+end;
+
+function TstgGatherGclCacheData.GetSubTenderCount: Integer;
+begin
+  Result := FSubTenders.Count;
+end;
+
+{ TstgGatherGclSubTender }
+
+constructor TstgGatherGclSubTender.Create(ARec: TsdDataRecord);
+begin
+  FID := ARec.ValueByName('ID').AsInteger;
+  FRec := ARec;
+end;
+
+{ TstgGclStageData }
+
+procedure TstgGclStageData.AddBGLCodeAndNum(ACode, ANum: string);
+var
+  sCode, sNum: string;
+begin
+  sCode := FQcBGLCode;
+  sNum := FQcBGLNum;
+  MergeRelaBGLAndNum(sCode, sNum, ACode, ANum);
+  FQcBGLCode := sCode;
+  FQcBGLNum := sNum;
+end;
+
+procedure TstgGclStageData.AddStageData(AStageData: TstgGclStageData);
+begin
+  FDealQuantity := FDealQuantity + AStageData.DealQuantity;
+  FDealTotalPrice := FDealTotalPrice + AStageData.DealTotalPrice;
+  FQcQuantity := FQcQuantity + AStageData.QcQuantity;
+  FQcTotalPrice := FQcTotalPrice + AStageData.QcTotalPrice;
+  AddBGLCodeAndNum(AStageData.QcBGLCode, AStageData.QcBGLNum);
+end;
+
+procedure TstgGclStageData.AssignedData(AStageRecord: TStageRecord);
+begin
+  FDealQuantity := AStageRecord.DealQuantity.AsFloat;
+  FDealTotalPrice := AStageRecord.DealTotalPrice.AsFloat;
+  FQcQuantity := AStageRecord.QcQuantity.AsFloat;
+  FQcTotalPrice := AStageRecord.QcTotalPrice.AsFloat;
+  FQcBGLCode := AStageRecord.QcBGLCode.AsString;
+  FQcBGLNum := AStageRecord.QcBGLNum.AsString;
+end;
+
+procedure TstgGclStageData.ClearData;
+begin
+  FDealQuantity := 0;
+  FDealTotalPrice := 0;
+  FQcQuantity := 0;
+  FQcTotalPrice := 0;
+  FQcBGLCode := '';
+  FQcBGLNum := '';
+end;
+
+{ TstgGclSubTenderStageData }
+
+function TstgGclSubTenderStageData.AddDetail(
+  ANode: TMeasureBillsIDTreeNode): TstgGclSubTenderDetailData;
+begin
+  Result := TstgGclSubTenderDetailData.Create(ANode);
+  FDetails.Add(Result);
+end;
+
+procedure TstgGclSubTenderStageData.CalculateGather;
+var
+  i: Integer;
+begin
+  FGather.ClearData;
+  for i := 0 to DetailCount - 1 do
+    FGather.AddStageData(Detail[i].DetailStage);
+end;
+
+constructor TstgGclSubTenderStageData.Create(ASubTenderID: Integer);
+begin
+  FSubTenderID := ASubTenderID;
+  FGather := TstgGclStageData.Create;
+  FDetails := TList.Create;
+end;
+
+destructor TstgGclSubTenderStageData.Destroy;
+begin
+  ClearObjects(FDetails);
+  FDetails.Free;
+  FGather.Free;
+  inherited;
+end;
+
+function TstgGclSubTenderStageData.GetDetail(
+  AIndex: Integer): TstgGclSubTenderDetailData;
+begin
+  Result := TstgGclSubTenderDetailData(FDetails.Items[AIndex]);
+end;
+
+function TstgGclSubTenderStageData.GetDetailCount: Integer;
+begin
+  Result := FDetails.Count;
+end;
+
+{ TstgGclSubTenderDetailData }
+
+constructor TstgGclSubTenderDetailData.Create(ANode: TMeasureBillsIDTreeNode);
+begin
+  FSerialNo := ANode.MajorIndex + 1;
+  FDetailStage := TstgGclStageData.Create;
+  if Assigned(ANode.StageRec) then
+    FDetailStage.AssignedData(ANode.StageRec);
+end;
+
+destructor TstgGclSubTenderDetailData.Destroy;
+begin
+  FDetailStage.Free;
+  inherited;
+end;
+
+end.

+ 172 - 0
SubTenderGatherGcl/stgGclExcelExport.pas

@@ -0,0 +1,172 @@
+unit stgGclExcelExport;
+
+interface
+
+uses
+  Classes, OExport, OExport_Vcl, OExport_VclForms, stgGatherGclDm, sdDB,
+  stgGatherGclCacheData, Graphics;
+
+type
+  TstgGclExcelExport = class
+  private
+    FTempFile: string;
+    FGatherData: TstgGatherGclData;
+    FOExport: TOExport;
+    FOExportor: TOCustomExporter;
+  protected
+    function AddHeadCell(ARow: TExportRow; const AHead: string; AWidth: Integer): TExportCellString;
+
+    function GetExportor(const AFileType: string): TOCustomExporter;
+
+    procedure SaveFile(const AFileName: string);
+
+    procedure BeforeExport;
+    procedure AfterExport;
+  public
+    constructor Create(AGatherData: TstgGatherGclData);
+
+    property GatherData: TstgGatherData read FGatherData;
+    property OExport: TOExport read FOExport;
+  end;
+
+  TstgGatherGclExcelExport = class(TstgGclExcelExport)
+  private
+    procedure InitSheet(ASheet: TExportWorkSheet);
+    procedure ExportGclToSheet(AGcl: TstgGatherGcl; ASheet: TExportWorkSheet);
+    procedure ExportGatherToSheet(ASheet: TExportWorkSheet);
+  public
+    procedure ExportGather(const AFileName: string);
+  end;
+
+implementation
+
+uses SysUtils, UtilMethods, ZhAPI;
+
+{ TstgGclExcelExport }
+
+function TstgGclExcelExport.AddHeadCell(ARow: TExportRow; const AHead: string;
+  AWidth: Integer): TExportCellString;
+begin
+  Result := ARow.AddCellString(AHead);
+  Result.SetAlignment(cahCenter);
+  Result.SetVAlignment(cavCenter);
+  Result.Font.Name := '黑体';
+  Result.Font.Size := 10;
+  Result.Width := AWidth;
+end;
+
+procedure TstgGclExcelExport.AfterExport;
+begin
+  FOExport.Free;
+  if Assigned(FOExportor) then
+    FOExportor.Free;
+  if FileExists(FTempFile) then
+    DeleteFile(FTempFile);
+end;
+
+procedure TstgGclExcelExport.BeforeExport;
+begin
+  FOExport := TOExport.Create;
+  FOExport.UseProgress := False;
+  FTempFile := GetTempFileName;
+end;
+
+constructor TstgGclExcelExport.Create(AGatherData: TstgGatherData);
+begin
+  FGatherData := AGatherData;
+end;
+
+function TstgGclExcelExport.GetExportor(
+  const AFileType: string): TOCustomExporter;
+begin
+  if SameText(AFileType, '.xls') then
+    FOExportor := TOCustomExporterXLS.Create
+  else //if SameText(AFileType, '.xlsx') then
+    FOExportor := TOCustomExporterXLSX.Create;
+end;
+
+procedure TstgGclExcelExport.SaveFile(const AFileName: string);
+begin
+  FOExport.SaveToFile(FTempFile, FOExportor);
+  if not FileExists(AFileName) or QuestMessage('存在同名文件,是否替换?') then
+    CopyFileOrFolder(FTempFile, AFileName);
+end;
+
+{ TstgGatherGclExcelExport }
+
+procedure TstgGatherGclExcelExport.ExportGather(const AFileName: string);
+begin
+  BeforeExport;
+  try
+    GetExportor(ExtractFileExt(AFileName));
+    ExportGatherToSheet(OExport.AddWorkSheet('分包数据汇总'));
+    SaveFile(AFileName);
+  finally
+    AfterExport;
+  end;
+end;
+
+procedure TstgGatherGclExcelExport.ExportGatherToSheet(
+  ASheet: TExportWorkSheet);
+var
+  i: Integer;
+begin
+  InitSheet(ASheet);
+  try
+    for (i := 0 to FGatherData.GatherGclCount - 1) do
+      ExportGclToSheet(FGatherData.GatherGcl[i], ASheet);
+  finally
+    vTree.Free;
+  end;
+end;
+
+procedure TstgGatherGclExcelExport.ExportGclToSheet(AGcl: TstgGatherGcl;
+  ASheet: TExportWorkSheet);
+
+  procedure AddCellString(ARow: TExportRow; const AStr: string; AColor: TColor);
+  var
+    vCell: TExportCellString;
+  begin
+    vCell := ARow.AddCellString(AStr);
+    vCell.Font.Color := AColor;
+  end;
+
+  procedure AddCellNumber(ARow: TExportRow; const ANum: Double; AColor: TColor);
+  var
+    vCell: TExportCellNumber;
+  begin
+    vCell := ARow.AddCellNumber(ANum);
+    vCell.Font.Color := AColor;
+    vCell.EmptyIfZero := True;
+  end;
+
+var
+  vColor: TColor;
+  vRow: TExportRow;
+  vCell: TExportCellNumber;
+begin
+  if not Assigned(ANode) then Exit;
+  vColor := clWindowText;
+  vRow := ASheet.AddRow;
+  AddCellString(vRow, AGcl.Rec.ValueByName('B_Code').AsString, vColor);
+  AddCellString(vRow, AGcl.Rec.ValueByName('Name').AsString, vColor);
+  AddCellString(vRow, AGcl.Rec.ValueByName('Units').AsString, vColor);
+  AddCellNumber(vRow, AGcl.Rec.ValueByName('Price').AsFloat, vColor);
+  AddCellNumber(vRow, AGcl.Rec.ValueByName('DealQuantity').AsFloat, vColor);
+  AddCellNumber(vRow, AGcl.Rec.ValueByName('QcQuantity').AsFloat, vColor);
+end;
+
+procedure TstgGatherGclExcelExport.InitSheet(ASheet: TExportWorkSheet);
+var
+  vRow: TExportRow;
+begin
+  vRow := ASheet.AddRow;
+  AddHeadCell(vRow, '清单编号', 120);
+  AddHeadCell(vRow, '名称', 250);
+  AddHeadCell(vRow, '单位', 60);
+  AddHeadCell(vRow, '单价', 80);
+  AddHeadCell(vRow, '合同计量', 100);
+  AddHeadCell(vRow, '数量变更计量', 100);
+end;
+
+end.

+ 99 - 0
SubTenderGatherGcl/stgGclGather.pas

@@ -0,0 +1,99 @@
+unit stgGclGather;
+
+interface
+
+uses
+  Classes, stgGatherGclCacheData, ProjectData, BillsTree, sdIDTree;
+
+type
+  TProgramHintEvent = procedure (const ATenderName: string) of Object;
+
+  TstgSubTenderFileGatherGcl = class
+  private
+    FCacheData: TstgGatherGclCacheData;
+    FProjectData: TProjectData;
+    FCurSubTenderID: Integer;
+    FLoadHint: TProgramHintEvent;
+    procedure GatherDetailData(AGatherGcl: TstgGatherGcl; ASourceNode: TMeasureBillsIDTreeNode);
+    procedure GatherSubTenderTreeNode(ANode: TsdIDTreeNode);
+    procedure GatherSubTender(ASubTenderID: Integer);
+  public
+    procedure GatherTo(AGatherGclCacheData: TstgGatherGclCacheData; ASubTenders: TList);
+
+    property LoadHint: TProgramHintEvent read FLoadHint write FLoadHint;
+  end;
+
+implementation
+
+uses Math, Globals, mDataRecord, UtilMethods, SysUtils, XMLDoc, XMLIntf;
+
+{ TstgSubTenderFileGatherGcl }
+
+procedure TstgSubTenderFileGatherGcl.GatherDetailData(
+  AGatherGcl: TstgGatherGcl; ASourceNode: TMeasureBillsIDTreeNode);
+var
+  vSubTender: TstgGclSubTenderStageData;
+begin
+  vSubTender := AGatherGcl.SafeSubTender(FCurSubTenderID);
+  vSubTender.AddDetail(ASourceNode);
+end;
+
+procedure TstgSubTenderFileGatherGcl.GatherSubTender(ASubTenderID: Integer);
+var
+  vNode: TsdIDTreeNode;
+begin
+  FCurSubTenderID := ASubTenderID;
+  vNode := ProjectManager.ProjectsTree.FindNode(ASubTenderID);
+  if vNode.Rec.ValueByName('Type').AsInteger = 1 then
+  begin;
+    FLoadHint(vNode.Rec.ValueByName('Name').AsString);
+    FProjectData := OpenProjectManager.FindProjectData(ASubTenderID);
+    try
+      if not Assigned(FProjectData) then
+      begin
+        FProjectData := TProjectData.Create;
+        FProjectData.OpenForSumUpGather(GetMyProjectsFilePath + vNode.Rec.ValueByName('FileName').AsString);
+      end;
+      FCacheData.AddSubTender(vNode.Rec);
+      GatherSubTenderTreeNode(FProjectData.BillsMeasureData.BillsMeasureTree.FirstNode);
+    finally
+      if not Assigned(OpenProjectManager.FindProjectData(ASubTenderID)) then
+        FProjectData.Free;
+    end;
+  end;
+end;
+
+procedure TstgSubTenderFileGatherGcl.GatherSubTenderTreeNode(
+  ANode: TsdIDTreeNode);
+var
+  vNode: TMeasureBillsIDTreeNode;
+  vCur: TstgGatherGcl;
+begin
+  if not Assigned(ANode) then Exit;
+
+  vNode := TMeasureBillsIDTreeNode(ANode);
+  if (not vNode.HasChildren) then
+  begin
+    if (vNode.Rec.B_Code.AsString <> '') then
+    begin
+      vCur := FCacheData.AddGatherGcl(vNode.Rec);
+      GatherDetailData(vCur, vNode);
+    end;
+  end
+  else
+    GatherSubTenderTreeNode(ANode.FirstChild);
+  GatherSubTenderTreeNode(ANode.NextSibling);
+end;
+
+procedure TstgSubTenderFileGatherGcl.GatherTo(AGatherGclCacheData: TstgGatherGclCacheData;
+  ASubTenders: TList);
+var
+  i, iSubTenderID: Integer;
+begin
+  FCacheData := AGatherGclCacheData;
+  for i := 0 to ASubTenders.Count - 1 do
+    GatherSubTender(Integer(ASubTenders.Items[i]));
+  FCacheData.CalculateAll;
+end;
+
+end.

+ 106 - 0
SubTenderGatherGcl/stgGclGatherControl.pas

@@ -0,0 +1,106 @@
+unit stgGclGatherControl;
+
+interface
+
+uses
+  Classes, stgGatherGclCacheData, stgGclGatherDm, stgGclResultFrm,
+  stgGclGather;
+
+type
+  TstgGclGatherControl = class
+  private
+    FProjects: TList;
+
+    FGatherGclCacheData: TstgGatherGclCacheData;
+    FGatherGclData: TstgGclGatherData;
+
+    FHintPosition: Integer;
+
+    procedure LoadHint(const ATenderName: string);
+
+    procedure GatherSubTenderFiles;
+    procedure SaveGatherResult;
+    procedure ShowGatherResult;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Gather;
+
+    property Projects: TList read FProjects;
+  end;
+
+implementation
+
+uses
+  ProgressHintFrm, SysUtils;
+
+{ TstgGatherControl }
+
+constructor TstgGclGatherControl.Create;
+begin
+  FProjects := TList.Create;
+  FGatherGclCacheData := TstgGatherGclCacheData.Create;
+  FGatherGclData := TstgGclGatherData.Create(nil);
+end;
+
+destructor TstgGclGatherControl.Destroy;
+begin
+  FGatherGclData.Free;
+  FGatherGclCacheData.Free;
+  FProjects.Free;
+  inherited;
+end;
+
+procedure TstgGclGatherControl.Gather;
+begin
+  FHintPosition := 0;
+  ShowProgressHint('正在准备数据...', FProjects.Count + 1);
+  GatherSubTenderFiles;
+  FGatherGclCacheData.CalculateAll;
+  UpdateProgressHint('正在检查汇总结果...');
+  UpdateProgressPosition(FProjects.Count + 1);
+  SaveGatherResult;
+  CloseProgressHint;
+  ShowGatherResult;
+end;
+
+procedure TstgGclGatherControl.GatherSubTenderFiles;
+var
+  vGather: TstgSubTenderFileGatherGcl;
+begin
+  vGather := TstgSubTenderFileGatherGcl.Create;
+  try
+    vGather.LoadHint := LoadHint;
+    vGather.GatherTo(FGatherGclCacheData, FProjects);
+  finally
+    vGather.Free;
+  end;
+end;
+
+procedure TstgGclGatherControl.LoadHint(const ATenderName: string);
+begin
+  Inc(FHintPosition);
+  UpdateProgressHint(Format('正在汇总分包标段"%s"...', [ATenderName]));
+  UpdateProgressPosition(FHintPosition);
+end;
+
+procedure TstgGclGatherControl.SaveGatherResult;
+begin
+  FGatherGclData.LoadGatherData(FGatherGclCacheData);
+end;
+
+procedure TstgGclGatherControl.ShowGatherResult;
+var
+  Form: TstgGclResultForm;
+begin
+  Form := TstgGclResultForm.Create(nil);
+  try
+    Form.SetGatherData(FGatherGclData);
+    Form.ShowModal;
+  finally
+    Form.Free;
+  end;
+end;
+
+end.

+ 283 - 0
SubTenderGatherGcl/stgGclGatherDm.dfm

@@ -0,0 +1,283 @@
+object stgGclGatherData: TstgGclGatherData
+  OldCreateOrder = False
+  Left = 932
+  Top = 260
+  Height = 253
+  Width = 482
+  object smpGatherGcl: TsdMemoryProvider
+    Left = 40
+    Top = 24
+  end
+  object sddGatherGcl: TsdDataSet
+    Active = True
+    Filtered = False
+    Provider = smpGatherGcl
+    Left = 40
+    Top = 87
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650809507265636973696F6E02000453697A6502000001044E616D
+      650606425F436F6465094669656C644E616D650606425F436F64650844617461
+      547970650218084461746153697A6502320549734B6579080F4E65656450726F
+      636573734E616D650809507265636973696F6E02000453697A6502000001044E
+      616D6506044E616D65094669656C644E616D6506044E616D6508446174615479
+      70650218084461746153697A6503FF000549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D650605556E697473094669656C644E616D650605556E697473084461746154
+      7970650218084461746153697A6502140549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D65060C4465616C5175616E74697479094669656C644E616D65060C4465616C
+      5175616E746974790844617461547970650206084461746153697A6502080549
+      734B6579080F4E65656450726F636573734E616D650809507265636973696F6E
+      02000453697A6502000001044E616D65060A51635175616E7469747909466965
+      6C644E616D65060A51635175616E746974790844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060E4465616C
+      546F74616C5072696365094669656C644E616D65060E4465616C546F74616C50
+      726963650844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060C5163546F74616C5072696365094669656C64
+      4E616D65060C5163546F74616C50726963650844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060951634247
+      4C436F6465094669656C644E616D650609516342474C436F6465084461746154
+      7970650218084461746153697A6503FF000549734B6579080F4E65656450726F
+      636573734E616D650809507265636973696F6E02000453697A6502000001044E
+      616D650608516342474C4E756D094669656C644E616D650608516342474C4E75
+      6D0844617461547970650218084461746153697A6503FF000549734B6579080F
+      4E65656450726F636573734E616D650809507265636973696F6E02000453697A
+      6502000001044E616D6506055072696365094669656C644E616D650605507269
+      63650844617461547970650206084461746153697A6502080549734B6579080F
+      4E65656450726F636573734E616D650809507265636973696F6E02000453697A
+      6502000000}
+  end
+  object sdvGatherGcl: TsdDataView
+    Active = False
+    DataSet = sddGatherGcl
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'B_Code'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'Units'
+      end
+      item
+        FieldName = 'DealQuantity'
+      end
+      item
+        FieldName = 'QcQuantity'
+      end
+      item
+        FieldName = 'Price'
+      end>
+    OnCurrentChanged = sdvGatherGclCurrentChanged
+    OnGetText = sdvGatherGclGetText
+    Left = 40
+    Top = 152
+  end
+  object smpSubTenders: TsdMemoryProvider
+    Left = 136
+    Top = 24
+  end
+  object sddSubTenders: TsdDataSet
+    Active = True
+    Filtered = False
+    Provider = smpSubTenders
+    Left = 136
+    Top = 88
+    FieldListData = {
+      0101044E616D6506024944094669656C644E616D650602494408446174615479
+      70650203084461746153697A6502040549734B6579080F4E65656450726F6365
+      73734E616D650809507265636973696F6E02000453697A6502000001044E616D
+      6506044E616D65094669656C644E616D6506044E616D65084461746154797065
+      0218084461746153697A6503FF000549734B6579080F4E65656450726F636573
+      734E616D650809507265636973696F6E02000453697A6502000000}
+  end
+  object sdvSubTenders: TsdDataView
+    Active = True
+    DataSet = sddSubTenders
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'ID'
+      end
+      item
+        FieldName = 'Name'
+      end
+      item
+        FieldName = 'ErrorCount'
+      end>
+    OnCurrentChanged = sdvSubTendersCurrentChanged
+    Left = 136
+    Top = 152
+  end
+  object smpBillsDetail: TsdMemoryProvider
+    Left = 248
+    Top = 24
+  end
+  object sddBillsDetail: TsdDataSet
+    Active = True
+    Filtered = False
+    Provider = smpBillsDetail
+    Left = 248
+    Top = 88
+    FieldListData = {
+      0101044E616D65060742696C6C734944094669656C644E616D65060742696C6C
+      7349440844617461547970650203084461746153697A6502040549734B657908
+      0F4E65656450726F636573734E616D650809507265636973696F6E0200045369
+      7A6502000001044E616D65060854656E6465724944094669656C644E616D6506
+      0854656E64657249440844617461547970650203084461746153697A65020405
+      49734B6579080F4E65656450726F636573734E616D650809507265636973696F
+      6E02000453697A6502000001044E616D65060A54656E6465724E616D65094669
+      656C644E616D65060A54656E6465724E616D6508446174615479706502180844
+      61746153697A6503FF000549734B6579080F4E65656450726F636573734E616D
+      650809507265636973696F6E02000453697A6502000001044E616D6506085365
+      7269616C4E6F094669656C644E616D65060853657269616C4E6F084461746154
+      7970650203084461746153697A6502040549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D65060C4465616C5175616E74697479094669656C644E616D65060C4465616C
+      5175616E746974790844617461547970650206084461746153697A6502080549
+      734B6579080F4E65656450726F636573734E616D650809507265636973696F6E
+      02000453697A6502000001044E616D65060E4465616C546F74616C5072696365
+      094669656C644E616D65060E4465616C546F74616C5072696365084461746154
+      7970650206084461746153697A6502080549734B6579080F4E65656450726F63
+      6573734E616D650809507265636973696F6E02000453697A6502000001044E61
+      6D65060A51635175616E74697479094669656C644E616D65060A51635175616E
+      746974790844617461547970650206084461746153697A6502080549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060C5163546F74616C5072696365094669656C64
+      4E616D65060C5163546F74616C50726963650844617461547970650206084461
+      746153697A6502080549734B6579080F4E65656450726F636573734E616D6508
+      09507265636973696F6E02000453697A6502000001044E616D65060951634247
+      4C436F6465094669656C644E616D650609516342474C436F6465084461746154
+      7970650218084461746153697A6503FF000549734B6579080F4E65656450726F
+      636573734E616D650809507265636973696F6E02000453697A6502000001044E
+      616D650608516342474C4E756D094669656C644E616D650608516342474C4E75
+      6D0844617461547970650218084461746153697A6503FF000549734B6579080F
+      4E65656450726F636573734E616D650809507265636973696F6E02000453697A
+      6502000000}
+  end
+  object sdvBillsDetail: TsdDataView
+    Active = False
+    DataSet = sddBillsDetail
+    Filtered = True
+    Columns = <
+      item
+        FieldName = 'BillsID'
+      end
+      item
+        FieldName = 'TenderID'
+      end
+      item
+        FieldName = 'TenderName'
+      end
+      item
+        FieldName = 'SerialNo'
+      end
+      item
+        FieldName = 'DealQuantity'
+      end
+      item
+        FieldName = 'DealTotalPrice'
+      end
+      item
+        FieldName = 'QcQuantity'
+      end
+      item
+        FieldName = 'QcTotalPrice'
+      end
+      item
+        FieldName = 'QcBGLCode'
+      end
+      item
+        FieldName = 'QcBGLNum'
+      end
+      item
+      end>
+    OnFilterRecord = sdvBillsDetailFilterRecord
+    OnGetText = sdvBillsDetailGetText
+    Left = 248
+    Top = 152
+  end
+  object sdmErrorDetail: TsdMemoryProvider
+    Left = 352
+    Top = 24
+  end
+  object sddErrorDetail: TsdDataSet
+    Active = True
+    Filtered = False
+    Provider = sdmErrorDetail
+    Left = 352
+    Top = 88
+    FieldListData = {
+      0101044E616D65060854656E6465724944094669656C644E616D65060854656E
+      64657249440844617461547970650203084461746153697A6502040549734B65
+      79080F4E65656450726F636573734E616D650809507265636973696F6E020004
+      53697A6502000001044E616D65060A54656E6465724E616D65094669656C644E
+      616D65060A54656E6465724E616D650844617461547970650218084461746153
+      697A6503FF000549734B6579080F4E65656450726F636573734E616D65080950
+      7265636973696F6E02000453697A6502000001044E616D65060852656C61436F
+      6465094669656C644E616D65060852656C61436F646508446174615479706502
+      18084461746153697A6502320549734B6579080F4E65656450726F636573734E
+      616D650809507265636973696F6E02000453697A6502000001044E616D65060C
+      52656C6153657269616C4E6F094669656C644E616D65060C52656C6153657269
+      616C4E6F0844617461547970650203084461746153697A6502040549734B6579
+      080F4E65656450726F636573734E616D650809507265636973696F6E02000453
+      697A6502000001044E616D65060A44657461696C436F6465094669656C644E61
+      6D65060A44657461696C436F6465084461746154797065021808446174615369
+      7A6502320549734B6579080F4E65656450726F636573734E616D650809507265
+      636973696F6E02000453697A6502000001044E616D65060E44657461696C5365
+      7269616C4E6F094669656C644E616D65060E44657461696C53657269616C4E6F
+      0844617461547970650203084461746153697A6502040549734B6579080F4E65
+      656450726F636573734E616D650809507265636973696F6E02000453697A6502
+      000001044E616D6506094572726F7254797065094669656C644E616D65060945
+      72726F72547970650844617461547970650203084461746153697A6502040549
+      734B6579080F4E65656450726F636573734E616D650809507265636973696F6E
+      02000453697A6502000000}
+    IndexListData = {
+      01044E616D65060B69647854656E64657249440A4669656C644E616D65730608
+      54656E64657249440000}
+  end
+  object sdvErrorDetail: TsdDataView
+    Active = False
+    DataSet = sddErrorDetail
+    Filtered = False
+    Columns = <
+      item
+        FieldName = 'TenderID'
+      end
+      item
+        FieldName = 'TenderName'
+      end
+      item
+        FieldName = 'RelaID'
+      end
+      item
+        FieldName = 'RelaCode'
+      end
+      item
+        FieldName = 'RelaSerialNo'
+      end
+      item
+        FieldName = 'DetailID'
+      end
+      item
+        FieldName = 'DetailCode'
+      end
+      item
+        FieldName = 'DetailSerialNo'
+      end
+      item
+        FieldName = 'ErrorType'
+      end>
+    OnFilterRecord = sdvErrorDetailFilterRecord
+    OnGetText = sdvErrorDetailGetText
+    Left = 352
+    Top = 152
+  end
+end

+ 216 - 0
SubTenderGatherGcl/stgGclGatherDm.pas

@@ -0,0 +1,216 @@
+unit stgGclGatherDm;
+// ½á¹ûչʾ£¬ÄÚ´æ±í
+
+interface
+
+uses
+  SysUtils, Classes, stgGatherGclCacheData, sdDB, sdProvider, stgGatherUtils;
+
+type
+  TstgGclGatherData = class(TDataModule)
+    smpGatherGcl: TsdMemoryProvider;
+    sddGatherGcl: TsdDataSet;
+    sdvGatherGcl: TsdDataView;
+    smpSubTenders: TsdMemoryProvider;
+    sddSubTenders: TsdDataSet;
+    sdvSubTenders: TsdDataView;
+    smpBillsDetail: TsdMemoryProvider;
+    sddBillsDetail: TsdDataSet;
+    sdvBillsDetail: TsdDataView;
+    sdmErrorDetail: TsdMemoryProvider;
+    sddErrorDetail: TsdDataSet;
+    sdvErrorDetail: TsdDataView;
+    procedure sdvBillsDetailGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+    procedure sdvBillsDetailFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvGatherGclCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvGatherGclGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+    procedure sdvErrorDetailFilterRecord(ARecord: TsdDataRecord;
+      var Allow: Boolean);
+    procedure sdvSubTendersCurrentChanged(ARecord: TsdDataRecord);
+    procedure sdvErrorDetailGetText(var Text: String;
+      ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+      DisplayText: Boolean);
+  private
+    procedure LoadSubTenders(ACacheData: TstgGatherGclCacheData);
+
+    procedure LoadGatherGclDetail(AGcl: TstgGatherGcl);
+    procedure LoadGatherGcl(AGcl: TstgGatherGcl);
+    procedure LoadGatherGcls(ACacheData: TstgGatherGclCacheData);
+  public
+    procedure LoadGatherData(ACacheData: TstgGatherGclCacheData);
+  end;
+
+implementation
+
+uses
+  Variants, DB, ConditionalDefines;
+
+{$R *.dfm}
+
+{ TstgGatherData }
+
+procedure TstgGclGatherData.LoadGatherData(ACacheData: TstgGatherGclCacheData);
+begin
+  LoadSubTenders(ACacheData);
+  LoadGatherGcls(ACacheData);
+
+  sdvGatherGcl.Active := True;
+  sdvBillsDetail.Active := True;
+  sdvBillsDetail.RefreshFilter;
+
+  sdvSubTenders.Active := True;
+end;
+
+procedure TstgGclGatherData.LoadGatherGcls(ACacheData: TstgGatherGclCacheData);
+var
+  i: Integer;
+begin
+  for i := 0 to ACacheData.GatherGclCount - 1 do
+    LoadGatherGcl(ACacheData.GatherGcl[i]);
+end;
+
+procedure TstgGclGatherData.LoadGatherGcl(AGcl: TstgGatherGcl);
+var
+  Rec: TsdDataRecord;
+begin
+  Rec := sddGatherGcl.Add;
+  Rec.ValueByName('ID').AsInteger := AGcl.ID;
+  Rec.ValueByName('B_Code').AsString := AGcl.B_Code;
+  Rec.ValueByName('Name').AsString := AGcl.Name;
+  Rec.ValueByName('Units').AsString := AGcl.Units;
+  Rec.ValueByName('Price').AsFloat := AGcl.Price;
+
+  Rec.ValueByName('DealQuantity').AsFloat := AGcl.Gather.DealQuantity;
+  Rec.ValueByName('DealTotalPrice').AsFloat := AGcl.Gather.DealTotalPrice;
+  Rec.ValueByName('QcQuantity').AsFloat := AGcl.Gather.QcQuantity;
+  Rec.ValueByName('QcTotalPrice').AsFloat := AGcl.Gather.QcTotalPrice;
+  Rec.ValueByName('QcBGLCode').AsString := AGcl.Gather.QcBGLCode;
+  Rec.ValueByName('QcBGLNum').AsString := AGcl.Gather.QcBGLNum;
+  
+  LoadGatherGclDetail(AGcl);
+end;
+
+procedure TstgGclGatherData.LoadGatherGclDetail(
+  AGcl: TstgGatherGcl);
+var
+  iSub, iDetail: Integer;
+  vSub: TstgGclSubTenderStageData;
+  vDetail: TstgGclSubTenderDetailData;
+  Rec: TsdDataRecord;
+  sSubTenderName: string;
+begin
+  for iSub := 0 to AGcl.SubTenderCount - 1 do
+  begin
+    vSub := AGcl.SubTender[iSub];
+    for iDetail := 0 to vSub.DetailCount - 1 do
+    begin
+      vDetail := vSub.Detail[iDetail];
+      Rec := sddBillsDetail.Add;
+      Rec.ValueByName('BillsID').AsInteger := AGcl.ID;
+      Rec.ValueByName('TenderID').AsInteger := vSub.SubTenderID;
+      Rec.ValueByName('TenderName').AsString := '';
+      Rec.ValueByName('SerialNo').AsInteger := vDetail.SerialNo;
+      Rec.ValueByName('DealQuantity').AsFloat := vDetail.DetailStage.DealQuantity;
+      Rec.ValueByName('DealTotalPrice').AsFloat := vDetail.DetailStage.DealTotalPrice;
+      Rec.ValueByName('QcQuantity').AsFloat := vDetail.DetailStage.QcQuantity;
+      Rec.ValueByName('QcTotalPrice').AsFloat := vDetail.DetailStage.QcTotalPrice;
+      Rec.ValueByName('QcBGLCode').AsString := vDetail.DetailStage.QcBGLCode;
+      Rec.ValueByName('QcBGLNum').AsString := vDetail.DetailStage.QcBGLNum;
+    end;
+  end;
+end;
+
+procedure TstgGclGatherData.LoadSubTenders(ACacheData: TstgGatherGclCacheData);
+var
+  i: Integer;
+  vSubTender: TstgGatherGclSubTender;
+  Rec: TsdDataRecord;
+begin
+  for i := 0 to ACacheData.SubTenderCount - 1 do
+  begin
+    vSubTender := ACacheData.SubTender[i];
+    Rec := sddSubTenders.Add;
+    Rec.ValueByName('ID').AsInteger := vSubTender.ID;
+    Rec.ValueByName('Name').AsString := vSubTender.Rec.ValueByName('Name').AsString;
+  end;
+end;
+
+procedure TstgGclGatherData.sdvBillsDetailGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+
+  function GetTenderName(ATenderID: Integer): string;
+  begin
+    Result := VarToStrDef(sddSubTenders.Lookup('ID', ATenderID, 'Name'), '');
+  end;
+
+begin
+  if DisplayText and (AColumn.FieldName = 'TenderName') then
+    Text := GetTenderName(ARecord.ValueByName('TenderID').asInteger);
+end;
+
+procedure TstgGclGatherData.sdvBillsDetailFilterRecord(ARecord: TsdDataRecord;
+  var Allow: Boolean);
+begin
+  if Assigned(sdvGatherGcl.Current) then
+    Allow := ARecord.ValueByName('BillsID').AsInteger = sdvGatherGcl.Current.ValueByName('ID').AsInteger
+  else
+    Allow := False;
+end;
+
+procedure TstgGclGatherData.sdvGatherGclCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvBillsDetail.RefreshFilter;
+end;
+
+procedure TstgGclGatherData.sdvGatherGclGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+begin
+  if (AValue.DataType = ftFloat) and (AValue.AsFloat = 0) then
+  begin
+    Text := '';
+  end;
+end;
+
+procedure TstgGclGatherData.sdvErrorDetailFilterRecord(ARecord: TsdDataRecord;
+  var Allow: Boolean);
+begin
+  if Assigned(sdvSubTenders.Current) then
+    Allow := ARecord.ValueByName('TenderID').AsInteger = sdvSubTenders.Current.ValueByName('ID').AsInteger
+  else
+    Allow := False;
+end;
+
+procedure TstgGclGatherData.sdvSubTendersCurrentChanged(
+  ARecord: TsdDataRecord);
+begin
+  sdvErrorDetail.RefreshFilter;
+end;
+
+procedure TstgGclGatherData.sdvErrorDetailGetText(var Text: String;
+  ARecord: TsdDataRecord; AValue: TsdValue; AColumn: TsdViewColumn;
+  DisplayText: Boolean);
+
+  function GetTenderName(ATenderID: Integer): string;
+  begin
+    Result := VarToStrDef(sddSubTenders.Lookup('ID', ATenderID, 'Name'), '');
+  end;
+
+begin
+  if DisplayText then
+  begin
+    if (AColumn.FieldName = 'TenderName') then
+      Text := GetTenderName(ARecord.ValueByName('TenderID').asInteger)
+    else if (AColumn.FieldName = 'ErrorType') then
+      Text := GetErrorTypeText(AValue.AsInteger);
+  end;
+end;
+
+end.

+ 355 - 0
SubTenderGatherGcl/stgGclResultFrm.dfm

@@ -0,0 +1,355 @@
+object stgGclResultForm: TstgGclResultForm
+  Left = 192
+  Top = 123
+  Width = 1305
+  Height = 675
+  ActiveControl = zgGatherGcl
+  BorderIcons = [biSystemMenu, biMaximize]
+  Caption = #20998#21253#27719#24635
+  Color = clBtnFace
+  Font.Charset = DEFAULT_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -11
+  Font.Name = 'MS Sans Serif'
+  Font.Style = []
+  OldCreateOrder = False
+  Position = poMainFormCenter
+  PixelsPerInch = 96
+  TextHeight = 13
+  object jpsResult: TJimPages
+    Left = 0
+    Top = 22
+    Width = 1297
+    Height = 594
+    ActivePage = jpsResultBillsDetail
+    ActivePageIndex = 0
+    Align = alClient
+    Caption = 'jpsResult'
+    object jpsResultBillsDetail: TJimPage
+      Left = 0
+      Top = 0
+      Width = 1297
+      Height = 594
+      TabName = 'BillsDetail'
+      Caption = 'Tree'
+      object Splitter1: TSplitter
+        Left = 924
+        Top = 0
+        Height = 594
+        Align = alRight
+      end
+      object pnlGatherTree: TPanel
+        Left = 0
+        Top = 0
+        Width = 924
+        Height = 594
+        Align = alClient
+        BevelOuter = bvNone
+        TabOrder = 0
+        object zgGatherGcl: TZJGrid
+          Left = 0
+          Top = 0
+          Width = 924
+          Height = 594
+          Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
+          OptionsEx = []
+          ColCount = 7
+          ShowGridLine = False
+          DefaultColWidth = 73
+          DefaultFixedColWidth = 25
+          Selection.AlphaBlend = False
+          Selection.TransparentColor = False
+          FrozenCol = 0
+          FrozenRow = 0
+          OnMouseDown = zgGatherGclMouseDown
+          Align = alClient
+        end
+      end
+      object pnlDetail: TPanel
+        Left = 927
+        Top = 0
+        Width = 370
+        Height = 594
+        Align = alRight
+        BevelOuter = bvNone
+        TabOrder = 1
+        object zgBillsDetail: TZJGrid
+          Left = 0
+          Top = 0
+          Width = 370
+          Height = 594
+          Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection]
+          OptionsEx = []
+          ShowGridLine = False
+          DefaultColWidth = 73
+          DefaultFixedColWidth = 25
+          Selection.AlphaBlend = False
+          Selection.TransparentColor = False
+          FrozenCol = 0
+          FrozenRow = 0
+          Align = alClient
+        end
+      end
+    end
+  end
+  object jtsGatherData: TJimTabSet
+    Left = 0
+    Top = 0
+    Width = 1297
+    Height = 22
+    Align = alTop
+    BackgroundColor = clGradientInactiveCaption
+    Font.Charset = DEFAULT_CHARSET
+    Font.Color = clWindowText
+    Font.Height = -12
+    Font.Name = 'smartSimSun'
+    Font.Style = []
+    SelectedColor = clWhite
+    XPSelectedColor = clWhite
+    XPUnSelectedColor = 15200496
+    Tabs.Strings = (
+      #27719#24635#32467#26524)
+    TabPosition = jtpTop
+    TabStyle = tdsNew
+    UnselectedColor = 15200496
+  end
+  object pnlResult: TPanel
+    Left = 0
+    Top = 616
+    Width = 1297
+    Height = 28
+    Align = alBottom
+    BevelOuter = bvNone
+    TabOrder = 2
+    Visible = False
+    object lblResult: TLabel
+      Left = 4
+      Top = 8
+      Width = 692
+      Height = 13
+      Caption = #20849#27719#24635'3'#20010#26631#27573#25968#25454#65292#20849#27719#24635#24037#31243#37327#28165#21333'X'#26465#65292#20854#20013'Y'#26465#27491#30830#27719#24635#65292#35813#37096#20998#21487#27491#30830#23548#20837#24635#21253#65292#26410#27491#30830#27719#24635#28165#21333#21487#35265#28165#21333#26126#32454#20013#28784#33394#37096#20998
+    end
+  end
+  object sdBillsDetail: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #26631#27573
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'TenderName'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #20301#32622
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'SerialNo'
+        Width = 50
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21512#21516#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DealQuantity'
+        Width = 85
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #25968#37327#21464#26356#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'QcQuantity'
+        Width = 85
+        ReadOnly = False
+      end>
+    Grid = zgBillsDetail
+    ExtendRowCount = 0
+    Options = []
+    Left = 157
+    Top = 110
+  end
+  object dxpmGatherTree: TdxBarPopupMenu
+    BarManager = MainForm.dxBarManager
+    ItemLinks = <
+      item
+        Item = MainForm.dxbtnExportStgResult
+        Visible = True
+      end
+      item
+        Item = MainForm.dxbtnExportStgResultExcel
+        Visible = True
+      end>
+    UseOwnFont = False
+    OnPopup = dxpmGatherTreePopup
+    Left = 104
+    Top = 148
+  end
+  object alStgResult: TActionList
+    Images = MainForm.Images
+    Left = 256
+    Top = 110
+    object actnExportStgResultExcel: TAction
+      Caption = #23548#20986#20998#21253#27719#24635'Excel'#26684#24335
+      ImageIndex = 13
+      OnExecute = actnExportStgResultExcelExecute
+    end
+    object actnExportStgResult: TAction
+      Caption = #23548#20986#20998#21253#27719#24635#36719#20214#26684#24335
+      ImageIndex = 28
+      OnExecute = actnExportStgResultExecute
+    end
+  end
+  object saGatherGcl: TsdGridDBA
+    Columns = <
+      item
+        Title.Caption = #28165#21333#32534#21495
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'B_Code'
+        Width = 120
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21517#31216
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Name'
+        Width = 250
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21333#20301
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Units'
+        Width = 60
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21333#20215
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Price'
+        Width = 80
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21512#21516#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'DealQuantity'
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #25968#37327#21464#26356#35745#37327
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taRightJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'QcQuantity'
+        ReadOnly = False
+      end>
+    Grid = zgGatherGcl
+    Left = 104
+    Top = 110
+  end
+end

+ 106 - 0
SubTenderGatherGcl/stgGclResultFrm.pas

@@ -0,0 +1,106 @@
+unit stgGclResultFrm;
+
+interface
+
+uses
+  stgGclGatherDm, UtilMethods, ExportExcel, stgGclSubGatherFile,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, JimTabs, JimPages, sdGridDBA, ZJGrid, ExtCtrls,
+  StdCtrls, dxBar, ActnList;
+
+type
+  TstgGclResultForm = class(TForm)
+    jpsResult: TJimPages;
+    jpsResultBillsDetail: TJimPage;
+    jtsGatherData: TJimTabSet;
+    pnlGatherTree: TPanel;
+    zgGatherGcl: TZJGrid;
+    pnlDetail: TPanel;
+    zgBillsDetail: TZJGrid;
+    Splitter1: TSplitter;
+    sdBillsDetail: TsdGridDBA;
+    pnlResult: TPanel;
+    lblResult: TLabel;
+    dxpmGatherTree: TdxBarPopupMenu;
+    alStgResult: TActionList;
+    actnExportStgResultExcel: TAction;
+    actnExportStgResult: TAction;
+    saGatherGcl: TsdGridDBA;
+    procedure zgGatherGclMouseDown(Sender: TObject; Button: TMouseButton;
+      Shift: TShiftState; X, Y: Integer);
+    procedure dxpmGatherTreePopup(Sender: TObject);
+    procedure actnExportStgResultExcelExecute(Sender: TObject);
+    procedure actnExportStgResultExecute(Sender: TObject);
+  private
+    FGatherData: TstgGclGatherData;
+  public
+    destructor Destroy; override;
+
+    procedure SetGatherData(AGatherData: TstgGclGatherData);
+  end;
+
+implementation
+
+uses
+  MainFrm;
+
+{$R *.dfm}
+
+procedure TstgGclResultForm.SetGatherData(AGatherData: TstgGclGatherData);
+begin
+  FGatherData := AGatherData;
+  saGatherGcl.DataView := AGatherData.sdvGatherGcl;
+  sdBillsDetail.DataView := AGatherData.sdvBillsDetail;
+end;
+
+procedure TstgGclResultForm.zgGatherGclMouseDown(Sender: TObject;
+  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+begin
+  if Button = mbRight then
+    dxpmGatherTree.PopupFromCursorPos;
+end;
+
+destructor TstgGclResultForm.Destroy;
+begin
+  inherited;
+end;
+
+procedure TstgGclResultForm.dxpmGatherTreePopup(Sender: TObject);
+begin
+  SetDxBtnAction(actnExportStgResult, MainForm.dxbtnExportStgResult);
+  SetDxBtnAction(actnExportStgResultExcel, MainForm.dxbtnExportStgResultExcel);
+end;
+
+procedure TstgGclResultForm.actnExportStgResultExcelExecute(Sender: TObject);
+var
+  sFileName: string;
+  ExcelExportor: TExcelExportor;
+begin
+  if SaveExcelFile(sFileName) then
+  begin
+    ExcelExportor := TExcelExportor.Create;
+    try
+      ExcelExportor.ExportToFile(zgGatherGcl, sFileName);
+    finally
+      ExcelExportor.Free;
+    end;
+  end;
+end;
+
+procedure TstgGclResultForm.actnExportStgResultExecute(Sender: TObject);
+var
+  sFileName: string;
+  vExportor: TstgGclSubGatherFileExportor;
+begin
+  if SaveFile(sFileName, '.sgfg') then
+  begin
+    vExportor := TstgGclSubGatherFileExportor.Create;
+    try
+      vExportor.ExportGatherDataTo(FGatherData, sFileName);
+    finally
+      vExportor.Free;
+    end;
+  end;
+end;
+
+end.

+ 222 - 0
SubTenderGatherGcl/stgGclSelectFileFrm.dfm

@@ -0,0 +1,222 @@
+object stgGclSelectFileForm: TstgGclSelectFileForm
+  Left = 443
+  Top = 206
+  Width = 910
+  Height = 533
+  Caption = #20998#21253#26631#27573#27719#24635
+  Color = clBtnFace
+  Font.Charset = ANSI_CHARSET
+  Font.Color = clWindowText
+  Font.Height = -12
+  Font.Name = #23435#20307
+  Font.Style = []
+  OldCreateOrder = False
+  Position = poMainFormCenter
+  PixelsPerInch = 96
+  TextHeight = 12
+  object pnlGatherFiles: TPanel
+    Left = 0
+    Top = 0
+    Width = 902
+    Height = 461
+    Align = alClient
+    BevelOuter = bvNone
+    TabOrder = 0
+    object pnlSelect: TPanel
+      Left = 0
+      Top = 0
+      Width = 450
+      Height = 461
+      Align = alLeft
+      BevelOuter = bvNone
+      TabOrder = 0
+      object zgTenderSelect: TZJGrid
+        Left = 0
+        Top = 23
+        Width = 450
+        Height = 438
+        Options = [goRangeSelect, goRowSizing, goColSizing, goCellNotMaintainData, goFixedRowShowNo, goFixedColShowNo, goAlwaysShowSelection, goShowTreeLine]
+        OptionsEx = []
+        ColCount = 3
+        RowCount = 1
+        ShowGridLine = False
+        DefaultColWidth = 35
+        DefaultFixedColWidth = 25
+        DefaultFixedRowHeight = 22
+        Selection.AlphaBlend = False
+        Selection.TransparentColor = False
+        FrozenCol = 0
+        FrozenRow = 0
+        OnGetCellText = zgTenderSelectGetCellText
+        OnSetCellText = zgTenderSelectSetCellText
+        OnCellTextChanged = zgTenderSelectCellTextChanged
+        OnDrawCellText = zgTenderSelectDrawCellText
+        OnShowHint = zgTenderSelectShowHint
+        Align = alClient
+      end
+      object pnlSelectTitle: TPanel
+        Left = 0
+        Top = 0
+        Width = 450
+        Height = 23
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 1
+        object lblTenderList: TLabel
+          Left = 6
+          Top = 4
+          Width = 72
+          Height = 12
+          Caption = #21487#36873#39033#30446#21015#34920
+          Font.Charset = ANSI_CHARSET
+          Font.Color = clBlue
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = []
+          ParentFont = False
+        end
+      end
+    end
+    object pnlDivision: TPanel
+      Left = 450
+      Top = 0
+      Width = 3
+      Height = 461
+      Align = alLeft
+      BevelOuter = bvNone
+      TabOrder = 1
+    end
+    object pnlResult: TPanel
+      Left = 453
+      Top = 0
+      Width = 449
+      Height = 461
+      Align = alClient
+      BevelOuter = bvNone
+      TabOrder = 2
+      object zgResult: TZJGrid
+        Left = 0
+        Top = 23
+        Width = 449
+        Height = 438
+        OptionsEx = []
+        ColCount = 2
+        RowCount = 2
+        ShowGridLine = False
+        DefaultColWidth = 365
+        DefaultFixedColWidth = 25
+        DefaultFixedRowHeight = 22
+        Selection.AlphaBlend = False
+        Selection.TransparentColor = False
+        FrozenCol = 0
+        FrozenRow = 0
+        Align = alClient
+      end
+      object pnlResultTitle: TPanel
+        Left = 0
+        Top = 0
+        Width = 449
+        Height = 23
+        Align = alTop
+        BevelOuter = bvNone
+        TabOrder = 1
+        object lblResultList: TLabel
+          Left = 3
+          Top = 4
+          Width = 72
+          Height = 12
+          Caption = #25152#36873#39033#30446#21015#34920
+          Font.Charset = ANSI_CHARSET
+          Font.Color = clBlue
+          Font.Height = -12
+          Font.Name = #23435#20307
+          Font.Style = []
+          ParentFont = False
+        end
+      end
+    end
+  end
+  object pnlBottom: TPanel
+    Left = 0
+    Top = 461
+    Width = 902
+    Height = 41
+    Align = alBottom
+    BevelOuter = bvNone
+    TabOrder = 1
+    DesignSize = (
+      902
+      41)
+    object btnOk: TButton
+      Left = 731
+      Top = 8
+      Width = 75
+      Height = 25
+      Anchors = [akTop, akRight]
+      Caption = #30830#23450
+      TabOrder = 0
+      OnClick = btnOkClick
+    end
+    object btnCancel: TButton
+      Left = 817
+      Top = 8
+      Width = 75
+      Height = 25
+      Anchors = [akTop, akRight]
+      Caption = #21462#28040
+      ModalResult = 2
+      TabOrder = 1
+    end
+  end
+  object stdTenderSelect: TsdGridTreeDBA
+    Columns = <
+      item
+        Title.Caption = #36873#25321
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taCenter
+        EditType = sgeCheckBox
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        Width = 30
+        ReadOnly = False
+      end
+      item
+        Title.Caption = #21517#31216
+        Title.CaptionAcrossCols = '1'
+        Title.Font.Charset = GB2312_CHARSET
+        Title.Font.Color = clWindowText
+        Title.Font.Height = -12
+        Title.Font.Name = #23435#20307
+        Title.Font.Style = []
+        Alignment = taLeftJustify
+        Font.Charset = GB2312_CHARSET
+        Font.Color = clWindowText
+        Font.Height = -12
+        Font.Name = #23435#20307
+        Font.Style = []
+        FieldName = 'Name'
+        Width = 365
+        ReadOnly = True
+      end>
+    Grid = zgTenderSelect
+    ExtendRowCount = 0
+    Options = [aoAllowEdit]
+    AutoExpand = True
+    TreeCellCol = 2
+    KeyFieldName = 'ID'
+    ParentFieldName = 'ParentID'
+    NextSiblingFieldName = 'NextSiblingID'
+    TreeOptions = []
+    TopLevelBold = True
+    Left = 124
+    Top = 177
+  end
+end

+ 301 - 0
SubTenderGatherGcl/stgGclSelectFileFrm.pas

@@ -0,0 +1,301 @@
+unit stgGclSelectFileFrm;
+
+interface
+
+uses
+  stgGclGatherControl,
+  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
+  Dialogs, StdCtrls, ExtCtrls, sdGridDBA, sdGridTreeDBA, ZJGrid, sdIDTree;
+
+type
+  TstgGclSelectFileForm = class(TForm)
+    pnlGatherFiles: TPanel;
+    pnlSelect: TPanel;
+    zgTenderSelect: TZJGrid;
+    pnlSelectTitle: TPanel;
+    lblTenderList: TLabel;
+    stdTenderSelect: TsdGridTreeDBA;
+    pnlDivision: TPanel;
+    pnlResult: TPanel;
+    zgResult: TZJGrid;
+    pnlResultTitle: TPanel;
+    lblResultList: TLabel;
+    pnlBottom: TPanel;
+    btnOk: TButton;
+    btnCancel: TButton;
+    procedure zgTenderSelectDrawCellText(ACanvas: TCanvas;
+      const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
+      const Text: String; var ADefaultDraw: Boolean);
+    procedure zgTenderSelectShowHint(var HintStr: String;
+      var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
+    procedure zgTenderSelectSetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgTenderSelectGetCellText(Sender: TObject;
+      const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+    procedure zgTenderSelectCellTextChanged(Sender: TObject; Col,
+      Row: Integer);
+    procedure btnOkClick(Sender: TObject);
+  private
+    FSelects: TList;
+
+    procedure AddRows(ANode: TsdIDTreeNode);
+    procedure RemoveRows(ANode: TsdIDTreeNode);
+
+    procedure InitResultGrid;
+    procedure AssignResultGrid;
+    procedure AssignResult;
+    function GetSelectCount: Integer;
+  public
+    constructor Create(AGatherControl: TstgGclGatherControl);
+    destructor Destroy; override;
+
+    procedure AssignSelect(AGatherControl: TstgGclGatherControl);
+    property SelectCount: Integer read GetSelectCount;
+  end;
+
+function SelectFileForSubTenderGclGather(AGatherControl: TstgGclGatherControl): Boolean;
+
+implementation
+
+uses MainFrm, Globals, UtilMethods;
+
+{$R *.dfm}
+
+function SelectFileForSubTenderGclGather(AGatherControl: TstgGclGatherControl): Boolean;
+var
+  vSelectFrm: TstgGclSelectFileForm;
+begin
+  vSelectFrm := TstgGclSelectFileForm.Create(AGatherControl);
+  try
+    Result := vSelectFrm.ShowModal = mrOk;
+    if Result then
+      vSelectFrm.AssignSelect(AGatherControl);
+  finally
+    vSelectFrm.Free;
+  end;
+end;
+
+procedure TstgGclSelectFileForm.zgTenderSelectDrawCellText(ACanvas: TCanvas;
+  const ARect: TRect; const ACoord: TPoint; AGrid: TZJGrid;
+  const Text: String; var ADefaultDraw: Boolean);
+
+  procedure GetBitmap(AImage: TBitmap);
+  begin
+    with stdTenderSelect.IDTree.Items[ACoord.Y - 1] do
+      if Rec.ValueByName('Type').AsInteger = 0 then
+        if Expanded and HasChildren then
+          MainForm.Images.GetBitmap(34, AImage)
+        else
+          MainForm.Images.GetBitmap(34, AImage)
+      else
+        MainForm.Images.GetBitmap(11, AImage);
+  end;
+
+const
+  rIconWidth = 16;
+  rIconHeight = 16;
+var
+  Img: TBitmap;
+  Cell: TZjCell;
+  rImg: TRect;
+begin
+ if (ACoord.X = 2) and (ACoord.Y > zgTenderSelect.FixedRowCount - 1) then
+  begin
+    Cell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
+    Img := TBitmap.Create;
+    try
+      GetBitmap(Img);
+      case Cell.Align of
+        gaTopLeft, gaTopCenter, gaTopRight:
+          rImg := Rect(ARect.Left + 2, ARect.Top, ARect.Left + rIconWidth, ARect.Top + rIconHeight);
+        gaCenterLeft, gaCenterCenter, gaCenterRight:
+          rImg := Rect(ARect.Left + 2, ARect.Top + (ARect.Bottom - ARect.Top - rIconHeight) div 2, ARect.Left + rIconWidth, ARect.Bottom - (ARect.Bottom - ARect.Top - rIconHeight) div 2);
+        gaBottomLeft, gaBottomCenter, gaBottomRight:
+          rImg := Rect(ARect.Left + 2, ARect.Bottom - rIconHeight, ARect.Left + rIconWidth, ARect.Bottom);
+      end;
+      ACanvas.StretchDraw(rImg, Img);
+      WriteText(ACanvas, Rect(ARect.Left + rIconWidth, ARect.Top, ARect.Right, ARect.Bottom)
+        , 2, 2, Text, Cell.Align, False);
+      ADefaultDraw := False;
+    finally
+      Img.Free;
+    end;
+  end;
+end;
+
+procedure TstgGclSelectFileForm.zgTenderSelectShowHint(var HintStr: String;
+  var CanShow: Boolean; var HintInfo: THintInfo; const ACoord: TPoint);
+var
+  vCell: TZjCell;
+  vNode: TsdIDTreeNode;
+  iLevelWidth: Integer;
+  rText: TRect;
+
+  procedure CalcTextRect(var R: TRect);
+  var
+    DC: HDC;
+    iTextHeight: Integer;
+  begin
+    DC := CreateCompatibleDC(0);
+    try
+      SelectObject(DC, vCell.Font.Handle);
+      iTextHeight := DrawText(DC, PChar(vCell.Text), Length(vCell.Text), R, DT_SINGLELINE or DT_VCenter
+        or DT_NOCLIP or DT_CALCRECT);
+    finally
+      DeleteDC(DC);
+    end;
+  end;
+
+begin
+  if ACoord.Y < 1 then Exit;
+
+  vCell := zgTenderSelect.Cells[ACoord.X, ACoord.Y];
+  with HintInfo do
+  begin
+    vNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if not Assigned(vNode) then Exit;
+    iLevelWidth := (vNode.Level + 1) * 20 + 16;
+
+    rText := CursorRect;
+    CalcTextRect(rText);
+    if (rText.Right - rText.Left + iLevelWidth > CursorRect.Right - CursorRect.Left) or
+      (rText.Right > ClientWidth) then
+    begin
+      CanShow := True;
+      HintStr := vCell.Text;
+      GetCursorPos(HintPos);
+    end;
+  end;
+end;
+
+procedure TstgGclSelectFileForm.zgTenderSelectSetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  stnNode: TsdIDTreeNode;
+begin
+  if ACoord.X = 1 then
+  begin
+    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if Value = 'True' then
+      AddRows(stnNode)
+    else
+      RemoveRows(stnNode);
+    AssignResult;
+  end;
+end;
+
+procedure TstgGclSelectFileForm.zgTenderSelectGetCellText(Sender: TObject;
+  const ACoord: TPoint; var Value: String; DisplayText: Boolean);
+var
+  stnNode: TsdIDTreeNode;
+begin
+  if ACoord.X = 1 then
+  begin
+    stnNode := stdTenderSelect.IDTree.Items[ACoord.Y - 1];
+    if Assigned(stnNode) and (FSelects.IndexOf(Pointer(stnNode.ID)) > -1) then
+      Value := 'True';
+  end;
+end;
+
+procedure TstgGclSelectFileForm.zgTenderSelectCellTextChanged(Sender: TObject;
+  Col, Row: Integer);
+begin
+  if (Col = 1) then
+    zgTenderSelect.InvalidateCol(1);
+end;
+
+procedure TstgGclSelectFileForm.AddRows(ANode: TsdIDTreeNode);
+var
+  iChild: Integer;
+begin
+  if not Assigned(ANode) then Exit;
+
+  if FSelects.IndexOf(Pointer(ANode.ID)) = -1 then
+    FSelects.Add(Pointer(ANode.ID));
+
+  if ANode.HasChildren then
+    for iChild := 0 to ANode.ChildCount - 1 do
+      AddRows(ANode.ChildNodes[iChild]);
+end;
+
+procedure TstgGclSelectFileForm.RemoveRows(ANode: TsdIDTreeNode);
+var
+  iChild: Integer;
+begin
+  if not Assigned(ANode) then Exit;
+
+  if FSelects.IndexOf(Pointer(ANode.ID)) > -1 then
+    FSelects.Remove(Pointer(ANode.ID));
+
+  if ANode.HasChildren then
+    for iChild := 0 to ANode.ChildCount - 1 do
+      RemoveRows(ANode.ChildNodes[iChild]);
+end;
+
+procedure TstgGclSelectFileForm.InitResultGrid;
+begin
+  zgResult.ColCount := 2;
+  zgResult.RowCount := 1;
+  zgResult.Cells[1, 0].Text := '所选项目';
+  zgResult.ColWidths[1] := 365;
+end;
+
+procedure TstgGclSelectFileForm.AssignResultGrid;
+var
+  i, iID: Integer;
+  vNode: TsdIDTreeNode;
+begin
+  for i := 0 to FSelects.Count - 1 do
+  begin
+    iID := Integer(FSelects.Items[i]);
+    vNode := stdTenderSelect.IDTree.FindNode(iID);
+    if vNode.Rec.ValueByName('Type').AsInteger = 1 then
+    begin
+      zgResult.RowCount := zgResult.RowCount + 1;
+      zgResult.Cells[1, zgResult.RowCount - 1].Text := vNode.Rec.ValueByName('Name').AsString;
+      zgResult.Cells[1, zgResult.RowCount - 1].Align := gaCenterLeft;
+      zgResult.Rows[zgResult.RowCount - 1].Data := vNode;
+    end;
+  end;
+end;
+
+procedure TstgGclSelectFileForm.AssignSelect(AGatherControl: TstgGclGatherControl);
+begin
+  AGatherControl.Projects.Assign(FSelects);
+end;
+
+constructor TstgGclSelectFileForm.Create(AGatherControl: TstgGclGatherControl);
+begin
+  inherited Create(nil);
+  stdTenderSelect.DataView := ProjectManager.sdvProjectsSpare;
+  FSelects := TList.Create;
+  FSelects.Assign(AGatherControl.Projects);
+  InitResultGrid;
+end;
+
+destructor TstgGclSelectFileForm.Destroy;
+begin
+  FSelects.Free;
+  inherited;
+end;
+
+procedure TstgGclSelectFileForm.AssignResult;
+begin
+  InitResultGrid;
+  AssignResultGrid;
+end;
+
+procedure TstgGclSelectFileForm.btnOkClick(Sender: TObject);
+begin
+  if SelectCount = 0 then
+    WarningMessage('请选择需要汇总的分包标段。', Handle)
+  else
+    ModalResult := mrOk;
+end;
+
+function TstgGclSelectFileForm.GetSelectCount: Integer;
+begin
+  Result := zgResult.RowCount - zgResult.FixedRowCount;
+end;
+
+end.

+ 205 - 0
SubTenderGatherGcl/stgGclSubGatherFile.pas

@@ -0,0 +1,205 @@
+unit stgGclSubGatherFile;
+// µ¼Èëµ¼³ö»ã×ܽá¹û
+
+interface
+
+uses
+  stgGclSubGatherFileDm, ADODB, sdDB, stgGclGatherDm, SysUtils, StageDm, mDataRecord;
+
+type
+  TstgGclSubGatherFileHelper = class
+  private
+    FTempFile: string;
+    FConnection: TADOConnection;
+    FGatherData: TstgGclSubGatherData;
+  public
+    constructor Create;
+    destructor Destroy; override;
+
+    procedure Open(const AFileName: string);
+    procedure Close;
+    procedure SaveTo(const AFileName: string);
+
+    property Connection: TADOConnection read FConnection;
+    property GatherData: TstgGclSubGatherData read FGatherData;
+  end;
+
+  TstgGclSubGatherFileExportor = class(TstgGclSubGatherFileHelper)
+  private
+    procedure LoadMemoryRecord(ARec: TsdDataRecord);
+    procedure LoadMemoryGatherData(AGatherData: TstgGclGatherData);
+  public
+    procedure ExportGatherDataTo(AGatherData: TstgGclGatherData; const AFileName: string);
+  end;
+
+  TstgGclSubGatherFileImportor = class(TstgGclSubGatherFileHelper)
+  private
+    procedure ClearOldData(AStageData: TStageData);
+    procedure ImportGatherData(AStageData: TStageData);
+  public
+    procedure ImportGatherDataTo(AStageData: TStageData; const AFileName: string);
+  end;
+
+implementation
+
+
+uses
+  UtilMethods, ZhAPI, Connections, stgGclTables, ScAutoUpdateUnit, Math;
+
+{ TstgGclSubGatherFileExportor }
+
+procedure TstgGclSubGatherFileExportor.ExportGatherDataTo(
+  AGatherData: TstgGclGatherData; const AFileName: string);
+begin
+  Open(GetEmptyDataBaseFileName);
+  try
+    LoadMemoryGatherData(AGatherData);
+  finally                             
+    SaveTo(AFileName);
+  end;
+end;
+
+procedure TstgGclSubGatherFileExportor.LoadMemoryRecord(ARec: TsdDataRecord);
+var
+  vRec: TsdDataRecord;
+begin
+  vRec := GatherData.sddBills.Add;
+  vRec.ValueByName('B_Code').AsString := ARec.ValueByName('B_Code').AsString;
+  vRec.ValueByName('Name').AsString := ARec.ValueByName('Name').AsString;
+  vRec.ValueByName('Units').AsString := ARec.ValueByName('Units').AsString;
+  vRec.ValueByName('Price').AsFloat := ARec.ValueByName('Price').AsFloat;
+  vRec.ValueByName('DealQuantity').AsFloat := ARec.ValueByName('DealQuantity').AsFloat;
+  vRec.ValueByName('DealTotalPrice').AsFloat := ARec.ValueByName('DealTotalPrice').AsFloat;
+  vRec.ValueByName('QcQuantity').AsFloat := ARec.ValueByName('QcQuantity').AsFloat;
+  vRec.ValueByName('QcTotalPrice').AsFloat := ARec.ValueByName('QcTotalPrice').AsFloat;
+  vRec.ValueByName('QcBGLCode').AsString := ARec.ValueByName('QcBGLCode').AsString;
+  vRec.ValueByName('QcBGLNum').AsString := ARec.ValueByName('QcBGLNum').AsString;
+end;
+
+procedure TstgGclSubGatherFileExportor.LoadMemoryGatherData(
+  AGatherData: TstgGclGatherData);
+var
+  i: Integer;
+  vRec: TsdDataRecord;
+begin
+  GatherData.sddBills.BeginUpdate;
+  try
+    for i := 0 to AGatherData.sddGatherGcl.RecordCount - 1 do
+    begin
+      vRec := AGatherData.sddGatherGcl.Records[i];
+      LoadMemoryRecord(vRec);
+    end;
+  finally
+    GatherData.sddBills.EndUpdate;
+  end;
+end;
+
+{ TstgGclSubGatherFileHelper }
+
+procedure TstgGclSubGatherFileHelper.Close;
+begin
+  FConnection.Close;
+  if FileExists(FTempFile) then
+    DeleteFile(FTempFile);
+end;
+
+constructor TstgGclSubGatherFileHelper.Create;
+begin
+  FConnection := TADOConnection.Create(nil);
+  FConnection.LoginPrompt := False;
+  FGatherData := TstgGclSubGatherData.Create(nil);
+end;
+
+destructor TstgGclSubGatherFileHelper.Destroy;
+begin
+  Close;
+  FGatherData.Free;
+  FConnection.Free;
+  inherited;
+end;
+
+procedure TstgGclSubGatherFileHelper.Open(const AFileName: string);
+
+  procedure UpdateDataTables;
+  var
+    Updater: TScUpdater;
+  begin
+    Updater := TScUpdater.Create;
+    try
+      Updater.ForceUpdate := True;
+      Updater.Open('', FConnection, '', '');
+      Updater.AddTableDef(sStgGclBills, @tdStgGclBills, Length(tdStgGclBills), False, False);
+      Updater.ExcuteUpdate;
+    finally
+      Updater.Free;
+    end;
+  end;
+
+begin
+  FTempFile := GetTempFileName;
+  CopyFileOrFolder(AFileName, FTempFile);
+  FConnection.ConnectionString := Format(SAdoConnectStr, [FTempFile]);
+  FConnection.Open;
+  UpdateDataTables;
+  GatherData.Open(FConnection);
+end;
+
+procedure TstgGclSubGatherFileHelper.SaveTo(const AFileName: string);
+begin
+  FGatherData.Save;
+  CopyFileOrFolder(FTempFile, AFileName);
+end;
+
+{ TstgGclSubGatherFileImportor }
+
+procedure TstgGclSubGatherFileImportor.ClearOldData(AStageData: TStageData);
+var
+  i: Integer;
+  vRec: TStageRecord;
+begin
+  for i := 0 to AStageData.sddStage.RecordCount - 1 do
+  begin
+    vRec := TStageRecord(AStageData.sddStage.Records[i]);
+    vRec.DealQuantity.AsFloat := 0;
+    vRec.DealTotalPrice.AsFloat := 0;
+    vRec.DealFlag.AsInteger := 0;
+    vRec.DealFormula.AsString := '';
+    vRec.EndDealQuantity.AsFloat := vRec.PreDealQuantity.AsFloat;
+    vRec.EndDealTotalPrice.AsFloat := vRec.PreDealTotalPrice.AsFloat;
+  end;
+end;
+
+procedure TstgGclSubGatherFileImportor.ImportGatherData(
+  AStageData: TStageData);
+var
+  i: Integer;
+  vOrgRec: TsdDataRecord;
+  vStageRec: TStageRecord;
+begin
+  for i := 0 to GatherData.sddBills.RecordCount - 1 do
+  begin
+    vOrgRec := GatherData.sddBills.Records[i];
+    if vOrgRec.ValueByName('IsSumBase').AsBoolean and vOrgRec.ValueByName('IsLeaf').AsBoolean then
+    begin
+      vStageRec := AStageData.StageRecordWithAdd(vOrgRec.ValueByName('ID').AsInteger);
+      vStageRec.DealQuantity.AsFloat := vOrgRec.ValueByName('DealQuantity').AsFloat;
+    end;
+  end;
+end;
+
+procedure TstgGclSubGatherFileImportor.ImportGatherDataTo(
+  AStageData: TStageData; const AFileName: string);
+begin
+  Open(AFileName);
+  AStageData.sddStage.BeginUpdate;
+  AStageData.BeforeBatchOperation;
+  try
+    ClearOldData(AStageData);
+    ImportGatherData(AStageData);
+  finally
+    AStageData.AfterBatchOperation;
+    AStageData.sddStage.EndUpdate;
+  end;
+end;
+
+end.

+ 53 - 0
SubTenderGatherGcl/stgGclSubGatherFileDm.dfm

@@ -0,0 +1,53 @@
+object stgGclSubGatherData: TstgGclSubGatherData
+  OldCreateOrder = False
+  Left = 27
+  Top = 244
+  Height = 202
+  Width = 186
+  object sdpBills: TsdADOProvider
+    TableName = 'Bills'
+    Left = 35
+    Top = 32
+  end
+  object sddBills: TsdDataSet
+    Active = False
+    Filtered = False
+    Provider = sdpBills
+    Left = 35
+    Top = 96
+    FieldListData = {
+      0101044E616D650606425F436F6465094669656C644E616D650606425F436F64
+      650844617461547970650218084461746153697A6502320549734B6579080F4E
+      65656450726F636573734E616D650909507265636973696F6E02000453697A65
+      02000001044E616D6506044E616D65094669656C644E616D6506044E616D6508
+      44617461547970650218084461746153697A6503C8000549734B6579080F4E65
+      656450726F636573734E616D650909507265636973696F6E02000453697A6502
+      000001044E616D650605556E697473094669656C644E616D650605556E697473
+      0844617461547970650218084461746153697A6502140549734B6579080F4E65
+      656450726F636573734E616D650909507265636973696F6E02000453697A6502
+      000001044E616D65060C4465616C5175616E74697479094669656C644E616D65
+      060C4465616C5175616E74697479084461746154797065020608446174615369
+      7A6502080549734B6579080F4E65656450726F636573734E616D650909507265
+      636973696F6E02000453697A6502000001044E616D65060E4465616C546F7461
+      6C5072696365094669656C644E616D65060E4465616C546F74616C5072696365
+      0844617461547970650206084461746153697A6502080549734B6579080F4E65
+      656450726F636573734E616D650909507265636973696F6E02000453697A6502
+      000001044E616D65060A51635175616E74697479094669656C644E616D65060A
+      51635175616E746974790844617461547970650206084461746153697A650208
+      0549734B6579080F4E65656450726F636573734E616D65090950726563697369
+      6F6E02000453697A6502000001044E616D65060C5163546F74616C5072696365
+      094669656C644E616D65060C5163546F74616C50726963650844617461547970
+      650206084461746153697A6502080549734B6579080F4E65656450726F636573
+      734E616D650909507265636973696F6E02000453697A6502000001044E616D65
+      0609516342474C436F6465094669656C644E616D650609516342474C436F6465
+      0844617461547970650218084461746153697A6503FF000549734B6579080F4E
+      65656450726F636573734E616D650909507265636973696F6E02000453697A65
+      02000001044E616D650608516342474C4E756D094669656C644E616D65060851
+      6342474C4E756D0844617461547970650218084461746153697A6503FF000549
+      734B6579080F4E65656450726F636573734E616D650909507265636973696F6E
+      02000453697A6502000001044E616D6506055072696365094669656C644E616D
+      65060550726963650844617461547970650206084461746153697A6502080549
+      734B6579080F4E65656450726F636573734E616D650909507265636973696F6E
+      02000453697A6502000000}
+  end
+end

+ 36 - 0
SubTenderGatherGcl/stgGclSubGatherFileDm.pas

@@ -0,0 +1,36 @@
+unit stgGclSubGatherFileDm;
+// 导入导出汇总结果,连接数据表
+
+interface
+
+uses
+  SysUtils, Classes, sdDB, sdProvider, ADODB, DB;
+
+type
+  TstgGclSubGatherData = class(TDataModule)
+    sdpBills: TsdADOProvider;
+    sddBills: TsdDataSet;
+  private
+  public
+    procedure Open(AConnection: TADOConnection);
+    procedure Save;
+  end;
+
+implementation
+
+{$R *.dfm}
+
+{ TstgSubGatherData }
+
+procedure TstgGclSubGatherData.Open(AConnection: TADOConnection);
+begin
+  sdpBills.Connection := AConnection;
+  sddBills.Open;
+end;
+
+procedure TstgGclSubGatherData.Save;
+begin
+  sddBills.Save;
+end;
+
+end.

+ 25 - 0
SubTenderGatherGcl/stgGclTables.pas

@@ -0,0 +1,25 @@
+unit stgGclTables;
+
+interface
+
+uses
+  DataBaseTables;
+
+const
+  sStgGclBills = 'Bills';
+  tdStgGclBills : array [0..9] of TScFieldDef = (
+    (FieldName: 'B_Code'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Name'; FieldType: ftString; Size: 200; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Units'; FieldType: ftString; Size: 50; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'Price'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'DealQuantity'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'DealTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcQuantity'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcTotalPrice'; FieldType: ftDouble; Size: 0; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcBGLCode'; FieldType: ftString; Size: 255; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False),
+    (FieldName: 'QcBGLNum'; FieldType: ftString; Size: 255; Precision: 0; NotNull: False; PrimaryKey: False; ForceUpdate: False)
+  );
+
+implementation
+
+end.