При интеграции 1С с внешними системами (сайтами, CRM, платежными сервисами) часто возникает задача: понять, изменилось ли что-то в документе или было ли выполнено его простое перепроведение. Это необходимо, чтобы своевременно обновить данные (сумму, контрагента или статус оплаты) во внешней базе данных, не выполняя при этом лишних и тяжелых операций по полной перегрузке всех данных. Рассмотрим основные механизмы, которые предоставляет платформа 1С для решения этой задачи.
У каждого ссылочного объекта в 1С (документы, справочники) есть скрытый системный реквизит ВерсияДанных. Он имеет тип BinaryData и автоматически изменяется платформой при каждой записи объекта в базу данных. Разберем особенности этого реквизита:
Записать(), даже если данные внутри документа не менялись, приведет к обновлению версии.Для реализации логики отслеживания нам необходимо сохранять текущее значение ВерсияДанных во внешней системе. При следующей итерации обмена мы сравниваем версию в 1С с той, что была сохранена ранее. Если значения различаются — документ был либо изменен, либо перепроведен.
Посмотрим на пример получения версии в коде:
// Получаем текущую версию документа для передачи во внешнюю систему
ВерсияОбъекта = СсылкаНаДокумент.ВерсияДанных;
СтрокаВерсии = Base64Строка(ВерсияОбъекта); // Преобразуем в строку для удобства хранения
Если задача стоит глобально — отслеживать изменения множества объектов — правильным архитектурным решением будет использование планов обмена. Проанализируем, как это работает. Мы создаем объект конфигурации ПланОбмена и включаем в его состав нужные документы. Когда пользователь проводит или изменяет документ, платформа автоматически ставит "метку" в специальной таблице регистрации изменений для конкретного узла обмена.
Преимущества этого подхода:
Разберем пример программного получения зарегистрированных изменений:
ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена, НомерСообщения);
Пока ВыборкаИзменений.Следующий() Цикл
Данные = ВыборкаИзменений.Получить();
Если ТипЗнч(Данные) = Тип("ДокументОбъект.Оплата") Тогда
// Выполняем выгрузку данных во внешнюю систему
КонецЕсли;
КонецЦикла;
Начиная с версии платформы 8.3.11, разработчикам доступен мощный инструмент — ИсторияДанных. Этот механизм позволяет не просто узнать факт изменения, но и понять, что именно изменилось. Рассмотрим подробнее, как программно проанализировать версии через этот объект.
С помощью метода ИсторияДанных.ВыбратьВерсии() можно получить список всех транзакций, связанных с документом. Это позволяет отфильтровать "пустые" перепроведения от реальных правок в реквизитах «Сумма» или «Контрагент».
ВыборкаВерсий = ИсторияДанных.ВыбратьВерсии(СсылкаНаДокумент);
Пока ВыборкаВерсий.Следующий() Цикл
// Каждая итерация дает доступ к метаданным версии: кто изменил, когда и какие поля
Сообщить("Версия №" + ВыборкаВерсий.НомерВерсии + " создана " + ВыборкаВерсий.ДатаВерсии);
КонецЦикла;
В некоторых случаях нам важно реагировать только на изменение конкретных бизнес-данных, игнорируя технические перепроведения (например, при восстановлении последовательности). Выясним, как это реализовать. Мы можем выбрать ключевые поля (Сумма, Дата, Контрагент, Договор) и при каждой записи формировать от них хеш-сумму.
Проанализируем пример функции формирования хеша:
Функция ПолучитьХешЗначимыхРеквизитов(ДокументОбъект)
ТекстДанных = Строка(ДокументОбъект.Дата)
+ "|" + Строка(ДокументОбъект.СуммаДокумента)
+ "|" + Строка(ДокументОбъект.Контрагент.УникальныйИдентификатор());
Хеширование = Новый ХешированиеДанных(ХешФункция.MD5);
Хеширование.Добавить(ТекстДанных);
Возврат НРег(СтрЗаменить(Строка(Хеширование.ХешСумма), " ", ""));
КонецФункции
Эту хеш-сумму можно хранить в дополнительном реквизите документа или в отдельном регистре сведений. При повторном проведении мы сравниваем новый хеш со старым. Если они идентичны — значимые данные не изменились, и внешнюю базу можно не беспокоить.
Для системных администраторов и разработчиков, имеющих прямой доступ к SQL-таблицам 1С, существует еще один способ. В таблицах MS SQL Server или PostgreSQL, где хранятся документы, есть скрытое поле _Version. Это поле типа timestamp (или rowversion), которое обновляется самой СУБД при любой модификации строки.
Важно: Прямое чтение из таблиц SQL в обход сервера приложений 1С не рекомендуется для бизнес-логики, но крайне эффективно для высокопроизводительных внешних сервисов синхронизации (например, через механизм Change Data Capture — CDC). Любое изменение в 1С мгновенно изменит значение _Version в базе данных SQL, что станет сигналом для внешней системы.
Подведем итог и выберем оптимальный путь:
ДатаПоследнегоОбновления и заполняйте его значением ТекущаяУниверсальнаяДатаВМиллисекундах() в процедуре ОбработкаПроведения. Внешняя система сможет запрашивать записи, где эта дата больше даты последней успешной выгрузки.ПланОбмена. Это самый надежный способ, встроенный в архитектуру 1С.ВерсияДанных через OData или COM-соединение.ИсторияДанных.Рассмотренные методы позволяют гибко настроить процесс синхронизации, минимизировать нагрузку на сеть и сервер, а также гарантировать актуальность данных во внешней системе оплат.