Внешняя печатная форма word
Понадобилась однажды срочно внешняя печатная форма на основе word-шаблона для типовой БП 3.0. Я себе примерно представлял как можно сделать такую внешнюю обработку с обычным макетом и встроить её в справочник ‘Дополнительные отчеты и обработки’, но как проделать то же самое с word я не представлял. Но все оказалось довольно-таки просто, правда и пришлось убить на это полдня.
Внимание! После прочтения этой статьи можете ознакомиться с более универсальным вариантом по этой статье ‘Внешняя печатная форма word.Часть2’ !
Итак, для начала создаем наш печатный макет word:
Параметры в этом файле я оформлял как <Параметр>, но вы можете оформлять их по любому другому шаблону, просто в коде будете заменять текст аналогично своему формату.
Далее создаем новый макет ‘МакетWORD’ с типом ‘Двоичные данные’:
После чего щелкаем по нему два раза и загружаем туда наш файл-шаблон ‘word’:
Переходим теперь к реквизитам и форме нашей внешней печатной обработки. Добавляем реквизит ‘СсылкаНаОбъект‘ с типом объекта, для которого мы делаем нашу печатную форму:
Добавляем реквизит формы ‘ОбъектыНазначения’ – для печати из дополнительных отчетов и обработок. На форму выводим наш реквизит ‘СсылкаНаОбъект’ и созданную нами команду ‘ПечатьСФормы’:
Итак, теперь приступаем к 1 этапу – делаем печать из формы обработки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
&НаКлиенте Процедура ПечатьСФормы(Команда) //Наша команда с формы СобратьМакет(Объект.СсылкаНаОбъект); КонецПроцедуры &НаСервере Функция ПолучитьДанныеМакета() ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); АдресХранилища = Новый УникальныйИдентификатор(); Макет = ОбработкаОбъект.ПолучитьМакет("МакетWORD"); ВременныйФайл = ПолучитьИмяВременногоФайла("doc"); Макет.Записать(ВременныйФайл); Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ВременныйФайл),АдресХранилища); УдалитьФайлы(ВременныйФайл); Возврат Адрес; КонецФункции &НаКлиенте Процедура СобратьМакет(п_СсылкаНаОбъект) Пользователь = ПользователиКлиентСервер.ТекущийПользователь(); Каталог = КаталогВременныхФайлов(); Каталог = ?(Прав(Каталог,1) = "\", Каталог, Каталог + "\"); ПолноеИмяФайла = Каталог + Строка(Новый УникальныйИдентификатор) + ".doc"; Попытка Индификатор = ПолучитьДанныеМакета(); МакетДоговора = ПолучитьИзВременногоХранилища(Индификатор); МакетДоговора.Записать(ПолноеИмяФайла); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; Попытка MSWord = Новый COMОбъект("Word.Application"); Исключение Сообщить("Ошибка при попытке создать объект ""MS Word""!" + Символы.ПС + "Возможно приложение ""MS Word"" не установлено или установлено неправильно.", СтатусСообщения.Внимание); КонецПопытки; MSWord.Documents.Open(ПолноеИмяФайла); Попытка Документ = MSWord.Application.Documents(1); Документ.Activate(); СамыйКрутойПрограмист1с = СокрЛП(п_СсылкаНаОбъект); Компания = "КРАФТ 1С"; СамыйКрутойБлогПро1с = "www.craft1c.ru"; ДатаПараметр = Строка(ТекущаяДата()); // Поиск и замена маркеров Замена = Документ.Content.Find; Замена.Execute("<СамыйКрутойПрограмист1с>",Ложь,Истина,Ложь,,,Истина,,Ложь,СамыйКрутойПрограмист1с); Замена = Документ.Content.Find; Замена.Execute("<Компания>", Ложь, Истина, Ложь, , , Истина , , Ложь, Компания); Замена = Документ.Content.Find; Замена.Execute("<СамыйКрутойБлогПро1с>", Ложь, Истина, Ложь, , , Истина , , Ложь, СамыйКрутойБлогПро1с); Замена = Документ.Content.Find; Замена.Execute("<ДатаПараметр>", Ложь, Истина, Ложь, , , Истина , , Ложь, ДатаПараметр); Исключение Сообщение = Новый СообщениеПользователю(); Сообщение.Текст = ОписаниеОшибки(); Сообщение.Сообщить(); MSWord.Application.Quit(); Возврат; КонецПопытки; MSWord.Application.Visible = Истина; MSWord.Activate(); КонецПроцедуры |
Результат выполнения данного кода будет следующий:
Супер, но есть проблема, как сделать так что бы это все печаталось через внешние отчеты и обработки? Это то с чем мне пришлось провозиться полдня, и решение на мой взгляд не самое оптимальное, но по крайней мере рабочее!
Для начала в модуле обработки добавляем функцию ‘СведенияОВнешнейОбработке‘:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
Функция СведенияОВнешнейОбработке() Экспорт ПараметрыРегистрации = Новый Структура; МассивНазначений = Новый Массив; //Для каждого МД Из Метаданные.Документы Цикл // МассивНазначений.Добавить(МД.ПолноеИмя()); //КонецЦикла; //Для каждого МД Из Метаданные.Справочники Цикл //МассивНазначений.Добавить(Метаданные.Справочники.Сотрудники); //КонецЦикла; ПараметрыРегистрации.Вставить("Вид" , "ПечатнаяФорма"); ПараметрыРегистрации.Вставить("Назначение" , МассивНазначений); ПараметрыРегистрации.Вставить("Наименование" , "craft1c_ВнешняяПечатнаяФормаWord"); ПараметрыРегистрации.Вставить("Версия" , "1.1.1"); ПараметрыРегистрации.Вставить("БезопасныйРежим" , ЛОЖЬ); ПараметрыРегистрации.Вставить("Информация" , "craft1c_ВнешняяПечатнаяФормаWord"); ТаблицаКоманд = Новый ТаблицаЗначений; ТаблицаКоманд.Колонки.Добавить("Представление"); ТаблицаКоманд.Колонки.Добавить("Идентификатор"); ТаблицаКоманд.Колонки.Добавить("Использование"); ТаблицаКоманд.Колонки.Добавить("ПоказыватьОповещение"); ТаблицаКоманд.Колонки.Добавить("Модификатор"); НоваяКоманда = ТаблицаКоманд.Добавить(); НоваяКоманда.Представление = "craft1c_ВнешняяПечатнаяФормаWord"; НоваяКоманда.Идентификатор = "craft1c_ВнешняяПечатнаяФормаWord"; НоваяКоманда.Использование = "ОткрытиеФормы"; //Важно! Открываем форму! НоваяКоманда.ПоказыватьОповещение = Истина; НоваяКоманда.Модификатор = "craft1c_ВнешняяПечатнаяФормаWord"; ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд); Возврат ПараметрыРегистрации; КонецФункции |
Затем в модуле формы обработки создаем 2 процедуры и прописываем алгоритм печати из дополнительных отчетов и обработок:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ОбъектыНазначения = Новый СписокЗначений; Если Параметры.Свойство("ОбъектыНазначения") Тогда Для Каждого Элемент Из Параметры.ОбъектыНазначения Цикл ОбъектыНазначения.Добавить(Элемент); КонецЦикла; КонецЕсли; КонецПроцедуры &НаКлиенте Процедура ПриОткрытии(Отказ) Если ЭтаФорма.ОбъектыНазначения.Количество() > 0 Тогда Для Каждого Элемент Из ОбъектыНазначения Цикл СобратьМакет(Элемент); КонецЦикла; ЭтаФорма.Закрыть(); КонецЕсли; КонецПроцедуры |
Алгоритм придумал сам, проанализировав типовой механизм работы с внешними печатными формами. Он далеко не идеален, я думаю можно было сделать и более грамотно. Но меня устраивает и так.
Теперь заходим в справочник ‘Дополнительные отчеты и обработки’:
И подключаем нашу обработку:
Все! Готово! Заходим в сотрудника и тестируем:
Открывается наш заполненные макет word-файла. Единственный минус что при первой печати программа может запросить разрешение на выполнение не безопасных действий. И придется второй раз выводить на печать. Но это будет только 1 раз в рамках одного сеанса.
Без изменения типовой конфигурации мы сделали внешнюю печатную форму word. Этот механизм работает на БП 3.0 версии ‘3.0.67.63’. Думаю будет работать и на других типовых конфигурациях.
Ну и как всегда готовый бесплатный файл для Вас! Удачи!
Скачать файлы ‘craft1c_ВнешняяПечатнаяФормаWord.epf’
Все круто не хвататет работы с табличной частью Все голову сломал не могу найти как добавлять в тч
Привет! Что ты имеешь ввиду? Расскажи подробнее, может помогу чем…
Через п_СсылкаНаОбъект передается только ФИО сотрудника, а как передавать другие данные? Например название организации?
Не очень понял, но смотри: п_СсылкаНаОбъект – это ссылка на объект справочника “Сотрудники”, откуда ты уже получаешь все его реквизиты. Имея ссылку на сотрудника, ты можешь любыми доступными способами получить всю связанную информацию (организации, физ. лицо и т.д. – запросами и т.д.). Или ты хочешь еще передавать вообще не связанную информацию с формы? Скинь пример того, что ты хочешь получить, помогу.
Конфигурация ЗУП ПРОФ 3.1.13.76
Например, мне нужно получить дату и номер трудового договора сотрудника.Я создаю функцию в которую передаю ссылку п_СсылкаНаОбъект,запросом вытягиваю данные отсюда ОсновныеДанныеКонтрактаДоговораСотрудникаСрезПоследних.НомерДоговораКонтракта(в этом регистре делаю отбор по п_СсылкаНаОбъект).
При запуске формы мне выдает Значение не является значением объектного типа
Написал на почту возможные причины ошибки
Она через открытие формы работает?((
Согласен, есть небольшой недостаток. Думаю можно сделать и без открытия. Посмотрю, если получится еще один вариант выложу.
считаю это важным аспектом
Есть Еще один вариант! Напишу статью сегодня. Оказывается столько всего интересного и крутого есть)!
Зацени этот вариант:
https://craft1c.ru/vneshnjaja-pechatnaja-forma-word-chast2/
Реализовал свой вариант. Если интересно могу скинуть.
Давай закинь на почту, только если он отличается от второй моей заметки)
Помогите, пожалуйста, новичку. Мне нужно в макете в Word получить из текущего документа Больничный лист (ЗУП КОРП 3.1.13.146) сотрудника, номер и дату листка нетрудоспособности, которые внесены в этот документ (не номер и дату документа Больничный лист).
Привет. А что не получается конкретно? Вывести эти данные в макет или получить их из конфигурации? Можем состыковаться по teamviewer – я визуально гляну и может быть подскажу. Просто так, бескорыстно.
Привет, комментарий Ивана натолкнул на мысль. Все получилось. Спасибо Вам за обработку – существенная помощь для таких новичков, как я.
Отлично!