Как установить значение перечисления в другой базе 1С при создании объекта через COM-соединение

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

При интеграции различных информационных систем на платформе 1С:Предприятие 8.3 через механизм COM-соединения программисты часто сталкиваются с проблемой передачи ссылочных данных. Одной из самых коварных задач является установка значения перечисления. Казалось бы, прямое присвоение через точку от объекта базы-источника должно работать, но на практике это часто приводит к ошибкам или записи пустого значения. Разберем подробно, почему так происходит и какие способы решения существуют.

Анализ проблемы: почему не работает прямое обращение

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

НовыйКонтрагент.ЮрФизЛицо = CRMбаза.Перечисления.КомпанияЧастноеЛицо.Компания;

Проанализируем причину неудачи. Несмотря на то что CRMбаза — это полноценное соединение, объект перечисления, полученный таким образом, не всегда корректно воспринимается менеджером записи удаленной базы как валидная ссылка. В некоторых случаях возникает конфликт типов, так как COM-объект перечисления должен быть «распознан» контекстом сервера удаленной базы именно как ссылка (Ref), а не просто как объект интерфейса. Кроме того, часто путают имя значения перечисления и его синоним, что в COM-соединении критично.

Решение №1: Использование метода ПредопределенноеЗначение

Как показала практика обсуждения на форуме, наиболее стабильным и простым способом является использование метода ПредопределенноеЗначение. Этот метод выполняется на стороне внешней базы и возвращает «чистую» ссылку, которую менеджер объекта может без проблем записать в базу данных.

Рассмотрим по шагам, как применить этот метод в коде:

  1. Создаем соединение с базой (объект V83.COMConnector).
  2. Создаем новый объект или получаем существующий в удаленной базе.
  3. Вызываем метод ПредопределенноеЗначение, передавая путь к перечислению в виде строки.

Пример реализации:


// Предположим, CRMбаза — это наше активное COM-соединение
НовыйКонтрагент = CRMбаза.Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = "ООО ТехноПром";

// Устанавливаем перечисление через строковое имя
НовыйКонтрагент.ЮрФизЛицо = CRMбаза.ПредопределенноеЗначение("Перечисление.КомпанияЧастноеЛицо.Компания");

НовыйКонтрагент.Записать();

Этот способ хорош тем, что он избавляет нас от необходимости обращаться к коллекции Перечисления напрямую и гарантирует получение верного типа данных ПеречислениеСсылка.

Решение №2: Обращение к коллекции по индексу

Иногда возникают ситуации, когда строковое имя значения перечисления может меняться или нам нужно динамически выбрать значение. В таких случаях можно использовать обращение по индексу. Индексация значений перечисления в 1С всегда начинается с нуля и соответствует порядку, заданному в конфигураторе.

Проанализируем ситуацию, когда нам нужно получить второе значение в списке перечисления:


ИндексНужногоЗначения = 1; // Например, второе значение по порядку
Значение = CRMбаза.Перечисления.КомпанияЧастноеЛицо.Получить(ИндексНужногоЗначения);
НовыйКонтрагент.ЮрФизЛицо = Значение;

Этот метод считается одним из самых надежных, так как он обходит механизмы разрешения имен и работает напрямую с внутренним порядком метаданных. Однако он требует уверенности в том, что порядок значений в обеих базах совпадает.

Решение №3: Обращение через квадратные скобки (строковый идентификатор)

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


// Обращение к менеджеру перечисления и его значению по именам метаданных
ИмяПеречисления = "КомпанияЧастноеЛицо";
ИмяЗначения = "Компания";

НовыйКонтрагент.ЮрФизЛицо = CRMбаза.Перечисления[ИмяПеречисления][ИмяЗначения];

В данном случае 1С внутри COM-соединения интерпретирует ["Имя"] как поиск в коллекции по внутреннему идентификатору, что часто работает стабильнее, чем разрешение свойств через точку в динамических языках и интерфейсах COM.

Решение №4: Синхронизация через XML-сериализацию

Выясним причину, по которой этот метод может быть полезен. Если в вашей текущей базе есть точно такое же перечисление с теми же именами значений, вы можете передать значение, не зная заранее его строкового представления в удаленной базе. Для этого используется XML-строка.

Разберем этот алгоритм:

  1. Получаем строковое имя значения в текущей базе с помощью функции XMLСтрока.
  2. Используем полученную строку для поиска значения в COM-базе.

// В текущей базе у нас есть ссылка: СсылкаВТекущейБазе
// Получаем ее имя (например, "Компания")
ИмяЗначенияXML = XMLСтрока(СсылкаВТекущейБазе); 

// В CRM базе находим аналогичное значение
НовыйКонтрагент.ЮрФизЛицо = CRMбаза.Перечисления.КомпанияЧастноеЛицо[ИмяЗначенияXML];

Важно помнить: XMLСтрока для перечисления возвращает именно его Имя (не синоним), что делает этот метод универсальным для синхронизации идентичных конфигураций.

Решение №5: Универсальный поиск через метаданные

Посмотрим на ситуацию, когда мы пишем универсальную обработку обмена данными и не знаем имен перечислений заранее. Мы можем программно обращаться к метаданным удаленной базы. Это более медленный путь, но он позволяет избежать жесткого кодирования имен.


// Получаем метаданные нужного перечисления в COM-базе
МетаДанныеПеречисления = CRMбаза.Метаданные.Перечисления.КомпанияЧастноеЛицо;
КоличествоЗначений = МетаДанныеПеречисления.ЗначенияПеречисления.Количество();

Для Инд = 0 По КоличествоЗначений - 1 Цикл
    ТекЗначениеМетаданных = МетаДанныеПеречисления.ЗначенияПеречисления.Получить(Инд);
    Если ТекЗначениеМетаданных.Имя = "Компания" Тогда
        НовыйКонтрагент.ЮрФизЛицо = CRMбаза.Перечисления.КомпанияЧастноеЛицо.Получить(Инд);
        Прервать;
    КонецЕсли;
КонецЦикла;

Хотя этот код выглядит избыточным для простой установки значения, он незаменим в сложных системах миграции данных, где соответствия типов настраиваются динамически.

Важные технические нюансы работы через COM

Проанализируем еще несколько критических моментов, которые могут влиять на результат:

Подводя итог, можно сказать, что использование CRMбаза.ПредопределенноеЗначение() является «золотым стандартом» при работе с перечислениями через COM. Это минимизирует количество обращений между процессами и гарантирует корректность передаваемой ссылки.

← На главную