Итак, пойдем по порядку. Подобная информация уже есть в сети, но для полноты картины кратко разъясню регистрацию обработки в системе:
1. Открываем модуль объекта обработки и создаем там Функцию СведенияОВнешнейОбработке() (естественно экспортную):
СведенияОВнешнейОбработке()
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Справочник.Сотрудники");//место(форма справочника или документа) куда будет добавлена кнопка для печати
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); //может быть - ЗаполнениеОбъекта, ДополнительныйОтчет, СозданиеСвязанныхОбъектов... (Нас интересует ПечатнаяФорма)
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений); //Массив, который будет содержать ссылки на объекты, с которыми предстоит работать
ПараметрыРегистрации.Вставить("Наименование", "ПФР(WORD)"); //имя под которым обработка будет зарегестрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("Версия", "1.0"); //версия обработки, которая будет зарегистрирована в справочнике внешних обработок
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь); //режим запуска обработки
ПараметрыРегистрации.Вставить("Информация", "ПФР(WORD)");//так будет выглядеть описание печ.формы для пользователя
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "ПФР(WORD)", "ФормаПФР", "ВызовКлиентскогоМетода", Истина, "ПечатьMXL");//Важно Четвертыйпараметр должен быть ВызовКлиентскогоМетода, а шестой ПечатьMXL
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Как мы видим, использовать будем ВызовКлиентскогоМетода, по скольку открыть файл нужно будет на компьютере пользователя.
Далее понадобится создать еще две процедуры здесь же:
2. Функция добавления команды, которую мы вызываем ранее(просто, чтобы все было визуально разделено и не награмождалось скопом в одной функции):
ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
Функция ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор= Идентификатор;
НоваяКоманда.Использование= Использование;
НоваяКоманда.ПоказыватьОповещение= ПоказыватьОповещение;
НоваяКоманда.Модификатор= Модификатор;
КонецФункции
3. И функция по созданию этой самой таблицы команд:
Функция ПолучитьТаблицуКоманд()
// Создадим пустую таблицу команд и колонки в ней
Команды = Новый ТаблицаЗначений;
// Как будет выглядеть описание печатной формы для пользователя
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
// Имя нашего макета, что бы могли отличить вызванную команду в обработке печати
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
// Тут задается, как должна вызваться команда обработки
// Возможные варианты:
// - ОткрытиеФормы - в этом случае в колонке идентификатор должно быть указано имя формы, которое должна будет открыть система
// - ВызовКлиентскогоМетода - вызвать клиентскую экспортную процедуру из модуля формы обработки
// - ВызовСерверногоМетода - вызвать серверную экспортную процедуру из модуля объекта обработки
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
// Следующий параметр указывает, необходимо ли показывать оповещение при начале и завершению работы обработки. Не имеет смысла при открытии формы
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
// Для печатной формы должен содержать строку ПечатьMXL
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
(Из комментариев можно подробней понять, для чего используется тот или иной параметр-поле данной таблицы)
На этом настройка регистрации внешней обработки в нужной вам конфигурации закончена.
Далее. Самое интересное: создание, заполнение и вывод макета клиенту.
Первое, что нам необходимо сделать, это создать макет нашего документа(Изображение 3). Макет понадобится двоичный, т.к. обычный мы на клиент не передадим(как я и говорил ранее). Заменяем нужные данные в шаблоне, перед загрузкой в обработку, "Параметрами", у меня они выглядят так, на примере: "{Сотрудник}"(кавычки не учитывать), после чего загружаем в Обработку-Макет.
Теперь в модуле формы создаем процедуру, которая будет вызвана при обращении к печати именно в таком виде(за исключением содержимого, заполнять можете как вам угодно), процедура так же должна быть экспортной и на клиенте, так как вызывается из конфигурации и выполнение назначено на клиентской стороне:
Печать(ИдентификаторКоманды, МассивОбъектов)
&НаКлиенте
Процедура Печать(ИдентификаторКоманды, МассивОбъектов) Экспорт //Здесь МассивОбъектов и есть ссылка или ссылки на документ или справочник, в который добавлена обработка
Для Каждого Элемент Из МассивОбъектов Цикл
СобратьМакет(Элемент);
КонецЦикла;
КонецПроцедуры
Макет я собираю и вызываю в отдельной процедуре, обязательно на клиенте.
СобратьМакет(СсылкаНаОбъект)
&НаКлиенте
Процедура СобратьМакет(СсылкаНаОбъект)
Данные = ПолучитьДанные(СсылкаНаОбъект);\получить данные для заполнения макета по параметрам в виде структуры
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("doc");
Адрес = ФормированиеДоговораПоШаблону();\ положить макет во временное хранилище на сервере и получить адрес на клиент
Если Адрес = Неопределено Тогда
Возврат;
КонецЕсли;
Макет = ПолучитьИзВременногоХранилища(Адрес); \получить макет из временного хранилища
Макет.Записать(ИмяВременногоФайла);\создать документ на основе макета в TEMP клиента
Word = Новый COMОбъект("Word.Application");\создаем COMОбъект
Документ = Word.Documents.Open(ИмяВременногоФайла);\подключаем макет к созданному COMОбъект
Попытка
ДокументЗаполнение = Документ.Application.Documents(1);
// Получить объект, который будем использовать для поиска и замены.
Для Каждого ЭлементДанных Из Данные Цикл
Замена = Документ.Content.Find;//поиск параметра в макете
Замена.Execute("{" + ЭлементДанных.Ключ + "}", Ложь, Истина, Ложь, Ложь, , Истина, , Ложь, ЭлементДанных.Значение, 2);//замена параметра на значение
КонецЦикла;
Word.Application.Visible = Истина;//установить видимость документа
Word.Activate();//открыть документ пользователю
Исключение
// Если произойдет ошибка, выводятся данные об ошибке, и объект закрывается.
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = ОписаниеОшибки();
Сообщение.Сообщить();
Word.Application.Quit();
КонецПопытки;
КонецПроцедуры // СобратьМакет()
Для сбора макета нам понадобится получить этот самый макет уже с сервера. Передаю я его через временное хранилище:
ПолучитьМакетСервер(ИмяМакета)
&НаСервере
Функция ПолучитьМакетСервер(ИмяМакета)
Макет = РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета);
Возврат Макет;
КонецФункции // ПолучитьМакетСервер(ИмяМакета)()
&НаСервере
Функция ФормированиеДоговораПоШаблону()
ИмяМакета = "Макет1";
АктивныйДокумент = ПолучитьМакетСервер(ИмяМакета);
УИД = Новый УникальныйИдентификатор();
Адрес = ПоместитьВоВременноеХранилище(АктивныйДокумент, УИД);
Возврат Адрес;
КонецФункции
Далее нужно получить данные для заполнения макета, естественно на сервере, по скольку может понадобиться обратиться к сторонним регистрам и справочникам, если нет, то можно выполнить и на клиенте, получив ссылку на интересующий нас объект:
ПолучитьДанные(СсылкаНаОбъект)
&НаСервере
Функция ПолучитьДанные(СсылкаНаОбъект)
Структура = Новый Структура();
Сотрудник = СсылкаНаОбъект.Сотрудник;
Структура.Вставить("Сотрудник", СсылкаНаОбъект.Сотрудник);
Возврат Структура;
КонецФункции // ПолучитьДанные()
Данные складываем в структуру,где ключ — имя параметра в макете(без фигурных скобок), а значение — собственно значение, которое необходимо подставить.
На этом завершается наше создание. Вы можете скачать обработку в готовом виде, в ней также реализован запуск через форму обработки, то есть с помощью открытия обработки без регистрации ее в конфигурации. Надеюсь, моя статья многим поможет и окажется полезной. Спасибо большое за внимание!
Все бы ничего, но за 10 стартмани врядли кто-то захочет скачать, тем более, что почти весь код приведен в статье)))
«Это моя первая статья на данном портале…» и я решил начать свою деятельность здесь попыткой грабежа местных
Автор может быть вы не в курсе, но 10 стартмани это 400 рублей, просить за это 400 рублей ? WTF ?
(3) Извините, не правильно понял курс) подправлю)
(1) Цену я поменял, а на счет все написано в статье, почти да. Но я долговато мучился с этой темой и надеюсь люди, которым статья поможет скачают ее в благодарность 🙂
(0) Автор как понимаю БСП никогда не смотрел с примерами. Полностью перепечатка оттуда. И самое интересное что в последних релизах БСП 1С отказалась от Word.Application теперь все делается через xml и сборку docx.
(6)
Спасибо, надо ознакомиться
(6) Если честно не смотрел, но видимо воссоздал их путь:-) Что тоже считаю не плохо 🙂
(8)Должен ли на сервере стоять ms office?
(9) С этим вопросом изначально и была проблема. Нет не должен, только на машине клиента.
(10)А вот если , допустим на серваке поставят ворд, то будет ли у клиента формироваться документ. Не сталкивались с таким?
(10) Выходит ошибка
http://v8.1c.ru/8.2/mngsrv/ws }response: Ошибка отображения типов:
{ВнешняяОбработка.БН_ПриказОПриёме.Форма.Форма.Форма(21)}: Ошибка при вызове метода контекста (ПолучитьИзВременногоХранилища): Ошибка получения значения из временного хранилища: Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа.: Ошибка преобразования данных XDTO:
Запись значения свойства ‘response’:
форма: Элемент
имя: {
Отсутствует отображение для типа ‘ОболочкаActiveDocument’
(11) В случае, если у клиента не установлен microsoft office обработка работать не будет, так как документ формируется на стороне клиента при помощи com объекта. Если вам необходимо формировать документ именно на сервере, то можно процедуру
Перенести на сервер:
и заменить
НА
(12) Какого вида у вас макет? Должен быть не ActiveDocument, а двоичный макет
(14)Да, ошибку я вчера заметил, забыл отписаться)
(13) я имел ввиду, если не по вашей обработке, работать, а через стандартное создание всего на сервере, но в прочем это чисто теоретический вопрос. так как вчера по Вашему образу состряпал свой говнокод, собрал параметры и вставил их в макет и сегодня все заработало.
(16) Рад, что вам помогло #k8SjZc9Dxk_#k8SjZc9Dxk
(16) Создать то все можно, а вот с передачей через сервер-клиент много проблем
(10) У меня ругается Процедура или функция с указанным именем не определена (ПолучитьИмяВременногоФайла)
Макет двоичный
Как решить проблему?
(19) Значит вы не добавили процедуру или функцию «ПолучитьИмяВременногоФайла» =)
(20) Вместо того, что бы смеяться помогли бы…
(21) Я и не смеюсь, ошибка означает именно это. В статье все очень подробно описано, и если скопировать код, то обработка уже будет готова
(21) возможно вы выбрали не правильную директиву компиляции (&НаКлиенте, &НаСервере)
(22) Я и скопировала весь код… И пробовала разные директивы и &НаКлиенте и &НаСервере. Данная ошибка выходит именно когда на &НаКлиенте, что мне предпочтительнее. Буду разбираться дальше. Если у кого есть решение или варианты пишите.
(24) Получите имя файла на сервере, и передайте на клиент
Подскажите, пожалуйста, как вставить картинку в ворд (программно), к каждому договору прикрепляется карта, если точек несколько, то несколько картинок с картой. Картинка находится в каталоге на диске.
В АктивДокумент получается картинку вставить, а вот как это сделать в случае с двоичными данными нигде не могу найти…
Добрый день
Есть некорректный код, см. ниже:
Показать
На ЗУП корпе ругается:
{ОбщийМодуль.УправлениеПечатью.Модуль(1510)}: Метод объекта не обнаружен (Печать)
ВнешняяОбработкаОбъект.Печать(
Что может быть?
(28) Скорее всего вы не сделали процедуру экспортной
(26) Не пробовал, не было задачи. Но должен работать тот же метод что и с АктивДокумент. Так как двоичный макет нужен для создания «Word = Новый COMОбъект(«Word.Application»);\создаем COMОбъект» А с ним дальше делайте все что вам нужно по методам работы с COMОбъект
Указал экспортную процедуру, все равно в ЗУП, не работает.
Если до этого в параметре команды Использование было указано «ВызовСерверногоМетода», то нужно пометить обработку на удаление и создать её заново. Видимо, тип команды устанавливается один раз при регистрации обработки.
(32) Не проверял такой возможности, спасибо за подсказку
(6)
Киньте ссылку на оригинал, пожалуйста. Просмотрел доку и не нашел там подобного. Интересно, что Вы имели в виду.
1
Спасибо за статью! Оч помогла.
(36) Всегда рад!
Спасибо за статью. Печатная форма формируется, всё прекрасно.
НО перестали работать стандартные печатные формы в этом документе.
Выдает ошибку при выборе стандартной печатной формы:
{ОбщийМодуль.УправлениеПечатью.Модуль(1510)}: Метод объекта не обнаружен (Печать)
ВнешняяОбработкаОбъект.Печать(
Не подскажите в чем может быть проблема?
(38) Здравствуйте. Не подскажу, не сталкивался с таким. Посмотрите отладкой.
(39)
В том то и дело… В отладке уже в описании команды сразу присутствует обращение к внешней обработке. А она же стандартная!
Пишет:
Помогите, пожалуйста!
Причем для Кадрового перевода всё в порядке, а для совмещений, выхода из отпуска за ребенком вот такая проблема!
Отличная статья. Спасибо!