Как получить данные из предыдущей версии объекта в 1С:Предприятии?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет Торговля и дистрибуция
← К списку

Нам часто требуется отслеживать изменения данных в нашей информационной базе. Механизм версионирования объектов в 1С:Предприятии — это мощный инструмент, который позволяет нам хранить историю изменений справочников, документов и других объектов. Он отличается от журнала регистрации тем, что мы можем не просто увидеть факт изменения, но и конкретные значения, которые были в объекте на определенный момент времени. Это крайне полезно для анализа, сравнения и, при необходимости, восстановления данных.

Настройка версионирования объектов

Прежде чем мы сможем программно работать с версиями, нам необходимо убедиться, что версионирование объектов включено и настроено в нашей конфигурации. Рассмотрим этот процесс по шагам:

  1. Включение функциональной опции: Мы должны перейти в раздел «НСИ и администрирование – Администрирование – Общие настройки» и установить флажок напротив функциональной опции «Хранить историю изменений».
  2. Настройка хранения: После включения опции станет доступна гиперссылка «Настройки хранения». Здесь мы можем подробно настроить, для каких объектов (справочников, документов, бизнес-процессов) будет вестись версионирование.
  3. Выбор варианта версионирования: Для каждого объекта мы можем выбрать один из следующих вариантов:
    • Не версионировать – история изменений объекта не будет вестись.
    • Версионировать при записи – новая версия объекта будет сохраняться при каждом изменении или создании справочника/документа.
    • Версионировать при проведении – этот вариант применяется только для документов. Первая версия документа создается после его первого проведения, а последующие — при каждой записи уже проведенного документа. Это позволяет нам экономить место в базе, избегая создания версий для новых и незаполненных документов.
    • По умолчанию – система установит рекомендуемые настройки (как правило, для справочников – никогда, для документов – при проведении, для бизнес-процессов – при старте).
  4. Срок хранения версий: Мы также можем установить срок хранения версий (например, за неделю, месяц, три месяца, полгода, год или бессрочно) и настроить автоматическое удаление устаревших версий по расписанию. Это помогает нам управлять объемом базы данных.
  5. Детализация версионирования: Механизм позволяет нам настроить версионирование не только для объекта целиком, но и для его отдельных реквизитов, включая табличные части. Это дополнительно способствует экономии места.

Получение данных из предыдущей версии объекта с помощью БСП

Когда версионирование настроено, мы можем программно получить данные из любой сохраненной версии объекта. Для этого нам на помощь приходят функции общего модуля ВерсионированиеОбъектов, который является частью Библиотеки стандартных подсистем (БСП).

Ключевой функцией для получения данных версии является ВерсионированиеОбъектов.РазборВерсии(Ссылка, НомерВерсии). Давайте разберем ее подробнее:

  1. Назначение: Эта функция позволяет нам получить данные конкретной версии объекта, указывая его ссылку и номер нужной версии.
  2. Возвращаемое значение: В результате своей работы функция возвращает структуру, которая содержит данные выбранной версии объекта. Эта структура будет включать в себя основные реквизиты объекта и его табличные части.
  3. Внутренний механизм: Функция РазборВерсии() в свою очередь вызывает процедуру ВерсионированиеОбъектов.РазборПредставленияОбъектаXML(ДанныеВерсии, Ссылка), которая считывает XML-представление версии и заполняет необходимые структуры данных. Мы можем изучить ее описание в модуле для более глубокого понимания.

После вызова функции РазборВерсии() мы получим объект, представляющий собой данные предыдущей версии. Например, если нам нужно получить данные табличной части "Услуги" из предыдущей версии документа, мы можем сделать это так:


Результат = ВерсионированиеОбъектов.РазборВерсии(Док, НомерВерсии);
ТЗ1      = Результат.ТабличныеЧасти.Получить("Услуги");

Здесь Док – это ссылка на наш текущий документ, а НомерВерсии – это числовой идентификатор предыдущей версии, которую мы хотим получить. Переменная ТЗ1 в результате будет содержать табличную часть "Услуги" из выбранной старой версии документа в виде объекта типа ТаблицаЗначений.

Частичное восстановление данных или обновление отдельных реквизитов

Часто нам не требуется полностью восстанавливать документ до предыдущей версии, а нужно лишь обновить отдельные реквизиты или строки табличной части. Рассмотрим, как мы можем это сделать, используя полученные данные.

Представим ситуацию: нам нужно обновить только поле "Содержание" в строках табличной части "Услуги" текущего документа, взяв данные из предыдущей версии. Мы можем это сделать, сопоставляя строки по их уникальному идентификатору. В БСП для этого используется реквизит ИдентификаторСтроки, который автоматически добавляется в табличные части версионируемых объектов.

Давайте проанализируем пошаговый алгоритм и посмотрим на пример кода:

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

Объединив эти шаги, мы получим следующий рабочий код для частичного обновления табличной части:


пр = 0; // Флаг изменений
Результат = ВерсионированиеОбъектов.РазборВерсии(Док, НомерВерсии);
ТЗ1      = Результат.ТабличныеЧасти.Получить("Услуги");
        
Для каждого стр Из Док1.Услуги Цикл
    стрТЗ1 = ТЗ1.Найти(стр.ИдентификаторСтроки, "ИдентификаторСтроки");
    Если стрТЗ1 <> Неопределено Тогда
        стр.Содержание = стрТЗ1.Содержание;
        пр = 1;
    КонецЕсли;
КонецЦикла;
        
Если пр = 1 Тогда
    Сообщить("Исправлен документ " + Док1);
    Док1.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;

Таким образом, мы видим, что ИдентификаторСтроки играет ключевую роль в сопоставлении строк табличных частей между разными версиями объекта.

Важные аспекты версионирования

Работая с версионированием, мы должны учитывать несколько важных моментов:

Используя описанные подходы, мы сможем эффективно работать с версиями объектов, восстанавливать данные или выборочно обновлять их, что значительно упрощает поддержку и анализ изменений в нашей информационной системе.

← К списку