Часто при интеграции старых баз на платформе 1С 7.7 и современных конфигураций на 1С 8 возникает задача сравнения данных, например, товарных остатков. При попытке выгрузить остатки из 7.7 в таблицу значений через COM-соединение и обработать её в 8-ке, программисты сталкиваются с ошибками. Рассмотрим подробнее типичную ситуацию: мы создаем объект таблицы в базе-источнике, заполняем его итогами регистра, но при попытке обхода в 1С 8 получаем ошибку "Итератор для значения не определен". Если же мы создаем таблицу значений средствами 1С 8, методы 7.7 отказываются с ней работать. Разберем по шагам, почему так происходит и как правильно решить эту задачу.
Для начала проанализируем, почему возникает ошибка при использовании привычного цикла обхода коллекций. Объекты 1С 7.7, созданные через OLE-соединение (COM-объекты V77.Application или V77S.Application), включая ТаблицаЗначений, не поддерживают внутренний COM-интерфейс перечисления. Этот интерфейс необходим платформе 1С 8 для работы конструкции Для Каждого ... Из ... Цикл. Именно отсутствие этого интерфейса вызывает сообщение об ошибке итератора.
Вторая проблема заключается в изолированности объектных моделей. Метод выгрузки итогов регистра 1С 7.7 ожидает на вход внутренний объект среды 7.7. Передать туда таблицу значений, созданную в 1С 8 через конструктор Новый ТаблицаЗначений, невозможно — среда 7.7 не распознает чужой объектный тип.
Если мы создаем таблицу значений на стороне 7.7 с помощью БазаИсточник.CreateObject("ТаблицаЗначений") и заполняем её остатками там же, на стороне 1С 8 обходить её нужно семерочными методами. Посмотрим на пример кода, который использует позиционирование по строкам:
// Предполагаем, что ТЗТиС создана и заполнена в базе 7.7
ТЗТиС.ВыбратьСтроки();
Пока ТЗТиС.ПолучитьСтроку() = 1 Цикл
// Читаем значения из колонок семерочной таблицы
КодТовара = ТЗТиС.Код;
Остаток = ТЗТиС.ОстатокТовара;
// Дальнейшая обработка данных
КонецЦикла;
Также можно использовать классический цикл со счетчиком. Сначала мы получаем общее количество строк методом КоличествоСтрок(), а затем в цикле перебираем индексы, получая значения ячеек методом ПолучитьЗначение(НомерСтроки, "ИмяКолонки").
Многие специалисты рекомендуют создавать таблицу значений там, где вы с ней работаете, то есть в 1С 8. В этом случае данные из базы 7.7 нужно извлекать не целиком в таблицу, а порциями, например, с помощью OLE-запроса, и построчно заполнять созданную в 8-ке таблицу. Проанализируем важный нюанс этого подхода: приведение ссылочных типов.
Значения из 1С 7.7 (например, ссылка на элемент справочника "Номенклатура") в 1С 8 предстают как внешние COM-объекты. Их нельзя напрямую сравнить с данными 8-ки. Необходимо извлекать из них примитивные типы, обращаясь к реквизитам. Создадим таблицу в 8-ке и заполним её примитивными данными:
ТЗ_8 = Новый ТаблицаЗначений;
ТЗ_8.Колонки.Добавить("Код");
ТЗ_8.Колонки.Добавить("Наименование");
ТЗ_8.Колонки.Добавить("Остаток");
// ... выполнение запроса в базе 7.7 через OLE ...
Пока Запрос77.Группировка(1) = 1 Цикл
НоваяСтрока = ТЗ_8.Добавить();
// Обращаемся к реквизитам OLE-объекта для получения примитивных типов
НоваяСтрока.Код = Запрос77.Товар.Код;
НоваяСтрока.Наименование = Запрос77.Товар.Наименование;
НоваяСтрока.Остаток = Запрос77.Количество;
КонецЦикла;
Важное замечание по поводу дат: Тип Дата в 1С 8 отличается от формата 1С 7.7. Передача 8-й даты в параметры функций или текст запроса 7.7 часто приводит к ошибкам. Чтобы 1С 7.7 поняла дату из 1С 8, её нужно передавать в строковом виде (например, "ДД.ММ.ГГГГ") и использовать функцию Дата() внутри OLE-среды 7.7.
Работа с 1С 7.7 через COM/OLE известна своей низкой скоростью, особенно при обработке большого количества номенклатуры (например, при получении остатков). Если объем данных велик, рассмотрим более производительные альтернативы:
v7plus.dll или MSXML), который затем легко прочитается в 1С 8 встроенными средствами платформы.Выбор метода зависит от частоты выполнения задачи и объемов данных. Для небольших выборок вполне сработает OLE с обходом таблицы по индексу, а для регулярных тяжелых обменов лучше смотреть в сторону XML или прямого чтения через ADO.