Как изменить существующий элемент и заполнить подчиненный справочник в 1С 8.3 при подключении через OLE из 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Разберем основные трудности, возникающие при управлении данными 1С 8.3 из внешней базы 7.7 через OLE/COM-соединение: изменение существующих справочников, корректное создание подчиненных элементов и способы заполнения контактной информации.

Различие моделей данных: почему не работает ТекущийЭлемент()

В платформе 1С 7.7 позиционирование на элементе справочника и его непосредственное изменение осуществляются через один и тот же объект. Если элемент найден методом НайтиПоКоду(), разработчик сразу может менять реквизиты и вызывать метод Записать().

В платформе 1С 8 объектная модель строго разделена на два разных типа:

  1. Ссылка (СправочникСсылка) — неизменяемый идентификатор записи в базе данных. Именно ссылку возвращают методы поиска менеджера справочника, такие как НайтиПоКоду() или НайтиПоНаименованию(). Через ссылку можно только считывать реквизиты, но изменять их напрямую нельзя. Проверка на то, найден ли элемент, выполняется методом ссылки Пустая().
  2. Объект (СправочникОбъект) — сущность, предназначенная для модификации данных в оперативной памяти с последующей записью в базу. Чтобы изменить существующую запись, необходимо получить объект из ссылки с помощью метода ПолучитьОбъект(). Если же элемент создается с нуля, вызывается метод менеджера СоздатьЭлемент().

Корректировка существующего и создание нового элемента справочника через OLE

Проанализируем типовой сценарий синхронизации контрагентов. Нам необходимо найти контрагента по коду в базе-приемнике 1С 8.3: если он существует — обновить его реквизиты, а если отсутствует — создать новую карточку.

Посмотрим на пример правильного кода на стороне 1С 7.7:


Процедура СинхронизироватьКонтрагента()
    Контр7 = СоздатьОбъект("Справочник.Контрагенты");
    Если Контр7.НайтиПоКоду("02608") = 0 Тогда
        Сообщить("Элемент в 7.7 не найден!");
        Возврат;
    КонецЕсли;

    МенеджерКонтр8 = БазаИсточник.Справочники.Контрагенты;
    
    // Поиск возвращает СправочникСсылка
    Ссылка8 = МенеджерКонтр8.НайтиПоКоду(Контр7.Код);

    Если Ссылка8.Пустая() = 1 Тогда
        // Создаем новый объект через менеджер справочника
        Объект8 = МенеджерКонтр8.СоздатьЭлемент();
        Объект8.Код = Контр7.Код;
    Иначе
        // Получаем объект из найденной ссылки для редактирования
        Объект8 = Ссылка8.ПолучитьОбъект();
    КонецЕсли;

    Объект8.Наименование = Контр7.Наименование;
    Объект8.НаименованиеПолное = Контр7.ПолнНаименование;
    Объект8.Записать();

    Сообщить("Успешно записан: " + Объект8.Наименование);
КонецПроцедуры

Работа с подчиненными справочниками: устранение ошибки «Несоответствие типов»

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

1C:Enterprise 8.3: Несоответствие типов (параметр номер '2')

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

Разберем по шагам правильное создание единицы измерения для найденной номенклатуры:


Тов7 = СоздатьОбъект("Справочник.ТМЦ");
МенеджерТов8 = БазаИсточник.Справочники.Номенклатура;
МенеджерЕд8 = БазаИсточник.Справочники.ЕдиницыИзмерения;

Тов7.ВыбратьЭлементы();
Пока Тов7.ПолучитьЭлемент() = 1 Цикл
    Если Тов7.ЭтоГруппа() = 1 Тогда
        Продолжить;
    КонецЕсли;

    // Ищем товар в 8.3 по коду (получаем СправочникСсылка)
    СсылкаТовар8 = МенеджерТов8.НайтиПоКоду("0000" + СокрЛП(Тов7.Код));

    Если СсылкаТовар8.Пустая() = 0 Тогда
        // Для создания нового подчиненного элемента используем менеджер справочника
        НоваяЕд8 = МенеджерЕд8.СоздатьЭлемент();
        
        // Владельцем всегда выступает ссылка на родительский элемент
        НоваяЕд8.Владелец = СсылкаТовар8;
        НоваяЕд8.ЕдиницаПоКлассификатору = СсылкаТовар8.БазоваяЕдиницаИзмерения;
        НоваяЕд8.Коэффициент = 1;
        
        // Сравнение реквизитов ссылочного типа: сравниваем код или наименование
        Если СокрЛП(СсылкаТовар8.БазоваяЕдиницаИзмерения.Код) = "0301" Тогда
            НоваяЕд8.Вес = 1;
        КонецЕсли;

        НоваяЕд8.Записать();
    КонецЕсли;
КонецЦикла;

Важный момент: никогда не сравнивайте ссылочный реквизит напрямую со строкой вида Т8.БазоваяЕдиницаИзмерения = "0301". В 1С 8 реквизит содержит ссылку на элемент классификатора, поэтому обращаться необходимо к его свойствам (например, БазоваяЕдиницаИзмерения.Код).

Особенности хранения контактной информации в 1С 8

При переносе контактных данных контрагентов (юридический адрес, телефон, email) разработчики часто пытаются присвоить значения полям формы напрямую, однако эти поля не являются простыми реквизитами справочника Контрагенты. Способ хранения зависит от поколения конфигурации-приемника:

  1. В конфигурациях прежних редакций (УПП 1.3, УТ 10.3, БП 2.0): контактная информация хранится в независимом регистре сведений КонтактнаяИнформация. Для записи данных создается менеджер записи регистра (СоздатьМенеджерЗаписи()), где заполняются измерения Объект (ссылка на контрагента), Тип (значение перечисления ТипыКонтактнойИнформации), Вид (ссылка на справочник ВидыКонтактнойИнформации) и ресурс Представление (строка адреса или телефона).
  2. В современных конфигурациях на базе БСП (БП 3.0, УТ 11, КА 2, ERP): информация хранится в табличной части КонтактнаяИнформация самого справочника Контрагенты. Чтобы добавить запись, необходимо получить объект контрагента (ПолучитьОбъект()), вызвать метод КонтактнаяИнформация.Добавить(), заполнить реквизиты строки Вид, Тип, строковое Представление, а также служебные данные разбора адреса.

Технические ограничения COM/OLE между 7.7 и 8.3

Рассмотрим подводные камни, которые необходимо учитывать при настройке OLE-обмена:

  1. Разрядность платформ: платформа 1С 7.7 является исключительно 32-битным приложением (x86). При использовании внутрипроцессного COM-соединения через V83.COMConnector на сервере с 64-битной версией платформы 8.3 возникнет ошибка несовместимости библиотек. Для стабильной работы следует использовать 32-разрядный клиент 1С 8.3 либо настраивать прокси-суррогат COM+ (dllhost.exe).
  2. Запуск через Application: прямое OLE-подключение через V83.Application запускает полноценное клиентское приложение 1cv8.exe. Это требует отдельной клиентской лицензии и расходует больше оперативной памяти, чем соединение через COMConnector.
  3. Освобождение памяти: среда 1С 7.7 удерживает COM-ссылки до полного закрытия базы. Чтобы не блокировать сеансы и таблицы в 1С 8.3, после выполнения обмена необходимо принудительно обнулять объект подключения командой вида БазаИсточник = 0;.
← На главную