Как правильно и быстро перенести макет печатной формы в другой документ в 1С

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

При разработке и кастомизации конфигураций на платформе 1С:Предприятие 8 часто возникает задача переноса существующей печатной формы из одного документа в другой. Например, когда в документе-источнике (допустим, РеализацияТоваровИУслуг) уже есть настроенный макет АктВыполненныхРабот, и точно такой же макет с минимальными изменениями требуется внедрить в документ-приемник (например, ОтчетКомитентуОПродажах).

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

Шаг 1. Физический перенос макета в конфигураторе

Для начала нам необходимо скопировать сам табличный документ (макет) из одного объекта метаданных в другой. Рассмотрим два наиболее удобных способа выполнения этой операции.

Способ А. Прямое копирование через буфер обмена

  1. Открываем конфигуратор и находим в дереве метаданных документ-источник.
  2. Раскрываем ветку Макеты у этого документа.
  3. Находим нужный макет (например, АктВыполненныхРабот), выделяем его и нажимаем комбинацию клавиш Ctrl+C (или выбираем пункт «Копировать» в контекстном меню).
  4. Переходим к документу-приемнику в дереве метаданных.
  5. Выделяем ветку Макеты документа-приемника и нажимаем Ctrl+V (или «Вставить» из контекстного меню).
  6. При необходимости переименовываем скопированный макет в соответствии с вашими требованиями к разработке.

Способ Б. Перенос через промежуточный файл MXL

  1. Открываем документ-источник, находим макет и открываем его двойным щелчком мыши.
  2. В главном меню программы выбираем пункт Файл – Сохранить копию....
  3. В диалоговом окне сохранения выбираем тип файла «Табличный документ (*.mxl)» и сохраняем его на локальный диск.
  4. В документе-приемнике нажимаем правой кнопкой мыши по ветке Макеты, выбираем команду Добавить. Задаем тип макета — «Табличный документ».
  5. Открываем созданный пустой макет, переходим в меню Таблица – Импорт... и выбираем ранее сохраненный файл .mxl. Также можно просто открыть сохраненный файл через конфигуратор, выделить все ячейки (Ctrl+A), скопировать их и вставить в новый макет документа-приемника.

Шаг 2. Анализ и адаптация параметров макета

Теперь, когда макет находится внутри нового документа, нам необходимо детально проанализировать его структуру. Откроем макет и обратим внимание на ячейки. Большинство из них содержат параметры, которые заполняются программно в момент печати. Параметры в 1С обозначаются в свойствах ячейки типом заполнения «Параметр» (в самом макете они отображаются в угловых скобках, например, <НомерДокумента>) или «Шаблон» (отображаются в квадратных скобках внутри текста, например, [ДатаДокумента]).

Проанализируем ситуацию: структура реквизитов документа-источника РеализацияТоваровИУслуг практически всегда отличается от структуры документа-приемника ОтчетКомитентуОПродажах. Выясним ключевые различия:

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

Шаг 3. Разработка запроса для получения данных

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

Рассмотрим пример построения запроса для документа-приемника. Нам нужно получить параметры шапки документа, информацию об организации, контрагенте (комитенте) и детальные строки табличной части.

Разберем пример шаблона такого запроса:


ВЫБРАТЬ
	ОтчетКомитенту.Ссылка КАК Ссылка,
	ОтчетКомитенту.Номер КАК НомерДокумента,
	ОтчетКомитенту.Дата КАК ДатаДокумента,
	ОтчетКомитенту.Организация КАК Организация,
	ОтчетКомитенту.Комитент КАК Получатель,
	ОтчетКомитенту.Договор КАК Договор
ПОМЕСТИТЬ ВТ_Шапка
ИЗ
	Документ.ОтчетКомитентуОПродажах КАК ОтчетКомитенту
ГДЕ
	ОтчетКомитенту.Ссылка В(&МассивОбъектов)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТабличнаяЧасть.НомерСтроки КАК НомерСтроки,
	ТабличнаяЧасть.Номенклатура.НаименованиеПолное КАК ТоварУслуга,
	ТабличнаяЧасть.Количество КАК Количество,
	ТабличнаяЧасть.Цена КАК Цена,
	ТабличнаяЧасть.Сумма КАК Сумма,
	ТабличнаяЧасть.СтавкаНДС КАК СтавкаНДС,
	ТабличнаяЧасть.СуммаНДС КАК СуммаНДС
ИЗ
	Документ.ОтчетКомитентуОПродажах.Товары КАК ТабличнаяЧасть
ГДЕ
	ТабличнаяЧасть.Ссылка В(&МассивОбъектов)

Проанализируем этот запрос. Мы выбираем данные из нового источника Документ.ОтчетКомитентуОПродажах, но при этом даем выходным полям точно такие же псевдонимы (НомерДокумента, ДатаДокумента, ТоварУслуга), какие использовались в коде вывода старого макета. Это позволит нам минимизировать изменения в коде заполнения областей макета.

Шаг 4. Написание программного кода вывода макета

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

Сначала зарегистрируем команду печати в модуле менеджера нашего документа-приемника. Найдем экспортную процедуру ДобавитьКомандыПечати и добавим туда описание нашей новой печатной формы:


Процедура ДобавитьКомандыПечати(КоллекцияКоманд) Экспорт
	
	КомандаПечати = КоллекцияКоманд.Добавить();
	КомандаПечати.Идентификатор = "АктВыполненныхРабот";
	КомандаПечати.Представление = НСтр("ru = 'Акт выполненных работ (перенесенный)'");
	КомандаПечати.ПроводитьПередПечатью = Истина;
	КомандаПечати.Порядок = 50;
	
КонецПроцедуры

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


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
	
	ПараметрыПечати = Новый Структура;
	
	Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "АктВыполненныхРабот") Тогда
		
		ТабличныйДокумент = СформироватьАктВыполненныхРабот(МассивОбъектов, ОбъектыПечати);
		УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
			КоллекцияПечатныхФорм,
			"АктВыполненныхРабот",
			НСтр("ru = 'Акт выполненных работ'"),
			ТабличныйДокумент
		);
		
	КонецЕсли;
	
КонецПроцедуры

Теперь напишем саму функцию СформироватьАктВыполненныхРабот, в которой будет происходить загрузка нашего макета, обход результата запроса и заполнение областей:


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

Шаг 5. Альтернативное и наиболее рекомендуемое решение: Внешняя печатная форма (ВПФ)

Если вы изменяете типовую конфигурацию 1С (например, 1С:Бухгалтерия или 1С:ERP), то прямое редактирование документов в конфигураторе приведет к снятию объектов с поддержки. Это существенно усложнит процедуру последующих обновлений программы.

Мы настоятельно рекомендуем использовать механизм Внешних печатных форм (ВПФ). Это позволит решить задачу без изменения типовой конфигурации. Рассмотрим, как это сделать по шагам:

  1. В конфигураторе выберите меню Файл – Новый... и создайте Внешнюю обработку. Сохраните ее на диск с расширением .epf.
  2. Перенесите скопированный макет в ветку Макеты созданной внешней обработки.
  3. В модуле объекта внешней обработки пропишите обязательную по стандартам БСП экспортную функцию СведенияОВнешнейОбработке(). Она регистрирует обработку в системе.
  4. В этом же модуле объекта разместите экспортную процедуру Печать(), которая будет отвечать за формирование табличного документа.

Рассмотрим пример кода для модуля объекта внешней печатной формы:


Функция СведенияОВнешнейОбработке() Экспорт
	
	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.0");
	
	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидДополнительнойВнешнейОбработкиПечатнаяФорма();
	ПараметрыРегистрации.Версия = "1.0";
	ПараметрыРегистрации.Наименование = "Акт выполненных работ (Внешний)";
	ПараметрыРегистрации.БезопасныйРежим = Истина;
	
	// Указываем, к какому документу подключается печатная форма
	ПараметрыРегистрации.Назначение.Добавить("Документ.ОтчетКомитентуОПродажах");
	
	// Настройка самой команды печати
	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = "Акт выполненных работ (ВПФ)";
	НоваяКоманда.Идентификатор = "АктВыполненныхРаботВПФ";
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовСерверногоМетода();
	НоваяКоманда.Модификатор = "ПечатьMXL";
	
	Возврат ПараметрыРегистрации;
	
КонецФункции

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
	
	ПараметрыПечати = Новый Структура;
	ТабличныйДокумент = СформироватьАктВыполненныхРабот(МассивОбъектов, ОбъектыПечати);
	
	// Выводим документ в коллекцию форм БСП
	УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
		КоллекцияПечатныхФорм,
		"АктВыполненныхРаботВПФ",
		"Акт выполненных работ (ВПФ)",
		ТабличныйДокумент
	);
	
КонецПроцедуры

Функцию СформироватьАктВыполненныхРабот внутри внешней обработки пишем аналогично той, что мы рассматривали для модуля менеджера. Главное отличие — макет мы получаем не из метаданных документа, а из метаданных самой внешней обработки с помощью вызова ЭтотОбъект.ПолучитьМакет("АктВыполненныхРабот").

После создания файла обработки достаточно зайти в режиме «1С:Предприятие» в раздел Администрирование – Печатные формы, отчеты и обработки – Дополнительные отчеты и обработки, нажать кнопку «Добавить из файла» и выбрать вашу обработку. Кнопка печати автоматически появится в меню «Печать» документа «Отчет комитенту о продажах» у всех пользователей.

← На главную