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:
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

  • edited 8:28PM
    I made a modification on FastReport code to try something... I get an error, so I returned everything back to original and compiled all projects... Now it's working well (I don't have any ideas of what happens)...

    regards.
  • edited 8:28PM
    Well... the error is apperaing sometimes... But I couldn't know what happens to it appears, but, going a little more on FastReport code, i saw the error is here:
    function TfrxReport.DoUserFunction(Instance: TObject; ClassType: TClass;
      const MethodName: String; var Params: Variant): Variant;
    begin
      if Assigned(FOnUserFunction) then
        Result := FOnUserFunction(MethodName, Params);
    end;
    

    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.
  • gordkgordk St.Catherines On. Canada.
    edited 8:28PM
    be carefull where and when you add your own functions
    make sure it is done only once.
    ;)
  • edited 8:28PM
    I'm adding the functions as many times as the report is generated, but I add the function to TfrxReport component that is Released of the memory after the report is printed...

    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.
  • gordkgordk St.Catherines On. Canada.
    edited 8:28PM
    Hi Gabe
    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.
    ;)
  • edited 8:28PM
    Now it's working very well!!!

    Thank you, gordk...

    I stopped using the TfrxReport.AddFunction method and used fsGlobalUnit.AddMethod, only one time on the executable...

    Regards.

Leave a Comment

Rich Text Editor. To edit a paragraph's style, hit tab to get to the paragraph menu. From there you will be able to pick one style. Nothing defaults to paragraph. An inline formatting menu will show up when you select text. Hit tab to get into that menu. Some elements, such as rich link embeds, images, loading indicators, and error messages may get inserted into the editor. You may navigate to these using the arrow keys inside of the editor and delete them with the delete or backspace key.