Как передавать из 1С 7.7 в 1С 8 через OLE только измененные объекты

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

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

В этой статье мы подробно разберем, как реализовать механизм отслеживания изменений в 1С 7.7 и организовать эффективную выборку данных для 1С 8, минимизируя время работы OLE-соединения.

Механизм регистрации изменений через дополнительный справочник

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

  1. Создание справочника в 1С 7.7: Назовем его ИзмененныеОбъекты.
  2. Добавление реквизитов:
    • ОбъектЗначение (Тип: Неопределенный) — сюда будет записываться ссылка на измененный элемент справочника или документ.
    • ТипОбъекта (Тип: Строка) — для хранения информации о том, справочник это или документ.
    • ВидОбъекта (Тип: Строка) — конкретный вид (например, "Номенклатура" или "Счет").
    • НачатОбмен (Тип: Число) — флаг-предохранитель (0 или 1), чтобы избежать удаления объекта из очереди, если он был изменен повторно во время текущего сеанса обмена.
    • Действие (Тип: Строка) — описание причины регистрации (например, "ОбновитьОстатки", "ИзменениеРеквизитов").

Важный нюанс: Для реквизита ОбъектЗначение невозможно установить признак "Сортировка", так как он имеет неопределенный тип. Это делает невозможным использование метода НайтиПоРеквизиту(). Мы будем использовать перебор или запросы.

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

Для того чтобы не дублировать код в каждом объекте, вынесем логику в Глобальный модуль конфигурации 1С 7.7. Разберем код процедуры ЗарегистрироватьДляОбмена, которая проверяет наличие объекта в очереди и добавляет его, если он там еще не зарегистрирован.


// В Глобальном модуле 1С 7.7
Процедура ЗарегистрироватьДляОбмена(Объект) Экспорт      
    Перем НашлиНет;
    НашлиНет = 0;
    Спр = СоздатьОбъект("Справочник.ИзмененныеОбъекты"); 
    
    // Проверяем, нет ли уже этого объекта в очереди на обмен
    Спр.ВыбратьЭлементы();
    Пока Спр.ПолучитьЭлемент() = 1 Цикл
        Если Спр.ОбъектЗначение = Объект Тогда
            // Если объект уже есть и обмен по нему еще не начат, дублировать запись не нужно
            Если Спр.НачатОбмен = 0 Тогда
                НашлиНет = 1; 
                Прервать; 
            КонецЕсли;
        КонецЕсли; 
    КонецЦикла;
    
    Если НашлиНет = 0 Тогда
        // Определяем тип и вид для удобства обработки в 1С 8
        ТипСтр = ТипЗначенияСтр(Объект);
        ВидСтр = "";
        Попытка
            ВидСтр = Объект.Вид();
        Исключение
            // Для некоторых типов вид может быть недоступен
        КонецПопытки;

        Спр.Новый();    
        Спр.ТипОбъекта = ТипСтр;
        Спр.ВидОбъекта = ВидСтр; 
        
        // Для реквизитов неопределенного типа в 7.7 нужно явно назначать тип перед записью
        Спр.НазначитьТип("ОбъектЗначение", ТипСтр + "." + ВидСтр);
        Спр.ОбъектЗначение = Объект;
        
        Спр.НачатОбмен = 0;
        Спр.Записать();
    КонецЕсли;     
КонецПроцедуры

Интеграция в прикладные объекты

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

Для справочника "Номенклатура":


Процедура ПриЗаписи()
    // Стандартные проверки...
    ЗарегистрироватьДляОбмена(ТекущийЭлемент());
КонецПроцедуры

Для документов (например, "Счет"):


Процедура ПриЗаписи()
    // В документах используем ТекущийДокумент()
    ЗарегистрироватьДляОбмена(ТекущийДокумент());
КонецПроцедуры

Обратите внимание, что программная запись объектов (через Записать() в обработках) не вызывает процедуру ПриЗаписи() модуля формы. Если в вашей системе данные часто меняются программно, вызовы регистрации придется добавить и в соответствующие обработки.

Оптимизация идентификации: использование GUID

Одной из главных проблем при обмене через OLE является сопоставление объектов. В 1С 7.7 нет привычного для 8-ки УникальныйИдентификатор(). Однако платформа 7.7 позволяет получить внутреннее строковое представление ссылки. Рассмотрим, как передать его в 1С 8.

Проанализируем пример получения ID на стороне 1С 8 через COM-объект:


// Код на стороне 1С 8
ОбъектV77 = Новый COMОбъект("v77.Application");
// ... инициализация соединения ...

НоменклатураОЛЕ = ОбъектV77.CreateObject("Справочник.Номенклатура");
// Допустим, мы нашли нужный элемент
ВнутреннийID = ОбъектV77.ЗначениеВСтрокуВнутр(НоменклатураОЛЕ.ТекущийЭлемент());
// Полученная строка будет иметь вид {"B","0","0","123","0","0","      456 "}
// Она уникальна и неизменна для каждого объекта

Совет: В 1С 8 создайте дополнительный реквизит (например, ID_V77) с длиной 36–40 символов, чтобы хранить этот внутренний идентификатор. Это позволит избежать дублей при переименовании товаров или изменении кодов в "семерке".

Обработка очереди изменений в 1С 8

Алгоритм работы регламентного задания или обработки обмена в 1С 8 должен выглядеть следующим образом:

  1. Подключиться к 1С 7.7 через OLE.
  2. Создать объект справочника ИзмененныеОбъекты.
  3. Выбрать все элементы, где НачатОбмен = 0.
  4. Для каждого элемента установить НачатОбмен = 1 (чтобы зафиксировать срез).
  5. Прочитать ОбъектЗначение, получить его данные и создать/обновить объект в 1С 8.
  6. После успешной обработки удалить запись из справочника ИзмененныеОбъекты в 1С 7.7.

Проанализируем ситуацию возникновения конфликта: если во время переноса данных (между шагами 4 и 6) пользователь в 1С 7.7 снова изменит тот же товар, наша процедура ЗарегистрироватьДляОбмена увидит, что в базе есть запись с НачатОбмен = 1, и создаст новую запись в справочнике. Таким образом, изменения не потеряются.

Почему не стоит использовать прямые флаги в справочнике товаров?

Рассмотрим вариант, когда в сам справочник "Товары" добавляется реквизит Изменен. Выясним, почему это плохое решение:

Использование отдельной очереди (справочника) — это классический паттерн "Change Data Capture", который гарантирует целостность данных и высокую скорость работы обмена.

Дополнительные рекомендации по ускорению OLE

Вызовы каждого реквизита через OLE (например, ТоварОЛЕ.Наименование, ТоварОЛЕ.Артикул) — это отдельные сетевые пакеты или переключения контекста процессора. Чтобы ускорить процесс, рекомендуется на стороне 7.7 написать функцию, собирающую все данные объекта в одну длинную строку с разделителями. Тогда за один вызов OLE вы получите все необходимые данные об объекте, что сократит время обмена в несколько раз.

Также помните, что работа с БухгалтерскимиИтогами через OLE требует предварительного выполнения метода ВыполнитьЗапрос(). Старайтесь выполнять его один раз для группы товаров, а не в цикле для каждого элемента, если это технически возможно в вашей структуре обмена.

← На главную