Как получить значения перечислений и справочников из 1С 7.7 через OLE в 1С 8?

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

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

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

Инициализация OLE-соединения с базой 7.7

Прежде всего, рассмотрим базовый код подключения к информационной базе 7.7 из среды 1С 8. Для этого используется объект V1CEnterprise.Application. Важно правильно сформировать строку подключения, указав путь к базе, пользователя и пароль.

Проанализируем пример кода для установления связи:


ПутьКБазе = "E:\base";
Пользователь = "Администратор";
Пароль = "";
ЗапускБезЗаставки = 1;

База = Новый COMОбъект("V1CEnterprise.Application");
СтрокаПодключения = "/D""" + СокрЛП(ПутьКБазе) + """ /N""" + СокрЛП(Пользователь) + """ /P""" + СокрЛП(Пароль) + """";

РезультатПодключения = База.Initialize(База.RMTrade, СтрокаПодключения, ?(ЗапускБезЗаставки = 1, "NO_SPLASH_SHOW", ""));

Если НЕ РезультатПодключения Тогда
    Сообщить("Не удалось произвести подключение к информационной базе");
    Возврат;
КонецЕсли;

Здесь метод Initialize принимает три параметра: контекст (обычно База.RMTrade), параметры командной строки и флаг отображения заставки. После успешного выполнения переменная База становится "окном" в мир семерки.

Проблема получения значений перечислений

Разберем ситуацию: мы пытаемся получить значение реквизита «Ставка НДС». В 1С 7.7 это обычно перечисление. Если написать код напрямую НДС = Спр.СтавкаНДС, в 8-ке мы получим COMОбъект, с которым невозможно работать (сравнивать или записывать в базу).

Решение 1: Использование метода Идентификатор()

Самый простой способ получить строковое представление значения перечисления (имя, заданное в конфигураторе) — это вызвать метод Идентификатор() непосредственно у объекта перечисления на стороне OLE.


// Получаем строковое имя значения перечисления
НДСТовара = Спр.СтавкаНДС.Идентификатор(); 
// Результат будет строкой: "НДС18", "НДС20" или "БезНДС"

Решение 2: Получение через индекс

Иногда требуется получить не имя, а порядковый номер значения в списке перечисления. Для этого можно воспользоваться методами глобального контекста семерки через OLE-объект:


ИндексЗначения = База.Перечисление.СтавкаНДС.Индекс(Спр.СтавкаНДС);
// Теперь ИндексЗначения содержит число (0, 1, 2...)

Почему Идентификатор() может работать некорректно?

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

Это происходит в двух случаях:

  1. Реквизит не заполнен: Если в базе 7.7 поле пустое, OLE-объект может указывать на начало коллекции (индекс 0). Перед обращением к идентификатору всегда проверяйте объект на пустоту.
  2. Объект является справочником: Если «Вид номенклатуры» в вашей конфигурации 7.7 — это не перечисление, а справочник, то метода Идентификатор() у него нет. В этом случае нужно обращаться к коду или наименованию.

Для надежности воспользуемся функцией ТипЗначенияСтр():


ТипОбъекта = База.ТипЗначенияСтр(Спр.ВидНоменклатуры);
Если ТипОбъекта = "Перечисление" Тогда
    Значение = Спр.ВидНоменклатуры.Идентификатор();
ИначеЕсли ТипОбъекта = "Справочник" Тогда
    Значение = Спр.ВидНоменклатуры.Наименование;
КонецЕсли;

Использование EvalExpr для сложных вычислений

Если стандартные методы получения свойств не помогают, мы можем заставить саму «семерку» вычислить нужное нам значение и вернуть его уже в виде простой строки или числа. Для этого используется метод EvalExpr (вычислить выражение).

Рассмотрим пример получения строкового представления любого объекта:


// Передаем объект обратно в семерку для преобразования в строку
СтроковоеЗначение = База.EvalExpr("СокрЛП(Строка(ТекущийОбъект))");

Однако в контексте цикла по справочнику передать конкретный элемент в EvalExpr сложно. В таких случаях лучше формировать строку кода динамически, но это замедляет работу.

Оптимизация: получение данных пачкой

Важно помнить: каждое обращение через точку в OLE (например, Спр.БазоваяЕдиница.ШтрихКод) — это отдельный сетевой вызов между процессами. Если у вас 10 000 товаров и 5 реквизитов, программа сделает 50 000 вызовов, что крайне медленно.

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

  1. Сначала получаем простые значения: Код, Наименование, Числа и Строки передаются быстро.
  2. Используем временную таблицу: Можно создать Таблицу Значений на стороне 7.7, заполнить её всеми данными (превратив перечисления в строки через Идентификатор()), а затем передать всю таблицу в 8-ку одним махом.
  3. Метод ЗначениеВСтрокуВнутр(): Самый быстрый способ — сформировать на стороне 7.7 большую строку со всеми данными и передать её в 8-ку для парсинга.

Завершение работы

После того как все данные получены, необходимо корректно закрыть соединение. Если этого не сделать, процесс 1cv77.exe может "зависнуть" в памяти, блокируя файлы базы данных.


База = Неопределено;
// Принудительно очищаем переменную, чтобы разорвать COM-соединение

Подведем итог: для получения перечислений используйте .Идентификатор(), для справочников — .Код или .Наименование, а для проверки типа данных на стороне источника — База.ТипЗначенияСтр(). Эти несложные правила позволят вам построить надежный механизм интеграции между разными поколениями систем 1С.

← На главную