вертикальный бэнд
привет!
вот возник такой вопрос, есть отчет с вертикальными бэндами, в бэнды надо выводить в ручную. Делаю через frxreportGetValue
CompareText(VarName, 'p1') = 0 then Value :=TableVals[frxUserDataSet1.RecNo+1,1];
Это понятно перемещаемся по вертикали, а как переместиться по горизонтали? MasterDetail2(вертикальный бэнд), как по нему перемещаться?
Вот еще вопросик, может как то решается следующая ситуация:
Есть отчет с переменным кол-вом строк и столбцов, делаем два датасета, один Master второй Detail(суммы по датам), но даты разные у каждой записи Master!
При выводе все смещается и получается каша! Вот пример
Как надо:
02.2009 | 03.2009 | 04.2009 | 05.2009
10 45 11
34 6
а выводится
02.2009 | 04.2009 | 05.2009 |
10 45 11
34 6
Помогите пожалуйста решить данный вопрос! А то то по вертикальным бэндам почти нет документации!
вот возник такой вопрос, есть отчет с вертикальными бэндами, в бэнды надо выводить в ручную. Делаю через frxreportGetValue
CompareText(VarName, 'p1') = 0 then Value :=TableVals[frxUserDataSet1.RecNo+1,1];
Это понятно перемещаемся по вертикали, а как переместиться по горизонтали? MasterDetail2(вертикальный бэнд), как по нему перемещаться?
Вот еще вопросик, может как то решается следующая ситуация:
Есть отчет с переменным кол-вом строк и столбцов, делаем два датасета, один Master второй Detail(суммы по датам), но даты разные у каждой записи Master!
При выводе все смещается и получается каша! Вот пример
Как надо:
02.2009 | 03.2009 | 04.2009 | 05.2009
10 45 11
34 6
а выводится
02.2009 | 04.2009 | 05.2009 |
10 45 11
34 6
Помогите пожалуйста решить данный вопрос! А то то по вертикальным бэндам почти нет документации!
Комментарии
Т.е. RowInddex = Index div ColumnCount;
Фильтровать датасет и скрывать все записи у которых нет дочерних.
Можно немного по подробнее, можно ли сделать это через DBDataset или ghbltncz UserDataset все таки!
Я неправильно отобразил данные и Вы не так поняли, вот как надо
Как надо:
02.2009 | 03.2009 | 04.2009 | 05.2009|
10 | 45 | | 11 |
| 34 | 6 | |
а выводится
02.2009 | 04.2009 | 05.2009 |
10 | 45 | 11 |
34 | 6 | |
Выше я написал общую формулу определения индекса строки относительно глобального индекса(который можно считать в том же OnGetValue).
Тогда не понятна сама структура отчета.
Можете показать конкретный отчет ?
вот файл отчета, к нему подключается два DBDateset соединенных как master-detail
мастер - это строки, а детаил - это столбцы.
допустим в мастер есть запись №1, в детаил на нее есть 4 записи с датами 03.2009,04.2009,05.2009,06.2009
есть запись №2, в детаил на нее есть 2 записи с датами 03.2009,06.2009
и тд.
И когда формируется отчет то записи смещаются влево, то есть данные второй записи смещаются на столбцы 03.2009,04.2009, а столбец с данными 06.2009 остается пустой!
то есть данные из детаил выводятся подряд, а не раскидываются по нужным столбцам с определенной датой!
Как это можно исправить?!
файл отчета в аттаче
И еще пару вопросов, что бы темы не плодить:
1. Как передать TStringList из Delphi в FastReport?
2. FR по умолчанию два раза проходит по отчету или это где то указывается?
Для примера самая первая строка выводит такие столбцы: 03.2009,04.2009,05.2009
а вторая : 03.2009,06.2009
Получается кроме того, чтобы смесить столбцы нужно еще добавить один столбец(пустой) в конец первой строки.
Но туда уже вернутся нельзя, бэнды просто печатают данные из датасета, т.е. сколько записей. столько и будет строк столбцов.
В Вашем случае придется нормализовать данные в матрицу, т.е. перед выводом объектов заполнить эту матрицу как это делать CrossTab.
Самый простой способ это найти в детали все уникальные даты (определить кол-во столбцов) и на каждую мастер запись добавлять даты которых для нее нет с пустыми данными.
В другом случае придется повозиться с сортировкой и расширением матрицы.v
Report.Script.AddObject('MyStringList',MyStringList); Menu -> Report -> Options -> general -> Doubble pass
Спасибо! Оцените вот такую стратегию:
Передаю из Delphi - StringGrid c датами и при выводе Вертикального я перебираю StringGrid и сравниваю с датой которая должна будет выводиться! Если даты не совпадают, то вывожу пустой Бэнд, если совпадают, то вывожу с данными.
Так можно реализовать?
Начал делать следующее, посмотрите где я ошибаюсь!?:
procedure Page1OnManualBuild(Sender: TfrxComponent);
var
DataSet,DataSet2: TfrxDataSet;
begin
DataSet := MasterData1.DataSet;
DataSet2 := MasterData2.DataSet;
DataSet.First;
DataSet2.First;
Engine.ShowBand(Header2);
i:=0;
if Engine.FinalPass then
begin
while not DataSet.Eof do
begin
Engine.ShowBand(MasterData1);
while not DataSet2.Eof do
begin
if List=<frxDBTNdet."MONTHDATE"> then
begin
Engine.ShowBand(MasterData2);
DataSet2.Next;
end else
begin
Memo32.Text:=List;
Engine.ShowBand(MasterData3);
DataSet2.Next;
end;
end;
DataSet.Next;
inc(i);
end;
end;
end;
По передаче, делаю как Вы сказали:
frxReport.Script.AddObject('ArrayDate',StringList1);
насколько я понял, в FR надо добавить эту переменную?!
обращаться с этой переменной как со StringList?
Выбрать запросом все уникальные даты из детали(если нельзя запросом, можно и в цикле пройтись по всем полям датасета, но запрос будет все-таки побыстрее) и заполнить список. Count этого списка будет определять кол-во столбцов. Т.е. вместо привязки Вертикального бэнда к датасету устанавливаем его RowCount := list.count. Создать переменные в отчете, которые послужат псевдонимами для полей. При печати столбца сверять дату со списком, если дата совпала устанавливать значения переменных значениями из датасета, переключить датасет на новую запись. Если дата не совпала, то сбрасывать значения и печатать пустой столбец.
Скрипт будет выглядеть примерно так: Где:
MasterData1 - горизонтальный бэнд.
MasterData2 - вертикальный бэнд.
'Var1', 'Var2' - переменные отчета (Report- Variables) используются как псевдонимы для полей.
В этом случае OnManualBuild не нужен.
В приложении нужно только правильно заполнить список с датами и передать его в скрипт.
frxReport.Script.AddObject('ArrayDate',StringList1); должен быть вызван перед PrepareReport.
Этот код добавляет переменную в скрипт с именем ArrayDate которая будет ссылается на StringList1.
Работать с ней можно как с обычным StringList.
Вот все сделал, вроде бы должно работать, но выпадает в ошибку! не могу понять почему!
Access violation at address 04CEA5C1 in module 'fs5.bpl' Read of address 0000000
Судя по ошибке - это ссылка на не созданный объект, но все вроде как создается и создано...
вот файлик, посмотрите пожалуйста!
даты вношу временно в процедуре frxReportOnStartReport(Sender: TfrxComponent);
а вообще будет из delphi по frxReport.Script.AddObject('List',StringList1);
Должно быть что-то вроде:
StringList1 := TStringList.Create();
frxReport.Script.AddObject('List',StringList1);
Заполнение
Report.PrepareReport;
А возможно просто не находит датасет Report.GetDataSet('frxDBTNdet') , убедитесь в правильности имени.
после обследования выяснилось следующее:
ругалось на MasterData2.RowCount :=List.Count;
List создавался на событии procedure frxReportOnStartReport(Sender: TfrxComponent);
перенес List := TStringList.Create(); в главный begin end; ругаться перестал!
Событие frxReportOnStartReport идет уже после главного begin end; ?
Теперь ругается на переменные! вот к примеру: memo12: Ошибка в выражении ": Expression expected"
все перерыл, голову сломал, на что там можно ругаться! Переменные завел правильно!
set('var1_','''' + '' + '''');
я про это уже нашел на форуме, спасибо! )))
вот в ходе дела еще вопросик возник!
событие MasterData1OnBeforePrint(Sender: TfrxComponent); один раз выполняется или после вывода каждой строчки?
Что то не могу найти событие , что бы выполнялось при выводе каждой строчки, что бы обнулять ColumnIndex, его же надо с каждой строчкой на начало передвигать!?
Событие OnBeforePrint вызывается перед выводом объекта, т.е. для бэнда оно вызывается каждый раз при выводе новой строки (столбца, для вертикального).
to -=Den=-
Спасибо большое за разъяснения и помощь! Приятно был удивлен отзывчивости службы поддержи!!!
Удачи!!!