Как объединить несколько документов в одну печатную форму в 1С?

Программист 1С v8.3 (Управляемые формы)
← На главную

При выделении нескольких документов в списке и нажатии кнопки печати платформа 1С по умолчанию выводит печатную форму для каждого документа по отдельности. В результате на печать выводится серия документов, где перед табличной частью каждого из них повторяется заголовок и шапка. Однако на практике часто возникает задача сформировать единый сводный документ, в заголовке которого будут перечислены номера всех выбранных накладных через запятую, а табличная часть будет содержать общий список номенклатуры.

Разберем подробно причины такого поведения программы и рассмотрим по шагам, как переработать алгоритм для формирования единого табличного документа.

Почему 1С создает отдельные формы для каждого документа?

Проанализируем стандартную логику механизмов печати (включая Библиотеку Стандартных Подсистем). При групповой печати процедура формирования печатной формы либо вызывается поочередно для каждого документа из массива переданных ссылок, либо собирает итоговый табличный документ путем последовательного присоединения сформированных страниц с использованием вызова ВывестиГоризонтальныйРазделительСтраниц().

Стандартные макеты спроектированы под один документ: область шапки с номером и датой выводится строго перед табличной частью соответствующего документа. Для получения сводной печатной формы требуется создать отдельную (или внешнюю) печатную форму и изменить логику выборки и вывода данных.

Алгоритм формирования сводной печатной формы

Рассмотрим порядок действий для реализации сводной формы, принимающей на вход массив документов:

  1. Передача массива ссылок: В функцию формирования печатной формы передаем не одиночную ссылку на документ, а массив ссылок МассивСсылок.
  2. Пакетный запрос к базе данных: Выполняем один запрос к базе данных по всем документам из массива. Запросом получаем типы, номера и даты документов, а также все строки их табличных частей.
  3. Формирование единой шапки: Собираем номера всех документов в одну строку с помощью функции СтрСоединить() или обходом выборки. Выводим заголовок один раз в начале табличного документа.
  4. Заполнение табличной части: Выводим в цикле строки всех товаров. При необходимости объединяем одинаковые позиции номенклатуры с помощью группировки в запросе (СГРУППИРОВАТЬ ПО).
  5. Вывод итогов: Подсчитываем общие суммы и количество по всем документам и выводим подвал печатной формы.

Пример кода для формирования единой печатной формы

Посмотрим на пример реализации функции формирования печатного документа на сервере:


Функция СформироватьСводнуюПечатнуюФорму(МассивДокументов, ОбъектыПечати) Экспорт

	ТабличныйДокумент = Новый ТабличныйДокумент;
	ТабличныйДокумент.АвтоМасштаб = Истина;
	
	Макет = ПолучитьМакет("МакетСводный");
	ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
	ОбластьШапкаТаблицы = Макет.ПолучитьОбласть("ШапкаТаблицы");
	ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
	ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
	
	// 1. Получаем список номеров документов для заголовка
	ЗапросНомера = Новый Запрос;
	ЗапросНомера.Текст = 
		"ВЫБРАТЬ
		|	РеализацияТоваровУслуг.Номер КАК Номер,
		|	РеализацияТоваровУслуг.Дата КАК Дата
		|ИЗ
		|	Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
		|ГДЕ
		|	РеализацияТоваровУслуг.Ссылка В(&МассивДокументов)
		|УПОРЯДОЧИТЬ ПО
		|	Дата ВОЗРАСТАНИЕ";
	ЗапросНомера.УстановитьПараметр("МассивДокументов", МассивДокументов);
	
	ВыборкаНомеров = ЗапросНомера.Выполнить().Выбрать();
	МассивНомеров = Новый Массив;
	Пока ВыборкаНомеров.Следующий() Цикл
		МассивНомеров.Добавить(СокращенныйНомер(ВыборкаНомеров.Номер));
	КонецЦикла;
	
	ОбластьЗаголовок.Параметры.НомераДокументов = СтрСоединить(МассивНомеров, ", ");
	ТабличныйДокумент.Вывести(ОбластьЗаголовок);
	ТабличныйДокумент.Вывести(ОбластьШапкаТаблицы);
	
	// 2. Выбираем товары из всех документов
	ЗапросТовары = Новый Запрос;
	ЗапросТовары.Текст = 
		"ВЫБРАТЬ
		|	ДокументТабличнаяЧасть.Номенклатура КАК Номенклатура,
		|	СУММА(ДокументТабличнаяЧасть.Количество) КАК Количество,
		|	СУММА(ДокументТабличнаяЧасть.Сумма) КАК Сумма
		|ИЗ
		|	Документ.РеализацияТоваровУслуг.Товары КАК ДокументТабличнаяЧасть
		|ГДЕ
		|	ДокументТабличнаяЧасть.Ссылка В(&МассивДокументов)
		|СГРУППИРОВАТЬ ПО
		|	ДокументТабличнаяЧасть.Номенклатура";
	ЗапросТовары.УстановитьПараметр("МассивДокументов", МассивДокументов);
	
	ВыборкаТоваров = ЗапросТовары.Выполнить().Выбрать();
	Пока ВыборкаТоваров.Следующий() Цикл
		ОбластьСтрока.Параметры.Заполнить(ВыборкаТоваров);
		ТабличныйДокумент.Вывести(ОбластьСтрока);
	КонецЦикла;
	
	// 3. Выводим подвал
	ТабличныйДокумент.Вывести(ОбластьПодвал);
	
	Возврат ТабличныйДокумент;

КонецФункции

Важные нюансы и рекомендации

При выгрузке данных в единый ТабличныйДокумент следует обратить внимание на следующие технические детали:

  1. Ширина колонок: Если вы комбинируете области с разной шириной колонок, используйте метод СоздатьФорматСтрок() для областей печатной формы, чтобы таблицы не деформировались.
  2. Производительность: Всегда извлекайте данные табличных частей массива документов за один запрос к базе данных. Выполнение запросов внутри цикла обхода массива документов существенно снизит скорость работы системы.
  3. Параметры страницы: Ориентация страницы и параметры масштабирования задаются для объекта ТабличныйДокумент целиком. Убедитесь, что параметры вывода установлены до возврата готовой формы.
← На главную