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

отредактировано 13:42 Раздел: FastReport 3.0
Поставил FR3_19_3, пропали пользовательские функции в 3_18_14 все работало
«1

Комментарии

  • dron-sdron-s Россия
    отредактировано October 2005
    Bali
    написал:
    Поставил FR3_19_3, пропали пользовательские функции в 3_18_14 все работало
    это связано с тем что в FR 3.19.3 включён FastScript 1.9. У него переработана архитектура, и в связи с этим некоторые функции будут не доступны...
  • отредактировано 13:42
    В таких случаях нужно хотя бы предупреждать. В версии 3.ХХ после выхода очередного релиза приходится проверять все отчеты. При таком подходе продукт годится только для домашнего использования, а не для промышленного, разработчики наверное забыли о совместимости.
  • gpigpi
    отредактировано 13:42
    У меня всё работает. Одно отличие - пользовательские функции (категория без названия) раньше располагались в конце списка, а теперь за агрегатными.
  • dron-sdron-s Россия
    отредактировано October 2005
    Bali
    Все те функции будут работать, просто теперь они подключаются немного по другому, в документации которая идёт с FastScript это всё описано
  • отредактировано October 2005
    Для подключения библиотеки своих функций нужно:

    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);
  • отредактировано 13:42
    Небольшое добавление - 2, 3 - не обязательно.
  • отредактировано 13:42
    При использовании fsGlobalUnit функции не подключились,
    помогло только непосредственная передача frxreport1.script в
    Userfunctions.create(frxreport1.script),
    но появилась ошибка "Несовместимые типы Class Extended, Extended", помогло
    следующее:

    tUserFunctions = class(TfsRTTIModule)
    ...

    constructor tUserFunctions.Create(frxRep: tFrxReport);
    begin
    inherited Create(frxrep.script);
    frxrep.script.Clear;
    with frxrep.script do
    begin
    AddType('Byte', fvtInt);
    AddType('Word', fvtInt);
    AddType('Integer', fvtInt);
    AddType('Longint', fvtInt);
    AddType('Cardinal', fvtInt);
    AddType('TColor', fvtInt);
    AddType('Boolean', fvtBool);
    AddType('Real', fvtFloat);
    AddType('Single', fvtFloat);
    AddType('Double', fvtFloat);
    AddType('Extended', fvtFloat);
    AddType('Currency', fvtFloat);
    AddType('TDate', fvtFloat);
    AddType('TTime', fvtFloat);
    AddType('TDateTime', fvtFloat);
    AddType('Char', fvtChar);
    AddType('String', fvtString);
    AddType('Variant', fvtVariant);
    AddType('Pointer', fvtVariant);
    AddType('Array', fvtArray);
    AddType('Constructor', fvtConstructor);

    AddMethod('Function UserFunc_1(par1:double):string', CallMethod, 'ctConv');
    ...
    AddMethod('Function UserFunc_n);

    end;
    end;

    По моему это ошибка, должно работать без добавления типов в скрипт.
  • отредактировано 13:42
    Скачайте последний 3.19.5, кое-что исправлено.
  • отредактировано November 2005
    Мда... в стабильной версии идет FastScript 1.8, а текущая 1.9. Почему такое несовпадения? И как теперь быть с интеграциями ? Паралельно не установиш и файлы одинаково называются... "тут играем тут не играем, тут рыбу заворачивали "(с)
  • отредактировано 13:42
  • отредактировано 13:42
    Причем тут последний билд ? Я говорю о стабильной версии. У меня задача написать интеграцию к фастрепорт 3.19
    Естественно в нем идет скрипт 1.8. Тоесть пока отчетер и скриптер развивались паралельно все было нормально. Теперь они идут вразнобой. Может есть смысл подумать об отдельных продуктах, тоесть скриптер для отчетера и скриптер как "сам по себе" ? В принципе в данном случае так оно и есть. Другого пути я ка бы не вижу потому как одновременно установить не получается... следовательно и единой интеграции быть не может. Или же просто синхронизируйте их.
  • отредактировано 13:42
    Смотрим по датам релизов:
    в начале был FastReport 3.19 и только потом FastScript 1.9
    отсюда следует что FastReport 3.19(стабильная версия) содержит FScript 1.8

    После выпуска FScript1.9, он автоматически идет в комплекте с FReport3.19.xx (помоему начиная с 3.19.3)

    Если вы хотите стабильную версию FR c FS1.9 - ждите выхода FR 3.20

    Надеюсь понятно объяснил? ;)
  • отредактировано November 2005
    Вполне. Когда примерно ждать ?
  • отредактировано 13:42
    Думаю на следующей неделе.
    Что вам мешает использовать последний билд? Боязнь "не стабильной " версии?
  • отредактировано 13:42
    Я занимаюсь интеграцией FIBPlus c другими продуктами и мне надо точно указвать для какой версии они написаны. А в данной ситуации должна надо писать для 1.9 отдельно. ПОэтому проще дождаться выхода релиза фастрепорта с 1.9 в своем составе и обновить обе интеграции сразу.
  • отредактировано 13:42
    написал:
    Для подключения библиотеки своих функций нужно:
    -=Serg=-
    Сделал всё как указано, теперь библиотека не регистрируется - ей TComponent подавай в качестве родителя. Я работаю на C++ Builder 5.0. FastReport 3.19 stable у меня вообще валил Builder насмерть с ошибкой в vcl50, сейчас поставил 3.19.22, вроде живёт, но функции, естественно, не работают. Что делать?

    Подключаемые функции написаны на Pascal.
    Строка
    RegisterComponents('FastReport 3.0', [Tfr3FunctionLibrary]);

    матерится: Incompatible types: 'TComponentClass' and 'Class reference'
    К сожалению, в Object Pascal я не силён, сорри за чайниковский вопрос.
  • отредактировано 13:42
    Покажите объявление класа Tfr3FunctionLibrary
  • отредактировано 13:42
    Tfr3PropisFunctionLibrary = class(TfsRTTIModule)
    protected
    ...
    published
    ...
    private
    function CallMethod(Instance: TObject; ClassType: TClass; const
    MethodName: String; Caller: TfsMethodHelper): Variant;

    function PropisCurr(Value: double; CurrID: integer): string;
    ...
    public
    constructor Create(AScript: TfsScript); override;
    destructor Destroy; override;

    end;
  • отредактировано 13:42
    Удалось немного продвинуться, подсмотрев исходники FastScript.

    fs_iadortti.pas:
    type
    TfsADORTTI = class(TComponent); // fake component

    implementation
    type
    TFunctions = class(TfsRTTIModule)

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

    Но в мой случай оказался несколько сложнее - мне надо в этот компонент данные передать. А как же я это сделаю, если в реальности работает совсем другой класс? ;)
    Программа так и не компилируется.
  • отредактировано 13:42
    Создайте такой же фальшивый компонент. А данные в свой класс передавайте каким-нибудь методом
  • отредактировано 13:42
    Данные в класс передавать нельзя - можно только в объект класса. А объекта нет, как такового... И как его создать - тоже непонятно, потому что в конструктор нужно передавать параметр AScript.

    В общем, механизм, который в FastReport работал, теперь использовать нельзя, а чем его заменить - неизвестно, надо какие-то костыли придумывать, с ходу ничего в голову не приходит ;)

    Если у Вас есть идеи - можно чуть подробнее? Может, c кусочком кода: как объявить компонент, как создать объект и как в него передать данные?
  • отредактировано 13:42
    Как у вас раньше было?
  • отредактировано 13:42
    Раньше было так. Создан Package нужных дополнений к FR - fr3Add. В нём исходник на pascal:

    Tfr3PropisFunctionLibrary = class(TComponent)
    protected
    FCurrDataSet: TDataSet;
    FCurrID: TIntegerField;
    FCurrAbbr: TStringField;
    FCurrSymbol: TStringField;
    ...
    procedure SetCurrDataSet(ADataSet: TDataSet);
    published
    property CurrDataSet: TDataSet read FCurrDataSet write SetCurrDataSet;
    ...
    { далее всё как было принято в FastReport до 3.18}
    end;

    procedure Tfr3PropisFunctionLibrary.SetCurrDataSet(ADataSet: TDataSet);
    begin
    FCurrDataSet:=ADataSet;
    ...
    end;

    procedure Register;
    begin
    RegisterComponents('FastReport 3.0', [Tfr3PropisFunctionLibrary]);
    end;

    Получаем компонент в палитре, кидаем его на нужную форму. При создании формы передаём в него данные (C++):
    fr3PropisFunctionLibrary->CurrDataSet=fOEdit->mCurrs;

    Можно всё прикрепить к проекту, без библиотеки, но тогда функции не будут видны в дизайнере отчётов из среды Builder/Delphi, и всё равно неясно, что за Script передавать в качестве параметра конструктора объекта. Если передавать nil, то эксцепшены валят, и всё падает.
  • отредактировано December 2005
    Я предполагаю что Tfr3PropisFunctionLibrary как раз и играет роль того самого "fake" component. Создайте еще один клас - библиотеку функций, которая и будет написанна в соответсвии с правилами. Получится что при добавлении на форму Tfr3PropisFunctionLibrary компонента - автоматом добавятся нужные функции.
  • отредактировано December 2005
    нет, Вы же спросили, как было раньше. Tfr3PropisFunctionLibrary - это раньше был реальный компонент. Когда я его добавлял на форму, я мог передавать ему данные как объекту, и в нём же были нужные функции (использующие переданные данные).

    Если я создаю fake-компонент, возникает две проблемы:
    1. Можно передать данные только в fake-компонент, а не в класс, в котором функции.
    2. Согласно описанной Вами методе в конструктор класса с функциями нужно передавать параметр AScript. При передаче туда NULL всё валится (вплоть до того, что валится IDE), а что другое туда передать - непонятно.

    Пожалуй, самый главный вопрос - что передать в качества параметра AScript, если мы используем FastReport, а не FastScript сам по себе. Все остальные проблемы я в крайнем случае способен сам решить. Help please!
  • отредактировано 13:42
    Не нужно явно вызывать конструктор, делайте так:
    fsRTTIModules.Add(TMyFunction);
  • отредактировано 13:42
    Тогда как обратиться к объекту класса TMyFunction?
  • отредактировано December 2005
    fsRTTIModules: TList

    а зачем?
  • отредактировано 13:42
    Хочу передать туда данные...

    В общем, всё оказалось гораздо хуже, чем я думал.
    Я отключил вообще все свои функции, и Package отключил - то есть FastReport (3.19.22) теперь работает без всяких надстроек.

    У меня в отчёте написан обработчик событий:

    procedure childSubHeaderOnBeforePrint(Sender: TfrxComponent);
    begin
    with childSubHeader, Engine do
    begin
    IF Trim(eInvcSubTitle.Lines.Text)='' THEN Visible:=false;
    end
    end;

    При выполнении получаем Access Violation - кто-то там обращается по адресу 000000008. Если убрать Trim - то всё проходит нормально. Причём в тексте Memo тот же Trim работает.

    В другом месте в Memo стоит текст:

    Итого на сумму: [FormatFloat('#,##0.00', SumAll)]

    То же самое - Access Violation. То есть, в моём проекте не работают даже ваши собственные функции ;) Возможно, так только в C++ Builder, но факт остаётся фактом.
  • отредактировано December 2005
    в документации по fs1.9 лежит старая информация о добавлении пользовательских процедур.

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

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