Hare.ru @ Коллективный разум / Hare.ru @ Дикое место

Архив hare.ru 
Мысли, конвертированные в текст

Собственные руки TM


Все статьи раздела

Как печатать правильные отчёты?

Дмитрий Гаранин (XGreenX) (сентябрь 2002)

В статье "Как печатать правильные накладные?" был описан способ переноса в печатной форме последней строки документа на последнюю страницу – во избежание ситуации, когда на последней странице остается только итоговая информация по всей накладной и места для подписей и печатей.

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

Оказывается, сделать это не просто, а очень просто ;-).

Для примера я взял отчет "ВедомостьПоПартиямТМЦ" из типовой конфигурации "Торговля и склад" версии 9.21.

Итак:

Шаг 1.

Размещаем на форме рядом со списком настройки детализации еще один список. В этом втором списке мы будем отмечать, по каким группировкам необходимо переходить на новую страницу, если вся информация по ней не умещается на текущей.

Рисунок 1

Шаг 2.

В модуле формы отчета в самый конец добавляем код (выделен цветом), который инициализирует наш список значений.

Группировки.ДобавитьЗначение("Фирма","Фирма");
Группировки.ДобавитьЗначение("СтатусПартии","Статус партии");
Группировки.ДобавитьЗначение("МОЛ","МОЛ");
Группировки.ДобавитьЗначение("Поставщик","Поставщик");
Группировки.ДобавитьЗначение("Номенклатура","Номенклатура");
Группировки.ДобавитьЗначение("СвойствоПартии","Свойство партии");
Группировки.ДобавитьЗначение("Партия","Партия");
Группировки.ДобавитьЗначение("Документ","Документы движения");

Группировки.Пометка(1, 1);
Группировки.Пометка(3, 1);
Группировки.Пометка(5, 1);

спНаСтранице.ДобавитьЗначение("Фирма","Фир");
спНаСтранице.ДобавитьЗначение("СтатусПартии","СтП");
спНаСтранице.ДобавитьЗначение("МОЛ","МОЛ");
спНаСтранице.ДобавитьЗначение("Поставщик","Пост");
спНаСтранице.ДобавитьЗначение("Номенклатура","Ном");
спНаСтранице.ДобавитьЗначение("СвойствоПартии","СвП");
спНаСтранице.ДобавитьЗначение("Партия","Пар");
спНаСтранице.ДобавитьЗначение("Документ","Док");

Шаг 3.

Синхронизируем изменение порядка значений в двух списках, путем изменения соответствующекй процедуры.

Процедура ИзменениеПорядкаГрупп(НаправлениеСдвига)

ТекСтр = Группировки.ТекущаяСтрока();
ПослСдвигСтр = Группировки.РазмерСписка() - 1;
Если ТекСтр <= ПослСдвигСтр Тогда
   Если не((НаправлениеСдвига = 1) и (ТекСтр = ПослСдвигСтр)) Тогда
      Группировки.СдвинутьЗначение(НаправлениеСдвига, ТекСтр);
      спНаСтранице.СдвинутьЗначение(НаправлениеСдвига, ТекСтр);
   КонецЕсли;
Иначе
   Предупреждение("Группировка ""По документам движения"" всегда находится
   |в конце списка и не перемещается.",60);
КонецЕсли;

КонецПроцедуры

Шаг 4.

Прикрепляем вывод строк к последующим. (Не очень понятно, но лучшего определения я просто не придумал ;-).

Для этого: открываем таблицу, выделяем все строки, которые входят в горизонтальные секции, и устанавливаем для них флажок "Вместе со следующим" ("Таблица-Положение на странице").

Теперь отчет будет представлять собой неразрывный блок, который будет стараться выводиться на одной странице. Этому будет мешать только окончание страницы. Если вставить в нужных местах своего рода "мягкие разделители", которые поделят отчет на несколько неразрывных блоков, то каждый блок будет начинаться с новой страницы, если не поместится на текущую.

Делаем этот самый "мягкий разделитель".

Шаг 5.

Создаем новую секцию. Называем ее "Перенос".

Рисунок 2

Выделяем строку, выбираем "Таблица-Положение на странице" и проверяем, чтобы опция "Вместе со следующим" была отключена. Теперь эта строка может быть последней на странице в неразрывном блоке.

Шаг 6.

Немного меняем процедуру вывода группировки отчёта.

Процедура ВывестиГруппировку(Запрос,Ном)

Если Ном <= КоличествоГруппировок Тогда

НазваниеГруппировки = СписокГруппировок.ПолучитьЗначение(Ном);

Если НазваниеГруппировки = "Документ" Тогда
   ТекОстС = Запрос.НачОстС;
   ТекОстК = Запрос.НачОстК;
КонецЕсли;

Пока Запрос.Группировка(Ном) = 1 Цикл

   Если НазваниеГруппировки = "Документ" Тогда
      НазваниеСекции="Документ";
   Иначе
      НазваниеСекции="Строка"+Ном;
   КонецЕсли;

   Если (Ном >= НомерГруппировкиПоТМЦ)
    и (Запрос.ЭтоГруппа(НазваниеГруппировки)=0) Тогда
      НазваниеСекции = НазваниеСекции + "К";
   КонецЕсли;

   ПечТекстСтроки = Запрос.ПолучитьАтрибут(НазваниеГруппировки);

   Если спНаСтранице.Пометка(
    спНаСтранице.НайтиЗначение(НазваниеГруппировки))=1 Тогда
      Таб.ВывестиСекцию("Перенос");
   КонецЕсли;

   Если (ТипЗначенияСтр(ПечТекстСтроки) = "Документ") или
    (ТипЗначенияСтр(ПечТекстСтроки) = "Справочник") Тогда
      ТекРасшифровка = ПечТекстСтроки;
   Иначе
      ТекРасшифровка = "";
   КонецЕсли;

   Если НазваниеГруппировки = "Партия" Тогда
      ПечТекстСтроки = СформироватьИнформациюОПартии(ПечТекстСтроки);
   ИначеЕсли (НазваниеГруппировки = "СвойствоПартии")
    и (ПустоеЗначение(ПечТекстСтроки) = 0)
   Тогда
      ПечТекстСтроки = "" + ПечТекстСтроки.Владелец + ": " +
       СокрЛП(ПечТекстСтроки);
   ИначеЕсли НазваниеГруппировки = "Документ" Тогда
      ПечТекстСтроки = "" + глПредставлениеДокумента(ПечТекстСтроки) +
      " (" + СокрЛП(глИнформацияПоДокументуВЖурнале(ПечТекстСтроки)) + ")";
   КонецЕсли;
   ПечТекстСтроки = ?(ПустоеЗначение(ПечТекстСтроки)=1,
    глПредставлениеПустогоЗначения(НазваниеГруппировки),ПечТекстСтроки);
   Если НазваниеГруппировки = "Документ" Тогда
      ПечатьСтрокиДокумента(Запрос,Ном,НазваниеСекции,ПечТекстСтроки,
       ТекРасшифровка,ТекОстС,ТекОстК);
   Иначе
      ПечатьСтроки(Запрос,Ном,НазваниеСекции,ПечТекстСтроки,
       ТекРасшифровка);
   КонецЕсли;

   // если есть более детальная группировка - выведем ее
   Если КоличествоГруппировок > Ном Тогда
      ВывестиГруппировку(Запрос,Ном+1);
   КонецЕсли;

   КонецЦикла;
КонецЕсли;

КонецПроцедуры

Суть изменения: определить момент начала вывода нового значения группировки, по которой необходимо переносить страницы, и вывести в этот момент созданный на предыдущем шаге "мягкий" разделитель.

Готово дело.

Вот и все изменения. Подытожим.

Нам потребовалось:

  1. Добавить на форму дополнительный элемент СписокЗначений, инициализировать его (восемь строк кода) и добавить еще одну строку на синхронизацию со списком группировок.
  2. Изменить опцию "Вместе со следующим" у всех строк таблицы.
  3. Создать дополнительную пустую секцию (у меня она заполнена для наглядности).
  4. Добавить три строчки кода для определения необходимости и непосредственно вывода разделителя.
Для простых отчетов с жестко заданными группировками необходимость в пункте 1 отпадает вообще, а в пункте 4 остается только одна строка, непосредственно выводящая разделитель.

На доработку рассмотренного отчета у меня ушло гораздо меньше времени, нежели на описание методики в этой вот статье, что-то около 20-30 минут.

Для отчета с жестко заданными группировками описанную модификацию можно сделать за буквально за пять минут.

И небольшое замечание. Чтобы разделитель не съедал в отчете много места, нужно сделать его высоту как можно меньше. Только не пользуйтесь пунктом "Высота строки" контекстного меню (там нельзя установить высоту строки меньше 4), а просто потяните мышкой, передвигая границу в поле заголовков. В этом случае можно убрать высоту строки практически до нуля.

Партнеры:


Также может быть интересно:

Канал Россия 1 на http://spbtvonline.ru/
   
 Сайт поддерживается за счет партнеров:
:::... Сайт содержит архив двух версий hare.ru Карта сайта