Error in report when executed by the 2nd time
Hi...
I'm having a problem with FastReports, especifically in own functions, when I execute the function by the second time...
See how I call the report:
When I execute my report by the 2nd time, I get an Access Violation error on PrepareReport function...
Searching in FastReport code, I see the error is exatly here (frxClass):
I don't know why, but on the first execution, the v.Value is returned as '', but then, on the 2nd time, it's returns Nil...
How can I solve?
regards.
I'm having a problem with FastReports, especifically in own functions, when I execute the function by the second time...
See how I call the report:
Procedure TFormMain.GeraRelatorio;
Var Relatorio : TFrxReport;
  FRCadProp, FRCadIpro, FRCadNot : TfrxDBDataset;
  PDF : TfrxPDFExport;
Begin
  Try
    FRCadProp := TfrxDBDataset.Create( Self );
    FRCadIpro := TfrxDBDataset.Create( Self );
    FRCadNot  := TfrxDBDataset.Create( Self );
    FRCadProp.DataSource := Dados.DSCadProp;
    FRCadProp.UserName := 'CadProp';
    FRCadProp.Open;
    FRCadIPro.DataSource := Dados.DSCadIPro;
    FRCadIPro.UserName := 'CadIPro';
    FRCadIPro.Open;
    FRCadNot.DataSource := Dados.DSCadNot;
    FRCadNot.UserName := 'CadNot';
    FRCadNot.Open;
    PDF := TfrxPDFExport.Create( Self );
    Relatorio := TfrxReport.Create( Self );
    Relatorio.PreviewOptions.AllowEdit := False;
    Relatorio.PreviewOptions.Buttons := [pbPrint, pbLoad, pbSave, pbExport, pbZoom, pbFind, pbOutline, pbPageSetup, pbTools, pbNavigator];
    Relatorio.ReportOptions.Author := 'Dinat?©cnica Ind??stria e Com?©rcio Ltda.';
    Relatorio.AddFunction( 'function AnsiReplaceStr(const AText: String; const AFromText: String; const AToText: String): String', 'ctString' );
    Relatorio.OnUserFunction := RelatorioUserFunction;
    If Relatorio.LoadFromFile( ExtractFilePath( Application.ExeName ) + 'proposta.fr3' ) Then Begin
      AlteraMemos( Relatorio );
      Relatorio.PrepareReport();
      PDF.ShowDialog := True;
      Relatorio.ShowPreparedReport
    End
    Else Begin
      MessageBox( Handle, 'N??o foi poss?vel carregar o arquivo de Relat??rio.'#13'Verifique as permiss?µes do usu??rio.', ' Erro', Mb_IconError );
      Exit;
    End;
  Finally
    If Relatorio <> Nil Then
      FreeAndNil( Relatorio );
    If PDF <> Nil Then
      FreeAndNil( PDF );
    If FRCadProp <> Nil Then
      FreeAndNil( FRCadProp );
    If FRCadIpro <> Nil Then
      FreeAndNil( FRCadIpro );
    If FRCadNot <> Nil Then
      FreeAndNil( FRCadNot );
  End;
End;
When I execute my report by the 2nd time, I get an Access Violation error on PrepareReport function...
Searching in FastReport code, I see the error is exatly here (frxClass):
function TfrxExpressionCache.Calc(const Expression: String;
 var ErrorMsg: String): Variant;
var
 i: Integer;
 v: TfsProcVariable;
begin
 ErrorMsg := '';
 i := FExpressions.IndexOf(Expression);
 if i = -1 then
 begin
  i := FExpressions.Count;
  FScript.Lines.Text := 'function _f' + IntToStr(i) + ': Variant; begin ' +
   'Result := ' + Expression + ' end; begin end.';
  FScript.SyntaxType := 'PascalScript';
  if FScript.Compile then
   v := TfsProcVariable(FScript.Find('_f' + IntToStr(i)))
  else
  begin
   ErrorMsg := frxResources.Get('clExprError') + ' ''' + Expression + ''': ' +
    FScript.ErrorMsg;
   Result := Null;
   Exit;
  end;
  FExpressions.AddObject(Expression, v);
 end
 else
  v := TfsProcVariable(FExpressions.Objects[i]);
 Result := v.Value;
end;
I don't know why, but on the first execution, the v.Value is returned as '', but then, on the 2nd time, it's returns Nil...
How can I solve?
regards.
Comments
regards.
I verified with a watch, and all parameters are correct, and the Assigned(FOnUserFunction) is true, but the Access violation occurs when debugger process the line 'FOnUserFunction(MethodName, Params);'...
Very strange... What's happening?
regards.
make sure it is done only once.
I don't need to add the function again (to another instance of TfrxReport)?
I'll test it and post the results soon...
Thank you!
regrads.
i posted a demo on user functions a while ago in the binaries
the best way is to create a function lib a .pas file and add it to the uses clause
of the form it will then be avail for all report components in design mode.
when you add repeated times, using addmethod, you end up with multiple copies of the function and some won't work. fr's functionlib is global.
if you are only using it for 1 report u can use addmethod in on formshow or create events of form as long as it is destroyed before calling it again.
Thank you, gordk...
I stopped using the TfrxReport.AddFunction method and used fsGlobalUnit.AddMethod, only one time on the executable...
Regards.