Как передать значение в реквизит ПолноеНаименование при интеграции 1С 7.7 и 8.3 через OLE

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

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

Анализируем причину возникновения ошибки

Давайте проанализируем ситуацию. В платформе 1С 8.x у всех ссылочных объектов (справочники, документы) существует встроенный метод ПолноеНаименование(). Этот метод предназначен для получения строки, содержащей наименования всех вышестоящих уровней иерархии (родителей) элемента. Если разработчик конфигурации на стороне 8.3 создает реквизит с точно таким же именем — ПолноеНаименование, возникает конфликт имен.

При обращении из внешней среды через COM-интерфейс (например, из 1С 7.7), система при попытке доступа к Объект.ПолноеНаименование в первую очередь обращается к методу платформы, а не к реквизиту данных. Поскольку метод предназначен только для чтения и возвращает значение, попытка присвоить ему новое значение (как свойству) приводит к ошибке интерпретации. Прямая запись в стиле НовыйЭлемент.ПолноеНаименование = "Значение" блокируется механизмом разрешения имен COM-соединения.

Способ №1: Использование структуры и метода ЗаполнитьЗначенияСвойств

Рассмотрим наиболее эффективное и изящное решение, которое позволяет обойти конфликт имен без изменения конфигурации 8.3. Этот способ основан на использовании универсального метода ЗаполнитьЗначенияСвойств, который работает внутри контекста базы-приемника и умеет корректно различать реквизиты объекта.

Основная идея заключается в том, чтобы создать в базе 8.3 объект типа Структура, заполнить его нужными данными (включая проблемное поле), а затем одной командой перенести эти данные в объект справочника. Выясним, как это выглядит в программном коде на стороне 1С 7.7:


// Предположим, подключение к V83.Application уже установлено в переменной V8
// Создаем новый элемент справочника в базе 8.3
оСпр = V8.Справочники.Номенклатура.СоздатьЭлемент();

// Создаем объект Структура в контексте 8.3
мСтруктура = V8.NewObject("Структура");

// Заполняем структуру значениями. 
// Обратите внимание: здесь мы используем имена реквизитов как ключи структуры
мСтруктура.Вставить("Наименование", "Краткое имя товара");
мСтруктура.Вставить("ПолноеНаименование", "Очень длинное и полное наименование товара");
мСтруктура.Вставить("Артикул", "АРТ-123");

// Используем метод глобального контекста 8.3 для переноса данных
// Этот метод "умнее" прямого обращения и запишет данные именно в реквизиты
V8.ЗаполнитьЗначенияСвойств(оСпр, мСтруктура);

// Завершаем создание элемента
Попытка
    оСпр.Записать();
    Сообщить("Элемент успешно создан!");
Исключение
    Сообщить("Ошибка записи: " + ОписаниеОшибки());
КонецПопытки;

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

Способ №2: Проверка реального имени реквизита

Прежде чем внедрять сложные обходы, давайте проанализируем структуру справочника в конфигураторе 1С 8.3. В большинстве типовых конфигураций (например, Бухгалтерия предприятия 3.0 или Управление торговлей 11) разработчики фирмы "1С" намеренно избегают коллизий. Поэтому реквизит для хранения длинного названия обычно называется НаименованиеПолное.

Если вы пытаетесь записать данные в ПолноеНаименование, а такого реквизита нет (есть только метод), вы получите ту же самую ошибку. Посмотрите на дерево метаданных: если вы видите реквизит НаименованиеПолное, просто измените ваш код в 1С 7.7:


// Пример для типовых конфигураций
НовыйЭлемент.Наименование = "Товар";
НовыйЭлемент.НаименованиеПолное = "Полное наименование товара"; // Правильное имя реквизита

Способ №3: Использование экспортных функций в базе 8.3

Если вам часто приходится выполнять сложные операции записи или вы сталкиваетесь с постоянными проблемами доступа к реквизитам через OLE, проанализируем возможность создания "прослойки" на стороне 8.3. Этот метод считается более надежным и быстрым, так как минимизирует количество вызовов через COM-границу.

Сделаем следующее: в конфигурации 8.3 создадим общий модуль (например, ОбменДаннымиСервер) и установим у него флаг "Внешнее соединение". Внутри модуля напишем простую процедуру:


// Код в 1С 8.3 (Общий модуль)
Процедура УстановитьРеквизитыНоменклатуры(ОбъектНоменклатуры, СтруктураДанных) Экспорт
    ЗаполнитьЗначенияСвойств(ОбъектНоменклатуры, СтруктураДанных);
    ОбъектНоменклатуры.Записать();
КонецПроцедуры

Теперь из 1С 7.7 мы будем вызывать эту процедуру напрямую. Это избавляет нас от необходимости контролировать каждый реквизит на стороне 7.7:


// Код в 1С 7.7
НовыйЭлемент = V8.Справочники.Номенклатура.СоздатьЭлемент();
Данные = V8.NewObject("Структура");
Данные.Вставить("Наименование", "Товар");
Данные.Вставить("ПолноеНаименование", "Полное описание");

// Вызываем процедуру из общего модуля 8.3
V8.ОбменДаннымиСервер.УстановитьРеквизитыНоменклатуры(НовыйЭлемент, Данные);

Рекомендации по работе с типами данных

При переносе данных из 7.7 в 8.3 через OLE важно помнить о различиях в типах данных. Разберем основные моменты, которые помогут избежать сопутствующих ошибок:

  1. Строки: В 7.7 строки могут иметь ограниченную длину. Используйте СокрЛП() перед передачей данных в 8.3, чтобы избежать лишних пробелов.
  2. Ссылки: Вы не можете просто присвоить коду или наименованию из 7.7 значение в поле справочника 8.3, если это поле имеет тип "СправочникСсылка". Сначала нужно найти соответствующую ссылку в базе 8.3 (например, через НайтиПоКоду или НайтиПоНаименованию).
  3. Перечисления: Обращайтесь к ним через коллекцию V8.Перечисления. Пример: НовыйЭлемент.ВидТМЦ = V8.Перечисления.ВидыТМЦ.Материал;.
  4. Числа: Платформы обычно хорошо понимают друг друга, но будьте внимательны с точностью (количеством знаков после запятой).

Важный совет: Если база 8.3 работает в клиент-серверном режиме, вместо V83.Application лучше использовать V83.COMConnector. Он работает значительно быстрее, так как не инициализирует графическую оболочку приложения, и потребляет меньше оперативной памяти на сервере.

Мы рассмотрели основные причины, по которым не переносится ПолноеНаименование. Используя метод со Структурой и ЗаполнитьЗначенияСвойств, вы сможете решить эту задачу максимально эффективно, сохранив работоспособность кода даже при обновлении платформы.

← На главную