При организации обмена данными между устаревшей платформой 1С 7.7 и современной 1С 8.x программисты часто сталкиваются с ситуацией, когда при обращении к реквизитам через COM-соединение (OLE) вместо ожидаемого значения (например, ставки НДС или вида товара) возвращается непонятный COMОбъект. Это происходит из-за того, что сложные типы данных 1С 7.7 не могут быть автоматически преобразованы в типы 1С 8.3.
В этой статье мы подробно разберем, как правильно инициализировать подключение и корректно извлекать данные различных типов, включая перечисления, справочники и периодические реквизиты.
Прежде всего, рассмотрим базовый код подключения к информационной базе 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...)
Иногда программисты замечают странное поведение: вызов Спр.ВидНоменклатуры.Идентификатор() всегда возвращает первое значение из списка перечислений, независимо от того, что выбрано в карточке товара. Выясним причину этой ситуации.
Это происходит в двух случаях:
Идентификатор() у него нет. В этом случае нужно обращаться к коду или наименованию.Для надежности воспользуемся функцией ТипЗначенияСтр():
ТипОбъекта = База.ТипЗначенияСтр(Спр.ВидНоменклатуры);
Если ТипОбъекта = "Перечисление" Тогда
Значение = Спр.ВидНоменклатуры.Идентификатор();
ИначеЕсли ТипОбъекта = "Справочник" Тогда
Значение = Спр.ВидНоменклатуры.Наименование;
КонецЕсли;
Если стандартные методы получения свойств не помогают, мы можем заставить саму «семерку» вычислить нужное нам значение и вернуть его уже в виде простой строки или числа. Для этого используется метод EvalExpr (вычислить выражение).
Рассмотрим пример получения строкового представления любого объекта:
// Передаем объект обратно в семерку для преобразования в строку
СтроковоеЗначение = База.EvalExpr("СокрЛП(Строка(ТекущийОбъект))");
Однако в контексте цикла по справочнику передать конкретный элемент в EvalExpr сложно. В таких случаях лучше формировать строку кода динамически, но это замедляет работу.
Важно помнить: каждое обращение через точку в OLE (например, Спр.БазоваяЕдиница.ШтрихКод) — это отдельный сетевой вызов между процессами. Если у вас 10 000 товаров и 5 реквизитов, программа сделает 50 000 вызовов, что крайне медленно.
Проанализируем, как ускорить этот процесс. Профессиональный подход заключается в минимизации обращений:
Таблицу Значений на стороне 7.7, заполнить её всеми данными (превратив перечисления в строки через Идентификатор()), а затем передать всю таблицу в 8-ку одним махом.После того как все данные получены, необходимо корректно закрыть соединение. Если этого не сделать, процесс 1cv77.exe может "зависнуть" в памяти, блокируя файлы базы данных.
База = Неопределено;
// Принудительно очищаем переменную, чтобы разорвать COM-соединение
Подведем итог: для получения перечислений используйте .Идентификатор(), для справочников — .Код или .Наименование, а для проверки типа данных на стороне источника — База.ТипЗначенияСтр(). Эти несложные правила позволят вам построить надежный механизм интеграции между разными поколениями систем 1С.