СКД. Вставка разрыва страницы

Столкнувшись с достаточно типовой проблемой при разработке отчетов на системе компоновки данных(СКД), вставка разрыва страницы в конце группировки, на форумах и в документации не нашел простого решения этой задачи. Пост-обработкой табличного документа заниматься не хотелось, хотя совсем этого избежать пока не удалось 🙂 , поэтому было найдено не сложное решение которым я хочу с вами поделиться.

 

Столкнувшись с достаточно типовой проблемой при разработке отчетов на системе компоновки данных(СКД), вставка разрыва страницы после в конце группировки, на форумах и в документации не нашел простого решения этой задачи. Пост-обработкой табличного документа заниматься не хотелось, хотя совсем этого избежать пока не удалось 🙂 , поэтому было найдено не сложное решение которым я хочу с вами поделиться.

Отчет будем формировать программно переопределив событие «ПриКомпоновкеРезультата»

 

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка=ЛОжь;

Настройки = КомпоновщикНастроек.ПолучитьНастройки();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,Настройки,ДанныеРасшифровки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

ПроцессорВывода.НачатьВывод();

ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Пока
ЭлементРезультата <> Неопределено Цикл
    Если
ЭлементРезультата.ЗначенияПараметров.Количество()=1 Тогда
            Если
ЭлементРезультата.ЗначенияПараметров[0].Значение = «Разорвать» Тогда
           
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
    КонецЕсли;
   
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
   
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();

 

Как вы видите здесь все шаблонно, весь фокус находится в анализе ЭлементРезультата, в нем нужно определить когда собсвенно резать. Как я это решил для себя:

В СКД был добавлен Параметр РазрывСтраницы с типом строка и заданным значением «Разорвать»

 

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

 

В настройка этой группировки я убрал Авто поля и вставил свой парметр РазрывСтраницы.

 

 

Далее для этой группировки сделал свой макет:

 

Чтобы сделать группировку не видимой я в настройках, для этой группировки установил условное оформление: цвета текста, фона, линий — белые.

На закладке Другие настройки установил: Тип макета — вертикально, Выводить отбор — не выводить.

Для чего все это было сделано, напомню кусочек кода:

 

    Если ЭлементРезультата.ЗначенияПараметров.Количество()=1 Тогда
            Если
ЭлементРезультата.ЗначенияПараметров[0].Значение = «Разорвать» Тогда
           
ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
        КонецЕсли;
    КонецЕсли;

 

Для группировки ГруппировкаРазрыв у нас количество в коллекции ЗначенияПараметров будет равно 1. Всегда будет 1 параметр и его значение будет всегда равно нашей строке «Разорвать»  Благодаря этому и появляется выловить его при обходе результата. В пост обработки табличного документа придется удалить 2 последние строки, иначе у нас будет печататься пустая страница.

С уважение Петр Юрьевич Чечин


57 Comments

  1. stoptime

    Столкнувшись с достаточно типовой проблемой при разработке отчетов на системе компоновки данных(СКД), вставка разрыва страницы в конце группировки, на форумах и в документации не нашел простого решения этой задачи. Пост-обработкой табличного документа заниматься не хотелось, хотя совсем этого избежать пока не удалось 🙂 , поэтому было найдено не сложное решение которым я хочу с вами поделиться.

    Перейти к публикации

    Reply
  2. Boroda

    Спасибо за хорошую публикацию, но почему-то, как ни старался, не могу посмотреть картинки к ней. Вместо них — лишь рамка с красным крестиком

    Reply
  3. stoptime

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

    Reply
  4. max082

    stoptime, как раз искал решение такой задачи месяц назад. В итоге решил тупо пост-обработкой(. Ваш вариант интереснее!

    Reply
  5. stoptime

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

    Reply
  6. echo77

    1С расчетные листки в ЗУПе постобработкой режет

    Reply
  7. Saipl

    А если в СКД в макете создать макет заголовка группировки для врачей, создать именную область макета в свойствах которой в группе Параграф указать «Начало страницы» ???

    Reply
  8. stoptime

    (6) Saipl, Пробовал. вставлять разрыв страницы в макете, настраивать параграф. Убирамть макет оформления. в нем кстате нельзя настроить Параграф. Вобщем я досточно пошарился по всему механизму работы с макетами. Все пробовал на платформе 8.2.13, надо будет посмотреть может в следующих они испавят это поведение

    Reply
  9. bulpi

    Все это здорово напоминает удаление гланд через задний проход. Виртуозно, да. А через рот не пробовали? ( в смысле, обязательно КАЖДЫЙ отчет делать в СКД? Это религия такая?)

    Reply
  10. dandrontiy

    Гениально просто. Это зачёт.

    Reply
  11. Kesr

    Тоже думал над этой проблемой в СКД. Попробую такой вариант.

    Reply
  12. stoptime

    (10) Если получится что то добавить к придумке, сообщи. Статью расширим

    Reply
  13. marinelle

    Спасибо!!! хоть появился еще один вариант, кроме постобработки.

    Reply
  14. rusrus

    Гениально. Спасибо

    Reply
  15. lsp71

    Присоединяюсь к плюсующим. Спасибо за идею.

    Reply
  16. irenkaN

    Большое спасибо, вы очень помогли

    Reply
  17. chmod660

    спасибо за идею, воспользовался!

    Reply
  18. Armando

    Спасибо

    Что бы группировка-пустышка не выводилась я дописал чуть-чуть:

    Если ЭлементРезультата.ЗначенияПараметров[0].Значение = «Разорвать» Тогда
    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Продолжить;
    КонецЕсли;
    
    Reply
  19. владимирп

    Все гениальное просто! Это надо взять на вооружение

    Reply
  20. www2000

    Спасибо, отличная идея!

    Но в конце поста левая картинка с правилами обмена данными, или они сюда каким-то боком относятся.

    Reply
  21. stoptime

    (19) Это я на редактировал. правил 2 статьи сразу.

    Reply
  22. Den_D

    Голь на выдумки хитра) Автору большое спасибо!

    Reply
  23. AlexO

    Т.е. снова «пустышку» выводим?

    Ничего в 1С не меняется… 🙁

    Reply
  24. vamleshka

    Спасибо за классную идею! буду пробовать ее реализовать

    Reply
  25. herfis

    Как уже было сказано выше, группировку-пустышку можно просто не выводить при поэлементном выводе отчета.

    Это сразу несколько плюшек дает:

    1) не выводится лишняя строка

    2) отпадает необходимость настраивать оформление группировки-пустышки, обеспечивая её условную невидимость

    3) а самое вкусное — не надо удалять строки с «хвостовым» разрывом строки. Т.к. после последнего разрыва теперь нет данных для вывода, то пустой лист не выгоняется.

    Reply
  26. pau74

    Спасибо за идею.

    Можно перед выводом элементов, найти в схеме компоновки данных макет, в котором присутствует нужный параметр и далее в цикле проверять, что в элементе результата содержится этот макет.

    Reply
  27. oafan

    Замечу следующее: если требуется выводить итоги к группировки (в вашем случае направивший врач) — то разделитель некорректно выводится. Мои рекомендации — в макете, где выводятся итоги (в вашем случае итогов нет, но в это относится к параметру «РазрывСтраницы» см. рис) слово итоги сделать параметром, а параметр можно заполнять в параметрах макета.

    Reply
  28. zus

    Гениально и просто! Спасибо за публикацию!

    Reply
  29. logarifm

    (17) Armando,

    можно и так

    Пока ЭлементРезультата <> Неопределено Цикл
    Если ЭлементРезультата.ЗначенияПараметров.Количество() = 1 Тогда
    Если ЭлементРезультата.ЗначенияПараметров[0].Значение = Истина Тогда
    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЕсли;
    Иначе
    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
    КонецЕсли;
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    КонецЦикла;
    
    
    

    Показать

    Reply
  30. kosmius
    //аналогично настройкам масштаба «по ширине страницы»

    МОжно подробней…? нету такого свойства у ТабДока…. и негде нету об этом ( как зделать чтобы при печати по умолчанию стояла «по ширине страницы»???

    Reply
  31. stoptime

    (29) Тебе наверное здесь спрашивать нужно было http://infostart.ru/public/83627/ . Табличный документ имеет свойства АвтоМасштаб. А по ширине страницы это в настройках печати нужно смотреть. а не в свойствах элемента.(меню файл, параметры страницы)

    Reply
  32. victory

    Спасибо за статью!

    Чтобы не терять расшифровки добавил бы:

    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ,ДанныеРасшифровки);

    Reply
  33. Kamikadze

    Спасибо за идею. С СКД в полной мере начинаю только работать. Механизм рабочий, даже скажу больше — делит на печатные страницы отлично.

    Reply
  34. AndroidRu

    Хорошее решение.

    Reply
  35. sank84

    Спасибо!

    Reply
  36. stoptime

    удивляюсь что все еще актуально. 🙂

    Reply
  37. igor-tit

    (25) Имена Макетов в СКД «Макет1», «Макет2» и т.д. НЕ совпадут и похожими именами макетов при выводе. Порядковые номера макетов в СКД завися от порядка их создания, а номера макетов при выводе связаны с порядком Группировок в структуре отчета.

    Reply
  38. igor-tit

    Спасибо. Очень к стати публикация.

    Reply
  39. NatalyaVP

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

    Подскажите, а в какую часть модуля нужно вставить процедуру «ПриКомпоновкеРезультата»?

    Я сделала всё как описано, но ничего не получилось, программа просто не заходит в процедуру «Процедура ПриКомпоновкеРезультата».

    Reply
  40. herfis

    (39) Это событие объекта «Отчет». Соответственно — в модуль отчета (не формы).

    Reply
  41. NatalyaVP

    Что значит «программно переопределив событие «ПриКомпоновкеРезультата»»?

    Как это сделать?

    Я скопировала полностью процедуру «ПриКомпоновкеРезультата» , вставила её в модуль отчета, но программа туда не заходит.

    Наверно, нужно что-то ещё написать. Подскажите, пожалуйста.

    Спасибо.

    Reply
  42. herfis

    (41)

    1) Может и заходит. Если клиент-сервер, то без перевода сервера в отладочный режим серверный модуль отладить не получится

    2) Да нет, копирования должно быть достаточно. Для переопределения события объекта (не формы) достаточно правильной сигнатуры процедуры.

    Для очистки совести можете в конфигураторе в модуле нажать Ctrl+Alt+P. Если «ПриКомпоновкеРезультата» будет в угловых скобках в конце списка — значит, не переопределилась (ошибка в названии или списке параметров). Ну или удалить всю вашу писанину и выбрать событие в угловых скобках из списка процедур/событий. Тогда конфигуратор сам переопределит событие, а вы внутрь скопируете все остальное.

    3) честно говоря, судя по уровню знаний, у вас в чем угодно может быть затык. В таких случаях бывает сложно удаленно диагностировать 🙂

    Reply
  43. NatalyaVP

    Я делаю согласно написанной инструкции, значит этот метод не ко всем отчетам подходит, либо инструкция так написана.

    Уровень знаний у меня нормальный, с скд только сейчас столкнулась.

    Reply
  44. NatalyaVP

    (42), » в модуле нажать Ctrl+Alt+P. Если «ПриКомпоновкеРезультата»» — я так и делаю. Не заходит программа в процедуру «ПриКомпоновкеРезультата».

    Reply
  45. user_2010

    Большое спасибо за статью!

    Выручила!

    сама не пробовала, но подумалось, чтобы не устанавливать цвет белый, может быть можно сделать пустым значение поля?

    вот так:

    Если ЭлементРезультата.ЗначенияПараметров.Количество()=1 Тогда
    Если ЭлементРезультата.ЗначенияПараметров[0].Значение = «Разорвать» Тогда

    ЭлементРезультата.ЗначенияПараметров[0].Значение = «»;

    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    КонецЕсли;
    КонецЕсли;
    

    или так нельзя изменять?

    Reply
  46. herfis

    (46) Читай комментарии. Смотри (17), (24), (28)

    Я делал так:

    ПроцессорВывода.НачатьВывод();
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Пока ЭлементРезультата <> Неопределено Цикл
    Если ЭлементРезультата.ЗначенияПараметров.Количество() = 1 И ЭлементРезультата.ЗначенияПараметров[0].Значение = «РазрывСтраницы» Тогда
    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    Иначе
    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
    КонецЕсли;
    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    КонецЦикла;
    ПроцессорВывода.ЗакончитьВывод();
    

    Показать

    Reply
  47. user_2010

    (47) Спасибо!

    Reply
  48. Elected

    Разрыв страницы работает только, если отчет «нарисован» в макете?

    Reply
  49. Elected

    В таблице разделитель страниц не работает, но зато правильно расставляет параметр в группировке.

    Reply
  50. BelskyAV

    Спасибо!

    Reply
  51. keyn5565`

    каряво работает, пол документа выводит разрыв другую половину нет

    Reply
  52. oafan

    (52) Отчет можно посмотреть?

    Reply
  53. keyn5565`

    (53)

    либо я запутался

    либо отчет криво написал

    пытался вместо параметра сделать через вычисляемое поле, результат тот же

    Reply
  54. oafan

    (54)Или закомментируйте Э

    лементРезультата = ПроцессорКомпоновки.Следующий();:
    Для каждого Стр из ЭлементРезультата.ЗначенияПараметров Цикл
    Если Стр.Значение = «Разорвать» Тогда
    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    //ЭлементРезультата = ПроцессорКомпоновки.Следующий();
    Выведена = истина;
    //Продолжить;
    КонецЕсли;
    КонецЦикла;
    
    Если выведена Тогда
    Продолжить
    КонецЕсли;
    
    или без
    Если выведена Тогда
    Продолжить
    КонецЕсли;

    Показать

    Reply
  55. keyn5565`

    (55)

    Спасибо что откликнулись!

    уже разобрался

    проблема была в моей невнимательности

    просто не указал

    СтандартнаяОбработка = Ложь

    в начале процедуры вывода

    Reply
  56. timurhv

    Если нельзя вклиниться в типовой вывод, можно использовать еще один велосипед в дополнение к статье:

    КонечнаяОбласть = ДокументРезультат.НайтиТекст(«Разорвать»);
    Если КонечнаяОбласть <> Неопределено Тогда
    пТабличныйДокумент1 = Новый ТабличныйДокумент;
    пТабличныйДокумент2 = Новый ТабличныйДокумент;
    пТабличныйДокумент1.Вывести(ДокументРезультат.ПолучитьОбласть(«R1:R» + Формат(КонечнаяОбласть.Верх — 1,»ЧГ=»)));
    пТабличныйДокумент2.Вывести(ДокументРезультат.ПолучитьОбласть(«R» + Формат(КонечнаяОбласть.Верх + 1,»ЧГ=») + «:R» + Формат(ДокументРезультат.ВысотаТаблицы,»ЧГ=»)));
    
    ДокументРезультат.Очистить();
    ДокументРезультат.Вывести(пТабличныйДокумент1);
    ДокументРезультат.ВывестиГоризонтальныйРазделительСтраниц();
    ДокументРезультат.Вывести(пТабличныйДокумент2);
    КонецЕсли;

    Показать

    P.S: это пример деления на 2 части, можно переделать под массив

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *