При переносе баз данных «1С:Управление торговлей 10.3» на новые платформы и серверы технические специалисты часто сталкиваются сбоями в работе внешних печатных форм. Одна из наиболее распространенных и неочевидных проблем — внезапный отказ работы механизмов печати договоров или коммерческих предложений через офисные пакеты LibreOffice или OpenOffice. Пользователь при этом получает системную ошибку: «Значение не является значением объектного типа (createSearchDescriptor)».
В этой статье мы подробно разберем, почему возникает этот сбой, проанализируем внутренние механизмы взаимодействия 1С с текстовыми процессорами через OLE/COM и рассмотрим несколько эффективных способов решения проблемы.
Для начала выясним причину сбоя на программном уровне. Когда внешняя печатная форма в 1С формирует документ на основе шаблона OpenOffice Writer (формат .odt), она обращается к установленной на компьютере программе через механизм COM-соединения. Типовой сценарий кода выглядит следующим образом:
// Инициализация COM-объекта LibreOffice
ServiceManager = Новый COMОбъект("com.sun.star.ServiceManager");
Desktop = ServiceManager.createInstance("com.sun.star.frame.Desktop");
// Загрузка файла шаблона
Параметры = Новый COMSafeArray("com.sun.star.beans.PropertyValue", 1);
xDocument = Desktop.LoadComponentFromURL(ПутьКФайлу, "_blank", 0, Параметры);
// Поиск текстовых маркеров для замены (например, [НомерДоговора])
xSearchDescr = xDocument.createSearchDescriptor();
В штатном режиме метод LoadComponentFromURL открывает файл шаблона и возвращает ссылку на объект документа. Однако, если в процессе инициализации или связывания библиотек происходит сбой, этот метод возвращает пустое значение — Неопределено (или значение Null в зависимости от окружения).
Поскольку в коде старых печатных форм конфигурации «УТ 10.3» проверка успешности открытия файла часто отсутствует, система пытается выполнить метод createSearchDescriptor() у несуществующего объекта. Платформа 1С закономерно сообщает, что значение не является объектным.
Прежде чем приступать к настройкам программного обеспечения, необходимо четко определить, в каком контексте выполняется код печати. В старых конфигурациях на обычных формах (таких как «УТ 10.3») печать практически всегда выполняется на клиентском компьютере в контексте толстого клиента.
Выясним это с помощью анализа стека вызовов в конфигураторе. Если в момент останова на ошибке стек показывает выполнение в модуле объекта внешней обработки на стороне клиента (например, под управлением Толстый клиент:Администратор), это означает, что офисный пакет LibreOffice или OpenOffice должен быть установлен именно на рабочей станции пользователя, а не на сервере приложений 1С.
Самым частым источником проблемы является несовпадение разрядности платформы 1С:Предприятие и установленного офисного пакета LibreOffice/OpenOffice. Операционная система Windows не может напрямую связать 32-битное приложение с 64-битной COM-библиотекой (и наоборот) без специальных системных прослоек.
Проанализируем ситуацию:
Для устранения ошибки достаточно удалить офисный пакет неподходящей разрядности и установить версию, которая строго соответствует разрядности запускаемого файла 1cv8.exe.
Что делать, если на рабочих станциях обязательно должен использоваться 64-битный офис, а платформа 1С по техническим причинам используется в 32-битной редакции? В таком случае мы можем настроить операционную систему Windows для работы через суррогатный процесс dllhost.exe.
Рассмотрим по шагам настройку службы компонентов:
dcomcnfg и нажмите Enter.Verbs OLE Document или соответствовать идентификатору класса LibreOffice).Это позволит операционной системе автоматически транслировать вызовы между процессами разной разрядности.
Если ваша печатная форма всё же формируется на стороне сервера 1С:Предприятие (в фоновом задании или при вызове серверного метода), инициализация COM-объекта будет происходить под учетной записью службы сервера 1С (обычно это USR1CV8).
По умолчанию у этой системной учетной записи нет прав на запуск и активацию локальных COM-серверов. Чтобы исправить это, выполните следующие действия:
dcomcnfg откройте свойства компонента LibreOffice.USR1CV8 (или локальную группу пользователей сервера 1С) и предоставьте ему полные права (Локальный запуск, Локальная активация).Использование COM-технологий для автоматизации офисных приложений признано устаревшим подходом. Он создает зависимость от стороннего ПО, нагружает оперативную память процессами soffice.bin и абсолютно несовместим с серверами на базе ОС Linux.
Рекомендуем рассмотреть перевод печатных форм на работу с файлами шаблонов напрямую. Документы LibreOffice .odt представляют собой обычные ZIP-архивы, внутри которых находятся XML-файлы с разметкой текста. Платформа 1С умеет работать с ними встроенными средствами.
Рассмотрим пример логики безопасной замены текста без использования COM-объектов:
// Пример распаковки шаблона и замены параметров средствами 1С
АрхивШаблона = Новый ЧтениеZipФайла(ПутьКШаблону);
АрхивШаблона.ИзвлечьВсе(КаталогВременныхФайлов);
АрхивШаблона.Закрыть();
// Чтение основного текстового содержимого
ПутьКДанным = КаталогВременныхФайлов + "content.xml";
ТекстДокумента = Новый ТекстовыйДокумент;
ТекстДокумента.Прочитать(ПутьКДанным, КодировкаТекста.UTF8);
СодержимоеXML = ТекстДокумента.ПолучитьТекст();
// Прямая замена текстовых маркеров на данные из 1С
СодержимоеXML = СтрЗаменить(СодержимоеXML, "[НомерДоговора]", НомерДоговора);
СодержимоеXML = СтрЗаменить(СодержимоеXML, "[ДатаДоговора]", Формат(Дата, "ДЛФ=DD"));
// Запись изменений обратно
ТекстДокумента.УстановитьТекст(СодержимоеXML);
ТекстДокумента.Записать(ПутьКДанным, КодировкаТекста.UTF8);
// Упаковка обратно в архив .odt
НовыйАрхив = Новый ЗаписьZipФайла(ПутьКГотовомуФайлу);
НовыйАрхив.Добавить(КаталогВременныхФайлов + "*.*", РежимСохраненияПутейZIP.СохранятьОтносительныеПути);
НовыйАрхив.Записать();
Этот метод работает в десятки раз быстрее, исключает любые проблемы с разрядностью операционной системы, не требует прав администратора и стабильно работает как на Windows, так и на Linux-системах.