При разработке и кастомизации конфигураций на платформе 1С:Предприятие 8 часто возникает задача переноса существующей печатной формы из одного документа в другой. Например, когда в документе-источнике (допустим, РеализацияТоваровИУслуг) уже есть настроенный макет АктВыполненныхРабот, и точно такой же макет с минимальными изменениями требуется внедрить в документ-приемник (например, ОтчетКомитентуОПродажах).
Многие начинающие разработчики совершают ошибку, полагая, что достаточно просто скопировать сетку табличного документа в конфигураторе. Однако визуальный перенос макета — это лишь малая часть работы. Основная сложность заключается в адаптации программного кода, формирующего и заполняющего этот макет данными. В этой статье мы подробно и пошагово разберем весь процесс: от физического копирования макета до переписывания запросов и интеграции печатной формы по стандартам БСП (Библиотеки стандартных подсистем).
Для начала нам необходимо скопировать сам табличный документ (макет) из одного объекта метаданных в другой. Рассмотрим два наиболее удобных способа выполнения этой операции.
Способ А. Прямое копирование через буфер обмена
Макеты у этого документа.АктВыполненныхРабот), выделяем его и нажимаем комбинацию клавиш Ctrl+C (или выбираем пункт «Копировать» в контекстном меню).Макеты документа-приемника и нажимаем Ctrl+V (или «Вставить» из контекстного меню).Способ Б. Перенос через промежуточный файл MXL
Макеты, выбираем команду Добавить. Задаем тип макета — «Табличный документ»..mxl. Также можно просто открыть сохраненный файл через конфигуратор, выделить все ячейки (Ctrl+A), скопировать их и вставить в новый макет документа-приемника.Теперь, когда макет находится внутри нового документа, нам необходимо детально проанализировать его структуру. Откроем макет и обратим внимание на ячейки. Большинство из них содержат параметры, которые заполняются программно в момент печати. Параметры в 1С обозначаются в свойствах ячейки типом заполнения «Параметр» (в самом макете они отображаются в угловых скобках, например, <НомерДокумента>) или «Шаблон» (отображаются в квадратных скобках внутри текста, например, [ДатаДокумента]).
Проанализируем ситуацию: структура реквизитов документа-источника РеализацияТоваровИУслуг практически всегда отличается от структуры документа-приемника ОтчетКомитентуОПродажах. Выясним ключевые различия:
Контрагент, а в отчете комитенту — Комитент. Договор в одном документе может называться ДоговорКонтрагента, в другом — просто Договор.Услуги. В отчетах комитенту перечень оказанных услуг или проданных товаров может находиться в табличных частях Товары, Услуги или специализированных секциях для вознаграждения.Рекомендуем составить простой план сопоставления параметров. Выпишем все используемые параметры макета на листок бумаги или в текстовый файл, а рядом укажем, из каких реквизитов нового документа мы будем получать эти данные. Если каких-то реквизитов в новом документе физически нет, принимаем решение: либо удаляем этот параметр из макета, либо рассчитываем его программно на основе имеющихся данных.
Для того чтобы заполнить параметры макета актуальными данными из базы, нам необходимо написать запрос. Как правильно заметили опытные разработчики на форуме, начинать нужно именно с проектирования запроса в специальном инструменте — Консоли запросов.
Рассмотрим пример построения запроса для документа-приемника. Нам нужно получить параметры шапки документа, информацию об организации, контрагенте (комитенте) и детальные строки табличной части.
Разберем пример шаблона такого запроса:
ВЫБРАТЬ
ОтчетКомитенту.Ссылка КАК Ссылка,
ОтчетКомитенту.Номер КАК НомерДокумента,
ОтчетКомитенту.Дата КАК ДатаДокумента,
ОтчетКомитенту.Организация КАК Организация,
ОтчетКомитенту.Комитент КАК Получатель,
ОтчетКомитенту.Договор КАК Договор
ПОМЕСТИТЬ ВТ_Шапка
ИЗ
Документ.ОтчетКомитентуОПродажах КАК ОтчетКомитенту
ГДЕ
ОтчетКомитенту.Ссылка В(&МассивОбъектов)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ТабличнаяЧасть.НомерСтроки КАК НомерСтроки,
ТабличнаяЧасть.Номенклатура.НаименованиеПолное КАК ТоварУслуга,
ТабличнаяЧасть.Количество КАК Количество,
ТабличнаяЧасть.Цена КАК Цена,
ТабличнаяЧасть.Сумма КАК Сумма,
ТабличнаяЧасть.СтавкаНДС КАК СтавкаНДС,
ТабличнаяЧасть.СуммаНДС КАК СуммаНДС
ИЗ
Документ.ОтчетКомитентуОПродажах.Товары КАК ТабличнаяЧасть
ГДЕ
ТабличнаяЧасть.Ссылка В(&МассивОбъектов)
Проанализируем этот запрос. Мы выбираем данные из нового источника Документ.ОтчетКомитентуОПродажах, но при этом даем выходным полям точно такие же псевдонимы (НомерДокумента, ДатаДокумента, ТоварУслуга), какие использовались в коде вывода старого макета. Это позволит нам минимизировать изменения в коде заполнения областей макета.
Современные конфигурации 1С, разработанные на базе БСП, используют модули менеджера документов для размещения логики печати. Нам нужно перенести и адаптировать код формирования печатной формы.
Сначала зарегистрируем команду печати в модуле менеджера нашего документа-приемника. Найдем экспортную процедуру ДобавитьКомандыПечати и добавим туда описание нашей новой печатной формы:
Процедура ДобавитьКомандыПечати(КоллекцияКоманд) Экспорт
КомандаПечати = КоллекцияКоманд.Добавить();
КомандаПечати.Идентификатор = "АктВыполненныхРабот";
КомандаПечати.Представление = НСтр("ru = 'Акт выполненных работ (перенесенный)'");
КомандаПечати.ПроводитьПередПечатью = Истина;
КомандаПечати.Порядок = 50;
КонецПроцедуры
После регистрации команды нам необходимо прописать обработку этой команды в процедуре Печать модуля менеджера. Проанализируем структуру вызова этой процедуры:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ПараметрыПечати = Новый Структура;
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АктВыполненныхРабот") Тогда
ТабличныйДокумент = СформироватьАктВыполненныхРабот(МассивОбъектов, ОбъектыПечати);
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"АктВыполненныхРабот",
НСтр("ru = 'Акт выполненных работ'"),
ТабличныйДокумент
);
КонецЕсли;
КонецПроцедуры
Теперь напишем саму функцию СформироватьАктВыполненныхРабот, в которой будет происходить загрузка нашего макета, обход результата запроса и заполнение областей:
Функция СформироватьАктВыполненныхРабот(МассивОбъектов, ОбъектыПечати)
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.АвтоМасштаб = Истина;
// Получаем макет из метаданных текущего документа
Макет = ПолучитьМакет("АктВыполненныхРабот");
// Получаем области макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
// Выполняем наш подготовленный запрос к БД
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ОтчетКомитенту.Ссылка КАК Ссылка,
| ОтчетКомитенту.Номер КАК НомерДокумента,
| ОтчетКомитенту.Дата КАК ДатаДокумента,
| ОтчетКомитенту.Организация КАК Организация,
| ОтчетКомитенту.Комитент КАК Получатель
|ИЗ
| Документ.ОтчетКомитентуОПродажах КАК ОтчетКомитенту
|ГДЕ
| ОтчетКомитенту.Ссылка В(&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаШапка = РезультатЗапроса.Выбрать();
Пока ВыборкаШапка.Следующий() Цикл
// Заполняем параметры области Шапка данными из выборки
ОбластьШапка.Параметры.Заполнить(ВыборкаШапка);
ТабличныйДокумент.Вывести(ОбластьШапка);
// Здесь должна быть логика вывода строк табличной части...
// Для каждой строки табличной части заполняем ОбластьСтрока и выводим:
// ТабличныйДокумент.Вывести(ОбластьСтрока);
// В конце выводим подвал документа
ТабличныйДокумент.Вывести(ОбластьПодвал);
// Добавляем разрыв страницы для печати нескольких документов за один раз
Если МассивОбъектов.Количество() > 1 Тогда
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Если вы изменяете типовую конфигурацию 1С (например, 1С:Бухгалтерия или 1С:ERP), то прямое редактирование документов в конфигураторе приведет к снятию объектов с поддержки. Это существенно усложнит процедуру последующих обновлений программы.
Мы настоятельно рекомендуем использовать механизм Внешних печатных форм (ВПФ). Это позволит решить задачу без изменения типовой конфигурации. Рассмотрим, как это сделать по шагам:
.epf.Макеты созданной внешней обработки.СведенияОВнешнейОбработке(). Она регистрирует обработку в системе.Печать(), которая будет отвечать за формирование табличного документа.Рассмотрим пример кода для модуля объекта внешней печатной формы:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.0");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидДополнительнойВнешнейОбработкиПечатнаяФорма();
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.Наименование = "Акт выполненных работ (Внешний)";
ПараметрыРегистрации.БезопасныйРежим = Истина;
// Указываем, к какому документу подключается печатная форма
ПараметрыРегистрации.Назначение.Добавить("Документ.ОтчетКомитентуОПродажах");
// Настройка самой команды печати
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Акт выполненных работ (ВПФ)";
НоваяКоманда.Идентификатор = "АктВыполненныхРаботВПФ";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовСерверногоМетода();
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ПараметрыПечати = Новый Структура;
ТабличныйДокумент = СформироватьАктВыполненныхРабот(МассивОбъектов, ОбъектыПечати);
// Выводим документ в коллекцию форм БСП
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"АктВыполненныхРаботВПФ",
"Акт выполненных работ (ВПФ)",
ТабличныйДокумент
);
КонецПроцедуры
Функцию СформироватьАктВыполненныхРабот внутри внешней обработки пишем аналогично той, что мы рассматривали для модуля менеджера. Главное отличие — макет мы получаем не из метаданных документа, а из метаданных самой внешней обработки с помощью вызова ЭтотОбъект.ПолучитьМакет("АктВыполненныхРабот").
После создания файла обработки достаточно зайти в режиме «1С:Предприятие» в раздел Администрирование – Печатные формы, отчеты и обработки – Дополнительные отчеты и обработки, нажать кнопку «Добавить из файла» и выбрать вашу обработку. Кнопка печати автоматически появится в меню «Печать» документа «Отчет комитенту о продажах» у всех пользователей.