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

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

Анализ проблемы и причин ошибки

При разработке внешних печатных форм (ВПФ) в формате Microsoft Word для конфигураций 1С на управляемых формах разработчики часто сталкиваются с ошибкой: «Ошибка передачи данных между клиентом и сервером. Значение недопустимого типа», а также с ошибкой Отсутствует отображение для типа 'КодВозвратаДиалога'.

Проанализируем ключевые причины возникновения данной проблемы:

  1. Попытка работы с интерфейсными объектами на сервере. Типы данных, относящиеся к пользовательскому интерфейсу (например, КодВозвратаДиалога, диалоги открытия файлов, вызовы ОткрытьФорму), доступны только в контексте клиента. Попытка их использования на сервере или передачи между клиентом и сервером вызывает сбой XDTO-сериализации.
  2. Работа с COM-объектом Word на сервере. При вызове метода MSWord.Application.Visible = Истина в серверном контексте система пытается отобразить окно приложения Microsoft Word на сервере, что недопустимо. Кроме того, сам COM-объект не может передаваться через границу клиент-сервер.
  3. Отсутствие экспортного объявления процедур и функций. Подсистема БСП (Библиотека Стандартных Подсистем) взаимодействует с модулем объекта внешней обработки извне. Если ключевые функции (СведенияОВнешнейОбработке, Печать) или вспомогательные методы не помечены ключевым словом Экспорт, механизм подключения обработок завершается ошибкой.

Корректное объявление функций регистрации ВПФ

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

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


Функция СведенияОВнешнейОбработке() Экспорт 
    ПараметрыРегистрации = Новый Структура; 
    МассивНазначений = Новый Массив; 
    МассивНазначений.Добавить("Документ.ПриемНаРаботу"); // Указываем документ-назначение

    ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма"); 
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений); 
    ПараметрыРегистрации.Вставить("Наименование", "Трудовой договор (Word)"); 
    ПараметрыРегистрации.Вставить("БезопасныйРежим", ЛОЖЬ); 
    ПараметрыРегистрации.Вставить("Версия", "1.0"); 
    ПараметрыРегистрации.Вставить("Информация", "Форма трудового договора в формате MS Word"); 
    
    ТаблицаКоманд = ПолучитьТаблицуКоманд(); 
    ДобавитьКоманду(ТаблицаКоманд, "Трудовой договор", "ПечатьТД", "ВызовСерверногоМетода", Истина, "ПечатьMXL"); 
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд); 
    
    Возврат ПараметрыРегистрации;
КонецФункции

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

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "") 
    НоваяКоманда = ТаблицаКоманд.Добавить(); 
    НоваяКоманда.Представление = Представление; 
    НоваяКоманда.Идентификатор = Идентификатор; 
    НоваяКоманда.Использование = Использование; 
    НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение; 
    НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры

Заполнение и замена меток в макете Word

Рассмотрим пример заполнения параметров макета Microsoft Word. Если обработка считывает макет типа ActiveDocument или двоичные данные, алгоритм поиска и замены строк выполняется через ComObject:


Процедура ЗаполнитьМакетWord(СсылкаНаОбъект) Экспорт

    // Получаем макет из обработки
    Макет = ПолучитьМакет("ТД");
    MSWord = Макет.Получить();

    Попытка
        Документ = MSWord.Application.Documents(1);
        
        // Подготавливаем данные для замены
        НомерДоговора = СсылкаНаОбъект.ТрудовойДоговорНомер;
        ДатаДоговора = Формат(СсылкаНаОбъект.ТрудовойДоговорДата, "ДФ='дд ММММ гггг'");

        // Поиск и замена параметров в документе
        Замена = Документ.Content.Find;
        Замена.Execute("<НомерТД>", Ложь, Истина, Ложь, Ложь, , Истина, , Ложь, НомерДоговора, 2);
        Замена.Execute("<ДатаНачалаТД>", Ложь, Истина, Ложь, Ложь, , Истина, , Ложь, ДатаДоговора, 2);
        
        // Делаем документ видимым на клиенте
        MSWord.Application.Visible = Истина;
        MSWord.Activate();
    Исключение
        Сообщить(ОписаниеОшибки());
        MSWord.Application.Quit();
    КонецПопытки;

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

Способы разделения контекста клиент/сервер

Чтобы избежать ошибок взаимодействия клиента и сервера при вызове внешней печатной формы, рекомендуются два подхода:

  1. Использование типа команды «ВызовКлиентскогоМетода»:

    В функции СведенияОВнешнейОбработке() для команды указывается тип использования "ВызовКлиентскогоМетода". В этом случае подсистема БСП вызывает форму обработки на клиенте. Серверная часть подготавливает и возвращает структуру данных (числа, строки, даты), а клиентская часть создает COM-объект Word и открывает готовый документ без ошибок передачи контекста.

  2. Формирование офисных документов средствами БСП:

    Штатный механизм БСП позволяет подготавливать файлы .docx на сервере без привлечения COM-объекта Microsoft Office. Для этого в обработку добавляется двоичный макет .docx, а заполнение выполняется через функции общего модуля УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента().

← На главную