В таких случаях нужно хотя бы предупреждать. В версии 3.ХХ после выхода очередного релиза приходится проверять все отчеты. При таком подходе продукт годится только для домашнего использования, а не для промышленного, разработчики наверное забыли о совместимости.
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);
При использовании fsGlobalUnit функции не подключились,
помогло только непосредственная передача frxreport1.script в
Userfunctions.create(frxreport1.script),
но появилась ошибка "Несовместимые типы Class Extended, Extended", помогло
следующее:
Мда... в стабильной версии идет FastScript 1.8, а текущая 1.9. Почему такое несовпадения? И как теперь быть с интеграциями ? Паралельно не установиш и файлы одинаково называются... "тут играем тут не играем, тут рыбу заворачивали "(с)
Причем тут последний билд ? Я говорю о стабильной версии. У меня задача написать интеграцию к фастрепорт 3.19
Естественно в нем идет скрипт 1.8. Тоесть пока отчетер и скриптер развивались паралельно все было нормально. Теперь они идут вразнобой. Может есть смысл подумать об отдельных продуктах, тоесть скриптер для отчетера и скриптер как "сам по себе" ? В принципе в данном случае так оно и есть. Другого пути я ка бы не вижу потому как одновременно установить не получается... следовательно и единой интеграции быть не может. Или же просто синхронизируйте их.
Смотрим по датам релизов:
в начале был 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
Я занимаюсь интеграцией FIBPlus c другими продуктами и мне надо точно указвать для какой версии они написаны. А в данной ситуации должна надо писать для 1.9 отдельно. ПОэтому проще дождаться выхода релиза фастрепорта с 1.9 в своем составе и обновить обе интеграции сразу.
-=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 я не силён, сорри за чайниковский вопрос.
Удалось немного продвинуться, подсмотрев исходники FastScript.
fs_iadortti.pas:
type
TfsADORTTI = class(TComponent); // fake component
implementation
type
TFunctions = class(TfsRTTIModule)
То есть в палитру добавляется фальшивый компонент, просто для того, чтобы модуль прицепился в проект. Я тоже так сделал, и библиотека вроде бы скомпилировалась.
Но в мой случай оказался несколько сложнее - мне надо в этот компонент данные передать. А как же я это сделаю, если в реальности работает совсем другой класс?
Программа так и не компилируется.
Данные в класс передавать нельзя - можно только в объект класса. А объекта нет, как такового... И как его создать - тоже непонятно, потому что в конструктор нужно передавать параметр AScript.
В общем, механизм, который в FastReport работал, теперь использовать нельзя, а чем его заменить - неизвестно, надо какие-то костыли придумывать, с ходу ничего в голову не приходит
Если у Вас есть идеи - можно чуть подробнее? Может, c кусочком кода: как объявить компонент, как создать объект и как в него передать данные?
Раньше было так. Создан 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, то эксцепшены валят, и всё падает.
Я предполагаю что Tfr3PropisFunctionLibrary как раз и играет роль того самого "fake" component. Создайте еще один клас - библиотеку функций, которая и будет написанна в соответсвии с правилами. Получится что при добавлении на форму Tfr3PropisFunctionLibrary компонента - автоматом добавятся нужные функции.
нет, Вы же спросили, как было раньше. Tfr3PropisFunctionLibrary - это раньше был реальный компонент. Когда я его добавлял на форму, я мог передавать ему данные как объекту, и в нём же были нужные функции (использующие переданные данные).
Если я создаю fake-компонент, возникает две проблемы:
1. Можно передать данные только в fake-компонент, а не в класс, в котором функции.
2. Согласно описанной Вами методе в конструктор класса с функциями нужно передавать параметр AScript. При передаче туда NULL всё валится (вплоть до того, что валится IDE), а что другое туда передать - непонятно.
Пожалуй, самый главный вопрос - что передать в качества параметра AScript, если мы используем FastReport, а не FastScript сам по себе. Все остальные проблемы я в крайнем случае способен сам решить. Help please!
В общем, всё оказалось гораздо хуже, чем я думал. Я отключил вообще все свои функции, и 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, но факт остаётся фактом.
Комментарии
Все те функции будут работать, просто теперь они подключаются немного по другому, в документации которая идёт с FastScript это всё описано
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);
помогло только непосредственная передача 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;
По моему это ошибка, должно работать без добавления типов в скрипт.
Естественно в нем идет скрипт 1.8. Тоесть пока отчетер и скриптер развивались паралельно все было нормально. Теперь они идут вразнобой. Может есть смысл подумать об отдельных продуктах, тоесть скриптер для отчетера и скриптер как "сам по себе" ? В принципе в данном случае так оно и есть. Другого пути я ка бы не вижу потому как одновременно установить не получается... следовательно и единой интеграции быть не может. Или же просто синхронизируйте их.
в начале был 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
Надеюсь понятно объяснил?
Что вам мешает использовать последний билд? Боязнь "не стабильной " версии?
Сделал всё как указано, теперь библиотека не регистрируется - ей 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 я не силён, сорри за чайниковский вопрос.
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;
fs_iadortti.pas:
type
TfsADORTTI = class(TComponent); // fake component
implementation
type
TFunctions = class(TfsRTTIModule)
То есть в палитру добавляется фальшивый компонент, просто для того, чтобы модуль прицепился в проект. Я тоже так сделал, и библиотека вроде бы скомпилировалась.
Но в мой случай оказался несколько сложнее - мне надо в этот компонент данные передать. А как же я это сделаю, если в реальности работает совсем другой класс?
Программа так и не компилируется.
В общем, механизм, который в FastReport работал, теперь использовать нельзя, а чем его заменить - неизвестно, надо какие-то костыли придумывать, с ходу ничего в голову не приходит
Если у Вас есть идеи - можно чуть подробнее? Может, c кусочком кода: как объявить компонент, как создать объект и как в него передать данные?
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, то эксцепшены валят, и всё падает.
Если я создаю fake-компонент, возникает две проблемы:
1. Можно передать данные только в fake-компонент, а не в класс, в котором функции.
2. Согласно описанной Вами методе в конструктор класса с функциями нужно передавать параметр AScript. При передаче туда NULL всё валится (вплоть до того, что валится IDE), а что другое туда передать - непонятно.
Пожалуй, самый главный вопрос - что передать в качества параметра AScript, если мы используем FastReport, а не FastScript сам по себе. Все остальные проблемы я в крайнем случае способен сам решить. Help please!
fsRTTIModules.Add(TMyFunction);
а зачем?
В общем, всё оказалось гораздо хуже, чем я думал.
Я отключил вообще все свои функции, и 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, но факт остаётся фактом.