Создание внешних печатных форм в формате Word (на практике CRM проектов)
Часто у клиентов возникает необходимость создания печатных форм, непредусмотренных в типовой конфигурации. В этом случае возникает 2 варианта решения этой проблемы: дорабатывать конфигурацию или же создать внешнюю печатную форму. Оба этих варианта рабочие, но почему же всё-таки лучше прибегнуть к внешним печатным формам?● Главным преимуществом таких форм является то, что при их создании не вносятся изменения в типовую конфигурацию, что упрощает в дальнейшем обновление базы.
● Еще одним плюсом внешних печатных форм является то, что после их доработки нет необходимости обновлять базу, достаточно зайти в справочник «Дополнительные отчеты и обработки» и загрузить новый вариант обработки в нужный элемент справочника.
● Так же, если регламенты компании изменятся, и эта печатная форма больше не будет использоваться, у клиента не возникнет необходимость дорабатывать конфигурацию снова, будет достаточно отключить использование обработки в справочнике, с чем сможет справиться пользователь, не прибегая к помощи разработчика.
● В типовом функционале CRM есть возможность использования автотекста для печатных форм, но список документов, для которых ее можно использовать ограничен. Поэтому для создания печатных форм других объектов конфигурации гораздо удобнее использовать именно внешние печатные формы.
Рассмотрим создание внешней печатной формы Word. Для начала необходимо создать макет. Это должен быть документ Word, в котором каждый параметр обозначается как {v8 НазваниеПараметра}, название параметра при этом может быть любым, но желательно, чтобы оно отображало смысл выводимых в него данных. Области в таких макетах тоже необходимо выделить, их обозначают как: {v8 Область.НазваниеОбласти} для открытия области и {/v8 Область.НазваниеОбласти}, чтобы показать, что область закончилась.
Например, чтобы документ после печати из 1С принял такой вид:
Пример документа для печати
Необходимо создать вот такой макет:Макет для документа
Затем создаем внешнюю обработку, добавляем макет типа «Двоичные данные» и загружаем в него созданный ранее макет Word.В модуле объекта обработки необходимо описать сведения о внешней обработке. Для того чтобы печатную форму можно было увидеть в группе «Печать», необходимо указать Назначение – это те объекты конфигурации, откуда будет производиться печать, а также указать Вид обработки.
МассивНазначений = Новый Массив; МассивНазначений.Добавить("Документ.ТАСС_ЗаявкаНаДоговор");
РегистрационныеДанные.Вставить("Вид", "ПечатнаяФорма"); РегистрационныеДанные.Вставить("Назначение", МассивНазначений);В таблицу команд нужно добавить команду печати:
НоваяКоманда = ТаблицаКоманд.Добавить(); НоваяКоманда.Представление = "Заявка на договор для ЮЛ"; НоваяКоманда.Идентификатор = "ЗаявкаНаДоговорДляЮЛ"; НоваяКоманда.Использование = "ВызовКлиентскогоМетода"; НоваяКоманда.ПоказыватьОповещение = Истина; НоваяКоманда.Модификатор = "ПечатьMXL";Теперь переходим в модуль формы обработки, в нем мы и будем описывать процедуры печати. Создаём экспортную процедуру «Печать». В данном случае документ после создания автоматически не открывается, а добавляется в присоединенные файлы объекта конфигурации.
&НаКлиенте Процедура Печать(Идентификатор, ОбъектыНазначения) ЭкспортПри этом функция ПолучитьДанныеПечати возвращает структуру с данными макета и значениями параметров, используемых в макете печатной формы. Для получения значения параметров в данном случае используется функция ПолучитьДанныеОбъекта, которая возвращает структуру, где ключ – название параметра из макета, а значение – это значение данного параметра.
СсылкаНаОбъект = ОбъектыНазначения[0];
ИмяМакета = "ПФ_DOC_ЗаявкаНаДоговорЮЛ"; МакетИДанныеОбъекта = ПолучитьДанныеПечати(СсылкаНаОбъект, ИмяМакета); АдресХранилищаПечатнойФормы = ВыполнитьПечатьВWordНаСервере(СсылкаНаОбъект, МакетИДанныеОбъекта, ИмяМакета);
Если АдресХранилищаПечатнойФормы <> Неопределено Тогда
ИмяБезРасширения = МакетИДанныеОбъекта.Данные[СсылкаНаОбъект][ИмяМакета].ИмяДокументаБезрасширения; РасширениеБезТочки = МакетИДанныеОбъекта.Данные[СсылкаНаОбъект][ИмяМакета].Расширение;
ПараметрыФайла = Новый Структура; ПараметрыФайла.Вставить("Автор", ПользователиКлиентСервер.ТекущийПользователь()); ПараметрыФайла.Вставить("ВладелецФайлов", СсылкаНаОбъект); ПараметрыФайла.Вставить("ИмяБезРасширения", ИмяБезРасширения); ПараметрыФайла.Вставить("РасширениеБезТочки", РасширениеБезТочки) ПараметрыФайла.Вставить("ВремяИзмененияУниверсальное", Неопределено); ПараметрыФайла.Вставить("кпд_ИДРоли", "Основной");
РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, АдресХранилищаПечатнойФормы);
ПоказатьОповещениеПользователя("Вложение", ,"Документ прикреплен в ""Документы по проекту""", БиблиотекаКартинок.Скрепка);
КонецЕсли;
КонецПроцедуры
НаСервере Функция ПолучитьДанныеПечати(Знач СсылкаНаОбъект, Знач ИмяМакета)Для того чтобы вывести области в документ и заполнить параметры, опишем функцию ВыполнитьПечатьВWordНаСервере:
ДанныеОбъектаПоМакетам = Новый Соответствие; ДанныеОбъектаПоМакетам.Вставить(ИмяМакета, ПолучитьДанныеОбъекта(СсылкаНаОбъект))
ДанныеПоВсемОбъектам = Новый Соответствие; ДанныеПоВсемОбъектам.Вставить(СсылкаНаОбъект, ДанныеОбъектаПоМакетам);
ОписаниеОбластей = Новый Соответствие; ОписаниеОбластей.Вставить(ИмяМакета, ПолучитьОписаниеОбластейМакетаОфисногоДокумента()); ТипыМакетов = Новый Соответствие; // Для обратной совместимости. ТипыМакетов.Вставить(ИмяМакета, "DOC"); ДвоичныеДанныеМакета = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета); ДвоичныеДанныеМакетов = Новый Соответствие; ДвоичныеДанныеМакетов.Вставить(ИмяМакета, ДвоичныеДанныеМакета);;
Макеты = Новый Структура; Макеты.Вставить("ОписаниеОбластей", ОписаниеОбластей); Макеты.Вставить("ТипыМакетов", ТипыМакетов); // Для обратной совместимости. Макеты.Вставить("ДвоичныеДанныеМакетов", ДвоичныеДанныеМакетов);
Результат = Новый Структура;
Результат.Вставить("Данные", ДанныеПоВсемОбъектам); Результат.Вставить("Макеты", Макеты);
Возврат Результат;
КонецФункции
&НаСервере Функция ВыполнитьПечатьВWordНаСервере(ДокументСсылка, МакетИДанныеОбъекта, ИмяМакета)Эта функция возвращает адрес хранилища печатной формы для прикрепления полученного файла к присоединенным.
ТипМакета = МакетИДанныеОбъекта.Макеты.ТипыМакетов[ИмяМакета]; ДвоичныеДанныеМакетов = МакетИДанныеОбъекта.Макеты.ДвоичныеДанныеМакетов; Области = МакетИДанныеОбъекта.Макеты.ОписаниеОбластей; ДанныеОбъекта = МакетИДанныеОбъекта.Данные[ДокументСсылка][ИмяМакета];
Макет = УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(ДвоичныеДанныеМакетов[ИмяМакета], ТипМакета, ИмяМакета); Если Макет = Неопределено Тогда Возврат Неопределено; КонецЕсли;
ЗакрытьОкноПечатнойФормы = Ложь; Попытка ПечатнаяФорма = УправлениеПечатью.ИнициализироватьПечатнуюФорму(ТипМакета, Макет.НастройкиСтраницыМакета, Макет); Если ПечатнаяФорма = Неопределено Тогда УправлениеПечатью.ОчиститьСсылки(Макет); Возврат Неопределено; КонецЕсли;
ОбластиМакета = Области[ИмяМакета];
Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластиМакета["ЗаголовокДоговора"]); УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь); АдресХранилищаПечатнойФормы = УправлениеПечатью.СформироватьДокумент(ПечатнаяФорма);
Исключение ОбщегоНазначенияКлиентСервер.СообщитьПользователю(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); ЗакрытьОкноПечатнойФормы = Истина; Возврат Неопределено; КонецПопытки;
УправлениеПечатью.ОчиститьСсылки(ПечатнаяФорма, ЗакрытьОкноПечатнойФормы); УправлениеПечатью.ОчиститьСсылки(Макет);
Возврат АдресХранилищаПечатнойФормы;
КонецФункции
Таким образом мы создали простейшую внешнюю печатную форму Word.
Теперь более детально рассмотрим, как сделать так, чтобы печатная форма Word выглядела красиво и читабельно, чтобы клиенту не приходилось исправлять её перед тем, как отправить на печать. В данной статье мы расскажем о некоторых лайфхаках, которые пригодятся каждому при создании печатной формы Word.
Иногда в печатных формах есть текст, который всегда должен начинаться с новой страницы, не сливаясь с предыдущим, например, это могут быть приложения к договору. Если обозначить эти части в отдельные области, то текст склеится. Для того чтобы это исправить, необходимо правильно настроить макет. Во-первых, необходимо, чтобы область заканчивалась хотя-бы после первой строки новой страницы.
Текст, который должен начинаться с новой страницы
Во-вторых, необходимо воспользоваться функцией разрыв страницы, только так текст не будет съезжать и всегда будет выглядеть аккуратно.Функция "Разрыв страницы"
Теперь разберем, как вывести нумерованные списки в печатную форму, когда один или несколько пунктов этого списка выводятся по условию.Нумерование списков в печатной форме
В данном варианте строки генерируются программно. Предполагаем, что строка {v8 СтрокиНовостиАрхивСток229} выводится по одному условию, а строки {v8 СтрокиНовостиАрхивСток2291}, {v8 СтрокиНовостиАрхивСток2292}, {v8 СтрокиНовостиАрхивСток2293}, {v8 СтрокиНовостиАрхивСток2294} выводятся, если выполняется другое условие. В коде прописываем получение этих строк:СтрокаЕслиСтокИстина2 = ?(СтрокаЕслиСтокИстина = "",СтрЗаменить(Выборка.СтрокаЕслиСтокИстина2,"2.9.","2.8."),Выборка.СтрокаЕслиСтокИстина2);Так же прописываем условия присоединения областей:
СтрокиНовостиАрхивСток2 = ""; СтрокиНовостиАрхивСток229 = ""; СтрокиНовостиАрхивСток2291 = ""; СтрокиНовостиАрхивСток2292 = ""; СтрокиНовостиАрхивСток2293 = ""; СтрокиНовостиАрхивСток2294 = "";
Если Выборка.АКАМ_ВПапкеСток Тогда СтрокиНовостиАрхивСток2 = "2.2.8. Для Произведений формата сток - право на переработку Произведений любыми способами не запрещёнными" ; КонецЕсли; Если Выборка.АКАМ_ВПапкеНовости И Выборка.АКАМ_ВПапкеАрхив Тогда Если СтрокиНовостиАрхивСток2 = "" Тогда СтрокиНовостиАрхивСток2 = "2.2.8. Для новостных и архивных Произведений:"; СтрокиНовостиАрхивСток2291 = "2.2.8.1. создание скриншотов на основе Произведений - видео, при условии приобретения лицензии"; СтрокиНовостиАрхивСток2292 = "2.2.8.2. изменение Произведения путём кадрирования и цветокоррекции"; СтрокиНовостиАрхивСток2293 = "2.2.8.3. редактирование Произведений для объединения с другим контентом (создание коллажей)"; СтрокиНовостиАрхивСток2294 = "2.2.8.4. обрезка персоны, изображенной на Произведении и изменение фона Произведения на однородный."; Иначе СтрокиНовостиАрхивСток229 = "2.2.9. Для новостных и архивных Произведений:"; СтрокиНовостиАрхивСток2291 = "2.2.9.1. создание скриншотов на основе Произведений - видео, при условии приобретения лицензии"; СтрокиНовостиАрхивСток2292 = "2.2.9.2. изменение Произведения путём кадрирования и цветокоррекции"; СтрокиНовостиАрхивСток2293 = "2.2.9.3. редактирование Произведений для объединения с другим контентом (создание коллажей)"; СтрокиНовостиАрхивСток2294 = "2.2.9.4. обрезка персоны, изображенной на Произведении и изменение фона Произведения на однородный."; КонецЕсли; КонецЕсли;
Если ДанныеОбъекта.СтрокиНовостиАрхивСток229 <> "" Тогда Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластиМакета["ОсновнойДоговор2"]); УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь); КонецЕсли;Вариант с обычными, не сгенерированными сроками можно организовать подобным образом:
Если ДанныеОбъекта.СтрокиНовостиАрхивСток2291 <> "" Тогда Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластиМакета["ПеречислениеСтрок"]); УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь); КонецЕсли;
Вариант с обычными строками
Соответственно, в данном случае условием видимости областей будет являться заполненность параметра {v8 СтрокаЕслиСтокИстина}:
Если ДанныеОбъекта.СтрокаЕслиСтокИстина <> "" Тогда Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластиМакета["Общая27или26"]); УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь); Иначе Область = УправлениеПечатью.ОбластьМакета(Макет, ОбластиМакета["Общая26или27"]); УправлениеПечатью.ПрисоединитьОбластьИЗаполнитьПараметры(ПечатнаяФорма, Область, ДанныеОбъекта, Ложь); КонецЕсли;Во многих документах происходит проблема съезжания подписи из-за объема выведенных реквизитов. Подписи всегда должны располагаться на одном уровне. В этой ситуации поможет справиться таблица.
Таблица, чтобы не съезжали подписи
После того, как таблица выглядит аккуратно, и все строки находятся на одинаковом уровне, просто обесцвечиваем её границы.Обесцвечивание границ таблицы
Примеры, описанные в данной статье, можно адаптировать под любую печатную форму Word — это те навыки, которые необходимы для того, чтобы клиент остался доволен проделанной работой и забыл о ручном исправлении документов.