Как проверить существование файла в FastReport 4

У меня есть отчет, написанный в DelphiXE с использованием FastReport 4.

Изображение загружается динамически во время выполнения с использованием имени файла, хранящегося в таблице, с использованием следующего:

procedure Picture1OnBeforePrint(Sender: TfrxComponent);
var  pname : string;                                     
begin
   pname := frxGlobalVariables['imgPath']+ <frxDBDataset1."PHOTO">;                                                      
   Picture1.Picture.LoadFromFile(pname);
end;

Он работает нормально, пока есть файлы. Как проверить, что загружаемый файл существует?

Я попытался использовать функцию Delphi FileExists(), но, по-видимому, ее нет в FastReport 4.


ОБНОВЛЕНИЕ. Следуя приведенным ниже инструкциям, я добавил в свой отчет функцию FrFileExists.

Я вызываю код в отчете следующим образом:

procedure MasterData1OnBeforePrint(Sender: TfrxComponent);
begin
   Photo := imgPath + <frxDBDataset1."PICTURENAME"> + '.jpg';
   if (FrFileExists(Photo)) then Picture1.LoadFromFile(Photo);
end;

Я запустил конструктор времени выполнения, и функция есть, но, запустив отчет, я получаю следующее:

The following error(s) have occured:  
Could not convert variant of type (Null) into type (Boolean)

И если вы считаете, что переменная Photo неверна, следующий код работает до тех пор, пока существует изображение:

Picture1.LoadFromFile(Photo);

Еще нужно заставить его работать.


person ChuckO    schedule 04.08.2015    source источник
comment
@Val Marinov: Что это: // необходимая логика. Это та часть, с которой мне нужна помощь.   -  person ChuckO    schedule 05.08.2015
comment
Чак, ты уже разместил этот комментарий к ответу Вэла. Вэл не будет уведомлен о вашем комментарии здесь к вопросу, только о комментарии к ответу. Но я уже ответил на ваш комментарий, поэтому, если вам все еще нужна помощь, задайте дополнительный вопрос.   -  person Rob Kennedy    schedule 05.08.2015


Ответы (3)


FastReport позволяет писать и использовать собственные функции.

Как это сделать вы можете найти в: FastReport DeveloperManual-en.pdf.

в главе "Использование пользовательских функций в отчете" стр. 37, 38, 39

Надеюсь, это поможет.

Обновить

Использование пользовательских функций в отчете

FastReport имеет большое количество встроенных стандартных функций для использования в дизайне отчетов. FastReport также позволяет писать и использовать пользовательские функции. Функции добавляются с помощью интерфейса библиотеки «FastScript», которая включена в FastReport (чтобы узнать больше о FastScript, обратитесь к руководству по библиотеке).

Давайте посмотрим, как в FastReport можно добавить процедуры и/или функции. Количество и типы параметров варьируются от функции к функции. Параметры типа «Set» и «Record» не поддерживаются FastScript, поэтому они должны быть реализованы с использованием более простых типов, например, TRect может быть передан как четыре целых числа: X0, Y0, X1, Y1. Подробнее об использовании функций с различными параметрами в документации FastScript.

В форме Delphi объявите функцию или процедуру и ее код.

function TForm1.MyFunc(s: String; i: Integer): Boolean;
begin
// required logic
end;
procedure TForm1.MyProc(s: String);
begin
// required logic
end;

Создайте обработчик функции onUser для компонента отчета.

function TForm1.frxReport1UserFunction(const MethodName: String;
var Params: Variant): Variant;
begin
  if MethodName = 'MYFUNC' then
    Result := MyFunc(Params[0], Params[1])
  else if MethodName = 'MYPROC' then
  MyProc(Params[0]);
end;

Используйте метод add компонента отчета, чтобы добавить его в список функций (обычно в событии onCreate или onShow формы Delphi).

frxReport1.AddFunction('function MyFunc(s: String; i: Integer):Boolean');
frxReport1.AddFunction('procedure MyProc(s: String)');

Добавленная функция теперь может использоваться в скрипте отчета и на нее могут ссылаться объекты типа «TfrxMemoView». Функция также отображается на вкладке функций "Дерево данных". На этой вкладке функции разбиты на категории, и при выборе функции в нижней части вкладки появляется подсказка о функции. Измените приведенный выше пример кода, чтобы зарегистрировать функции в отдельных категориях и отобразить описательные подсказки:

frxReport1.AddFunction('function MyFunc(s: String; i: Integer): Boolean',
'My functions',
' MyFunc function always returns True');
frxReport1.AddFunction('procedure MyProc(s: String)',
'My functions',
' MyProc procedure does not do anything');

Добавленные функции появятся в категории «Мои функции». Для регистрации функций в существующих категориях используйте одно из следующих имен категорий:

  • Строковая функция ctString
  • Функции даты/времени ctDate
  • Функции преобразования ctConv
  • Форматирование ctFormat
  • Математические функции ctMath
  • 'ctOther' другие функции

Если имя категории оставить пустым, функция будет помещена в корень дерева функций. Для добавления большого количества функций рекомендуется всю логику размещать в отдельном блоке библиотеки. Вот пример:

unit myfunctions;
interface
implementation
uses SysUtils, Classes, fs_iinterpreter;
// you can also add a reference to any other external library here
type
  TFunctions = class(TfsRTTIModule)
    private
    function CallMethod(Instance: TObject; ClassType: TClass;
    const MethodName: String; var Params: Variant):Variant;
    public
    constructor Create(AScript: TfsScript); override;
end;

function MyFunc(s: String; i: Integer): Boolean;
begin
// required logic
end;

procedure MyProc(s: String);
begin
// required logic
end;
{ TFunctions }
constructor TFunctions.Create;
begin
  inherited Create(AScript);
  with AScript do
    AddMethod('function MyFunc(s: String; i: Integer): Boolean',CallMethod,'My functions', ' MyFunc function always returns True');
    AddMethod('procedure MyProc(s: String)', CallMethod,'My functions','MyProc procedure does not do anything'');
  end;
end;

function TFunctions.CallMethod(Instance: TObject; ClassType: TClass;
const MethodName: String;
var Params: Variant): Variant;
begin
  if MethodName = 'MYFUNC' then
    Result := MyFunc(Params[0], Params[1])
  else if MethodName = 'MYPROC' then
    MyProc(Params[0]);
  end;
initialization
 fsRTTIModules.Add(TFunctions);
end.

Сохраните файл с расширением .pas, затем добавьте ссылку на него в разделе «uses» формы вашего Delphiproject. После этого все ваши пользовательские функции будут доступны для использования в любом компоненте отчета без необходимости написания кода для добавления этих функций в каждый «TfrxReport» и без необходимости написания дополнительного кода для обработчика функции «onUser» каждого компонента отчета.

Обновление 2

Чтобы создать пользовательскую функцию FileExists, объявите функцию в Delphi, например:

function TForm1.FrFileExists(FileName : string):boolean;
begin
  // required logic
  Result := FileExists(FileName);
end; 

Используйте метод add компонента отчета, чтобы добавить его в список функций (обычно в событии onCreate или onShow формы Delphi).

procedure TForm1.FormCreate(Sender: TObject);
begin
  frxReport1.AddFunction('function FrFileExists(FileName:String):Boolean','My functions',
'This function returns True if file exists');
  frxReport1.DesignReport; //<-- THIS SHOW REPORT DESIGNER RUNTIME
end;

Создайте обработчик функции onUser для компонента отчета.

function TForm1.frxReport1UserFunction(const MethodName: string;var Params: Variant): Variant;
begin
  if MethodName = 'FrFileExists' then
    Result := FrFileExists(Params[0])
end;

Вы не можете ожидать увидеть функции во время разработки Fast report IDE. Чтобы увидеть функцию во время выполнения IDE, выполните:

включить frxDesgn в пункт использования;

используйте этот код, чтобы показать дизайнеру:

 frxReport1.DesignReport; //see code On create above

Запустите проект и увидите Fast Report Ide и нашу новую функцию FrFileExists

введите здесь описание изображения

person Val Marinov    schedule 04.08.2015
comment
Что это: // необходимая логика. Это та часть, с которой мне нужна помощь. - person ChuckO; 04.08.2015
comment
Подумай об этом на мгновение, Чак. Что, если бы вы позвонили туда FileExists? - person Rob Kennedy; 04.08.2015
comment
@ChuckO См. Обновление 2 - person Val Marinov; 05.08.2015

Я не знаю, почему, но MethodName передает строку в верхнем регистре, исправьте функцию в верхнем регистре MethodName = 'FRFILEEXISTS'

После этого он заработает (я проверил его в своем проекте) Джон

person John    schedule 25.11.2019

Я рад найти эту функцию frFileExists, и, поскольку я использую C++ Builder, я преобразовал ее в C++ Builder. После успешной компиляции функция не отображается в FastReport IDE. Может кто-нибудь помочь указать на мою ошибку и большое спасибо. Мой код добавлен ниже:

// To create custom function FileExists
boolean __fastcall TForm1::FrFileExists(String FileName)
{
  return (FileExists(FileName.c_str()));
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  frxReport1->AddFunction(L"FrFileExists", L"My Functions",
     L"This function return true if file exists" );
  frxReport1->DesignReport();
}

Variant __fastcall TForm1::frxReport1UserFunction(const UnicodeString MethodName,
      Variant &Params)
{
  if (MethodName == "FrFileExist") {
      return (FrFileExists(Params));
  }
}
person Sa Lang    schedule 01.07.2020
comment
Если вы хотите получить ответ, вы должны опубликовать новый вопрос. Размещение этого в качестве ответа на вопрос 5-летней давности делает его невидимым. - person ChuckO; 30.08.2020