Передача даты в запрос.
Добрый день!!!
Мне необходимо из дельфи передать в запрос отчета две даты для задания диаппазона выборки. Как это сделать корректно.
В рук. по fastreport есть пример как обращаться и работать с объектом мемо из дельфи. Но мне кажеться это немного нето. Заранее спасибо.
Мне необходимо из дельфи передать в запрос отчета две даты для задания диаппазона выборки. Как это сделать корректно.
В рук. по fastreport есть пример как обращаться и работать с объектом мемо из дельфи. Но мне кажеться это немного нето. Заранее спасибо.
Комментарии
1: Диалоговая форма в самом отчете.
2: Ч/з обработчик TfrxReport.OnGetValue (см. документацию)
3:
Я создал две переменные в отчет и в запросе указал их как параметры.
Из дельфи к ним обратился как: Все зарботало. Просто сначала наврал в синтаксисе.
Добавил в мемо переменые StartDate и StopDate для отображения диаппазона за который произойдет выборка.
При выполнении запроса он даты отобразил как 3691,2154.
Как или где задается тип переменной.
В моем случае мне нужен тип Date а он по умолчаню похоже на Variant.
Подходящую функцию конвертации ненашол.
Memo.DisplayFormat.FormatStr='dd/mm/yyyy' (Можно и через контекстное меню)
А указать тип переменной я все таки могу или нет?
В приложении создается экземпляр TFrxReport.
Программно добавляется новая переменная:
AddVariable('Категория', 'МояДата', StrToDate('10.02.2006'));
При работе приложения вызывается дизайнер отчета.
На пустую форму добавляется переменная "МояДата".
Вызывается окно предварительного просмотра.
Отчет формируется и отображается корректно.
Окно предварительного просмотра закрывается и вызывается повторно.
Возникает сообщение об ошибке "Ошибка в выражении '10.02.2006':;".
Отладка показала, что в процедуре TfrxReport.DoGetValue на участке
val:= FVariables.Items.Value;
if (TVarData(val).VType = varString) or (TVarData(val).VType = varOleStr) then
при первом просмотре отчета VType = 7, т.е. дата.
Но при втором просмотре VType уже равен 256 и ядро пытается выполнить Value:= Calc(val);!!! И выражение '10.02.2006' не поддается "расчету".
Почему в коллекции FVariables VType отдельных элементов меняется с 7 на 256 я никак не могу понять!
Определение обработчика OnGetValue исключает эту ситуацию, но вопрос принципа!
В код функции TfrxReport.DoGetValue добавляем для отладки ShowMessage, после чего отчетливо видно, что VType меняется с 7 на 256:
...
i:= FVariables.IndexOf(Expr);
if i<>-1 then
begin
val:= FVariables.Items.Value;
ShowMessage(Format('TVarData(val).VType = %d', [TVarData(val).VType]));
if (TVarData(val).VType = varString) or (TVarData(val).VType = varOleStr) then
begin
if Pos(#13#10, val)<>0 then
Value:= val
else
Value:= Calc(val);
end
else
Value:= val;
Result:= True;
Exit;
end;
...
Оказывается после PrepareReport все объекты, в том числе и пременные, тянуться из Stream в виде xml тегов. Соответсвенно значение даты парсируется как значение свойства "value" из строки "value=10.02.2006". Выделеная подстрока "10.02.2006" присваивается в элемент коллекции FVariables именно как строка (... Value: String...). Естественно все типы летят к чертовой матери. Это относится и к другим типам, не только к дате. Только, например, целые числа парсер разбирает нормально. Но, сам факт вызова парсера, начиная со второго просмотра - это чересчур! Производительности - никакой!
Если я сумбурно и непонятно выразился, пишите коменты. Я хочу разобраться в этой проблеме. Может быть я неправильно установил значения каких либо свойств, может "проблемы" вообще не существует...
Проверяется так: в обработчик события OnGetValue включаем текст
Value := Freport.Variables[VarName];
ShowMessage(Format('TVarData("%s").VType = %d', [VarName, TVarData(Value).VType]));
Подчеркиваю, что при первом формировании отчета значение переменной (не только с типом дата) возвращается из коллекции TfrxReport.Variables. При повторном построении отчета ВСЕ переменные воспринимаются как текст и "вычисляются" как выражения движком FastScript. Фактически в моей ситуации получаются две проблемы:
1) FastScript не умеет интерпретировать даты (целые числа без проблем, к примеру)
2) Потеря заданного при создании переменной типа при сохранении и извлечении из Stream - а это уже существенный баг!!!
3) Ненужные "вычисления выражений", начиная со второй попытки формирования, вместо того, чтобы напрямую брать значения переменных.
Если я не прав, укажите где.
Имеем код:
FReport.Name := 'TestReport';
FReport.EngineOptions.DestroyForms := false;
FReport.DesignReport;
В дизайнере формируем страницу и запускаем предварительный просмотр.
Ставим предварительно в модуле frClass точку останова в начале функции TfrxReport.PrepareReport. в Watch выводим свойство Name и FEngineOptions.DestroyForms. И что же видим?!
Name = 'TestReport' - отлично!!!
FEngineOptions.DestroyForms = true - ???!!!?????
Что это?
Естественно блок
if FEngineOptions.DestroyForms then
begin
TempStream := TMemoryStream.Create;
SaveToStream(TempStream);
end;
выполняется всегда.