808 lines
23 KiB
ObjectPascal
808 lines
23 KiB
ObjectPascal
unit reportDMUnit;
|
||
|
||
{$mode ObjFPC}{$H+}
|
||
|
||
interface
|
||
|
||
uses
|
||
Classes, SysUtils, frxClass, frxExportPDF, frxExportODF, frxExportHTML,
|
||
frxExportHTMLDiv, xpMemParamManagerUnit, AbUnzper, AbZipper, frxDBSet, cgiDM,
|
||
extTypes;
|
||
|
||
type
|
||
TExportFileType = (ftPDF,ftRTF,ftXLS,ftHTML);//(ftPDF,ftMail,ftRTF,ftXLS,ftHTML);
|
||
{ TReportDM }
|
||
TReportQuery=class;
|
||
|
||
TVariableFillProc=procedure(AVariables: TxpMemParamManager) of object;
|
||
TCalcHashProc=function(Data: TStream): string of object;
|
||
TReportQuery=class
|
||
private
|
||
fQueries: TList;
|
||
fOwner: TReportQuery;
|
||
fData: TNIDBDM;
|
||
function getQuery(index: integer): TReportQuery;
|
||
function getQueryCount: integer;
|
||
public
|
||
Name,SQL,LinkField,Description: string;
|
||
ID,ParentID: integer;
|
||
Data: TfrxDBDataset;
|
||
property Queries[index: integer]:TReportQuery read getQuery;
|
||
property QueryCount: integer read getQueryCount;
|
||
property MasterQuery: TReportQuery read fOwner;
|
||
constructor Create;
|
||
destructor Destroy; override;
|
||
procedure Clear;
|
||
procedure AddQuery(q: TReportQuery);
|
||
procedure RemoveQuery(q: TReportQuery);
|
||
function Find(QueryID: integer): TReportQuery;
|
||
end;
|
||
|
||
TReportDM = class(TDataModule)
|
||
AbUnZipper1: TAbUnZipper;
|
||
AbZipper1: TAbZipper;
|
||
frxHTML4DivExport1: TfrxHTML4DivExport;
|
||
frxHTMLExport1: TfrxHTMLExport;
|
||
frxODSExport1: TfrxODSExport;
|
||
frxODTExport1: TfrxODTExport;
|
||
frxPDFExport1: TfrxPDFExport;
|
||
frxReport: TfrxReport;
|
||
procedure frxReportEndDoc(Sender: TObject);
|
||
function frxReportLoadDetailTemplate(Report: TfrxReport;
|
||
const TemplateName: String; const AHyperlink: TfrxHyperlink): Boolean;
|
||
procedure frxReportLoadTemplate(Report: TfrxReport;
|
||
const TemplateName: String);
|
||
private
|
||
TempTableAlreadyCreated : Boolean;
|
||
ComponentContainer : TList;
|
||
MasterDataSets: TStringList; // Список Master-датасетов (TfrxDBDataset) - не забыть создать/удалить как ComponentContainer. Возможно, не нужен???
|
||
DetailDataSets: TStringList; // Список Detail-датасетов. В Objects - TStringList (id query + Detail-датасет(TfrxDBDataset))
|
||
ReportVariables: TxpMemParamManager;
|
||
ReportQueries: TReportQuery;
|
||
fOnVars: TVariableFillProc;
|
||
|
||
procedure CreateDBDataSet(Query:TReportQuery; EditReport: Boolean = False);
|
||
procedure CreateSignaturesDataSet(EditReport: Boolean = False);
|
||
procedure CreateLogosDataSet(EditReport: Boolean = False);
|
||
procedure BuildPodpis(AVariables : TxpMemParamManager);
|
||
// Возвращает имя Master-датасета по id Detail-а (пустую строку если датасет не имеет Master-а)
|
||
function GetMasterDSName(qryID: integer): string;
|
||
// Возвращает имя ключевого поля (для Master-датасета - ключевое поле, для Detail-датасета - поле внешнего ключа)
|
||
function GetLinkFieldName(qryID: integer): string;
|
||
// Возвращает строку для фильтрации Detail-датасета. Параметры:
|
||
// - detail_key_fields, master_key_fields - строки, описывающие поля связи master и detail - датасета,
|
||
// - Link_type - тип связи ("ID" - по id, "BETWEEN" - по диапазону дат, "LIKE" - по подстроке и т.п. - сейчас пока только по id)
|
||
// - MasterDataSet - Master-датасет.
|
||
function GetFilterClause(detail_key_fields, master_key_fields, Link_type: string; MasterDataSet: TfrxDBDataset): string;
|
||
procedure PrepareBuildInfo(AVariables : TxpMemParamManager);
|
||
function GetVariable(AVariables: TxpMemParamManager; VarName: string; DefaultValue: string): string;
|
||
class function maskFRSpecial(value: string): string;
|
||
class function maskFRSpecialPreservingEOLs(value: string): string;
|
||
procedure frxReportPreview(Sender: TObject);
|
||
procedure LoadQueries;
|
||
procedure LoadDefaultVariables(AVariables : TxpMemParamManager);
|
||
procedure LoadLogos(AVariables : TxpMemParamManager);
|
||
procedure LoadVariables(AVariables, AParam : TxpMemParamManager);
|
||
procedure OnMasterRecord(Sender: TObject);
|
||
function LoadReportTemplate(OnHash: TCalcHashProc): string;
|
||
procedure SaveReportTemplate(hash: string;OnHash: TCalcHashProc);
|
||
procedure CopyReportVariables(AVariables, AParam: TxpMemParamManager);
|
||
procedure LogExport(Sender: TObject);
|
||
public
|
||
RecordID: integer;
|
||
NidbData: TNIDBDM;
|
||
procedure ExportReport( ExportType: TExportFileType; Data: TStream; OnStage: TLogger; OnVars: TVariableFillProc);
|
||
procedure EditReport(OnVars: TVariableFillProc; OnHash: TCalcHashProc);
|
||
end;
|
||
|
||
var
|
||
ReportDM: TReportDM;
|
||
|
||
implementation
|
||
uses
|
||
xpReportUtil, Variants,DB,lazUTF8, xpUtilUnit,nnz_data_components,frxCross, Graphics, fr_utils;
|
||
{$R *.lfm}
|
||
|
||
{ TReportQuery }
|
||
|
||
function TReportQuery.getQuery(index: integer): TReportQuery;
|
||
begin
|
||
result :=TReportQuery(fQueries[index]);
|
||
end;
|
||
|
||
function TReportQuery.getQueryCount: integer;
|
||
begin
|
||
result := fQueries.Count;
|
||
end;
|
||
|
||
constructor TReportQuery.Create;
|
||
begin
|
||
fQueries := TList.Create;
|
||
fOwner := nil;
|
||
ID := 0;
|
||
ParentID := 0;
|
||
end;
|
||
|
||
destructor TReportQuery.Destroy;
|
||
begin
|
||
Clear;
|
||
fQueries.Free;
|
||
if assigned(Data) then
|
||
FreeAndNil(Data);
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TReportQuery.Clear;
|
||
var
|
||
i: integer;
|
||
begin
|
||
for i := 0 to fQueries.Count-1 do
|
||
TReportQuery(fQueries[i]).Free;
|
||
fQueries.Clear;
|
||
end;
|
||
|
||
procedure TReportQuery.AddQuery(q: TReportQuery);
|
||
var
|
||
p: TReportQuery;
|
||
begin
|
||
p := self;
|
||
while assigned(p) do
|
||
begin
|
||
if p=q then exit;
|
||
p := p.MasterQuery;
|
||
end;
|
||
if assigned(q.MasterQuery) then
|
||
q.MasterQuery.RemoveQuery(q);
|
||
fQueries.Add(q);
|
||
q.fOwner := self;
|
||
end;
|
||
|
||
procedure TReportQuery.RemoveQuery(q: TReportQuery);
|
||
begin
|
||
fQueries.Remove(q);
|
||
end;
|
||
|
||
function TReportQuery.Find(QueryID: integer): TReportQuery;
|
||
var
|
||
i: integer;
|
||
begin
|
||
result := nil;
|
||
if self.ID=QueryID then result := self
|
||
else
|
||
for i := 0 to QueryCount-1 do
|
||
begin
|
||
Result := Queries[i].Find(QueryID);
|
||
if assigned(Result) then
|
||
exit;
|
||
end;
|
||
|
||
end;
|
||
|
||
{ TReportDM }
|
||
|
||
procedure TReportDM.frxReportLoadTemplate(Report: TfrxReport;
|
||
const TemplateName: String);
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadTemplate '+TemplateName);
|
||
end;
|
||
|
||
function TReportDM.frxReportLoadDetailTemplate(Report: TfrxReport;
|
||
const TemplateName: String; const AHyperlink: TfrxHyperlink): Boolean;
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadDetailTemplate '+TemplateName);
|
||
end;
|
||
|
||
procedure TReportDM.frxReportEndDoc(Sender: TObject);
|
||
begin
|
||
NidbData.log(mtDebug,Sender,'TReportDM.frxReportEndDoc');;
|
||
end;
|
||
|
||
procedure TReportDM.CreateDBDataSet(Query: TReportQuery; EditReport: Boolean);
|
||
var
|
||
i: integer;
|
||
DBQuery: TnnzQuery;
|
||
ds: TfrxDBDataset;
|
||
begin
|
||
if Query.ID>0 then
|
||
begin
|
||
NidbData.log(mtDebug,self,'CreateDBDataSet '+Query.Name);
|
||
ds := TfrxDBDataset.Create(Self);
|
||
Query.Data := ds;
|
||
ds.Tag := PtrInt(Query);
|
||
// Master/Detail
|
||
if Query.ParentID=0 then
|
||
begin // Если это мастер-датасет, добавить его в список и присвоить ему события
|
||
Query.Data.OnFirst := @OnMasterRecord;
|
||
Query.Data.OnNext := @OnMasterRecord;
|
||
end;
|
||
Query.Data.Name := Query.Name;
|
||
|
||
|
||
DBQuery := TnnzQuery.Create(Self);
|
||
DBQuery.Connection := NidbData.connection;
|
||
DBQuery.SQL.Text := Query.SQL;
|
||
try
|
||
DBQuery.Open;
|
||
except on E: Exception do
|
||
begin
|
||
NidbData.logError(self,e,Query.SQL);
|
||
raise Exception.Create(Format('%s::"%s"'#13#10' '#13#10'%s',[e.ClassName,e.Message,Query.SQL]));
|
||
end;
|
||
end;
|
||
Query.Data.DataSet := DBQuery;
|
||
|
||
end;
|
||
for i := 0 to Query.QueryCount-1 do
|
||
begin
|
||
CreateDBDataSet(query.Queries[i],EditReport);
|
||
end;
|
||
end;
|
||
|
||
procedure TReportDM.CreateSignaturesDataSet(EditReport: Boolean);
|
||
begin
|
||
|
||
end;
|
||
|
||
procedure TReportDM.CreateLogosDataSet(EditReport: Boolean);
|
||
begin
|
||
|
||
end;
|
||
|
||
procedure TReportDM.BuildPodpis(AVariables: TxpMemParamManager);
|
||
begin
|
||
|
||
end;
|
||
|
||
function TReportDM.GetMasterDSName(qryID: integer): string;
|
||
begin
|
||
|
||
end;
|
||
|
||
function TReportDM.GetLinkFieldName(qryID: integer): string;
|
||
begin
|
||
|
||
end;
|
||
|
||
function TReportDM.GetFilterClause(detail_key_fields, master_key_fields,
|
||
Link_type: string; MasterDataSet: TfrxDBDataset): string;
|
||
begin
|
||
|
||
end;
|
||
|
||
procedure TReportDM.PrepareBuildInfo(AVariables: TxpMemParamManager);
|
||
begin
|
||
|
||
end;
|
||
|
||
function TReportDM.GetVariable(AVariables: TxpMemParamManager; VarName: string;
|
||
DefaultValue: string): string;
|
||
begin
|
||
|
||
end;
|
||
|
||
class function TReportDM.maskFRSpecial(value: string): string;
|
||
var
|
||
i: integer;
|
||
isSpace: boolean;
|
||
uchar: string;
|
||
begin
|
||
isSpace := false;
|
||
result := '';
|
||
value := UTF8Trim(value);
|
||
for i := 1 to UTF8Length(value) do
|
||
begin
|
||
uchar := UTF8Copy(value,i,1);
|
||
if uchar <= ' ' then // убиваем и заменяем одинарным пробелом все последовательности непечатаемых символов, включая перенос строки
|
||
begin
|
||
if not isSpace then
|
||
result := result + ' ';
|
||
|
||
isSpace := true;
|
||
end
|
||
else
|
||
begin
|
||
if uchar = #39 then // одиночная кавычка, апостроф (')
|
||
result := result + #39#39
|
||
else
|
||
result := result + uchar;
|
||
|
||
isSpace := false;
|
||
end;
|
||
|
||
end;
|
||
|
||
result := #39 + result + #39; // 'result'
|
||
// result :=QuotedStr('');
|
||
end;
|
||
class function TReportDM.maskFRSpecialPreservingEOLs(value: string): string;
|
||
var
|
||
i: integer;
|
||
isSpace, isEOL: boolean;
|
||
uchar: string;
|
||
begin
|
||
isSpace := false;
|
||
isEOL := false;
|
||
result := '';
|
||
value := UTF8Trim(value);
|
||
for i := 1 to UTF8length(value) do
|
||
begin
|
||
uchar := UTF8Copy(value,i,1);
|
||
if inArray(uChar,[#13,#10],false) then // любые последовательности переноса строк, в т.ч. от макоси (#13) и линукса (#10), меняем одним #13#10
|
||
begin
|
||
if not isEOL then
|
||
result := result + sFRBreak;
|
||
isEOL := true;
|
||
isSpace := false;
|
||
end
|
||
else if (uchar <= ' ') then // заменяем одинарным пробелом все последовательности пробелов и непечатаемых символов, КРОМЕ переносов строк
|
||
begin
|
||
if not isSpace then
|
||
result := result + ' ';
|
||
|
||
isSpace := true;
|
||
isEOL := false;
|
||
end
|
||
else
|
||
begin
|
||
if uchar = #39 then // одиночная кавычка, апостроф (')
|
||
result := result + #39#39
|
||
else
|
||
result := result + UTF8Copy(value,i,1);
|
||
|
||
isSpace := false;
|
||
isEOL := false;
|
||
end;
|
||
|
||
end;
|
||
|
||
if (utf8pos(#13, result) = 0) then // в строке result нет символа CR; нужно забрать всё в одинарные кавычки, и FR их не покажет
|
||
result := #39 + result + #39;
|
||
// result := QuotedStr('');
|
||
end;
|
||
|
||
procedure TReportDM.frxReportPreview(Sender: TObject);
|
||
var
|
||
Report: TfrxReport;
|
||
begin
|
||
NidbData.log(mtDebug,Sender,'TReportDM.frxReportPreview');;
|
||
inherited;
|
||
end;
|
||
|
||
procedure TReportDM.LoadQueries;
|
||
var
|
||
SQL: string;
|
||
q: TReportquery;
|
||
i: integer;
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadQueries');
|
||
SQL := format(
|
||
'select q.xp_rpt_q_id,qp.xp_rpt_q_id as ParentID,q.Link_field, '+
|
||
' q.Name,'+
|
||
' q.Description, q.SQL '+
|
||
'FROM xp_report_query q '+
|
||
' left join xp_report_query qp ON q.Parent_q_id=qp.xp_rpt_q_id AND qp.xp_rpt_id=q.xp_rpt_id '+
|
||
'WHERE q.xp_rpt_id = %0:d '+
|
||
'ORDER BY qp.xp_rpt_q_id is not null, q.Name ',
|
||
[integer(RecordID)]);
|
||
with NidbData.GetData(SQL) do
|
||
try
|
||
while not eof do
|
||
begin
|
||
q := TReportQuery.Create;
|
||
ReportQueries.AddQuery(q);
|
||
q.Name:=fieldbyname('Name').AsString;
|
||
q.SQL:=fieldbyname('SQL').AsString;
|
||
q.LinkField:=fieldbyname('Link_field').AsString;
|
||
q.Description:=fieldbyname('Description').AsString;
|
||
q.ID:=fieldbyname('xp_rpt_q_id').AsInteger;
|
||
q.ParentID:=fieldbyname('ParentID').AsInteger;
|
||
|
||
next;
|
||
end;
|
||
finally
|
||
free;
|
||
end;
|
||
for i := ReportQueries.QueryCount-1 downto 0 do
|
||
if ReportQueries.Queries[i].ParentID>0 then
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadQueries.'+ReportQueries.Queries[i].Name);
|
||
q := ReportQueries.Find(ReportQueries.Queries[i].ParentID);
|
||
if assigned(q) then
|
||
q.AddQuery(ReportQueries.Queries[i]);
|
||
end;
|
||
NidbData.log(mtDebug,self,'LoadQueries-OK');
|
||
end;
|
||
|
||
procedure TReportDM.LoadDefaultVariables(AVariables: TxpMemParamManager);
|
||
var
|
||
SQL: string;
|
||
l: TStrings;
|
||
i: integer;
|
||
OptionName,
|
||
OptionValue: String;
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadDefaultVariables');
|
||
|
||
SQL := 'select name,value from options where name in (''GOU_Name'',''Dep_Name'')';
|
||
with NidbData.GetData(sql) do
|
||
try
|
||
while not eof do
|
||
begin
|
||
AVariables[fieldbyname('name').asString] := fieldbyname('value').asString;
|
||
next;
|
||
end;
|
||
finally
|
||
free;
|
||
end;
|
||
for i := 1 to 5 do
|
||
AVariables['GOU_Name'+inttostr(i)] := AVariables['GOU_Name'];
|
||
with NidbData.GetData('SELECT name,value from options WHERE name like ''GOU_Name%'' ') do
|
||
try
|
||
while not eof do
|
||
begin
|
||
OptionName := fieldByName('name').AsString;
|
||
OptionValue := AnsiString(FieldByName('Value').AsString);
|
||
AVariables[OptionName] := trim(OptionValue);
|
||
Next;
|
||
end;
|
||
finally
|
||
Free;
|
||
end;
|
||
end;
|
||
|
||
procedure TReportDM.LoadLogos(AVariables: TxpMemParamManager);
|
||
var
|
||
sql: string;
|
||
img: TJPEGImage;
|
||
p: TPicture;
|
||
s: TStream;
|
||
v: Variant;
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadLogos');
|
||
SQL := 'select name,value from options where name in (''Dep_Logo'',''GOU_Logo'')';
|
||
with NidbData.GetData(sql) do
|
||
try
|
||
while not eof do
|
||
begin
|
||
s := CreateBlobStream(FieldByName('value'),bmRead);
|
||
p:=TPicture.Create;
|
||
img := TJPEGImage.Create();
|
||
try
|
||
img.LoadFromStream(s);
|
||
p.Graphic:=img;
|
||
// внутри вызывается Assign, поэтому img больше не нужен
|
||
finally
|
||
s.Free();
|
||
img.Free;
|
||
end;
|
||
v := PtrInt(p);
|
||
AVariables[fieldbyname('name').asString] := PtrInt(p);
|
||
p := TPicture(PtrInt(v));
|
||
|
||
next;
|
||
end;
|
||
finally
|
||
free;
|
||
end;
|
||
end;
|
||
|
||
procedure TReportDM.LoadVariables(AVariables, AParam: TxpMemParamManager);
|
||
var
|
||
sql: string;
|
||
begin
|
||
NidbData.log(mtDebug,self,'LoadVariables');
|
||
sql := 'select name,value_string, value_int from tmp_report_variables where var_type=0';
|
||
with NidbData.GetData(sql) do
|
||
try
|
||
while not eof do
|
||
begin
|
||
NidbData.log(mtDebug,self,fieldbyname('name').AsString);
|
||
if not fieldbyname('value_string').IsNull then
|
||
AVariables[fieldbyname('name').AsString] := fieldbyname('value_string').AsString
|
||
else if not fieldbyname('value_int').IsNull then
|
||
AVariables[fieldbyname('name').AsString] := fieldbyname('value_int').AsInteger;
|
||
Next;
|
||
end;
|
||
finally
|
||
free;
|
||
end;
|
||
NidbData.log(mtDebug,self,'LoadParams');
|
||
sql := 'select name,value_string, value_int from tmp_report_variables where var_type=1';
|
||
with NidbData.GetData(sql) do
|
||
try
|
||
while not eof do
|
||
begin
|
||
NidbData.log(mtDebug,self,fieldbyname('name').AsString);
|
||
if not fieldbyname('value_string').IsNull then
|
||
AParam[fieldbyname('name').AsString] := fieldbyname('value_string').AsString
|
||
else if not fieldbyname('value_int').IsNull then
|
||
AParam[fieldbyname('name').AsString] := fieldbyname('value_int').AsInteger;
|
||
Next;
|
||
end;
|
||
finally
|
||
free;
|
||
end;
|
||
//
|
||
|
||
//
|
||
NidbData.log(mtDebug,self,'LoadVariables-OK');
|
||
end;
|
||
|
||
procedure TReportDM.OnMasterRecord(Sender: TObject);
|
||
var MasterDS_Index, i, idx: integer;
|
||
masterDS,detailDS: TfrxDBDataset;
|
||
master_key_field, detail_key_field, FilterClause: string;
|
||
DetailDSList: TStringList;
|
||
q: TReportQuery;
|
||
|
||
begin
|
||
try
|
||
master_key_field := '';
|
||
detail_key_field := '';
|
||
FilterClause := '';
|
||
masterDS := TfrxDBDataset(Sender);
|
||
q := TReportQuery(masterDS.Tag) ;
|
||
master_key_field := q.LinkField;
|
||
for i := 0 to q.QueryCount-1 do
|
||
begin
|
||
detailDS := q.Queries[i].Data;
|
||
detail_key_field := q.Queries[i].LinkField;
|
||
FilterClause := GetFilterClause(detail_key_field, master_key_field, 'ID', masterDS);
|
||
if FilterClause <> '' then
|
||
begin
|
||
detailDS.DataSet.Filter := FilterClause;
|
||
detailDS.DataSet.Filtered := True;
|
||
end;
|
||
end;
|
||
|
||
except on e: Exception do
|
||
begin
|
||
NidbData.logError(self,e,'OnMasterRecord');
|
||
raise;
|
||
end;
|
||
|
||
end;
|
||
end;
|
||
|
||
function TReportDM.LoadReportTemplate(OnHash: TCalcHashProc): string;
|
||
var
|
||
ReportStream : TMemoryStream;
|
||
BlobStream : TStream;
|
||
|
||
begin
|
||
NidbData.log(mtDebug,self,'ExportReport.TemplateArh');
|
||
ReportStream := TMemoryStream.Create;
|
||
try
|
||
with NidbData.GetData(format('select TemplateArh from xp_report where xp_rpt_id=%d',[RecordID])) do
|
||
try
|
||
BlobStream := CreateBlobStream(FieldByName('TemplateArh'), bmRead);
|
||
try
|
||
UnpackReport(BlobStream, ReportStream,AbUnZipper1);
|
||
finally
|
||
BlobStream.Free;
|
||
end;
|
||
|
||
finally
|
||
free;
|
||
end;
|
||
if ReportStream.Size > 0 then
|
||
begin
|
||
ReportStream.Position := 0;
|
||
try
|
||
if assigned(OnHash) then
|
||
result := onHash(ReportStream)
|
||
else
|
||
result := '';
|
||
frxReport.LoadFromStream(ReportStream);
|
||
|
||
except on e: Exception do
|
||
begin
|
||
NidbData.logError(self,e,'frxReport.LoadFromStream');
|
||
raise;
|
||
end;
|
||
end;
|
||
end;
|
||
finally
|
||
ReportStream.Free;
|
||
end; // try
|
||
end;
|
||
|
||
procedure TReportDM.SaveReportTemplate(hash: string; OnHash: TCalcHashProc);
|
||
var
|
||
ReportStream : TMemoryStream;
|
||
BlobStream : TStream;
|
||
ASQL: string;
|
||
newhash: string;
|
||
begin
|
||
NidbData.log(mtDebug,self,'ExportReport.TemplateArh');
|
||
ReportStream := TMemoryStream.Create;
|
||
BlobStream := TMemoryStream.Create;
|
||
try
|
||
frxReport.SaveToStream(ReportStream);
|
||
newhash := onHash(ReportStream);
|
||
if newhash=hash then exit;
|
||
ReportStream.seek(0,soFromBeginning);
|
||
PackReport(ReportStream,BlobStream,AbZipper1);
|
||
ASQL := format('update xp_report set TemplateArh=%s where xp_rpt_id=%d',[TNIDBDM.StreamAsSQL(BlobStream),RecordID]);
|
||
NidbData.ExecuteSQL(ASQL);
|
||
finally
|
||
ReportStream.Free;
|
||
BlobStream.Free;
|
||
end; // try
|
||
end;
|
||
|
||
|
||
procedure TReportDM.CopyReportVariables(AVariables, AParam: TxpMemParamManager);
|
||
var
|
||
i: integer;
|
||
v: variant;
|
||
begin
|
||
NidbData.log(mtDebug,self,'CopyReportVariables');
|
||
for I := Low(AVariables.Params) to High(AVariables.Params) do
|
||
begin
|
||
if VarIsStr(AVariables.Params[i][1]) then
|
||
v := maskFRSpecial(VarToStr(AVariables.Params[i][1]))
|
||
else
|
||
v:= AVariables.Params[i][1];
|
||
frxReport.Variables[AVariables.Params[i][0]] := v;
|
||
end;
|
||
for I := Low(AParam.Params) to High(AParam.Params) do
|
||
begin
|
||
if VarIsStr(AParam.Params[i][1]) then
|
||
v := maskFRSpecialPreservingEOLs(VarToStr(AParam.Params[i][1]))
|
||
else
|
||
v := AParam.Params[i][1];
|
||
frxReport.Variables[AParam.Params[i][0]] := v;
|
||
end;
|
||
|
||
end;
|
||
|
||
procedure TReportDM.LogExport(Sender: TObject);
|
||
begin
|
||
NidbData.log(mtDebug,Sender,'export-started');
|
||
end;
|
||
|
||
|
||
|
||
procedure TReportDM.ExportReport(ExportType: TExportFileType; Data: TStream;
|
||
OnStage: TLogger; OnVars: TVariableFillProc);
|
||
var
|
||
I : Integer;
|
||
flt : TfrxCustomExportFilter;
|
||
v : Variant;
|
||
AVariables, AParam: TxpMemParamManager;
|
||
oldHash: string;
|
||
begin
|
||
fOnVars:=OnVars;
|
||
frxReport.EngineOptions.EnableThreadSafe:=true;
|
||
NidbData.log(mtDebug,self,'ExportReport');
|
||
ReportQueries := TReportQuery.Create;
|
||
AVariables := TxpMemParamManager.Create;
|
||
AParam := TxpMemParamManager.Create;
|
||
try
|
||
if assigned(OnStage) then
|
||
OnStage(mtExtra, self,'список запросов');
|
||
LoadQueries;
|
||
LoadDefaultVariables(AVariables);
|
||
LoadLogos(AVariables);
|
||
LoadVariables(AVariables,AParam);
|
||
if assigned(fOnVars) then fOnVars(AVariables);
|
||
frxReport.EngineOptions.DestroyForms := False;
|
||
// Создаём источники данных
|
||
if assigned(OnStage) then
|
||
OnStage(mtExtra,self,'подготовка данных');
|
||
|
||
CreateDBDataSet(ReportQueries);
|
||
if assigned(OnStage) then
|
||
OnStage(mtExtra,self,'загрузка шаблона');
|
||
|
||
oldHash := LoadReportTemplate(nil);
|
||
CopyReportVariables(AVariables,AParam);
|
||
TxpFRFunctions.SetReport(NidbData,AVariables);
|
||
if assigned(OnStage) then
|
||
OnStage(mtExtra,self,'формирование отчета');
|
||
|
||
begin
|
||
try
|
||
frxReport.PrepareReport(False);
|
||
frxReport.OnPreview := @frxReportPreview;
|
||
frxReport.SaveToFile(Extractfilepath(paramstr(0))+'out/report.fr3');
|
||
except on e: Exception do
|
||
begin
|
||
NidbData.logError(self,e,'frxReport.PrepareReport');
|
||
raise;
|
||
end;
|
||
end;
|
||
|
||
case ExportType of
|
||
ftPDF: flt := frxPDFExport1;
|
||
ftRTF: flt := frxODTExport1;
|
||
ftXLS: flt := frxODSExport1;
|
||
ftHTML: flt := frxHTML4DivExport1;
|
||
end;
|
||
flt.OnBeforeExport:=@LogExport;
|
||
flt.OnBeginExport:=@LogExport;
|
||
|
||
try
|
||
if assigned(OnStage) then
|
||
OnStage(mtExtra,self,'выгрузка');
|
||
|
||
flt.ShowDialog := false;
|
||
flt.Stream := Data;
|
||
flt.FileName:='';
|
||
flt.ShowProgress := false;
|
||
try
|
||
if not frxReport.Export(flt) then
|
||
NidbData.log(mtWarning,self,'ERROR EXPORT PDF');
|
||
|
||
except on e: Exception do
|
||
begin
|
||
NidbData.logError(self,e,'frxReport.Export');
|
||
raise;
|
||
end;
|
||
end;
|
||
finally
|
||
//flt.Free;
|
||
end;
|
||
end;
|
||
//FreeContainer;
|
||
finally
|
||
ReportQueries.Free;
|
||
AVariables.Free;
|
||
AParam.Free;
|
||
end;
|
||
NidbData.log(mtDebug,self,'Report complete');
|
||
end;
|
||
|
||
procedure TReportDM.EditReport(OnVars: TVariableFillProc; OnHash: TCalcHashProc
|
||
);
|
||
var
|
||
I : Integer;
|
||
flt : TfrxCustomExportFilter;
|
||
v : Variant;
|
||
AVariables, AParam: TxpMemParamManager;
|
||
oldHash: string;
|
||
begin
|
||
fOnVars:=OnVars;
|
||
frxReport.EngineOptions.EnableThreadSafe:=true;
|
||
NidbData.log(mtDebug,self,'EditReport');
|
||
ReportQueries := TReportQuery.Create;
|
||
AVariables := TxpMemParamManager.Create;
|
||
AParam := TxpMemParamManager.Create;
|
||
try
|
||
LoadQueries;
|
||
LoadDefaultVariables(AVariables);
|
||
LoadLogos(AVariables);
|
||
LoadVariables(AVariables,AParam);
|
||
if assigned(fOnVars) then fOnVars(AVariables);
|
||
frxReport.EngineOptions.DestroyForms := False;
|
||
// Создаём источники данных
|
||
CreateDBDataSet(ReportQueries);
|
||
oldHash:=LoadReportTemplate(onHash);
|
||
CopyReportVariables(AVariables,AParam);
|
||
TxpFRFunctions.SetReport(NidbData,AVariables);
|
||
|
||
try
|
||
frxReport.DesignReport;
|
||
SaveReportTemplate(oldHash,onHash);
|
||
except on e: Exception do
|
||
begin
|
||
NidbData.logError(self,e,'frxReport.PrepareReport');
|
||
raise;
|
||
end;
|
||
end;
|
||
|
||
|
||
finally
|
||
ReportQueries.Free;
|
||
AVariables.Free;
|
||
AParam.Free;
|
||
end;
|
||
NidbData.log(mtDebug,self,'Report complete');
|
||
end;
|
||
|
||
|
||
|
||
end.
|
||
|