unit ReportManager;

interface

uses
  rmGclBillsBGDm, rmGclBillsCompareDm, rmGridHeaderDm, rmFxBillsCompareDm,
  rmBGLExecutionDm, rmGclBillsAddDm, rmFxBillsAddDm, rmBillsGatherDm,
  rmGclBillsAuditCompareDm, rmDealInfosDm, rmXmjBGLDetailDm,
  rmOtherReport1Dm, rmGcl_XmjBillsDm, rmGclBillsPlaneDm,
  rmMentalCustomized1Dm, rmCustomized2Dm, rmHaBaiCustomizedDm,
  rmWeiWuZjjlGatherDm,
  rmTestFrm,
  ReportInteractInfo,
  Classes, ScFileArchiver, IniFiles, Graphics, DB, ProjectData,
  sdDB, ADODB;

type
  TTemplateNode = class
  private
    FFileName: string;

    FPropertyStr: String;

    FTemplateName: string;
    FClassNum: string;
    FClassName: string;
    FSubClassNum: string;
    FSubClassName: string;
    FHasPriceChange: Boolean;
    FIsMulti: Boolean;
    FIsExtra: Boolean;
    FInteractFlag: Integer;
    FInteractSubFlag: Integer;

    FInteractInfo: TInteractInfo;
    FDataPrepareFlag: Integer;
    FDataBaseFlag: Integer;
    FSelfFormat: Integer;

    procedure ReadPropertyStr;
    procedure AnalyzePropertyStr;
    procedure LoadReportInteract;

    procedure LoadTemplateProperties;
    function GetMultiFileNames(APhaseIndex: Integer): string;
  public
    constructor Create(AFileName: string);
    destructor Destroy; override;

    procedure RefreshTemplateProperties;

    property FileName: string read FFileName write FFileName;

    property TemplateName: string read FTemplateName;
    property ClassNum: string read FClassNum;
    property ClassName: string read FClassName;
    property SubClassNum: string read FSubClassNum;
    property SubClassName: string read FSubClassName;
    property HasPriceChange: Boolean read FHasPriceChange;
    // 多表筛选
    property IsMulti: Boolean read FIsMulti;
    property MultiFileNames[APhaseIndex: Integer]: string read GetMultiFileNames;
    // 含附加
    property IsExtra: Boolean read FIsExtra;
    // 交互表 -- 部分数据需要用户选择后存入指定的数据表中
    property InteractFlag: Integer read FInteractFlag;
    property InteractSubFlag: Integer read FInteractSubFlag;

    // 数据准备类型
    property DataPrepareFlag: Integer read FDataPrepareFlag;
    // 链接数据库
    property DataBaseFlag: Integer read FDataBaseFlag;

    // 自主格式
    property SelfFormat: Integer read FSelfFormat;

    property InteractInfo: TInteractInfo read FInteractInfo;
  end;

  PTemplateNode = ^TTemplateNode;

  TTemplateManager = class
  private
    FTemplateList: TList;
    FTemplateNode: TTemplateNode;

    procedure Clear;
    function GetCount: Integer;
    function GetTemplate(AIndex: Integer): TTemplateNode;
  public
    constructor Create;
    destructor Destroy; override;
    procedure RefreshTemplates;
    procedure LoadReportTemplates(const sTemplateDir: String);

    function AddReportTemplate(const AFileName: string): TTemplateNode;
    procedure DeleteReportTemplate(ANode: TTemplateNode);

    function FindTemplate(const AFileName: string): TTemplateNode;

    property Count: Integer read GetCount;
    property Template[AIndex: Integer]: TTemplateNode read GetTemplate;

    property Current: TTemplateNode read FTemplateNode write FTemplateNode;
  end;

  TReportConfig = class
  private
    FIniFile: TIniFile;

    FLeftEdge: Integer;
    FRightEdge: Integer;
    FDownEdge: Integer;
    FUpEdge: Integer;

    FContentIsNarrow: Boolean;
    FRepCellVerLine: Boolean;
    FRepCellHorLine: Boolean;
    FRepBorderUnderLine: Boolean;
    FAutoRetLine: Boolean;
    FRepBorderVerLine: Boolean;
    FBorderLine: Integer;
    FReportCellLine: Double;
    FPageSize: string;
    FGridHeaderFont: TFont;
    FHeaderFont: TFont;
    FTitleFont: TFont;
    FColumnFont: TFont;
    FGatherFont: TFont;
    FContentFont: TFont;
    FGatherLevel: Integer;
    FGclCompare: Integer;
    FXmjCompare: Integer;

    procedure LoadPaperSettings;
    procedure LoadPageSettings;
    procedure LoadGatherSettings;

    procedure SavePaperSettings;
    procedure SavePageSettings;
    procedure SaveGatherSettings;

    function GetBorderUnderLineWidth: Integer;
    function GetBorderVerLineWidth: Integer;
    function GetCellHorLineWidth: Double;
    function GetCellVerLineWidth: Double;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Load;
    procedure Save;

    //------------- 纸张 -------------
    // Size
    property PageSize: string read FPageSize write FPageSize;
    // 上边距
    property UpEdge: Integer read FUpEdge write FUpEdge;
    // 下边距
    property DownEdge: Integer read FDownEdge write FDownEdge;
    // 左边距
    property LeftEdge: Integer read FLeftEdge write FLeftEdge;
    // 右边距
    property RightEdge: Integer read FRightEdge write FRightEdge;

    //------------- 页面 -------------
    {字体}
    // 表标题
    property TitleFont: TFont read FTitleFont write FTitleFont;
    // 列标题
    property ColumnFont: TFont read FColumnFont write FColumnFont;
    // 表正文
    property ContentFont: TFont read FContentFont write FContentFont;
    // 表合计
    property GatherFont: TFont read FGatherFont write FGatherFont;
    // 表眉/表脚
    property GridHeaderFont: TFont read FGridHeaderFont write FGridHeaderFont;
    // 页眉/页脚
    property HeaderFont: TFont read FHeaderFont write FHeaderFont;
    {其他}
    // 表格线粗
    property ReportCellLine: Double read FReportCellLine write FReportCellLine;
    // 边框线粗
    property BorderLine: Integer read FBorderLine write FBorderLine;
    // 表格边框横线
    property RepBorderUnderLine: Boolean read FRepBorderUnderLine write FRepBorderUnderLine;
    property BorderUnderLineWidth: Integer read GetBorderUnderLineWidth;
    // 表格边框竖线
    property RepBorderVerLine: Boolean read FRepBorderVerLine write FRepBorderVerLine;
    property BorderVerLineWidth: Integer read GetBorderVerLineWidth;
    // 报表表格横线
    property RepCellHorLine: Boolean read FRepCellHorLine write FRepCellHorLine;
    property CellHorLineWidth: Double read GetCellHorLineWidth;
    // 报表表格竖线
    property RepCellVerLine: Boolean read FRepCellVerLine write FRepCellVerLine;
    property CellVerLineWidth: Double read GetCellVerLineWidth;
    // 自动换行打印
    property AutoRetLine: Boolean read FAutoRetLine write FAutoRetLine;
    // 报表内容窄体
    property ContentIsNarrow: Boolean read FContentIsNarrow write FContentIsNarrow;

    //------------- 汇总 -------------
    property GatherLevel: Integer read FGatherLevel write FGatherLevel;
    property XmjCompare: Integer read FXmjCompare write FXmjCompare;
    property GclCompare: Integer read FGclCompare write FGclCompare;
  end;

  TMemoryReportManager = class
  private
    FrmGridHeaderData: TrmGridHeaderData;
    FrmGclBillsBGData: TrmGclBillsBGData;
    FrmGclBillsCompareData: TrmGclBillsCompareData;
    FrmFxBillsCompareData: TrmFxBillsCompareData;
    FrmBGLExecutionData: TrmBGLExecutionData;
    FrmGclBillsAddData: TrmGclBillsAddData;
    FrmFxBillsAddData: TrmFxBillsAddData;
    FrmBillsGatherData: TrmBillsGatherData;
    FrmGclBillsAuditCompareData: TrmGclBillsAuditCompareData;
    FrmDealInfosData: TrmDealInfosData;
    FrmXmjBGLDetailData: TrmXmjBGLDetailData;
    FrmOtherReport1Data: TrmOtherReport1Data;
    FrmGcl_XmjBillsData: TrmGcl_XmjBillsData;
    FrmGclBillsPlaneData: TrmGclBillsPlaneData;
    FrmMentalCustomized1Data: TrmMentalCustomized1Data;
    FrmCustomized2Data: TrmCustomized2Data;
    FrmHaBaiCustomizedData: TrmHaBaiCustomizedData;
    FrmWeiWuZjjlGatherData: TrmWeiWuZjjlGatherData;

    FMemoryQuery: TADOQuery;

    FProjectID: Integer;
    FTenders: TList;          // 仅储存选择汇总标段后，剔除项目分类节点的数据，为方便汇总做一次中转
    FProjects: TList;         // 普通汇总
    FE_PCDProjects: TList;    // 须选择初步设计，施工图设计
    FE_AProjects: TList;      // 须选择批准概算
    FDealProjects: TList;     // 可选择多合同项目

    function OpenProject(ARec: TsdDataRecord): TProjectData;
    procedure FreeProject(AProjectData: TProjectData);

    function SelectProjectID: Integer;
    function SelectProjectIDs(AProjects: TList; ADataSetID: Integer): Boolean;
    procedure GenerateTenders(AProjects: TList);

    function SelectSourceAndAssignData(ADataSetID: Integer;
      AProjectData: TProjectData): TDataSet;
    function SelectProjectsAndAssignData(ADataSetID: Integer): TDataSet;
  public
    constructor Create;
    destructor Destroy; override;

    function GetMemoryDataSet(ADataSetID: Integer;
      AProjectData: TProjectData): TDataSet;
    function GetSqlResultDataSet(const ASql: string; AProjectData: TProjectData): TDataSet;
  end;

implementation

uses
  SysUtils, ZhAPI, UtilMethods, Globals, ProjectManagerDm,
  rmSelectProjectFrm, Controls;

{ TTemplateNode }

procedure TTemplateNode.AnalyzePropertyStr;
var
  sgs: TStrings;
  I: Integer;
begin
  if FPropertyStr <> '' then
  begin
    sgs := TStringList.Create;
    try
      sgs.Text := FPropertyStr;
      for I := 0 to sgs.Count - 1 do
      begin
        if SameText(sgs.Names[I], '名称') then
          FTemplateName := sgs.Values[sgs.Names[I]]
        else if SameText(sgs.Names[I], '分类') then
          FClassNum := sgs.Values[sgs.Names[I]]
        else if SameText(sgs.Names[I], '分类名称') then
          FClassName := sgs.Values[sgs.Names[I]]
        else if SameText(sgs.Names[I], '子分类') then
          FSubClassNum := sgs.Values[sgs.Names[I]]
        else if SameText(sgs.Names[I], '子分类名称') then
          FSubClassName := sgs.Values[sgs.Names[I]]
        else if SameText(sgs.Names[I], '含单价变更') then
          FHasPriceChange := SameText(sgs.Values[sgs.Names[I]], '是')
        else if SameText(sgs.Names[I], '多表筛选') then
          FIsMulti := SameText(sgs.Values[sgs.Names[I]], '是')
        else if SameText(sgs.Names[I], '含附加') then
          FIsExtra := SameText(sgs.Values[sgs.Names[I]], '是')
        else if SameText(sgs.Names[I], '交互类型') then
          FInteractFlag := StrToIntDef(sgs.Values[sgs.Names[I]], 0)
        else if SameText(sgs.Names[I], '交互子类型') then
          FInteractSubFlag := StrToIntDef(sgs.Values[sgs.Names[I]], 0)
        else if SameText(sgs.Names[I], '数据准备') then
          FDataPrepareFlag := StrToIntDef(sgs.Values[sgs.Names[I]], 0)
        else if SameText(sgs.Names[I], '数据库') then
          FDataBaseFlag := StrToIntDef(sgs.Values[sgs.Names[I]], 0)
        else if SameText(sgs.Names[I], '自主格式') then
          FSelfFormat := StrToIntDef(sgs.Values[sgs.Names[I]], 0);
      end;
    finally
      sgs.Free;
    end;
  end;
end;

constructor TTemplateNode.Create(AFileName: string);
begin
  FFileName := AFileName;
  FInteractFlag := 0;
  FInteractSubFlag := 0;
  FDataPrepareFlag := 0;
  FDataBaseFlag := 0;
  FSelfFormat := 0;
  LoadTemplateProperties;
end;

destructor TTemplateNode.Destroy;
begin
  if Assigned(FInteractInfo) then
    FInteractInfo.Free;
  inherited;
end;

function TTemplateNode.GetMultiFileNames(APhaseIndex: Integer): string;
var
  sName, sPath: string;
begin
  sPath := ExtractFilePath(FFileName);
  sName := ExtractSimpleFileName(FFileName);
  Result := Format('%s%s\%s_%d.srt', [sPath, sName, sName, APhaseIndex]);
end;

procedure TTemplateNode.LoadReportInteract;
begin
  if Assigned(FInteractInfo) then
    FInteractInfo.LoadXmlFromStream
  else
    FInteractInfo := TInteractInfo.Create(FileName);
end;

procedure TTemplateNode.LoadTemplateProperties;
begin
  try
    ReadPropertyStr;
    AnalyzePropertyStr;
    if FIsExtra then
      LoadReportInteract;
  except
    on E: Exception do
    begin
      TipMessage(Format('报表文件[%s]无法打开，错误信息：'#13#10'%s.'#13#10 +
        '请与纵横软件客服中心联系：(0756)3850888。', [FFileName, E.Message]));
    end;
  end;
end;

procedure TTemplateNode.ReadPropertyStr;
var
  vStream: TFileStream;
  FileHead: TScFileHead;
begin
  vStream := TFileStream.Create(FFileName, fmOpenRead);
  try
    vStream.Seek($00, soFromBeginning);
    vStream.Read(FileHead, Sizeof(TScFileHead));
    if FileHead.ReportProperties[0] <> #0 then
      SetString(FPropertyStr, FileHead.ReportProperties, 256);
  finally
    vStream.Free;
  end;
end;

procedure TTemplateNode.RefreshTemplateProperties;
begin
  FInteractFlag := 0;
  FInteractSubFlag := 0;
  FDataPrepareFlag := 0;
  FDataBaseFlag := 0;
  FSelfFormat := 0;
  LoadTemplateProperties;
end;

{ TTemplateManager }

function TTemplateManager.AddReportTemplate(const AFileName: string): TTemplateNode;
begin
  Result := TTemplateNode.Create(AFileName);
  FTemplateList.Add(Result);
end;

procedure TTemplateManager.Clear;
begin
  ClearObjects(FTemplateList);
end;

constructor TTemplateManager.Create;
begin
  FTemplateList := TList.Create;
  LoadReportTemplates(GetAppFilePath + 'ReportTemplates');
end;

procedure TTemplateManager.DeleteReportTemplate(ANode: TTemplateNode);
begin
  FTemplateList.Remove(ANode);
  ANode.Free;
end;

destructor TTemplateManager.Destroy;
begin
  Clear;
  FTemplateList.Free;
  inherited;
end;

function TTemplateManager.FindTemplate(
  const AFileName: string): TTemplateNode;
var
  iTemplate: Integer;
  vTemplate: TTemplateNode;
begin
  Result := nil;
  for iTemplate := 0 to FTemplateList.Count - 1 do
  begin
    vTemplate := Template[iTemplate];
    if vTemplate.FileName = AFileName then
    begin
      Result := vTemplate;
      Break;
    end;
  end;
end;

function TTemplateManager.GetCount: Integer;
begin
  Result := FTemplateList.Count;
end;

function TTemplateManager.GetTemplate(AIndex: Integer): TTemplateNode;
begin
  Result := TTemplateNode(FTemplateList.Items[AIndex]);
end;

procedure TTemplateManager.LoadReportTemplates(const sTemplateDir: String);
var
  sFiles: TStringList;
  I: Integer;
begin
  Clear;
  sFiles := TStringList.Create;
  try
    FilterFiles(sTemplateDir, '.srt', sFiles);
    for I := 0 to sFiles.Count - 1 do
      AddReportTemplate(sTemplateDir + '\' + sFiles[I]);
  finally
    sFiles.Free;
  end;
end;

procedure TTemplateManager.RefreshTemplates;
begin
  LoadReportTemplates(GetAppFilePath + 'ReportTemplates');
end;

{ TReportConfig }

constructor TReportConfig.Create;
begin
  inherited Create;
  FTitleFont := TFont.Create;
  FColumnFont := TFont.Create;
  FContentFont := TFont.Create;
  FGatherFont := TFont.Create;
  FGridHeaderFont := TFont.Create;
  FHeaderFont := TFont.Create;
  Load;
end;

destructor TReportConfig.Destroy;
begin
  Save;
  FHeaderFont.Free;
  FGridHeaderFont.Free;
  FGatherFont.Free;
  FContentFont.Free;
  FColumnFont.Free;
  FTitleFont.Free;
  inherited;
end;

function TReportConfig.GetBorderUnderLineWidth: Integer;
begin
  Result := 0;
  if RepBorderUnderLine then
    Result := BorderLine;
end;

function TReportConfig.GetBorderVerLineWidth: Integer;
begin
  Result := 0;
  if RepBorderVerLine then
    Result := BorderLine;
end;

function TReportConfig.GetCellHorLineWidth: Double;
begin
  Result := 0;
  if RepCellHorLine then
    Result := ReportCellLine;
end;

function TReportConfig.GetCellVerLineWidth: Double;
begin
  Result := 0;
  if RepCellVerLine then
    Result := ReportCellLine;
end;

procedure TReportConfig.Load;
begin
  try
    FIniFile := TIniFile.Create(GetAppFilePath + 'Report.ini');
    LoadPaperSettings;
    LoadPageSettings;
    LoadGatherSettings;
  finally
    FIniFile.Free;
  end;
end;

procedure TReportConfig.LoadGatherSettings;
begin
  FGatherLevel := FIniFile.ReadInteger('汇总', '层次', 5);
  FXmjCompare := FIniFile.ReadInteger('汇总', '项目节规则', 0);
  FGclCompare := FIniFile.ReadInteger('汇总', '清单规则', 0);
end;

procedure TReportConfig.LoadPageSettings;

  procedure LoadFont(const AFontName: string; AFont: TFont);
  begin
    AFont.Name := FIniFile.ReadString('页面', AFontName + '_字体', 'SmartSumSun');
    AFont.Size := FIniFile.ReadInteger('页面', AFontName + '_字体大小', 9);
    if FIniFile.ReadBool('页面', AFontName + '_字体粗', False) then
      AFont.Style := AFont.Style + [fsBold]
    else
     AFont.Style := AFont.Style - [fsBold];
    if FIniFile.ReadBool('页面', AFontName + '_字体斜', False) then
      AFont.Style := AFont.Style + [fsItalic]
    else
     AFont.Style := AFont.Style - [fsItalic];
    if FIniFile.ReadBool('页面', AFontName + '_字体下划线', False) then
      AFont.Style := AFont.Style + [fsUnderline]
    else
      AFont.Style := AFont.Style - [fsUnderline];
    //AFont.Height := FIniFile.ReadInteger('页面', AFontName + '_行高', 9);
  end;

begin
  LoadFont('表标题', TitleFont);
  LoadFont('列标题', ColumnFont);
  LoadFont('表正文', ContentFont);
  LoadFont('表合计', GatherFont);
  LoadFont('表眉/表脚', GridHeaderFont);
  LoadFont('页眉/页脚', HeaderFont);
  FReportCellLine := FIniFile.ReadFloat('页面', '表格线粗', 0.75);
  FBorderLine := FIniFile.ReadInteger('页面', '边框线粗', 2);
  FRepBorderUnderLine := FIniFile.ReadBool('页面', '报表边框横线', True);
  FRepBorderVerLine := FIniFile.ReadBool('页面', '报表边框竖线', False);
  FRepCellHorLine := FIniFile.ReadBool('页面', '报表表格横线', True);
  FRepCellVerLine := FIniFile.ReadBool('页面', '报表表格竖线', True);
  FAutoRetLine := FIniFile.ReadBool('页面', '自动换行打印', False);
  FContentIsNarrow := FIniFile.ReadBool('页面', '内容窄体输出', False);
end;

procedure TReportConfig.LoadPaperSettings;
begin
  FPageSize := FIniFile.ReadString('纸张', '幅面', 'A4');
  FUpEdge := FIniFile.ReadInteger('纸张', '上边距', 12);
  FDownEdge := FIniFile.ReadInteger('纸张', '下边距', 12);
  FLeftEdge := FIniFile.ReadInteger('纸张', '左边距', 12);
  FRightEdge := FIniFile.ReadInteger('纸张', '右边距', 12);
end;

procedure TReportConfig.Save;
begin
  try
    FIniFile := TIniFile.Create(GetAppFilePath + 'Report.ini');
    SavePaperSettings;
    SavePageSettings;
  finally
    FIniFile.Free;
  end;
end;

procedure TReportConfig.SaveGatherSettings;
begin
  FIniFile.WriteInteger('汇总', '层次', FGatherLevel);
  FIniFile.WriteInteger('汇总', '项目节规则', FXmjCompare);
  FIniFile.WriteInteger('汇总', '清单规则', FGclCompare);
end;

procedure TReportConfig.SavePageSettings;

  procedure SaveFont(const AFontName: string; AFont: TFont);
  begin
    FIniFile.WriteString('页面', AFontName + '_字体', AFont.Name);
    FIniFile.WriteInteger('页面', AFontName + '_字体大小', AFont.Size);
    FIniFile.WriteBool('页面', AFontName + '_字体粗', fsBold in AFont.Style);
    FIniFile.WriteBool('页面', AFontName + '_字体斜', fsItalic in AFont.Style);
    FIniFile.WriteBool('页面', AFontName + '_字体下划线', fsUnderline in AFont.Style);
    FIniFile.WriteInteger('页面', AFontName + '_行高', AFont.Height);
  end;

begin
  SaveFont('表标题', TitleFont);
  SaveFont('列标题', ColumnFont);
  SaveFont('表正文', ContentFont);
  SaveFont('表合计', GatherFont);
  SaveFont('表眉/表脚', GridHeaderFont);
  SaveFont('页眉/页脚', HeaderFont);
  FIniFile.WriteFloat('页面', '表格线粗', FReportCellLine);
  FIniFile.WriteInteger('页面', '边框线粗', FBorderLine);
  FIniFile.WriteBool('页面', '报表边框横线', FRepBorderUnderLine);
  FIniFile.WriteBool('页面', '报表边框竖线', FRepBorderVerLine);
  FIniFile.WriteBool('页面', '报表表格横线', FRepCellHorLine);
  FIniFile.WriteBool('页面', '报表表格竖线', FRepCellVerLine);
  FIniFile.WriteBool('页面', '自动换行打印', FAutoRetLine);
  FIniFile.WriteBool('页面', '内容窄体输出', FContentIsNarrow);
end;

procedure TReportConfig.SavePaperSettings;
begin
  FIniFile.WriteString('纸张', '幅面', FPageSize);
  FIniFile.WriteInteger('纸张', '上边距', FUpEdge);
  FIniFile.WriteInteger('纸张', '下边距', FDownEdge);
  FIniFile.WriteInteger('纸张', '左边距', FLeftEdge);
  FIniFile.WriteInteger('纸张', '右边距', FRightEdge);
end;

{ TMemoryReportManager }

constructor TMemoryReportManager.Create;
begin
  FrmGridHeaderData := TrmGridHeaderData.Create(nil);
  FrmGclBillsBGData := TrmGclBillsBGData.Create;
  FrmGclBillsCompareData := TrmGclBillsCompareData.Create;
  FrmFxBillsCompareData :=  TrmFxBillsCompareData.Create(nil);
  FrmBGLExecutionData := TrmBGLExecutionData.Create(nil);
  FrmGclBillsAddData := TrmGclBillsAddData.Create(nil);
  FrmFxBillsAddData := TrmFxBillsAddData.Create(nil);
  FrmBillsGatherData := TrmBillsGatherData.Create(nil);
  FrmGclBillsAuditCompareData := TrmGclBillsAuditCompareData.Create;
  FrmDealInfosData := TrmDealInfosData.Create(nil);
  FrmXmjBGLDetailData := TrmXmjBGLDetailData.Create(nil);
  FrmOtherReport1Data := TrmOtherReport1Data.Create(nil);
  FrmGcl_XmjBillsData := TrmGcl_XmjBillsData.Create(nil);
  FrmGclBillsPlaneData := TrmGclBillsPlaneData.Create(nil);
  FrmMentalCustomized1Data := TrmMentalCustomized1Data.Create(nil);
  FrmCustomized2Data := TrmCustomized2Data.Create(nil);
  FrmHaBaiCustomizedData := TrmHaBaiCustomizedData.Create(nil);
  FrmWeiWuZjjlGatherData := TrmWeiWuZjjlGatherData.Create(nil);

  FMemoryQuery := TADOQuery.Create(nil);

  FProjectID := -1;
  FTenders :=  TList.Create;
  FProjects := TList.Create;
  FE_PCDProjects := TList.Create;
  FE_AProjects := TList.Create;
  FDealProjects := TList.Create;
end;

destructor TMemoryReportManager.Destroy;
begin
  FTenders.Free;
  ClearObjects(FProjects);
  FProjects.Free;
  ClearObjects(FE_PCDProjects);
  FE_PCDProjects.Free;
  ClearObjects(FE_AProjects);
  FE_AProjects.Free;
  ClearObjects(FDealProjects);
  FDealProjects.Free;

  FMemoryQuery.Free;

  FrmWeiWuZjjlGatherData.Free;
  FrmHaBaiCustomizedData.Free;
  FrmCustomized2Data.Free;
  FrmMentalCustomized1Data.Free;
  FrmGclBillsPlaneData.Free;
  FrmGcl_XmjBillsData.Free;
  FrmOtherReport1Data.Free;
  FrmXmjBGLDetailData.Free;
  FrmDealInfosData.Free;
  FrmGclBillsAuditCompareData.Free;
  FrmBillsGatherData.Free;
  FrmFxBillsAddData.Free;
  FrmGclBillsAddData.Free;
  FrmBGLExecutionData.Free;
  FrmFxBillsCompareData.Free;
  FrmGclBillsCompareData.Free;
  FrmGclBillsBGData.Free;
  FrmGridHeaderData.Free;
  inherited;
end;

procedure TMemoryReportManager.FreeProject(AProjectData: TProjectData);
begin
  if not Assigned(OpenProjectManager.FindProjectData(AProjectData.ProjectID)) then
    AProjectData.Free;
end;

procedure TMemoryReportManager.GenerateTenders(AProjects: TList);
var
  i: Integer;
  SelectProject: TSelectProject;
begin
  FTenders.Clear;
  for i := 0 to AProjects.Count - 1 do
  begin
    SelectProject := TSelectProject(AProjects.Items[i]);
    if SelectProject.IsTender then
      FTenders.Add(SelectProject);
  end;
end;

function TMemoryReportManager.GetMemoryDataSet(
  ADataSetID: Integer; AProjectData: TProjectData): TDataSet;
begin
  //ADataSetID := 56;
  {if FrmHaBaiCustomizedData.hbGatherType = hbgt_CS then
    ADataSetID := 51
  else
    ADataSetID := 50;}
  case ADataSetID of
    1: Result := FrmGridHeaderData.AssginData(AProjectData);   // 各表表头
    2: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseGather, rmgtGather); // 工程量清单[本期完成]
    3, 4, 41:
    // 审表01、02, 粤台 账07
       Result := SelectSourceAndAssignData(ADataSetID, AProjectData);
    5: Result := FrmBGLExecutionData.AssignData(AProjectData); // 支表09
    6: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtEndGather, rmgtGather); // 工程量清单[截止本期完成]
    7: Result := FrmGclBillsAddData.AssignData(AProjectData); // 多审表02
    8: Result := FrmFxBillsAddData.AssignData(AProjectData); // 多审表02-1
    9, 10, 11, 12, 13,
    // 决算04, 05, 05-2, 04-1, 02,
       20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
       // 02/03部颁, 07部颁, 08部颁, 09部颁, 11部颁, 12部颁, 16部颁, 17部颁, 18部颁, 19部颁,
       32, 33, 35, 36, 39, 40, 44,
       // 粤竣9, 粤竣06-1, 粤竣04, 粤竣01, 工程量清单进度[甘肃高管局定制], [广东肇庆定制]计量汇总表
       45, 46, 47, 48, 49, 50,
       // 内蒙古哈白定制表(支表2, 支表3, 支表14, 支表3-1, 支表4-1, 会签)
       52, 53, 54, 55:
       // 内蒙古306国道定制(支表2, 支表3, 支表3-1, 支表4-1)
        Result := SelectProjectsAndAssignData(ADataSetID);
    14: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseDeal, rmgtGather); // 工程量清单[本期合同]
    15: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseQc, rmgtGather); // 工程量清单[本期数量变更]
    16: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhasePc, rmgtGather); // 工程量清单[本期单价变更]
    17: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtEndDeal, rmgtGather); // 工程量清单[截止本期合同]
    18: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtEndQc, rmgtGather); // 工程量清单[截止本期数量变更]
    19: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtEndPc, rmgtGather); // 工程量清单[截止本期单价变更]
    30: Result := FrmGclBillsBGData.AssignData(AProjectData, rmtPhaseQc, rmgtFlow);
    31: Result := FrmGclBillsAuditCompareData.AssignData(AProjectData, rmftPhaseGather); // 工程量清单[原报&批复，完成]
    34: Result := FrmXmjBGLDetailData.AssignData(AProjectData); // 变更台账
    37: Result := FrmGcl_XmjBillsData.AssignData(AProjectData, gxtTopGcl); // 工程量清单审核
    38: Result := FrmGclBillsPlaneData.AssignData(AProjectData); // 工程量清单平面表[福建0号台账]
    42: Result := FrmGcl_XmjBillsData.AssignData(AProjectData, gxtFlowGcl); // 云南标准表，台账明细表
    43: Result := FrmGcl_XmjBillsData.AssignData(AProjectData, gxtWithoutXmj); // 云南标准表，单标段清单汇总表
    51: Result := FrmHaBaiCustomizedData.AssignAssistantData(hbgt_CS); //内蒙古哈白、国道306定制表--会签辅助表
    56: Result := FrmWeiWuZjjlGatherData.AssignData(AProjectData); // 甘肃渭武 -- 单标段、计量支付汇总表
  end;
  // For Inner Test
  //if _IsDebugView then
    //ShowTestForm(Result);
end;

function TMemoryReportManager.GetSqlResultDataSet(const ASql: string;
  AProjectData: TProjectData): TDataSet;
begin
  if ASql <> '' then
  begin
    FMemoryQuery.Close;
    FMemoryQuery.Connection := AProjectData.ADOConnection;
    FMemoryQuery.SQL.Clear;
    FMemoryQuery.SQL.Add(ASql);
    FMemoryQuery.Open;
  end;
  Result := FMemoryQuery;
  //ShowTestForm(Result);
end;

function TMemoryReportManager.OpenProject(
  ARec: TsdDataRecord): TProjectData;
begin
  Result := OpenProjectManager.FindProjectData(ARec.ValueByName('ID').AsInteger);
  if not Assigned(Result) then
  begin
    Result := TProjectData.Create;
    Result.OpenForReport(GetMyProjectsFilePath + ARec.ValueByName('FileName').AsString);
  end;
end;

function TMemoryReportManager.SelectProjectID: Integer;
var
  SelectFrm: TProjectSelectForm;
begin
  Result := -1;
  SelectFrm := TProjectSelectForm.Create(False, FProjectID, FProjects);
  //SelectFrm.LoadHistorySelect(FProjectID);
  try
    if SelectFrm.ShowModal = mrOk then
    begin
      SelectFrm.SelectResult(FProjectID);
      Result := FProjectID;
    end;
  finally
    SelectFrm.Free;
  end;
end;

function TMemoryReportManager.SelectProjectIDs(AProjects: TList;
  ADataSetID: Integer): Boolean;
var
  SelectFrm: TProjectSelectForm;
begin
  Result := False;
  SelectFrm := TProjectSelectForm.Create(True, FProjectID, AProjects);
  case ADataSetID of
    13, 33: SelectFrm.MultiSelectType := mstE_PCD;
    20, 36: SelectFrm.MultiSelectType := mstE_A;
    32: SelectFrm.MultiSelectType := mstDeal;
    40: SelectFrm.MultiSelectType := mstMental1;
    else SelectFrm.MultiSelectType := mstCommon;
  end;

  try
    if SelectFrm.ShowModal = mrOk then
    begin
      SelectFrm.SelectResult(AProjects);
      Result := True;
    end;
  finally
    SelectFrm.Free;
  end;
end;

function TMemoryReportManager.SelectProjectsAndAssignData(
  ADataSetID: Integer): TDataSet;
var
  Projects: TList;
begin
  Result := nil;
  case ADataSetID of
    13, 33: Projects := FE_PCDProjects;
    20, 36: Projects := FE_AProjects;
    32: Projects := FDealProjects;
    else Projects := FProjects;
  end;

  if SelectProjectIDs(Projects, ADataSetID) then
  begin
    case ADataSetID of
      9: FrmBillsGatherData.GatherType := bgtFx;
      10: FrmBillsGatherData.GatherType := bgtXmj;
      11: FrmBillsGatherData.GatherType := bgtGcl;
      12: FrmBillsGatherData.GatherType := bgtMultiXmj;
      13: FrmBillsGatherData.GatherType := bgtEstimate;  // 决算02
      20: FrmBillsGatherData.GatherType := bgtEstimate1; // 决算02/03部颁
      21: FrmBillsGatherData.GatherType := bgtFinal07; // 决算07
      22: FrmBillsGatherData.GatherType := bgtFinal08;
      23: FrmBillsGatherData.GatherType := bgtFinal09;
      24: FrmBillsGatherData.GatherType := bgtFinal11;
      25: FrmBillsGatherData.GatherType := bgtFinal12;
      26: FrmBillsGatherData.GatherType := bgtFinal16;
      27: FrmBillsGatherData.GatherType := bgtFinal17;
      28: FrmBillsGatherData.GatherType := bgtFinal18;
      29: FrmBillsGatherData.GatherType := bgtFinal19;
      33: FrmBillsGatherData.GatherType := bgtG_Final06_1;
      35: FrmBillsGatherData.GatherType := bgtG_Final04;
      39: FrmMentalCustomized1Data.MentalType := 0;
      40: FrmMentalCustomized1Data.MentalType := 1;
    end;
    GenerateTenders(Projects);
    case ADataSetID of
      32: Result := FrmDealInfosData.AssignData(FTenders);
      36: Result := FrmOtherReport1Data.AssignData(FTenders);
      39, 40: Result := FrmMentalCustomized1Data.AssignData(FTenders);
      44: Result := FrmCustomized2Data.AssignData(FTenders);
      45: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt2, True);
      46: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3, True);
      47: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt14, True);
      48: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3_1, True);
      49: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt4_1, True);
      50: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt_CS, True);
      52: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt2, False);
      53: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3, False);
      54: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt3_1, False);
      55: Result := FrmHaBaiCustomizedData.AssignData(FTenders, hbgt4_1, False);
      else Result := FrmBillsGatherData.AssignData(FTenders);
    end;
  end;
end;

function TMemoryReportManager.SelectSourceAndAssignData(
  ADataSetID: Integer; AProjectData: TProjectData): TDataSet;
var
  sRec, cRec: TsdDataRecord;
  sProject, cProject: TProjectData;
begin
  sRec := ProjectManager.sddProjectsInfo.FindKey('idxID', SelectProjectID);
  cRec := ProjectManager.sddProjectsInfo.FindKey('idxID', AProjectData.ProjectID);
  if Assigned(sRec) and Assigned(cRec) then
  begin
    sProject := OpenProject(sRec);
    cProject := OpenProject(cRec);
    try
      case ADataSetID of
        4: FrmFxBillsCompareData.CompareType := fctCommon;
        41: FrmFxBillsCompareData.CompareType := fctG07;
      end;
      
      case ADataSetID of
        3: Result := FrmGclBillsCompareData.AssignData(sProject, cProject);
        4: Result := FrmFxBillsCompareData.AssignData(sProject, cProject);
        41: Result := FrmFxBillsCompareData.AssignData(sProject, cProject);
      end;
    finally
      FreeProject(sProject);
      FreeProject(cProject);
    end;
  end;
end;

end.
