Пример формирования внешней печатной формы из макета Word. БСП
Теги: 1С,ВнешняяОбработка,БСП 3,Word,Печать

Демонстрация процесса формирования внешней печатной формы документа из макета Word средствами БСП, колонтитулы, коллекции, и обычные параметры

# Код реализации

```1c
Функция СведенияОВнешнейОбработке() Экспорт

	// Стандартное описание сведений о внешней печатной форме

	ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();

	ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();

	ПараметрыРегистрации.БезопасныйРежим = Ложь;
	ПараметрыРегистрации.Вставить("Версия", "1.0");
	ПараметрыРегистрации.Наименование = "Название печатной формы";

	ПараметрыРегистрации.Назначение.Добавить("Справочник.ФизическиеЛица");

	НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
	НоваяКоманда.Представление = "Название команды";   //Синоним
	НоваяКоманда.Идентификатор = "НазваниеКоманды";   //ПолноеИмя
	НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();

	Возврат ПараметрыРегистрации;

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

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

	// Просто передаем управление дальше если удовлетворяет условию

	Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "НазваниеКоманды") Тогда
		ПечатьДокумента(КоллекцияПечатныхФорм, МассивОбъектов, ОбъектыПечати);
	КонецЕсли;

КонецПроцедуры

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

	 // Сначала получим данные а потом передадим их для заполнения макета

	МассивДанныхЗаполнения = ПолучитьДанныеДляПечатиДокумента(МассивОбъектов);

	ВывестиДанныеДокументаВТабличныйДокумент(КоллекцияПечатныхФорм, МассивДанныхЗаполнения, ОбъектыПечати);

КонецПроцедуры

Функция ПолучитьДанныеДляПечатиДокумента(МассивОбъектов)

	// здесь происходит заполнение данными для ПФ

	Данные = Новый Структура;
	Данные.Вставить("Организация", "ООО ""Рога и копыта""");
	Данные.Вставить("Контрагент", "ИП Иванов");
	Данные.Вставить("СуммаОплаты", 10523);
	Данные.Вставить("Дата", '202110102158');

	ТаблицаДанных = Новый ТаблицаЗначений;
	ТаблицаДанных.Колонки.Добавить("Номенклатура");
	ТаблицаДанных.Колонки.Добавить("Количество");
	ТаблицаДанных.Колонки.Добавить("Сумма");

	Строка = ТаблицаДанных.Добавить();
	Строка.Номенклатура = "тест";
	Строка.Количество = 2;
	Строка.Сумма = 50;

	Строка = ТаблицаДанных.Добавить();
	Строка.Номенклатура = "тест1";
	Строка.Количество = 3;
	Строка.Сумма = 55;

	Строка = ТаблицаДанных.Добавить();
	Строка.Номенклатура = "тест2";
	Строка.Количество = 4;
	Строка.Сумма = 51;

	ТаблицаДанныхВМассиве = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаДанных);

	Данные.Вставить("ТаблицаДанных", ТаблицаДанныхВМассиве);

	Возврат Данные;

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

Процедура ВывестиДанныеДокументаВТабличныйДокумент(КоллекцияПечатныхФорм, МассивДанныхЗаполнения, ОбъектыПечати)

	ДвоичныеДанныеМакета = ПолучитьМакет("ПФ_DOC_НазваниеМакета");

	Если ДвоичныеДанныеМакета <> Неопределено Тогда

		// Инициализируем печатную форму

		ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "НазваниеКоманды");

		// Наличие пустого табличного документа в коллекции обязательно

		ПечатнаяФорма.ТабличныйДокумент = Новый ТабличныйДокумент;

		Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета,Неопределено);
		ПечатнаяФормаДокумента = УправлениеПечатью.ИнициализироватьПечатнуюФорму(Неопределено, Макет.НастройкиСтраницыМакета, Макет);

		// Определим какие области в документе Word хотим заполнить
		// Для этого у нас документ должен быть размечен конструкциями
		// {v8 Область.НазваниеОбласти}
		// {/v8 Область.НазваниеОбласти}
		// наличие областей обязательно

		// Область для заполнения обычных параметров в тексте

		ОбластьЗаголовок = Новый Структура;
		ОбластьЗаголовок.Вставить("ИмяОбласти", "Заголовок");
		ОбластьЗаголовок.Вставить("ТипОбласти", "Общая");

		// Пример определения областей коллекций (таблица и нумерованный или обычный списки)
		ОбластьШапкаТаблицы = Новый Структура;
		ОбластьШапкаТаблицы.Вставить("ИмяОбласти", "ШапкаТаблицы");
		ОбластьШапкаТаблицы.Вставить("ТипОбласти", "Общая");

		ОбластьСтрокаТаблицы = Новый Структура;
		ОбластьСтрокаТаблицы.Вставить("ИмяОбласти", "СтрокаТаблицы");
		ОбластьСтрокаТаблицы.Вставить("ТипОбласти", "СтрокаТаблицы");

		// Область должна быть определена первым элементом списка
		// {v8 Область.НумерованныйСписок}
		// 1.{v8 Номенклатура}
		// {/v8 Область.НумерованныйСписок}

		ОбластьНумерованныйСписка = Новый Структура;
		ОбластьНумерованныйСписка.Вставить("ИмяОбласти", "НумерованныйСписок");
		ОбластьНумерованныйСписка.Вставить("ТипОбласти", "Список");

		// Область должна быть определена первым элементом списка
		// {v8 Область.МаркированныйСписок}
		// • {v8 Номенклатура}
		// {/v8 Область.МаркированныйСписок}

		ОбластьМаркированногоСписка = Новый Структура;
		ОбластьМаркированногоСписка.Вставить("ИмяОбласти", "МаркированныйСписок");
		ОбластьМаркированногоСписка.Вставить("ТипОбласти", "Список");

		// Пример определения областей колонтитулов, эти области в документе есть по умолчанию,
		// если колонтитулы определены в самом документе

		ОбластьВерхнийКолонтитул = Новый Структура;
		ОбластьВерхнийКолонтитул.Вставить("ИмяОбласти", "ВерхнийКолонтитул");
		ОбластьВерхнийКолонтитул.Вставить("ТипОбласти", "ВерхнийКолонтитул");

		ОбластьНижнийКолонтитул = Новый Структура;
		ОбластьНижнийКолонтитул.Вставить("ИмяОбласти", "НижнийКолонтитул");
		ОбластьНижнийКолонтитул.Вставить("ТипОбласти", "НижнийКолонтитул");

		// Передаем данные заполнения для заполнения печатной формы
		// Имена параметров данных заполнения должны совпадать с размеченными параметрами в документе в виде
		// {v8 НазваниеПараметра}

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьЗаголовок);
		УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения, Ложь);


		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьВерхнийКолонтитул);
		УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения);

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьНижнийКолонтитул);
		УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения);

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьШапкаТаблицы);
		УправлениеПечатью.ПрисоединитьОбласть(ПечатнаяФормаДокумента, Область, Ложь);

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьСтрокаТаблицы);
		УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения.ТаблицаДанных);

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьНумерованныйСписка);
		УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения.ТаблицаДанных);

		Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьМаркированногоСписка);
		УправлениеПечатью.ПрисоединитьИЗаполнитьКоллекцию(ПечатнаяФормаДокумента, Область, МассивДанныхЗаполнения.ТаблицаДанных);

		// Поместим получившийся документ в коллекцию печатных форм, в раздел ОфисныеДокументы
		// так БСП поймет что нужно открывать Word при формировании печатной формы

		АдресХранилищаОфисныйДокумент = УправлениеПечатью.СформироватьДокумент(ПечатнаяФормаДокумента);
		УправлениеПечатью.ОчиститьСсылки(ПечатнаяФормаДокумента, Ложь);
		УправлениеПечатью.ОчиститьСсылки(Макет);

		ОфисныеДокументы = Новый Соответствие;

		ОфисныеДокументы.Вставить(АдресХранилищаОфисныйДокумент, НСтр("ru = 'Название документа'"));

		ПечатнаяФорма.СинонимМакета    = НСтр("ru = 'Название документа (документ Microsoft Word)'");
		ПечатнаяФорма.ОфисныеДокументы = ОфисныеДокументы;

	КонецЕсли;

КонецПроцедуры
```

# Примечания

- Всем привет. Делаю по аналогии, у меня ничего не выходит. Куда копнуть?

- (1) Evgaid, Что значит не выходит? ) Ошибка какая?

- А если нужно для списка объектов вывести печатку? Просто весь код с выводом будет в цикле?

- Еще бы понять как отладочную форму прицепить. Тут ведь не одна из процедур не возвращает табличныйдокумент. Просто происходит какая то "магия" в конце

- (3) Wefast, В общем так сделал
	
Процедура ВывестиДанныеДокументаВТабличныйДокумент(КоллекцияПечатныхФорм, МассивОбъектов, ОбъектыПечати)
	
	ДвоичныеДанныеМакета = ПолучитьМакет("ПФ_DOC");
	
	Если ДвоичныеДанныеМакета <> Неопределено Тогда
		ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, ЭтотОбъект.Метаданные().Имя);	
		ОфисныеДокументы = Новый Соответствие;
		УстановитьПривилегированныйРежим(Истина);
		Для Каждого ОбъектСсылка из МассивОбъектов Цикл	
			
			ПечатнаяФорма.ТабличныйДокумент = Новый ТабличныйДокумент;
			
			Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакета,Неопределено);
			ПечатнаяФормаДокумента = УправлениеПечатью.ИнициализироватьПечатнуюФорму(Неопределено, Макет.НастройкиСтраницыМакета, Макет);
			
			ОбластьЗаголовок = Новый Структура;
			ОбластьЗаголовок.Вставить("ИмяОбласти", "Общая");
			ОбластьЗаголовок.Вставить("ТипОбласти", "Общая");
			
			ПараметрыЗаполнения = Новый Структура;
			
			ФИО = "Иванов ИИ";
			
			ПараметрыЗаполнения.Вставить("фиополные", ФИО);	
			
			Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластьЗаголовок);
			УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФормаДокумента, Область, ПараметрыЗаполнения, Ложь); 
			
			АдресХранилищаОфисныйДокумент = УправлениеПечатью.СформироватьДокумент(ПечатнаяФормаДокумента);
			
			ОфисныеДокументы.Вставить(АдресХранилищаОфисныйДокумент, КадровыеДанные.ФИО);
			
		КонецЦикла;
		
		ПечатнаяФорма.СинонимМакета    = ФИО;   // Тут видимо не ФИО а что то общее надо, но и так работает
		ПечатнаяФорма.ОфисныеДокументы = ОфисныеДокументы;
		
		УправлениеПечатью.ОчиститьСсылки(ПечатнаяФормаДокумента, Ложь);
		УправлениеПечатью.ОчиститьСсылки(Макет);
		УстановитьПривилегированныйРежим(ЛОЖЬ);   
		
	КонецЕсли;
КонецПроцедуры

- Код отрабатывает без ошибок, но по окончанию не открывает вордовский документ. Что нужно ещё дополнительно прописать?

- (6) ilgobe, Такая же проблема. Почему-то все внешние обработки открывают вордовский документ, а три из них не открывают. Хотя код верный