Как решить проблемы при обмене данными между базами 1С через COM/OLE соединение?

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

Интеграция различных информационных баз 1С — это классическая задача для любого разработчика. Одним из исторически популярных, но капризных инструментов для этого является COM-соединение (OLE). На практике программисты часто сталкиваются с неочевидным поведением системы, зависанием процессов или системными ошибками Windows вроде «Класс не зарегистрирован». В этой статье мы подробно разберем все тонкости настройки COM-подключения, исправим частые ошибки в коде и рассмотрим, как правильно зарегистрировать необходимые библиотеки в операционной системе.

Разница между V83.Application и V83.COMConnector: почему возвращается «Истина»

Начнем анализ с первой ключевой проблемы, с которой часто сталкиваются разработчики при использовании объекта V83.Application. При попытке выполнить метод Connect() система возвращает логическое значение (Истина или Ложь), а не ссылку на саму базу данных.

Рассмотрим эту разницу подробнее. Объект V83.Application предназначен для полноценного запуска клиентского приложения 1С. Когда мы пишем код подключения, результатом работы метода является булево значение успешности авторизации:


// ОШИБКА: Base1С получит значение Истина, а не объект базы!
Base1С = V82COMConnector.Connect("File=""C:\DB"";Usr=""Администратор"";");
// Данный вызов вызовет ошибку "Значение не является значением объектного типа"
СсылкаНаОбъект = Base1С.Справочники.Номенклатура.НайтиПоКоду("00000010000");

Если мы используем V83.Application, все дальнейшие обращения к метаданным внешней базы нужно делать не через переменную результата подключения, а через первоначальный COM-объект, который мы создали через конструктор Новый COMОбъект. Посмотрим на пример правильной реализации:


&НаСервере
Процедура ПодключитьсяЧерезApplication()
    V83App = Новый COMОбъект("V83.Application");
    Попытка
        ПодключениеУспешно = V83App.Connect("File=""C:\Base1C"";Usr=""User"";Pwd=""Pass"";");
    Исключение
        Сообщить("Не удалось подключиться: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    Если ПодключениеУспешно Тогда
        // Обращаемся напрямую к объекту приложения V83App, а не к результату Connect!
        // Внимание: обязательно используем множественное число "Справочники"
        СсылкаНоменклатура = V83App.Справочники.Номенклатура.НайтиПоКоду("00000010000");
        Если ЗначениеЗаполнено(СсылкаНоменклатура) Тогда
            Сообщить("Успешно найдено: " + СсылкаНоменклатура.Наименование);
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Важный нюанс: при использовании V83.Application на компьютере физически запускается полноценный сеанс 1С со всем его интерфейсом. Это расходует большое количество оперативной памяти, работает медленно и требует обязательного вызова метода V83App.Quit() в конце работы, иначе процесс 1cv8.exe навсегда зависнет в диспетчере задач.

Организация фонового обмена через V83.COMConnector

Для оптимизации работы, ускорения обмена данными и исключения визуального открытия окон программы следует использовать легковесный объект V83.COMConnector. Он не запускает графический интерфейс платформы, а работает в фоновом режиме, напрямую обращаясь к серверной или файловой СУБД внешней базы.

Разберем по шагам, как правильно написать код для подключения через V83.COMConnector. Обратите внимание, что в отличие от Application, метод Connect() здесь возвращает именно объектную ссылку на внешнюю информационную базу:


&НаСервере
Процедура ВыполнитьПодключениечерезCOMConnector()
    // Создаем экземпляр COM-коннектора
    Connector = Новый COMОбъект("V83.COMConnector");
    СтрокаПодключения = "File=""C:\Base1C"";Usr=""Администратор"";Pwd=""Пароль"";";
    
    Попытка
        // Метод Connect возвращает саму внешнюю базу, а не логическое Истина!
        ВнешняяБаза = Connector.Connect(СтрокаПодключения);
    Исключение
        Сообщить("Ошибка соединения с информационной базой: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // Теперь мы можем работать напрямую с объектом ВнешняяБаза
    СсылкаНаНоменклатуру = ВнешняяБаза.Справочники.Номенклатура.НайтиПоКоду("00000010000");
    
    Если ВнешняяБаза.ЗначениеЗаполнено(СсылкаНаНоменклатуру) Тогда
        Сообщить("Элемент найден во внешней базе успешно!");
    Иначе
        Сообщить("Номенклатура с таким кодом отсутствует.");
    КонецЕсли;
    
    // Очищаем соединение, чтобы освободить память на сервере
    ВнешняяБаза = Неопределено;
    Connector = Неопределено;
КонецПроцедуры

Обратите внимание на конструкцию ВнешняяБаза.ЗначениеЗаполнено(...). Метод ЗначениеЗаполнено() является методом локальной платформы. Чтобы проверить заполненность ссылки, полученной из другой базы, мы должны вызывать этот метод через контекст внешнего соединения.

Решение ошибки «Класс не зарегистрирован» (0x80040154)

Часто при попытке создать объект Новый COMОбъект("V83.COMConnector") программисты сталкиваются с системным сбоем: «Класс не зарегистрирован. Ошибка -2147221164(0x80040154)». Это означает, что операционная система Windows не знает, к какой динамической библиотеке обратиться при вызове этого программного идентификатора.

Для исправления этой ошибки разберем два основных шага.

Шаг 1. Ручная регистрация библиотеки comcntr.dll

Библиотека comcntr.dll поставляется вместе с платформой 1С:Предприятие и лежит в папке установленной версии. Чтобы зарегистрировать её в реестре Windows, выполним следующие действия:

  1. Откройте меню «Пуск» на сервере или компьютере, где запускается код.
  2. Найдите приложение «Командная строка» (cmd), кликните по нему правой кнопкой мыши и обязательно выберите пункт «Запуск от имени администратора». Если запустить командную строку без административных прав, вызов функции DllRegisterServer завершится ошибкой.
  3. Введите команду регистрации, указав точный путь к вашей версии платформы 1С:

    regsvr32 "C:\Program Files\1cv8\8.3.15.1830\bin\comcntr.dll"

  4. Нажмите Enter. При успешной регистрации операционная система выдаст окно с подтверждением «Успешное выполнение DllRegisterServer».

Шаг 2. Устранение конфликта разрядности процессов (32-bit vs 64-bit)

Если вы зарегистрировали библиотеку, но при запуске кода &НаСервере ошибка «Класс не зарегистрирован» повторяется, мы имеем дело с несовпадением разрядности процессов.

Проанализируем ситуацию: серверная служба 1С (процесс rphost.exe) на современных серверах практически всегда является 64-разрядной. Если на сервере установлена 32-разрядная платформа 1С, то библиотека comcntr.dll будет 32-битной. Процесс rphost.exe физически не может загрузить 32-битную DLL напрямую в свое адресное пространство. Также возможна и обратная ситуация.

Решить эту проблему можно с помощью настройки обертки COM+ в Windows, которая запустит библиотеку в изолированном системном процессе dllhost.exe:

  1. Нажмите сочетание клавиш Win + R, введите команду dcomcnfg и нажмите Enter. Откроется оснастка «Службы компонентов».
  2. Раскройте дерево: Службы компонентов -> Компьютеры -> Мой компьютер.
  3. Выделите пункт Приложения COM+, нажмите по нему правой кнопкой мыши и выберите Создать -> Приложение.
  4. В открывшемся мастере выберите пункт «Создать новое приложение». Задайте понятное имя, например, V83_COMConnector. В параметрах способа активации обязательно укажите «Серверное приложение» (это заставит Windows запускать dll в отдельном хост-процессе).
  5. На шаге выбора учетной записи укажите пользователя, под которым работает серверная служба 1С (обычно это USR1CV8) или администратора сети.
  6. После создания приложения, разверните его ветку, найдите папку Компоненты. Нажмите правой кнопкой мыши -> Создать -> Компонент.
  7. Выберите пункт «Установка новых компонентов» и укажите путь к файлу comcntr.dll нужной вам версии платформы 1С.
  8. Зайдите в свойства созданного приложения COM+, перейдите на вкладку «Безопасность» и снимите флаг «Принудительная проверка доступа для приложений», а также установите уровень аутентификации в положение «Отсутствует».

После проведения данных настроек вызовы V83.COMConnector на сервере начнут перенаправляться через системный мост Windows, и проблема разрядности будет полностью решена.

Современные альтернативы COM-соединениям

Несмотря на то, что COM-соединения остаются рабочим инструментом, в современной практике разработки они считаются устаревшими. COM жестко привязан к операционной системе Windows (не работает на Linux-серверах), крайне чувствителен к несовпадению версий платформы 1С у баз-партнеров и сильно нагружает оперативную память сервера.

Если вы проектируете интеграцию сегодня, рекомендуем рассмотреть более надежные веб-технологии:

← На главную