В практике сопровождения крупных систем на базе 1С:Управление производственным предприятием (УПП) часто возникает ситуация, когда необходимо настроить выгрузку данных в другую конфигурацию, но при этом вносить изменения в саму УПП категорически запрещено (конфигурация находится на поддержке без возможности редактирования, или наложен административный запрет). Если при этом платформа версии 8.2 или 8.3 не поддерживает расширения в силу режима совместимости, задача становится нетривиальной. Рассмотрим подробнее, как реализовать синхронизацию регистра сведений (РС), используя только внешние инструменты и стандартные механизмы платформы.
Если нам нельзя внедрять механизмы подписки на события или изменять планы обмена, мы можем использовать данные, которые система записывает самостоятельно. Каждое изменение в регистре сведений фиксируется в Журнале регистрации, если в настройках конфигуратора не отключено логирование для этого объекта.
Разберем по шагам, как построить алгоритм выгрузки через внешнюю обработку:
Данные.Изменение и Данные.Добавление.ВыгрузитьЖурналРегистрации(). Мы можем наложить фильтр по объекту (метаданным нашего регистра) и по периоду с момента последней удачной синхронизации.Данные, где хранится представление записи или структура с ключевыми полями.Посмотрим на пример кода, который можно использовать во внешней обработке:
Фильтр = Новый Структура;
Фильтр.Вставить("ДатаНачала", ДатаПоследнейВыгрузки);
Фильтр.Вставить("Событие", "_$Data$_.Post"); // Для документов или "_$Data$_.Update" для РС
Фильтр.Вставить("Метаданные", Метаданные.РегистрыСведений.НашРегистр);
ТЗ_Лог = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ТЗ_Лог, Фильтр, "Дата, Данные, ПредставлениеДанных");
Для Каждого СтрокаЛога Из ТЗ_Лог Цикл
// Здесь получаем ключи записи и выгружаем их в приемник
КонецЦикла;
Важно помнить, что Журнал регистрации при очень интенсивной работе может быть «узким местом». Поэтому рекомендуется хранить дату последнего обработанного события с точностью до секунды.
Если база данных работает на Microsoft SQL Server, мы можем обойти ограничения уровня приложения 1С и обратиться напрямую к возможностям СУБД. Механизм Change Tracking (CT) — это легковесное решение, которое фиксирует только факт изменения строки и значения первичного ключа.
Рассмотрим алгоритм реализации этого метода:
Change Tracking для таблицы, соответствующей нашему регистру сведений.ADOConnection для подключения к своей же базе данных.CHANGETABLE.Этот способ является наиболее производительным, так как он не нагружает сервер 1С и не требует чтения тяжелых журналов. Мы получаем только ID или измерения регистра, которые изменились. Выясним причину эффективности: SQL Server делает это на уровне страниц данных, что практически не влияет на скорость записи в 1С.
В ситуациях, когда регистр не является гигантским (до нескольких сотен тысяч записей), мы можем применить метод «снимков». Проанализируем ситуацию: нам нужно понять, что изменилось, не имея меток времени в самом регистре.
Разберем, как это работает:
ХешированиеДанных.Пример формирования хеша в 1С:
ХешОбъект = Новый ХешированиеДанных(ХешФункция.MD5);
ТекстДляХеша = Строка(Запись.Измерение1) + Строка(Запись.Ресурс1) + Строка(Запись.Период);
ХешОбъект.Добавить(ТекстДляХеша);
ТекущийХеш = НРег(СтрЗаменить(Строка(ХешОбъект.ХешСумма), " ", ""));
Чтобы ускорить процесс, можно группировать записи по периодам (например, по месяцам) и сначала проверять хеш всей группы. Если хеш месяца совпал — записи внутри него не менялись, и мы их пропускаем.
Если база-приемник имеет возможность инициировать соединение, мы можем реализовать механизм «вытягивания» данных. Поскольку автор темы указал, что «гонять запрос за пару суток» — плохой вариант, мы оптимизируем этот подход.
Рассмотрим стратегию «плавающего окна»:
COMConnector.Загрузить() для набора записей, который автоматически обновляет существующие записи по измерениям и добавляет новые.Часто в сильно перепиленных УПП программисты забывают, что в системе уже есть стандартные планы обмена, такие как «Полный» или «ОбменУправленческий». Проверим, не включен ли наш регистр в состав какого-либо из них.
Даже если мы не можем менять состав плана обмена, мы можем программно регистрировать изменения на узле, который уже существует. Выясним, как это сделать:
ПланыОбмена.ЗарегистрироватьИзменения().Если база-приемник работает на платформе 8.3.6 и выше, мы можем подключить таблицы УПП напрямую как Внешние источники данных. Это позволит нам писать SQL-запросы к источнику прямо из кода приемника.
Посмотрим на преимущества:
JOIN запросов для сопоставления данных приемника и источника прямо в одном запросе 1С.Подводя итог, можно сказать, что даже при самых жестких ограничениях «фигвама» (как выразился автор темы), у разработчика остается широкий инструментарий. Наиболее надежным и современным способом будет SQL Change Tracking, а наиболее простым в реализации «внутри 1С» — анализ Журнала регистрации или метод контрольных сумм с группировкой по периодам.