Динамический CrossView
Здраствуйте!
Столкнулся с проблемой при динамическом создании отчета. Облазил форум, хелп, но ничего не нашел по своей проблеме.
Необходимо динамически создать отчет, исходя из каких-то моих данных. Набор данных может меняться произвольно.
Создаю отчет, так как сказано в помощи:
Далее идет вызов самого отчета:
Так вот при frReport.ShowReport вылетает ошибка:
EVariantTypeCastError: "Could not convert variant of type (String) into type (Double)"
Если оставить тот же самы обработчик OnBeforePrint, но в дизайнере скинуть CrossView на отчет, то все работает как надо, выводятся данные, красота вобщем.
Еще одно наблюдение.... После динамического создания отчета, сохраняю его в fr3 формате (читай XML) и сохраняю отчет созданный в дизайнере. Сравниваю. Вижу что нет никаких отличий, кроме поля "PropData" у объекта "TfrxCrossView". В нем шестандцатитеричная муть, которая и отличается.
Отсюда возникает несколько вопросов:
1. Что я делаю не так, поправьте пожалуйста.
2. Что хранится в PropData у XML`а?
3. Почему возникает ошибка конвертации?
4. Как сделать правильное динамическое создание отчета с CrossView?
Заранее спасибо!
Столкнулся с проблемой при динамическом создании отчета. Облазил форум, хелп, но ничего не нашел по своей проблеме.
Необходимо динамически создать отчет, исходя из каких-то моих данных. Набор данных может меняться произвольно.
Создаю отчет, так как сказано в помощи:
.....// глобальные переменные
var
Form1: TForm1;
cross : TfrxCrossView;
Page : TfrxReportPage;
implementation
.....
Procedure Tform1.BuildRep;
Begin
frReport.Clear;
Page := TfrxReportPage.Create(frReport);
Page.CreateUniqueName;
Page.SetDefaults;
Page.Orientation := poPortrait;
Cross := TfrxCrossView.Create(Page);
Cross.CreateUniqueName;
Cross.Top := 20;
Cross.Left := 20;
Cross.width := 95;
Cross.Height := 19;
Cross.ShowColumnHeader := true;
Cross.ShowColumnTotal := false;
Cross.ShowRowHeader := false;
Cross.ShowRowTotal := false;
Cross.RowLevels := 1;
Cross.ColumnLevels := 1;
Cross.CellLevels := 1;
End;
При нажатии на кнопку Превью вызывается дизайнер :
procedure TForm1.btDesignClick(Sender: TObject);
begin
frReport.DesignReport;
end;
В нем видно, что все создалось как надо. Есть отчет, страничка и CrossView с указанными свойствами.Далее идет вызов самого отчета:
procedure TForm1.btShowClick(Sender: TObject);
begin
table1.Open;
frReport.ShowReport;
end;
На обработчике события OnBeforePrint висит следующее:
procedure TForm1.frReportBeforePrint(Sender: TfrxReportComponent);
var
i, j: Integer;
begin
Table1.First;
i := 0;
while not Table1.Eof do
begin
for j := 0 to Table1.Fields.Count - 1 do
Cross.AddValue([i], [Table1.Fields[j].DisplayLabel], [Table1.Fields[j].AsString]);
Table1.Next;
Inc(i);
end;
end;
То есть все тоже самое, что и в примере.Так вот при frReport.ShowReport вылетает ошибка:
EVariantTypeCastError: "Could not convert variant of type (String) into type (Double)"
Если оставить тот же самы обработчик OnBeforePrint, но в дизайнере скинуть CrossView на отчет, то все работает как надо, выводятся данные, красота вобщем.
Еще одно наблюдение.... После динамического создания отчета, сохраняю его в fr3 формате (читай XML) и сохраняю отчет созданный в дизайнере. Сравниваю. Вижу что нет никаких отличий, кроме поля "PropData" у объекта "TfrxCrossView". В нем шестандцатитеричная муть, которая и отличается.
Отсюда возникает несколько вопросов:
1. Что я делаю не так, поправьте пожалуйста.
2. Что хранится в PropData у XML`а?
3. Почему возникает ошибка конвертации?
4. Как сделать правильное динамическое создание отчета с CrossView?
Заранее спасибо!
Комментарии
Решил частично проблему следующим образом:
Добавил
cross.CellFunctions[j] := cfNone;
в обработчик OnBeforePrint.
(возникает еще один вопрос... Зачем при задании количества ячеек, автоматически давать им агрегатную функцию?)
После этого, отчет стал выводиться и ошибка о конвертации исчезла.
Но возникла другая проблема. Колонки автоматически сортируются (опять-таки вопрос, если я явно при создании объекта ему не сказал этого делать, то зачем автоматом ставить soAscending ???)
Эта проблема была, как бы была тоже решена....
cross.ColumnSort[0] := soNone
Все работает как полагается, но.....
допустим у меня 10 полей.... 8 из них идут на первую страницу, остальные 2 на вторую.... Беру запросом набор данных из 30 полей и усе.... акссес виолейшн..... вобщем опытным путем было установленно, что при заполнении второй страницы, прорисовывая колонки на второй части (по вертикали) возникает ошибка....
Отсюда вопрос.... я где-то опять забыл найти свойства (как например, soNone и cfNone) и установить их в нужное значение? Разработчики, будьте любезны ответьте.....
И еще одно.....
Бог с ними с полями... тяну запросом данные, состоящие всего из 4-5 полей, и с количеством строк 1000-2000, Крос строится, НО ОЧЕНЬ МЕДЛЕННО (это понятно почему, исходя из предложенного ручного заполнения на ОнБефоПринт), что не есть гут. Так как у меня будут отчеты больше 16000 строк.... Другого алгоритма заполнения Кросса нет?
Воть такие вопросики у меня... кто нибудь ответит?
Про поля - у нас подобной ошибки не наблюдается. Высылайте тестовое приложение, чтобы мы могли найти причину.
Другого способа заполнения кросса нет.