Печать Pagefooterа только на первой странице

отредактировано June 2010 Раздел: FastReport 4.0
Опишу свой шаблон.
GroupHeader
MasterData
Header
DetailData
Footer
PageFooter

Строки в DetailData могут расширяться по высоте
В GroupHeader стоит обнуление нумерации страниц, отчет двухпроходный

Нужно на первой странице, после вывода части данных из DetailData, напечатать штамп, который я поместил в PageFooter, а на второй и последующих, этого штампа быть не должно.

Что я делал.
На событие OnBeforePrint PageFootera повесил следующий код: PageFooter1.Visible := <Page> = 1;
Имею следующее: На первой странице штамп печатается, на второй не печатается, но под него выделена область, которая не заполняется данными из DetailData. Интуитивно я догадываюсь, что так происходит потому, что в тот момент, когда печатаются данные из DetailData, у PageFooterа еще стоит свойство Visible в true, но на третьей и последующих страницах место под PageFooter по-прежнему выделяется, следовательно, размер области, куда будут печататься данные из DetailData определяется единожды и хранится в какой-то переменной.
Следующий момент: Header у меня содержит штамп, который появляется на второй и последующих страницах, для этого на его событие OnBeforePrint повесил Header1.Visible := <Page> <> 1; Все работает пустого места на первой странице, на его месте нет. Сломал уже всю голову почему так.

Пробовал поместить штамп в ColumnFooter - тоже самое, только еще и штамп то выше печатается, то ниже (притягивается к колонкам). Пробовал повесить скрытие PageFootera на OnBeforePrint GroupHeaderа, результат такой же. Чувствую, что все-таки надо программно менять переменную, хранящую область печати для DetailData, но не могу нигде найти как она называется.

Версия Fast Report 4.9.32

P.S.: Ув. модераторы, если такая тема была, то прошу огромнейше простить меня за повтор и послать в топик, или подсказать поисковые слова. Я честно воспользовался поиском, нашел все, что связано PageFooter-ом и прочитал. Узнал много нового, но ответа на свой впрос не нашел.

Комментарии

  • gpigpi
    отредактировано 12:57
    Попробуйте разместить штамп на дочернем бэнде и после расчёта высоты бэндов отчёта проверяйте свободное место. Если места остаётся только на штамп, то
    Engine.ShowBand(Child1);
    Engine.NewPage;
  • отредактировано 12:57
    Кинул Child. На него поместил штамп. Child привязал к DetailData. На событие DetailData OnAfterCalcHeigth повесил то, что вы сказали:
    Engine.ShowBand(Child1);
    Engine.NewPage;
    Насколько я понимаю, Child изначально должен быть невидимым (в дизайнере поставил Visible в false)
    Правильно я все сделал?
    Вопрос такой. Какая переменная отвчает за свободное место и как узнать высоту childa
  • gpigpi
    отредактировано 12:57
    написал:
    Child привязал к DetailData
    Child не нужно привязывать к какому-либо бэнду
    написал:
    Какая переменная отвчает за свободное место и как узнать высоту childa
    Engine.FreeSpace и Child1.Height
  • отредактировано 12:57
    Премного благодарю. Завтра попробую, о результатах отпишу.

    Возникает еще такой вопрос. С учетом того, что строки бэнда с данными (тот, который до штампа) могут расширяться, штамп будет немного плавать вверх вниз
    Будет ли штамп прижат к нижней границе листа, если я проделаю следующие действия:
    Добавлю еще один Child (Child2), на него повешу вертикальные линии, расположенные, как в бэнде с данными, настрою свойство StretchMode=smMaxHeigth, скрою его (Child) и на событие OnAfterCalcHeigth бэнда с данными напишу
    if Engine.FreeSpace <= Child1.Height then
    begin
    Child2.Height := Engine.FreeSpace - Child1.Height;
    Engine.ShowBand(Child2);
    Engine.ShowBand(Child1);
    Engine.NewPage;
    end;
  • отредактировано June 2010
    Проверил. Описываю что и где я написал.
    На событие DetailData1OnAfterCalcHeigth
    if ((Engine.FreeSpace <= Child1.Height + 60) and (<Page> = 1))  
           then
           begin
                   Engine.ShowBand(Child1);
                   Engine.NewPage;
           end;
    
    +60 потому, что иначе никак, видимо FreeSpace содержит и отступ

    На событие Footer1OnAfterPrint
    if (<Page> = 1)
           then
           begin
                   Engine.ShowBand(Child1);
                  
           end;
    
    Footer1 Содержит итоги по DetailData1.
    Что имею: Штамп печатается там где надо, но из-за того, что Строки DetailData могут расширяться, штамп немного плавает вверх-вниз. Пробовал впихнуть Child2 с линиями, но не получилось почему-то.
    Вот соответствующий код:
    if ((Engine.FreeSpace <= Child1.Height + 60) and (<Page> = 1)) 
           then
           begin
                   Line148.Height := Engine.FreeSpace - Child1.Height;  Эта линия принадлежит Child2
                   Set('Engine.FreeSpace', Engine.FreeSpace - Line148.Height);   
                   Engine.ShowBand(Child2);
                   Engine.ShowBand(Child1);
                   Engine.NewPage;
           end;
    
    Линия 148 принадлежит Child2

    Получается, что childы наслаиваются один на другой, кроме этого, высота Child2 визуально намного больше, чем надо.
    Да, кстати, Оба Childa видимые (Visible=true).

    Уважаемый gpi, подскажите, можно как-то решить эту проблему?
  • gpigpi
    отредактировано 12:57
    Пример в аттаче
  • отредактировано June 2010
    Спасибо огромное за пример. Правда я сделал еще вчера и немного по-другому.

    На событие DetailData1 OnAfterCalcHeigth поместил вот это:
    if ((Engine.FreeSpace <= Child1.Height + DetailData1.Height) and (<Page> = 1))
           then
           begin
                  Child2.Height := Engine.FreeSpace - Child1.Height;                   
                  Memo118.Height := Engine.FreeSpace - Child1.Height;
                  Engine.ShowBand(Child2);
                  Engine.ShowBand(Child1);
                  Engine.NewPage;
           end;
    
    А на событие Footer1 OnAfterPrint вот это:
    if (<Page> = 1)
          then
           begin
                  Child2.Height := Engine.FreeSpace - Child1.Height;                   
                  Memo118.Height := Engine.FreeSpace - Child1.Height;
                  Engine.ShowBand(Child2);
                  Engine.ShowBand(Child1);
           end;
    

    Работает именно так как надо. Штамп расположен внизу, до него с помощью chld2 дорисовываются линии. Если данных в DetailData хватает только на один лист, то второй пустой лист создан не будет.

    Вообщем, огромное спасибо gpi за указание правильного пути в поиск решения. Было бы, конечно, хорошо, если бы этот функционал на уровне свойств компонентов(не печатуемость pagefootera на первой странице и заполнение пустого места до pagefootera вертикальными линиями последнего напечатанного бэнда) появился в следующих версиях, но это уже к разработчикам.
  • отредактировано 12:57
    Дабы не описывать свою задачу снова, задам вопрос в этой же теме. Итак, спустя некоторое время, мне требуется осуществить сортировку среди данных DetailData по некоторому полю. Подскажите как это сделать.

    Данные поступают в отчет так:
    TAdoQuery-> TfrxDBDataSet1 - это master
    TAdoTable-> TfrxDBDataSet2 - это detail

    В свойствах TAdoTable указано кто является мастером (TAdoQuery) и по каким полям нужно устанавливать связь. TAdoTable связан с таблицей-представлением (viev).

    Использовать TAdoQuery вместо TAdoTable и прописать там "order by <my_field>" не могу, т.к. у TAdoQuery нет свойств MasterFields, MasterSource, и тогда я не смогу установить связь master-detail.

    Заранее благодарю.
  • gpigpi
    отредактировано 12:57
    написал:
    т.к. у TAdoQuery нет свойств MasterFields, MasterSource, и тогда я не смогу установить связь master-detail.
    Зато есть событие OnAfterScroll
  • отредактировано 12:57
    В продолжение истории возникли еще вопросы.

    В процессе эксплуатации нашлись такие записи в DetailData, которые длинны настолько, что первая же строка DetailData является непомерно длинной, что в свою очередь приводит к тому, что внизу листа печатается штамп (Child1), а печать этих данных переносится на следующую страницу.
    Поставил у DetailData свойство split = true, то есть я хочу, чтобы DetailData частично печаталась перед штампом Child1, а остальное переносилось на другой лист, но ситуация не изменилась, поскольку возможность "сплитирования" не учитывается в расчетах FreeSpase

    Как мне заставить DetailData разбить (если это необходимо) очередную строку не по Engin.FreeSpace, а по Engine.FreeSpace - Child1.Height?

    Или может есть другие способы?

    Благодарю заранее за помощь.

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

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