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

2»

Комментарии

  • отредактировано January 2006
    В руководстве разработчика FastReport стр. 40 - 41. приведен пример модуля для подключения библиотеки своих функций, который работает для FastReport 3.18 (FastScript 1.7). К сожалению, документация не обновляется и этот пример тоже."Чайнику" остается с трудом разбираться в сообщениях этого форума. Вот как мне в итоге удалось изменить этот модуль, чтобы все заработало с FastReport 3.20 (модуль достатачно добавить в проект).


    unit myfunctions;
    interface
    uses SysUtils, Classes, fs_iinterpreter;

    implementation

    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(str:string):string;
    begin
    // нужная логика
    end;

    constructor TFunctions.Create(AScript: TfsScript);
    begin
    inherited Create(AScript);
    with AScript do
    AddMethod('function MyFunc(str:string):string', CallMethod, 'Мои функции', 'Функция MyFunc');
    end;

    function TFunctions.CallMethod(Instance: TObject; ClassType: TClass;
    const MethodName: String; var Params: Variant): Variant;
    begin
    if UpperCase(MethodName) = 'MYFUNC' then Result := MyFunc(Params[0]);
    end;

    initialization
    fsRTTIModules.Add(TFunctions);
    end.
  • NauNau
    отредактировано 21:19
    написал:
    Для подключения библиотеки своих функций нужно:

    1. Изменить наследника
    type
      TMyFunction = class(TfsRTTIModule)

    2. Изменить заголовок
        function CallMethod(Instance: TObject; ClassType: TClass; const MethodName:
            String; Caller: TfsMethodHelper): Variant;

    2.1 Регистрация функции:
    constructor TMyFunction .Create(AScript: TfsScript);
    begin
      inherited Create(AScript);
      with AScript do
      begin
        AddMethod(...);
      end;
    end.


    3. Доступ к параметрам функции
      Caller.Params[0], Caller.Params[1] и т.д

    4. И если надо
    initialization
      fsRTTIModules.Add(TMyFunction);
    Здравствуйте, прочитал ваш ответ по поводу подключения своих функций в fastreport и подправил свой код, который работал в FR3.19, по вашему совету под FR 3.21, но результат отрицательный.
    Помогите пожалуйста разобрать где я не досмотрел. Проект горит.
    Пример кода:

    unit frRoubleUnit;
    interface
    uses Classes, fs_iinterpreter, SysUtils, math;
    type
    TFunctions = class(TfsRTTIModule) //class(TObject)
    private
    function CallMethod(Instance: TObject; ClassType: TClass;
    const MethodName: String; Caller: TfsMethodHelper): Variant;
    public
    constructor Create(AScript: TfsScript);
    destructor Destroy; override;
    end;

    Function RealToRouble(c:Double; Currency: integer):String;
    Function NumToStr(s:String):String;

    var
    Functions: TFunctions;
    Script: TfsScript;
    implementation

    Function NumToStr(s:String):String;{Возвращает число прописью}
    Begin
    //Логика
    End;{NumToStr}

    Function RealToRouble(c:Double; Currency: integer):String;
    begin {Возвращает число прописью с рублями и копейками}
    //Логика
    end;

    constructor TFunctions.Create(AScript: TfsScript);
    begin
    inherited Create(AScript);
    with AScript do // здесь возникает Exception Access Vialation
    begin
    AddedBy := Self;
    AddMethod('Function NumToStr(s:String):String', CallMethod,
    'ctOther',
    'Функция NumToStr возвращает число прописью.');
    AddMethod('Function RealToRouble(c:Double; Currency: integer):String', CallMethod,
    'ctOther',
    'Функция RealToRouble возвращает денежную сумму прописью.');
    AddedBy := nil;
    end;
    end;

    destructor TFunctions.Destroy;
    begin
    if fsGlobalUnit <> nil then fsGlobalUnit.RemoveItems(Self);
    inherited;
    end;

    function TFunctions.CallMethod(Instance: TObject; ClassType: TClass;
    const MethodName: String; Caller: TfsMethodHelper): Variant;
    begin
    if MethodName = 'NUMTOSTR' then Result := NumToStr(Caller.Params[0])
    else if MethodName = 'REALTOROUBLE' then Result := RealToRouble(Caller.Params[0],Caller.Params[1]);
    end;

    initialization
    Functions := TFunctions.Create(Script);
    fsRTTIModules.Add(TFunctions);
    finalization
    Functions.Free;
    end.
  • отредактировано 21:19
    1) Деструктор классу TFunctions не нужен.
    2) finalization Functions.Free; - тоже не нужно.
    3) Переменные Functions: TFunctions; Script: TfsScript; -не нужны.
    4) в initialization должно быть только fsRTTIModules.Add(TFunctions); создавать объект не нужно.

    Смотрите вышеприведенный вариант, в него кроме своей логики добавлять ничего не нужно.
  • NauNau
    отредактировано June 2006
    написал:
    1) Деструктор классу TFunctions не нужен.
    2) finalization Functions.Free; - тоже не нужно.
    3) Переменные Functions: TFunctions; Script: TfsScript; -не нужны.
    4) в initialization должно быть только fsRTTIModules.Add(TFunctions); создавать объект не нужно.

    Смотрите вышеприведенный вариант, в него кроме своей логики добавлять ничего не нужно.

    Спасибо, все получилось. Еще одно замечание возникло по поводу форматирования полей Memo. Ситуация такая же то, что раньше работало в 3.18 в 3.21 выдает ошибку. Например, MemoNN.Memo =
    [qCurrency."Prefix"][qForAllDocJournalItem."TotalSum"][qCurrency."Postfix"]
    формат поля число %2.2f
    взависимости от валюты, например рубль выводилось 1000р.
    если доллар - $1000
    а теперь в версии 3.21 возникает ошибка: Could not convert variant of type (String) into type (Double).
    Выполняя по шагом я заметил что отдельно форматируется значения полей БД а не целиком Memo-поле [qForAllDocJournalItem."TotalSum"] т.е. 1000, отдельно [qCurrency."Postfix"] т.е. р. но уже с ошибкой.
    Получается, что frReport встретив в Memo-поле поле БД [qForAllDocJournalItem."TotalSum"] со значением 1000 форматирует его в 1000.00 а потом встретив [qCurrency."Postfix"] со значение р. пытается и его отформатировать в число %2.2f и естественно возникает ошибка.
    Как избегали такую ситуацию в версии 3.18 и на что можно обратить внимание чтоб это исправить?
    Спасибо.
  • отредактировано 21:19
    [qCurrency."Prefix"] и [qCurrency."Postfix"] - наверное поля типа string, а формат мемо float.
    FR пытается перевести содержимое мемо в Double, но так как мемо содержить текст появляется ошибка.
    Поставьте формат мемо в текст, а для вывода поля [qForAllDocJournalItem."TotalSum"] в нужном формате используйте функцию FormatFloat.
  • NauNau
    отредактировано 21:19
    написал:
    [qCurrency."Prefix"] и [qCurrency."Postfix"] - наверное поля типа string, а формат мемо float.
    FR пытается перевести содержимое мемо в Double, но так как мемо содержить текст появляется ошибка.
    Поставьте формат мемо в текст, а для вывода поля [qForAllDocJournalItem."TotalSum"] в нужном формате используйте функцию FormatFloat.
    Вы все верно поняли и написали но глупость ситуации в том что это в таком виде работало в предыдущих версиях FR

Оставить комментарий

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.