К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как получить значение COM-объекта в 1С

Как подключиться к базе 1С через COM-connector и получить значение объекта: свойства, реквизиты, табличные части, запросы. Примеры кода, ошибки и FAQ.

COM-соединение — один из основных способов обмена данными между базами 1С и внешними приложениями. Через объект V83.COMConnector (или V82 для старых платформ) можно подключиться к другой информационной базе, получить ссылку на документ или справочник и прочитать значения его реквизитов так, будто вы работаете внутри самой базы. При этом у разработчиков чаще всего возникают вопросы именно на этапе извлечения значений: как обратиться к реквизиту, как прочитать табличную часть, как получить примитивное значение вместо COM-объекта.

Ключевая особенность работы через COM — типы данных. Числа, строки, даты и булево передаются между базами напрямую, а вот ссылки, перечисления, объекты и табличные части приходят как COM-объекты, с которыми нужно обращаться через методы соединения. Если этого не учитывать, код либо падает с ошибкой, либо возвращает неперевариваемые значения.

Материал рассчитан на разработчиков и администраторов, которые настраивают интеграцию между базами 1С или выгрузку данных во внешние системы. Разберём подключение, получение значений разных типов, работу с запросами через COM и типичные ошибки.

Как устроено получение данных через COM в 1С

Механизм строится на технологии OLE Automation. Одна база 1С (или внешнее приложение) выступает клиентом, другая — сервером автоматизации. Клиент создаёт COM-объект коннектора, открывает соединение и через него обращается к менеджерам объектов: Справочники, Документы, Перечисления и так далее.

Когда вы читаете реквизит объекта через COM, результат зависит от типа реквизита. Строка, число, дата и булево возвращаются как обычные значения, с которыми можно сразу работать. Ссылочные типы (другой справочник, документ, перечисление) возвращаются как новые COM-объекты. Попытка вывести такое значение в строку даст либо служебное описание, либо ошибку преобразования.

Отсюда главное правило: любое ссылочное значение, полученное через COM, нужно «разворачивать» до примитивов — читать его Наименование, Код, УникальныйИдентификатор или другие примитивные реквизиты, либо передавать в запрос на стороне базы-источника.

Как установить COM-соединение с базой 1С

Прежде чем получать значения, нужно открыть соединение. Для файловой базы строка подключения выглядит как путь к каталогу, для клиент-серверной — как указание сервера и имени базы. Код подключения в типовом виде:

Коннектор = Новый COMОбъект("V83.COMConnector");

СтрокаПодключения = "File=""D:\Bases\Trade""; Usr=""Администратор""; Pwd=""12345"";";

Соединение = Коннектор.Connect(СтрокаПодключения);

Для серверной базы строка меняется: Srvr="Server1";Ref="Trade";Usr="...";Pwd="...";. Имя класса зависит от версии платформы: V83 для платформы 8.3, V82 для 8.2. Если на машине установлено несколько версий, регистрируется коннектор той версии, которая нужна базе-источнику — иначе получите ошибку несовместимости версий.

После успешного Connect() переменная Соединение становится аналогом глобального контекста удалённой базы: через неё доступны Соединение.Справочники, Соединение.Документы, Соединение.NewObject() и другие привычные конструкции.

Порядок подключения и чтения значения
  1. 1
    Создайте COMОбъект V83.COMConnector на стороне клиента
  2. 2
    Сформируйте строку подключения с путем к базе, пользователем и паролем
  3. 3
    Выполните Connect() и убедитесь, что соединение не равно Неопределено
  4. 4
    Получите ссылку через менеджер объекта (НайтиПоКоду, НайтиПоНаименованию, ПолучитьСсылку)
  5. 5
    Прочитайте нужные реквизиты, разворачивая ссылочные значения до примитивов
  6. 6
    Закройте соединение, обнулив переменные (Соединение = Неопределено)

Как получить ссылку на объект через COM

Любое чтение начинается с получения ссылки. Способов несколько: поиск по коду, по наименованию, по уникальному идентификатору или выборка всех элементов. Примеры:

// По коду

Контрагент = Соединение.Справочники.Контрагенты.НайтиПоКоду("000000123");

// По наименованию

Номенклатура = Соединение.Справочники.Номенклатура.НайтиПоНаименованию("Кирпич М-150");

// По GUID — самый надёжный способ при регулярном обмене

УИД = Соединение.NewObject("УникальныйИдентификатор", "a1b2c3d4-...");

Ссылка = Соединение.Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИД);

Если элемент не найден, методы поиска вернут пустую ссылку, а не Неопределено — это частая ловушка. Проверяйте результат через Ссылка.Пустая() перед обращением к реквизитам, иначе получите либо пустые значения, либо ошибку.

Для регулярных интеграций предпочтителен поиск по GUID: коды и наименования могут меняться или дублироваться, а уникальный идентификатор стабилен. Идентификатор удобно хранить в базе-приёмнике в служебном регистре соответствий.

Как прочитать реквизиты и развернуть ссылочные значения

Примитивные реквизиты читаются прямым обращением по имени:

Наименование = Контрагент.Наименование;   // строка

ИНН = Контрагент.ИНН; // строка

ДатаДокумента = Документ.Дата; // дата

Сумма = Документ.СуммаДокумента; // число

Ссылочные реквизиты требуют разворачивания. Например, реквизит «Организация» документа — это COM-объект ссылки. Чтобы получить её название, обращайтесь к примитивному реквизиту вложенного объекта:

ОрганизацияСсылка = Документ.Организация;          // COM-объект

НазваниеОрганизации = ОрганизацияСсылка.Наименование; // строка

ГУИДОрганизации = Соединение.String(ОрганизацияСсылка.УникальныйИдентификатор());

Обратите внимание на метод Соединение.String() — он преобразует значение в строку на стороне удалённой базы и возвращает обычную строку, а не COM-объект. Аналогично работают Boolean(), Number(), Date(). Для перечислений через COM нельзя сравнивать значение напрямую с локальным перечислением — получайте его имя через метаданные или индекс и сопоставляйте по строке.

Как получить значения табличной части и результаты запроса

Табличная часть документа через COM — это коллекция строк, каждая из которых тоже COM-объект. Обход выполняется циклом:

Для Каждого СтрокаТЧ Из Документ.Товары Цикл

Товар = СтрокаТЧ.Номенклатура.Наименование; // разворачиваем ссылку

Количество = СтрокаТЧ.Количество; // примитив

Цена = СтрокаТЧ.Цена;

КонецЦикла;

Такой перебор медленный на больших объёмах. Производительная альтернатива — выполнить запрос целиком на стороне удалённой базы и забрать выгрузку:

Запрос = Соединение.NewObject("Запрос");

Запрос.Текст = "ВЫБРАТЬ Номенклатура.Наименование КАК Товар, СУММА(Количество) КАК Кол

|ИЗ Документ.РеализацияТоваровУслуг.Товары

|ГДЕ Ссылка.Дата МЕЖДУ &Нач И &Кон

|СГРУППИРОВАТЬ ПО Номенклатура";

Запрос.УстановитьПараметр("Нач", НачалоМесяца(ТекущаяДата()));

Запрос.УстановитьПараметр("Кон", КонецМесяца(ТекущаяДата()));

Результат = Запрос.Выполнить().Выгрузить();

Таблица значений, полученная через Выгрузить(), остаётся COM-объектом, но обход её строк через Выбор() или Выгрузить() с последующим циклом всё равно быстрее, чем тысячи точечных чтений реквизитов. В тексте запроса сразу выбирайте примитивные представления ссылок (Наименование, Код), чтобы не разворачивать их на клиенте.

Если нужно передать большую таблицу значений из удалённой базы, сериализуйте её на стороне источника в строку (например, через ЗначениеВСтрокуВнутр или JSON) и передайте одним строковым значением — это на порядок быстрее построчного чтения через COM.
ПЗ
Практическое замечание

Типичные ошибки при получении значений через COM

Первая группа ошибок связана с подключением. «Ошибка при создании объекта V83.COMConnector» означает, что на машине не зарегистрирован коннектор нужной версии — лечится регистрацией comcntr.dll из каталога нужной платформы командой regsvr32. «Несовместимость версий» возникает, когда коннектор одной версии пытается открыть базу другой.

Вторая группа — ошибки типов. Попытка присвоить COM-ссылку локальной переменной ссылочного типа, сравнение COM-перечисления со строкой, передача локального объекта (например, таблицы значений) в метод удалённой базы — всё это вызывает ошибки преобразования. Правило простое: через границу COM передавайте только примитивы и строки, а объекты создавайте через Соединение.NewObject() на той стороне, где они будут использоваться.

Третья группа — права и блокировки. Пользователь из строки подключения должен иметь права на чтение нужных объектов в базе-источнике, иначе реквизиты будут пустыми или чтение упадёт с ошибкой доступа. Также COM-соединение создаёт сеанс в базе: открытые и незакрытые соединения накапливаются и могут мешать регламентным операциям.

Типичные ошибки
01
Чтение реквизитов без проверки НайтиПоКоду на пустую ссылку — получаете пустые значения без явной ошибки
02
Сравнение COM-перечисления с локальным значением — всегда ложь или ошибка типов; сравнивайте по имени
03
Построчное чтение тысяч строк табличной части через COM — обмен длится минутами вместо секунд
04
Не закрытое соединение — висящие сеансы блокируют обновление и архивацию базы
05
Использование коннектора версии, отличной от версии базы-источника, — ошибка несовместимости

Как проверить результат и когда COM лучше заменить

После получения значений проверьте их полноту: количество обработанных записей, контрольные суммы по ключевым документам, отсутствие пустых ссылок там, где они недопустимы. Для отладки полезно выводить полученные примитивы в журнал регистрации или файл лога — так видно, на каком объекте обрывается чтение.

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

Способы получить данные из другой базы 1С

COM-соединение

Полный доступ к объектной модели, простой код. Только Windows, сеанс в базе, зависимость от версии платформы

HTTP-сервисы

Кроссплатформенно, не держит постоянный сеанс, подходит внешним системам. Требует разработки и публикации сервиса

Веб-сервисы (SOAP)

Строгий контракт через WSDL, поддержка сторонних систем. Более тяжёлая настройка и формат

Обмен через файлы (XML/JSON)

Работает без прямой связи между базами, устойчив к разрывам. Нет мгновенного доступа к актуальным данным

Контрольные точки

Как проверить результат

Соединение установлено
Норма

Connect() вернул объект без исключения

Тревожный признак

Ошибка создания COMОбъекта или несовместимости версий

Ссылка найдена
Норма

Ссылка.Пустая() возвращает Ложь

Тревожный признак

Пустая ссылка — реквизиты будут пустыми

Значения реквизитов
Норма

Примитивы содержат ожидаемые строки, числа, даты

Тревожный признак

COM-объект вместо значения — нужно развернуть ссылку

Сеанс завершён
Норма

После обмена переменные обнулены, сеанс закрыт

Тревожный признак

В консоли кластера висят активные сеансы COM

Частые вопросы

Почему вместо значения реквизита я получаю «COMОбъект»?

Реквизит имеет ссылочный тип: справочник, документ или перечисление. Через COM он передаётся как объект, а не как примитив. Обратитесь к его примитивному свойству — например, Реквизит.Наименование — или преобразуйте через Соединение.String().

Как передать уникальный идентификатор между базами?

Получите GUID вызовом Ссылка.УникальныйИдентификатор() на стороне источника и преобразуйте в строку через Соединение.String(). На приёмнике создайте идентификатор из строки конструктором Новый УникальныйИдентификатор(СтрокаГУИД) и найдите ссылку через ПолучитьСсылку().

Можно ли через COM записывать данные, а не только читать?

Да. Получите объект через Ссылка.ПолучитьОбъект() или создайте новый через Соединение.Документы.ИмяДокумента.СоздатьДокумент(), заполните реквизиты и вызовите Записать(). Ссылочные реквизиты при этом должны быть COM-ссылками той же удалённой базы.

Почему обмен через COM работает очень медленно?

Каждое обращение к свойству COM-объекта — отдельный межпроцессный вызов. Тысячи таких обращений в цикле дают основную задержку. Перенесите логику в запрос на стороне источника, выбирайте сразу примитивные представления и передавайте большие объёмы сериализованной строкой.

Работает ли COM-соединение на Linux или через веб-клиент?

Нет. Технология COM доступна только на Windows. На Linux-серверах и в веб-клиенте используйте HTTP-сервисы, веб-сервисы или файловый обмен.

Что делать с ошибкой «Класс не зарегистрирован» при создании V83.COMConnector?

На машине, где выполняется код, не зарегистрирована библиотека comcntr.dll. Найдите её в каталоге bin нужной версии платформы и зарегистрируйте командой regsvr32 с правами администратора. Версия библиотеки должна совпадать с версией платформы базы-источника.

Итог

Что важно запомнить

Получение значения COM-объекта 1С сводится к трём шагам: установить соединение через V83.COMConnector, найти ссылку и прочитать реквизиты. Примитивы приходят напрямую, ссылки разворачивайте до примитивов, большие объёмы забирайте запросом. Всегда проверяйте пустые ссылки, совпадение версий коннектора и закрывайте сеанс после обмена.