При разработке внешних печатных форм (ВПФ) в среде 1С:Предприятие часто возникает задача сформировать единый сводный документ (например, сводную спецификацию, накладную или реестр) по нескольким выбранным документам. Стандартный механизм БСП при передаче массива документов обычно формирует отдельный лист для каждого документа, выводя шапку, строки табличной части, подвал и вставляя разделитель страниц. Рассмотрим, как объединить строки всех выбранных документов в одну общую таблицу и сгруппировать одинаковые позиции номенклатуры.
В типовом коде формирования печатной формы для каждого документа из переданного массива МассивОбъектов выполняется отдельный цикл. Внутри этого цикла последовательно выводятся:
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц().Для объединения всех данных в одну таблицу нам требуется решить две задачи: убрать циклический вывод шапок и разделителей, а также изменить структуру запроса, сгруппировав однотипные строки по всей выборке переданных документов.
Разберем подробно изменения, которые необходимо внести в алгоритм формирования печатной формы:
НомерСтроки и ссылку на документ из полей выборки строк. Добавляем секцию СГРУППИРОВАТЬ ПО по номенклатуре, характеристике, упаковке и ставке НДС. Числовые показатели (количество, упаковки, суммы, суммы НДС) оборачиваем в агрегатную функцию СУММА().ОбластьШапка).ОбластьСтрока).ОбластьПодвал).ВывестиГоризонтальныйРазделительСтраниц.Посмотрим на практическую реализацию функции, формирующей единый табличный документ:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати) Экспорт
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РеализацияТоваров_СводнаяСпецификация";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Документ.Ссылка КАК Ссылка,
| Документ.Дата КАК Дата,
| Документ.Организация КАК Поставщик,
| Документ.Контрагент КАК Получатель,
| Документ.УчитыватьНДС КАК УчитыватьНДС,
| Документ.ЦенаВключаетНДС КАК ЦенаВключаетНДС,
| Документ.Номер КАК Номер
|ИЗ
| Документ.РеализацияТоваров КАК Документ
|ГДЕ
| Документ.Ссылка В(&МассивОбъектов)
| И Документ.Проведен
|
|УПОРЯДОЧИТЬ ПО
| Ссылка,
| Дата
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| ТаблицаТовары.Номенклатура КАК Номенклатура,
| ТаблицаТовары.Номенклатура.Представление КАК Товар,
| ВЫРАЗИТЬ(ТаблицаТовары.Номенклатура.НаименованиеПолное КАК СТРОКА(200)) КАК НоменклатураПредставление,
| ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Характеристика) КАК ХарактеристикаПредставление,
| ВЫБОР
| КОГДА ТаблицаТовары.Упаковка <> ЗНАЧЕНИЕ(Справочник.УпаковкиНоменклатуры.ПустаяСсылка)
| ТОГДА ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Упаковка.ЕдиницаИзмерения)
| ИНАЧЕ ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Номенклатура.ЕдиницаИзмерения)
| КОНЕЦ КАК ЕдиницаИзмерения,
| СУММА(ТаблицаТовары.Количество) КАК Количество,
| СУММА(ТаблицаТовары.КоличествоУпаковок) КАК КоличествоУпаковок,
| МАКСИМУМ(ВЫБОР
| КОГДА ТаблицаТовары.Количество = 0
| ТОГДА ТаблицаТовары.Количество
| ИНАЧЕ ТаблицаТовары.Сумма / ТаблицаТовары.Количество
| КОНЕЦ) КАК Цена,
| СУММА(ТаблицаТовары.Сумма) КАК Сумма,
| СУММА(ТаблицаТовары.СуммаНДС) КАК СуммаНДС,
| ТаблицаТовары.СтавкаНДС КАК СтавкаНДС
|ИЗ
| Документ.РеализацияТоваров.Товары КАК ТаблицаТовары
|ГДЕ
| ТаблицаТовары.Ссылка В(&МассивОбъектов)
| И ТаблицаТовары.Ссылка.Проведен
|
|СГРУППИРОВАТЬ ПО
| ТаблицаТовары.Номенклатура,
| ТаблицаТовары.Номенклатура.Представление,
| ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Характеристика),
| ВЫБОР
| КОГДА ТаблицаТовары.Упаковка <> ЗНАЧЕНИЕ(Справочник.УпаковкиНоменклатуры.ПустаяСсылка)
| ТОГДА ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Упаковка.ЕдиницаИзмерения)
| ИНАЧЕ ПРЕДСТАВЛЕНИЕ(ТаблицаТовары.Номенклатура.ЕдиницаИзмерения)
| КОНЕЦ,
| ВЫРАЗИТЬ(ТаблицаТовары.Номенклатура.НаименованиеПолное КАК СТРОКА(200)),
| ТаблицаТовары.СтавкаНДС
|
|УПОРЯДОЧИТЬ ПО
| Номенклатура
|АВТОУПОРЯДОЧИВАНИЕ";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Результаты = Запрос.ВыполнитьПакет();
Макет = ПолучитьМакет("Макет");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
ВыборкаПоДокументам = Результаты[0].Выбрать();
ВыборкаПоТабличнымЧастям = Результаты[1].Выбрать();
// Заполняем реквизиты шапки из первого документа массива
Если ВыборкаПоДокументам.Следующий() Тогда
ОбластьШапка.Параметры.Номер = ВыборкаПоДокументам.Номер;
ОбластьШапка.Параметры.Дата = Формат(ВыборкаПоДокументам.Дата, "ДЛФ=DD");
ТабличныйДокумент.Вывести(ОбластьШапка);
КонецЕсли;
ИтогоСуммаБезНДС = 0;
ИтогоСуммаСНДС = 0;
ИтогоНДС = 0;
// Выводим сгруппированные строки всех документов
Пока ВыборкаПоТабличнымЧастям.Следующий() Цикл
ОбластьСтрока.Параметры.Заполнить(ВыборкаПоТабличнымЧастям);
ОбластьСтрока.Параметры.Товар = ФормированиеПечатныхФормСервер.ПолучитьПредставлениеНоменклатурыДляПечати(
ВыборкаПоТабличнымЧастям.НоменклатураПредставление,
ВыборкаПоТабличнымЧастям.ХарактеристикаПредставление
);
СтавкаНДСЧисло = ОбработкаТабличнойЧастиТоварыКлиентСерверПовтИсп.ПолучитьСтавкуНДСЧислом(ВыборкаПоТабличнымЧастям.СтавкаНДС) * 100;
Если ВыборкаПоДокументам.ЦенаВключаетНДС Тогда
ЦенаБезНдс = Окр(ВыборкаПоТабличнымЧастям.Цена * 100 / (100 + СтавкаНДСЧисло), 2);
СуммаБезНдс = ВыборкаПоТабличнымЧастям.Сумма - ВыборкаПоТабличнымЧастям.СуммаНДС;
СуммаСНдс = ВыборкаПоТабличнымЧастям.Сумма;
Иначе
ЦенаБезНдс = ВыборкаПоТабличнымЧастям.Цена;
СуммаБезНдс = ВыборкаПоТабличнымЧастям.Сумма;
СуммаСНдс = ВыборкаПоТабличнымЧастям.Сумма + ВыборкаПоТабличнымЧастям.СуммаНДС;
КонецЕсли;
ИтогоСуммаБезНДС = ИтогоСуммаБезНДС + СуммаБезНдс;
ИтогоСуммаСНДС = ИтогоСуммаСНДС + СуммаСНдс;
ИтогоНДС = ИтогоНДС + ВыборкаПоТабличнымЧастям.СуммаНДС;
ОбластьСтрока.Параметры.ЦенаБезНдс = ЦенаБезНдс;
ОбластьСтрока.Параметры.СуммаБезНдс = СуммаБезНдс;
ОбластьСтрока.Параметры.СуммаСНдс = СуммаСНдс;
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
// Заполнение и вывод подвала
ОбластьПодвал.Параметры.ИтогоСуммаБезНДС = ИтогоСуммаБезНДС;
ОбластьПодвал.Параметры.ИтогоСуммаСНДС = ИтогоСуммаСНДС;
ОбластьПодвал.Параметры.ИтогоСуммаБезНДСПрописью = ФормированиеПечатныхФормСервер.СформироватьСуммуПрописью(ИтогоСуммаСНДС);
ОбластьПодвал.Параметры.ИтогоСуммаСНДС = ИтогоСуммаСНДС;
Руководители = ФормированиеПечатныхФормСервер.ОтветственныеЛицаОрганизаций(ВыборкаПоДокументам.Поставщик, ВыборкаПоДокументам.Дата);
ОбластьПодвал.Параметры.ПостДиректор = ФормированиеПечатныхФормСервер.ФамилияИнициалыФизЛица(Руководители.Руководитель);
ПредставлениеПоставщика = ФормированиеПечатныхФормСервер.ОписаниеОрганизации(
ФормированиеПечатныхФормСервер.СведенияОЮрФизЛице(ВыборкаПоДокументам.Поставщик, ВыборкаПоДокументам.Дата), "ПолноеНаименование,");
ОбластьПодвал.Параметры.Поставщик = ПредставлениеПоставщика;
ПредставлениеПолучателя = ФормированиеПечатныхФормСервер.ОписаниеОрганизации(
ФормированиеПечатныхФормСервер.СведенияОЮрФизЛице(ВыборкаПоДокументам.Получатель, ВыборкаПоДокументам.Дата), "ПолноеНаименование,");
ОбластьПодвал.Параметры.Покупатель = ПредставлениеПолучателя;
ТабличныйДокумент.Вывести(ОбластьПодвал);
// Регистрация области печати в БСП для каждого объекта
Для Каждого ДокументСсылка Из МассивОбъектов Цикл
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабличныйДокумент, 1, ОбъектыПечати, ДокументСсылка);
КонецЦикла;
ТабличныйДокумент.АвтоМасштаб = Истина;
Возврат ТабличныйДокумент;
КонецФункции
При объединении строк нескольких документов следует учитывать следующие особенности:
МАКСИМУМ(Цена) может исказить среднюю цену. Если позиции должны объединяться только при условии совпадения цен, необходимо добавить поле цены в список секции СГРУППИРОВАТЬ ПО. Если же объединение должно производиться всегда, средневзвешенную цену рассчитывают делением общей суммы на общее количество: СУММА(Сумма) / СУММА(Количество).ЦенаВключаетНДС или выписаны от разных организаций/контрагентов, перед выполнением печати рекомендуется проверять однородность реквизитов массива, чтобы не допустить ошибок в расчетах.УправлениеПечатью.ЗадатьОбластьПечатиДокумента должна вызываться для всех объектов из МассивОбъектов с указанием единого диапазона строк (от первой до последней строки документа), чтобы подсистема БСП не выдавала ошибок при сохранении и отправке печатных форм.