Вопрос организации эффективного обмена данными в среде 1С:Предприятие 7.7 остается актуальным для многих крупных систем, которые в силу различных причин не перешли на более современные платформы. Основная сложность здесь заключается в том, что штатные механизмы «семерки» ограничены, а требования к скорости и точности регистрации изменений постоянно растут. В рамках данной статьи мы подробно проанализируем различные подходы — от классической УРБД до продвинутых решений с использованием SQL-триггеров и внешних компонент.
Самый очевидный и «дуракоустойчивый» метод — это использование стандартной компоненты Управление распределенными информационными базами (УРБД). Система автоматически отслеживает изменения объектов, если они включены в состав миграции. Рассмотрим, как мы можем управлять этим процессом программно.
Для принудительной регистрации объекта в плане обмена мы можем использовать метод РегистрацияИзменений(). Это позволяет нам гибко управлять тем, какие именно данные уйдут в подчиненную или центральную базу. Проанализируем пример кода:
// Пример принудительной регистрации объекта для конкретной информационной базы
Объект = СоздатьОбъект("Справочник.Номенклатура");
Объект.НайтиПоКоду("00001");
// Регистрируем изменения для базы с кодом "ЦБ"
Объект.РегистрацияИзменений("ЦБ");
Важно помнить, что УРБД фиксирует факт записи объекта, но не хранит историю того, какие именно реквизиты изменились. Если нам нужно реализовать более тонкую фильтрацию, нам придется заглянуть «под капот» этой системы.
Если в базе включена компонента УРБД, 1С ведет учет всех изменений в специальной системной таблице 1CUPDTS (в версии SQL) или в аналогичном файле 1CUPDTS.DBF. Выясним причину, по которой программисты часто обращаются к ней напрямую: это позволяет получить список всех измененных объектов без фактической выгрузки файла обмена.
Рассмотрим структуру таблицы 1CUPDTS. Основные поля, которые нас интересуют:
TYPEID — тип объекта (справочник, документ и т.д.).OBJID — внутренний идентификатор объекта.DBSIG — сигнатура (код) информационной базы, для которой зарегистрировано изменение.Используя прямые SQL-запросы (через ODBCRecordset в 1С++), мы можем выбрать данные об изменениях за определенный период, если будем комбинировать данные из 1CUPDTS и системного журнала регистрации. Это позволяет построить отчет о том, что «накопилось» к обмену на данный момент.
Для высоконагруженных систем на базе MS SQL Server использование триггеров является наиболее производительным решением. Разберем этот метод по шагам. Мы создаем в SQL-базе отдельную таблицу-стек, в которую триггеры будут записывать ID измененных строк из таблиц справочников и документов.
Посмотрим на пример логики триггера AFTER UPDATE:
-- Пример упрощенного триггера на стороне SQL
CREATE TRIGGER [trg_Nomenclature_Update] ON [SC123] -- Таблица справочника
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
INSERT INTO CustomChangeLog (TableID, ObjectID, ChangeDate, OperationType)
SELECT 'SC123', ID, GETDATE(), 'U' FROM inserted
END
Этот подход позволяет нам регистрировать изменения даже в тех случаях, когда запись происходит напрямую через SQL (минуя объектную модель 1С), что крайне полезно при интеграции с внешними системами. Однако будьте осторожны: триггеры увеличивают время транзакции записи в 1С.
Для интерактивных изменений мы можем использовать возможности внешних компонент. Например, FormEx позволяет перехватывать событие ПослеЗаписи() в форме. Но, как отмечалось в обсуждении, этого «мало», так как программная запись объекта (через Записать() в коде) не вызывает событий формы.
Более мощным инструментом является 1С++ с его механизмом перехватчиков (интерфейс IUnitOfWork или использование классов-оберток). Мы можем создать глобальный перехватчик, который будет срабатывать при каждом вызове метода Записать(). Рассмотрим алгоритм:
Интересная идея была предложена в сообщении 57: использование механизма последовательностей. Мы можем создать новую последовательность и включить в нее документы, движения которых нам нужно отслеживать. При перепроведении документа последовательность «сбивается», и мы всегда можем программно определить диапазон документов, требующих повторной обработки или выгрузки.
Проанализируем преимущества этого метода: он штатный, не требует SQL-триггеров и корректно обрабатывает «заднее число». Если документ месячной давности был изменен, граница последовательности переместится на этот документ, и наш механизм обмена поймет, что нужно начинать выгрузку именно с этой точки.
Если база работает в файловом режиме и УРБД не включена, можно использовать анализ журнала регистрации. С помощью компоненты 1С++ и класса LogDataProvider мы можем быстро прочитать записи журнала. Выясним, как это работает: мы устанавливаем фильтр на события «Изменение», «Проведение» и «Удаление» за нужный нам период.
// Пример использования LogDataProvider
Провайдер = СоздатьОбъект("LogDataProvider");
Провайдер.SetPeriod(ДатаНачала, ДатаКонца);
Провайдер.Filter.Add("Event", "ObjectChanged");
// Перебор измененных объектов
Пока Провайдер.Next() = 1 Цикл
Сообщить("Объект изменен: " + Провайдер.Object);
КонецЦикла;
Однако стоит учитывать, что при интенсивной работе журнал регистрации может стать очень тяжелым, и скорость выборки данных значительно упадет по сравнению с SQL-решениями.
Одной из главных проблем всех вышеперечисленных методов является «ложная» регистрация. В 1С 7.7 объект считается измененным даже в том случае, если вы просто открыли его и нажали «ОК», не поменяв ни одного реквизита. Чтобы избежать избыточного обмена, рассмотрим метод хэширования.
Перед записью объекта мы вычисляем хэш-сумму его значимых полей и сравниваем её с хэшем, сохраненным в базе при прошлой записи. Регистрацию для обмена выполняем только при изменении самого хэша. Разберем логику:
Стр = Код + Наименование + Цена + Остаток;.ТекущийХэш = глПолучитьХэш(Стр);.ТекущийХэш <> СтарыйХэш, тогда вызываем РегистрацияИзменений().Выбор механизма регистрации зависит от ваших технических условий. Для стандартных задач обмена между базами 1С лучшим выбором остается штатная УРБД. Если же вы строите сложную систему интеграции с веб-сайтами или внешними SQL-системами, обратите внимание на SQL-триггеры или механизм CDC, которые обеспечивают максимальную производительность без нагрузки на логику самой 1С.