Простой механизм версионирования для нетиповых конфигураций, или зачем нужны утки и медведи
Предлагается вариант простого ненастраиваемого механизма версионирования, сделанного при помощи сравнения перед записью объекта и его ссылки по наименованиям реквизитов в метаданных, записи результата сравнения в журнал регистрации и последующего его извлечения.
- Описание
- Подробнее
Описание
В комментарии к моей публикации с простой обработкой, показывающей, кто изменял документ по журналу регистрации, многоуважаемый коллега заметил, что обработка на самом деле никакой информации об изменениях не дает, а внедрять подсистему версионирования из УПП не комильфо, так как это перегрузит систему.
Тем не менее, вопросы пользователей, кто изменил «мой» документ (справочник), а главное ЧТО изменил, остаются актуальными.
В результате был разработан простой механизм, который позволяет регистрировать изменения данных реквизитов документов и справочников, а также простое изменение их табличных частей.
Суть в следующем.
В процедуре общего модуля по подписке на событие «ПередЗаписью» документа или справочника выполняем поиск различий по значениям совпадающих по наименованиям реквизитов метаданных объекта и ссылки (аналогичным образом выполняется и сравнение табличных частей).
Процедура ПередЗаписьюКонтрольИзмененияРеквизитовДокументов(Источник, Отказ) Экспорт
Если НЕ Отказ И НЕ Источник.ЭтоНовый() Тогда
ТЗРазличий = Новый ТаблицаЗначений;
ТЗРазличий.Колонки.Добавить("ИмяРеквизита");
ТЗРазличий.Колонки.Добавить("До");
ТЗРазличий.Колонки.Добавить("После");
МетаданныеДок = Источник.Метаданные();
Для Каждого Реквизит Из МетаданныеДок.Реквизиты Цикл
Если Источник[Реквизит.Имя] <> Источник.Ссылка[Реквизит.Имя] Тогда
СтрокаТЗ = ТЗРазличий.Добавить();
СтрокаТЗ.ИмяРеквизита = Реквизит.Имя;
СтрокаТЗ.До = Строка(Источник[Реквизит.Имя]);
СтрокаТЗ.После = Строка(Источник.Ссылка[Реквизит.Имя]);
КонецЕсли;
КонецЦикла;
...
КонецПроцедурыКак видно из кода, значения реквизитов Источника, это то, что было ДО изменения, значения реквизитов Источник.Ссылка — это то, что БУДЕТ ПОСЛЕ записи изменения в случае, если объект таки будет записан.
По результатам анализа создаем структуру, содержащую в качестве значений таблицы различий реквизитов, а также таблицы изменений реквизитов табличных частей.
СтруктураРазличий = Новый Структура
СтруктураРазличий.Вставить("РазличияРеквизитов", ТЧРазличий)Структуру помещаем в системное строковое представление при помощи ЗначениеВСтрокуВнутр.
СтруктураВнутр = ?(БылиИзменения, ЗначениеВСтрокуВнутр(СтруктураРазличий);Делаем запись в журнале регистрации, где полученное представление помещаем в комментарий, указываем ссылку на измененный документ или справочник, и называем это вроде «Изменения реквизитов документа».
ЗаписьЖурналаРегистрации("Изменение реквизитов документа", УровеньЖурналаРегистрации.Информация, Источник.Метаданные(), Источник.Ссылка, СтруктураВнутр);В дальнейшем при необходимости это представление извлекается,
ТабЖур = Новый ТаблицаЗначений;
Фильтр = Новый Структура;
Фильтр.Вставить("ДатаНачала", ДатаНачала);
Фильтр.Вставить("ДатаОкончания", ДатаОкончания);
МассивСобытий = Новый Массив;
МассивСобытий.Добавить("Изменение реквизитов документа");
Фильтр.Вставить("Событие", МассивСобытий);
//Фильтр.Вставить("Данные", ДокументАнализа); // раскомментировать, если по одному документу
КолонкиСтрокой = "Дата, ИмяПользователя, Событие, ПредставлениеДанных, Комментарий";
ВыгрузитьЖурналРегистрации(ТабЖур, Фильтр, КолонкиСтрокой, , );вытаскивается из колонки «Комментарий», преобразовывается обратно в структуру через ЗначениеИзСтрокиВнутр
СтруктураИзВнутр = ЗначениеИзСтрокиВнутр(СтруктураВнутр);и обратной обработкой развертывается в удобочитаемом виде.
Ну а дальше сложность анализа, как справедливо заметили коллеги к публикации с «уткой», может нарастать, как минимум должно быть нечеткое сравнение табличных частей, потому что уже выявлен недостаток вышеописанного метода: при добавлении строки в документ механизм фиксирует только изменение суммы документа, ведь первые N строк табличных частей до записи совпадают…
И последнее, к вопросу о скорости работы механизма. Видимого замедления записи или проведения объекта не замечено. Восстановление последовательности партионного учета при включенном механизме также прошло без замеченных тормозов. Механизм внедрен и работает на нетиповой УТ 10.3.
P.S. Закономерный вопрос: «Причем здесь утки?!»
Отвечаю. Если интересует полный код анализа различий по значениям совпадающих по наименованию реквизитов объектов, помещение в структуру и развертывание обратно из структуры с выводом в удобочитаемый вид, прошу сюда, в публикацию с «уткой»:
//sale.itcity.ru/public/388917/
P.P.S. И второй закономерный вопрос: «Ну хорошо, а причем здесь медведи?!»
А это уже вариант, как может быть реализовано для конечного использования. В ту самую простую обработку, которая показывает изменения документа, можно добавить вывод вида события «Изменения реквизитов документа (справочника)» и по двойному щелчку развертывать расшифровку этих изменений. За обработкой прошу сюда, в публикацию с «медведями»:

