В конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), таких как «1С:Бухгалтерия 3.0», часто включена подсистема Версионирование объектов. Иногда возникают задачи, когда необходимо не просто откатить документ целиком, а программно извлечь конкретные данные из его прошлой версии (например, восстановить содержание только в одной табличной части, сохранив текущие суммы). Разберем, как это реализовать.
Для работы с историей изменений в БСП предусмотрен общий модуль ВерсионированиеОбъектов. Основным инструментом для получения данных конкретной версии является функция РазборВерсии(). Проанализируем, как она работает: она принимает ссылку на объект и номер версии, а возвращает структуру, содержащую реквизиты и табличные части объекта на тот момент времени. Чтобы быстрее освоить программный интерфейс библиотеки, рекомендуем изучить справочник по методам БСП с примерами использования.
Рассмотрим пошаговый алгоритм восстановления данных в табличной части:
ВерсионированиеОбъектов.РазборВерсии().ТаблицыЗначений.Предположим, нам нужно восстановить колонку Содержание в табличной части Услуги, сопоставляя строки по уникальному идентификатору. Посмотрим на пример кода:
// Получаем структуру данных версии
Результат = ВерсионированиеОбъектов.РазборВерсии(СсылкаНаДокумент, НомерПредыдущейВерсии);
// Извлекаем таблицу значений нужной ТЧ
ТЗ_Версия = Результат.ТабличныеЧасти.Получить("Услуги");
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
Изменено = Ложь;
Для каждого СтрТекущая из ДокОбъект.Услуги Цикл
// Важно: используем ИдентификаторСтроки для точного сопоставления
СтрИзВерсии = ТЗ_Версия.Найти(СтрТекущая.ИдентификаторСтроки, "ИдентификаторСтроки");
Если СтрИзВерсии <> Неопределено Тогда
// Проверяем, отличается ли значение, и обновляем его
Если СтрТекущая.Содержание <> СтрИзВерсии.Содержание Тогда
СтрТекущая.Содержание = СтрИзВерсии.Содержание;
Изменено = Истина;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Если Изменено Тогда
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Сообщить("Данные в документе " + СсылкаНаДокумент + " успешно исправлены");
КонецЕсли;
Проанализируем ключевые моменты, которые помогут избежать ошибок при работе с версиями:
1. Идентификатор строки. В приведенном примере используется ИдентификаторСтроки. Это системный реквизит БСП, который позволяет однозначно найти ту же самую строку в разных версиях объекта. Если в вашей конфигурации для конкретной ТЧ поддержка идентификаторов строк отключена, сопоставление придется делать по комбинации других полей (например, Номенклатура + НомерСтроки), что менее надежно.
2. Как узнать номер предыдущей версии? Чтобы получить именно предыдущую версию относительно текущей, можно воспользоваться методом ВерсионированиеОбъектов.ВыбратьВерсииОбъекта(Ссылка). Он возвращает таблицу всех версий. Отсортировав её по номеру по убыванию, вторая строка будет соответствовать состоянию объекта до последнего изменения. В случаях, когда правок много, удобнее использовать переход на предыдущую версию для списка объектов или выполнить групповой переход на другие версии объектов по дате с помощью специализированных инструментов — для этого подойдёт обработка массового отката и групповой отмены изменений в 1С.
3. Платформенный механизм «История данных». Начиная с версии 8.3.11, существует нативный механизм платформы. Если в вашей базе используется именно он (а не БСП-версионирование), для получения данных следует использовать менеджер ИсторияДанных.ВыбратьВерсии(Ссылка) и методы ИсторияДанных.ПолучитьДанные(). Если вы планируете унифицировать хранение истории, можно осуществить переход с платформенного механизма «История данных» на механизм «Версионирование объектов» БСП — в этом поможет утилита детальной истории изменений и перехода на БСП-версионирование.
4. Метод восстановления объекта целиком. Если вам нужно восстановить не отдельное поле, а весь объект, рассмотрите функцию ВерсионированиеОбъектов.ВосстановитьОбъектИзВерсии(Ссылка, НомерВерсии) — для этого есть обработка ведения быстрого журнала изменений и восстановления объектов 1С. Она возвращает полностью заполненный объект документа, готовый к записи или дальнейшей обработке. При разработке собственных инструментов также бывает полезно использовать шаблон внешней обработки с историей изменений, чтобы сохранять прозрачность процесса разработки.
Выясним причину, почему стоит записывать изменения с режимом Запись: при такой записи в истории версий создастся новая запись, которая зафиксирует программное исправление документа, что позволит сохранить прозрачность аудита изменений.