Ширина страницы в зависимости от ширины CrossTab'а

Обсуждение Stimulsoft Reports.NET
Ответить
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Леонид »

Доброе утро, уважаемые!

Возник ещё один вопрос, на злобу дня.

На странице есть CrossTab. Необходимо после отрисовки страницы выставлять ширину страницы равную ширине уже отрисованного кросс-таба.

Т.е. что-то вроде this.Page.Width = CrossTab.Width, но на какое событие это делать?
Aleksey
Сообщения: 2761
Зарегистрирован: 22 апр 2010, 06:57

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Aleksey »

Здравствуйте,

В событии BeforePrint страницы вы можете использовать следующий код:

Код: Выделить всё

Page1.PageWidth = CrossTab1.Width;
Спасибо.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Леонид »

Да, попробовал. Но так не работает, или работает, но не так, как надо.

А меня собственно, если более конкретно, интересует следующая ситуация. Печатается CrossTab с N-количеством колонок.
Мне нужно чтобы все страницы растягивались бы с макс. шириной кросс-таба.

То есть, к примеру, если в кросс-табе 2 колонки (Январь, Февраль), то ширина одна, если выборка из весь год, то колонок 12, и ширина уже другая.

А так Page1.PageWidth = CrossTab1.Width получается, что ширина всех страниц будет равна ширине, равной ширине кросс-таба, установленной в дизайнере.
Aleksey
Сообщения: 2761
Зарегистрирован: 22 апр 2010, 06:57

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Aleksey »

Здравствуйте,

Вы можете использовать следующий код в событии "EndRender" отчета

Код: Выделить всё

StiReport report = (StiReport)sender;
foreach(StiPage page in report.RenderedPages)
{
	StiContainer crossTab = (StiContainer)page.Components["CrossTab1"];
	page.Width = crossTab.Width;
}
При этом, обязательно, необходимо установить какой-либо цвет (можно белый) для фона кросстаба.

Спасибо.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Леонид »

Вот, теперь, как надо. Всё заработало! :biggrin:

Единственное дополнение. Если, например crosstab лежит на странице, размером (шириной) в 29.7 см., и он сам такого же размера, то он не растягивается на всю ширину, кот. будет после рендеренга, что естесственно.

Так вот в событии BeginRender я делаю так:

Код: Выделить всё

const int maxWidth = 500;

  Page1.Width = maxWidth;
  CrossTab1.Width = maxWidth;
Т.е. ставлю ширину страницы в некий предполагаемый максимум, чтобы у меня была "простыня" из данных (скажем за год).

А в событии EndReder уже сжимаю так:

Код: Выделить всё

  // make pages width equal to crosstab (rendered) width
  StiReport report = (StiReport)sender;

  foreach (StiPage page in report.RenderedPages)
  {
    StiContainer crossTab = (StiContainer)page.Components["CrossTab1"];
    page.Width = (crossTab.Width > 29.7) ? crossTab.Width : 29.7; // only if it's bigger than landscape paper width
  }
Благодарю за помошь!
Aleksey
Сообщения: 2761
Зарегистрирован: 22 апр 2010, 06:57

Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Aleksey »

Здравствуйте,

Всегда рады помочь.
Сообщите, если понадобится дополнительная помощь.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Леонид »

Добрый вечер!

Не думал, что опять всплывёт эта тема, но тем не менее. Коротко о проблеме:

1) Запускаем отчёт с кросстабом. В отчёте одна страница Page1, устанавливаем в событии отчёта BeginRender:

Код: Выделить всё

const int maxWidth = 500;
Page1.Width = maxWidth;
2) Рендерим очёт в потоке, и в событии (в коде программы) _RunWorkerCompleted(), т.е. когда поток завершён и отчёт отрендерен вызываем процедуру (SetCrossTabReportFixes()) для корректировки ширины страницы до ширины CrossTab'а, которая высчитывает отрендеренную ширину CrossTab'а на первой странице, и проходит по всем страницам (отрендеренным), выставляя одинаковую ширину:

Код: Выделить всё

      // redefine pages widths
      foreach (StiPage p in stiReport.RenderedPages)
        p.PageWidth = finalPageWidth;
. Всё работает, во всех отчётах, кроме одного. Мы включили простейший пример с тестовыми данными во вложение к данному топику.

А проблема в том, что на некоторых компьютерах (например на Win10 x64) сначала печатается белый лист, затем уже данные. Если запустить отчёт второй раз, не уничтожая StiView, то повторно рендерится как надо.
Самое главное, когда делаем зум, то почему-то ширина страниц (но не всех!) вновь становится 500 пикселей, как мы установили ранее, но под отладчиком видно, что ширина устанавливается (.PageWidth = ) для каждой страницы однинаковая.

Выглядит это, как на скриншоте во вложении.

Вы когда-то рекомендовали добавлять такой код в EndRender:

Код: Выделить всё

  // make pages width equal to crosstab (rendered) width 
  StiReport report = (StiReport)sender; 

  foreach (StiPage page in report.RenderedPages) 
  { 
    StiContainer crossTab = (StiContainer)page.Components["CrossTab1"]; 
    page.Width = (crossTab.Width > 29.7) ? crossTab.Width : 29.7; // only if it's bigger than landscape paper width 
  }
Но теперь он не работает, т.к. с какой-то версии Стимула sender уже вовсе не StiReport.
Но даже не в этом суть, т.к. в любом случае мы делаем это из кода, т.к. отчётов очень много, и мы просто вызываем одну процедуру в конце рендеринга.

Даже не знаем, что с этим делать, прямо беда, пользователи жалуются, т.к. это один из самых используемых отчётов.
Вложения
Clipboard04.png
Clipboard04.png (29.94 КБ) 4222 просмотра
Clipboard03.png
Clipboard03.png (464.25 КБ) 4222 просмотра
Clipboard02.png
Clipboard02.png (97.47 КБ) 4222 просмотра
Clipboard01.png
Clipboard01.png (98.02 КБ) 4222 просмотра
StiCrossTabTest2.7z
Пример с тестовыми данными
(19.24 КБ) 143 скачивания
Aleksey
Сообщения: 2761
Зарегистрирован: 22 апр 2010, 06:57

Re: Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Aleksey »

Здравствуйте,

Спасибо за детальное описание проблемы.
Нужно некоторое время чтобы разобраться.

Спасибо.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Леонид »

Добрый день!

Не знаю, поможет это вам или нет, но в приложении два файла, один - old.mrt, второй - rebuild.mrt.
Это тот же самый отчёт, данные можете взять из примера в этом же топике. Там 6 кросстабов, но сути это не меняет.
Для теста можете оставить только один - CrossTab1 (самый верхний).

Что мы сделали? Создали новый отчёт и полностью с нуля создали все (каждый отдельно) кросстабы. И всё заработало, при абсолютно прочих равных. Вероятно, опять в каких-то тегах есть разница.

Тем не менее, это не отменяет того, что мы не меняли ни код, ни что-либо ещё, а только отчёт и странное поведение пропало.

Offtopic. К слову, к CrossTab компоненту и его дизайнеру есть немало претензий, которые не менялись уже очень много лет. Мы позже это всё опишем, но это не баги, а скорее необходимость. В частности, необходимость прописывать в ProcessCell событии разные штуки (а в коде HashTable) для подсчёта итоговых сумм, когда, ещё в стародавние времена в FastReport'е, например, был просто флажок и ещё кое-какие другие неудобства.
Вложения
Отгрузка (оплата) по менеджерам (% выполнения плана)_rebuild.mrt
Переделаннаая версия отчёта
(193.45 КБ) 288 скачиваний
Отгрузка (оплата) по менеджерам (% выполнения плана) - OLD.mrt
Текущая версия отчёта
(193.42 КБ) 324 скачивания
Aleksey
Сообщения: 2761
Зарегистрирован: 22 апр 2010, 06:57

Re: Ширина страницы в зависимости от ширины CrossTab'а

Сообщение Aleksey »

Здравствуйте,

Спасибо за дополнительную информацию, разбираемся.
Дадим знать, если будут какие-либо результаты.

Спасибо.
Ответить