#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
#Область ДляВызоваИзДругихПодсистем
Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
| ЧтениеОбъектаРазрешено(Объект)";
Ограничение.ПоВладельцуБезЗаписиКлючейДоступа = Истина;
КонецПроцедуры
Процедура ПередВыгрузкойОбъекта(Контейнер, МенеджерВыгрузкиОбъекта, Сериализатор, Объект, Артефакты, Отказ) Экспорт
ВыгружаемыеТипы = Новый Соответствие;
Для Каждого Запись Из Объект Цикл
Если Запись.АвторВерсии = Неопределено Тогда
Продолжить;
КонецЕсли;
Тип = ТипЗнч(Запись.АвторВерсии);
Выгружать = ВыгружаемыеТипы[Тип];
Если Выгружать = Неопределено Тогда
Выгружать = Не ОбщегоНазначения.ЭтоПланОбмена(Запись.АвторВерсии.Метаданные());
ВыгружаемыеТипы.Вставить(Тип, Выгружать);
КонецЕсли;
Если Не Выгружать Тогда
Запись.АвторВерсии = Неопределено;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура УдалитьИнформациюОбАвтореВерсии(Знач АвторВерсии) Экспорт
Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 10000
| *
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.АвторВерсии = &АвторВерсии";
Запрос.УстановитьПараметр("АвторВерсии", АвторВерсии);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Количество() > 0 Цикл
Пока Выборка.Следующий() Цикл
НаборЗаписей = СоздатьНаборЗаписей();
НаборЗаписей.Отбор["Объект"].Установить(Выборка["Объект"]);
НаборЗаписей.Отбор["НомерВерсии"].Установить(Выборка["НомерВерсии"]);
Запись = НаборЗаписей.Добавить();
ЗаполнитьЗначенияСвойств(Запись, Выборка);
Запись.АвторВерсии = Неопределено;
НаборЗаписей.Записать();
КонецЦикла;
Если ТранзакцияАктивна() Тогда
Прервать;
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
КонецЦикла;
КонецПроцедуры
Процедура СформироватьОтчетПоИзменениям(ПараметрыОтчета, АдресРезультата) Экспорт
Перем ВерсияОбъекта;
Перем счетчикУникальныйИд;
СсылкаНаОбъект = ПараметрыОтчета.СсылкаНаОбъект;
СписокВерсий = ПараметрыОтчета.СписокВерсий;
ОбщийШаблон = ПолучитьМакет("СтандартныйМакетПредставленияОбъекта");
ТЧОтчета = Новый ТабличныйДокумент;
МассивНомеровВерсий = СписокВерсий.ВыгрузитьЗначения();
КоличествоВерсийОбъекта = МассивНомеровВерсий.Количество();
ТаблицаИзмененийРеквизитов = Новый ТаблицаЗначений;
ПодготовитьКолонкиТаблицИзмененийРеквизитов(ТаблицаИзмененийРеквизитов, МассивНомеровВерсий);
ТаблицаИзмененийТабличныхЧастей = Новый Соответствие;
ТабличныеДокументы = Новый СписокЗначений;
ТаблицаИзмененийТабличныхДокументов = Новый ТаблицаЗначений;
ТаблицаИзмененийТабличныхДокументов.Колонки.Добавить("Наименование");
ТаблицаИзмененийТабличныхДокументов.Колонки.Добавить("Представление");
ВерсияОбъекта_Пред = СчитатьНачальныеЗначенияРеквизитовИТабличныхЧастей(ТаблицаИзмененийРеквизитов, ТаблицаИзмененийТабличныхЧастей,
КоличествоВерсийОбъекта, МассивНомеровВерсий, СсылкаНаОбъект);
ТабличныеДокументы.Добавить(ВерсияОбъекта_Пред.ТабличныеДокументы);
ТаблицаИзмененийТабличныхДокументов.Колонки.Добавить("Версия" + Формат(МассивНомеровВерсий[0], "ЧГ=0"));
счетчикУникальныйИд = ПолучитьУникальныеУникальныйИд(ТаблицаИзмененийТабличныхЧастей, "Версия" + Формат(МассивНомеровВерсий[0], "ЧГ=0"));
Для ИндексВерсии = 2 По МассивНомеровВерсий.Количество() Цикл
НомерВерсии = МассивНомеровВерсий[ИндексВерсии-1];
НомерПредыдущейВерсии = "Версия" + (Формат(МассивНомеровВерсий[ИндексВерсии-2], "ЧГ=0"));
ИмяКолонкиТекущейВерсии = "Версия" + Формат(НомерВерсии, "ЧГ=0");
РезультатСравнения = РассчитатьИзменения(НомерВерсии, ВерсияОбъекта_Пред, ВерсияОбъекта, СсылкаНаОбъект);
ТабличныеДокументы.Добавить(ВерсияОбъекта.ТабличныеДокументы);
ЗаполнитьХарактеристикуИзмененияРеквизита(РезультатСравнения["Реквизиты"]["и"],
"И", ТаблицаИзмененийРеквизитов, ИмяКолонкиТекущейВерсии, ВерсияОбъекта);
ЗаполнитьХарактеристикуИзмененияРеквизита(РезультатСравнения["Реквизиты"]["д"],
"Д", ТаблицаИзмененийРеквизитов, ИмяКолонкиТекущейВерсии, ВерсияОбъекта);
ЗаполнитьХарактеристикуИзмененияРеквизита(РезультатСравнения["Реквизиты"]["у"],
"У", ТаблицаИзмененийРеквизитов, ИмяКолонкиТекущейВерсии, ВерсияОбъекта);
ИзмененияТабличныхЧастей = РезультатСравнения["ТабличныеЧасти"]["и"];
Для Каждого ЭлементСоответствия Из ВерсияОбъекта.ТабличныеЧасти Цикл
ИмяТаблицы = ЭлементСоответствия.Ключ;
Если ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы] = Неопределено Тогда
Продолжить;
КонецЕсли;
ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][ИмяКолонкиТекущейВерсии] =
ВерсияОбъекта.ТабличныеЧасти[ИмяТаблицы].Скопировать();
СсылкаНаВерсиюТаблицы = ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][ИмяКолонкиТекущейВерсии];
СсылкаНаВерсиюТаблицы.Колонки.Добавить(ИмяКолонкиИдСтроки());
Для Каждого СтрокаТаблицы Из СсылкаНаВерсиюТаблицы Цикл
СтрокаТаблицы[ИмяКолонкиИдСтроки()] = СтрокаТаблицы.НомерСтроки;
КонецЦикла;
СсылкаНаВерсиюТаблицы.Колонки.Добавить(ИмяКолонкиМодификация());
СсылкаНаВерсиюТаблицы.ЗаполнитьЗначения(Ложь, ИмяКолонкиМодификация());
СсылкаНаВерсиюТаблицы.Колонки.Добавить(ИмяКолонкиИзменения(), Новый ОписаниеТипов("Массив"));
ТаблицаСИзменениями = ИзмененияТабличныхЧастей.Получить(ИмяТаблицы);
Если ТаблицаСИзменениями <> Неопределено Тогда
ИзмененныеСтроки = ТаблицаСИзменениями["И"];
ДобавленныеСтроки = ТаблицаСИзменениями["Д"];
УдаленныеСтроки = ТаблицаСИзменениями["У"];
Для Каждого ЭлементТЧ Из ИзмененныеСтроки Цикл
СтрокаТИЗ = ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][НомерПредыдущейВерсии][ЭлементТЧ.ИндексВТЧ0-1];
СсылкаНаВерсиюТаблицы[ЭлементТЧ.ИндексВТЧ1-1][ИмяКолонкиИдСтроки()] = СтрокаТИЗ[ИмяКолонкиИдСтроки()];
СсылкаНаВерсиюТаблицы[ЭлементТЧ.ИндексВТЧ1-1][ИмяКолонкиМодификация()] = "И";
СсылкаНаВерсиюТаблицы[ЭлементТЧ.ИндексВТЧ1-1][ИмяКолонкиИзменения()] = ЭлементТЧ.Различия;
КонецЦикла;
Для Каждого ЭлементТЧ Из ДобавленныеСтроки Цикл
СсылкаНаВерсиюТаблицы[ЭлементТЧ.ИндексВТЧ1-1][ИмяКолонкиИдСтроки()] = УвеличитьСчетчик(счетчикУникальныйИд, ИмяТаблицы);
СсылкаНаВерсиюТаблицы[ЭлементТЧ.ИндексВТЧ1-1][ИмяКолонкиМодификация()] = "Д";
КонецЦикла;
Для Индекс = 1 По СсылкаНаВерсиюТаблицы.Количество() Цикл
Если СсылкаНаВерсиюТаблицы[Индекс-1][ИмяКолонкиИдСтроки()] = Неопределено Тогда
СтрокаТЧ = СсылкаНаВерсиюТаблицы[Индекс-1];
ПараметрыОтбора = Новый Структура;
ОбщиеКолонки = НайтиОбщиеКолонки(СсылкаНаВерсиюТаблицы, ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][НомерПредыдущейВерсии]);
Для Каждого ИмяКолонки Из ОбщиеКолонки Цикл
Если (ИмяКолонки <> ИмяКолонкиИдСтроки()) И (ИмяКолонки <> ИмяКолонкиМодификация()) Тогда
ПараметрыОтбора.Вставить(ИмяКолонки, СтрокаТЧ[ИмяКолонки]);
КонецЕсли;
КонецЦикла;
МассивСтрокПредыдущейТЧ = ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][НомерПредыдущейВерсии].НайтиСтроки(ПараметрыОтбора);
ПараметрыОтбора.Вставить(ИмяКолонкиМодификация(), Неопределено);
МассивСтрокТекущейТЧ = СсылкаНаВерсиюТаблицы.НайтиСтроки(ПараметрыОтбора);
Для ИндПоТЗ_Текущей = 1 По МассивСтрокТекущейТЧ.Количество() Цикл
Если ИндПоТЗ_Текущей <= МассивСтрокПредыдущейТЧ.Количество() Тогда
МассивСтрокТекущейТЧ[ИндПоТЗ_Текущей-1][ИмяКолонкиИдСтроки()] = МассивСтрокПредыдущейТЧ[ИндПоТЗ_Текущей-1][ИмяКолонкиИдСтроки()];
КонецЕсли;
МассивСтрокТекущейТЧ[ИндПоТЗ_Текущей-1][ИмяКолонкиМодификация()] = Ложь;
КонецЦикла;
КонецЕсли;
КонецЦикла;
Для Каждого ЭлементТЧ Из УдаленныеСтроки Цикл
СтрокаМнимая = СсылкаНаВерсиюТаблицы.Добавить();
СтрокаМнимая[ИмяКолонкиИдСтроки()] = ТаблицаИзмененийТабличныхЧастей[ИмяТаблицы][НомерПредыдущейВерсии][ЭлементТЧ.ИндексВТЧ0-1][ИмяКолонкиИдСтроки()];
СтрокаМнимая[ИмяКолонкиМодификация()] = "У";
КонецЦикла;
КонецЕсли;
КонецЦикла;
ТаблицаИзмененийТабличныхДокументов.Колонки.Добавить(ИмяКолонкиТекущейВерсии);
РезультатТаблица = РезультатСравнения["ТабличныеДокументы"]["и"];
Для Каждого ТекСтрока Из РезультатТаблица Цикл
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Найти(ТекСтрока.Значение, "Наименование");
Если СтрокаТаблицыИзменений = Неопределено Тогда
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Добавить();
СтрокаТаблицыИзменений.Наименование = ТекСтрока.Значение;
СтрокаТаблицыИзменений.Представление = ТекСтрока.Представление;
КонецЕсли;
СтрокаТаблицыИзменений[ИмяКолонкиТекущейВерсии] = "И";
КонецЦикла;
РезультатТаблица = РезультатСравнения["ТабличныеДокументы"]["д"];
Для Каждого ТекСтрока Из РезультатТаблица Цикл
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Найти(ТекСтрока.Значение, "Наименование");
Если СтрокаТаблицыИзменений = Неопределено Тогда
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Добавить();
СтрокаТаблицыИзменений.Наименование = ТекСтрока.Значение;
СтрокаТаблицыИзменений.Представление = ТекСтрока.Представление;
КонецЕсли;
СтрокаТаблицыИзменений[ИмяКолонкиТекущейВерсии] = "Д";
КонецЦикла;
РезультатТаблица = РезультатСравнения["ТабличныеДокументы"]["у"];
Для Каждого ТекСтрока Из РезультатТаблица Цикл
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Найти(ТекСтрока.Значение, "Наименование");
Если СтрокаТаблицыИзменений = Неопределено Тогда
СтрокаТаблицыИзменений = ТаблицаИзмененийТабличныхДокументов.Добавить();
СтрокаТаблицыИзменений.Наименование = ТекСтрока.Значение;
СтрокаТаблицыИзменений.Представление = ТекСтрока.Представление;
КонецЕсли;
СтрокаТаблицыИзменений[ИмяКолонкиТекущейВерсии] = "У";
КонецЦикла;
ВерсияОбъекта_Пред = ВерсияОбъекта;
КонецЦикла;
Параметры = Новый Структура;
Параметры.Вставить("ТаблицаИзмененийРеквизитов", ТаблицаИзмененийРеквизитов);
Параметры.Вставить("ТаблицаИзмененийТабличныхЧастей", ТаблицаИзмененийТабличныхЧастей);
Параметры.Вставить("ТаблицаИзмененийТабличныхДокументов", ТаблицаИзмененийТабличныхДокументов);
Параметры.Вставить("счетчикУникальныйИд", счетчикУникальныйИд);
Параметры.Вставить("СписокВерсий", СписокВерсий);
Параметры.Вставить("ТЧОтчета", ТЧОтчета);
Параметры.Вставить("ОбщийШаблон", ОбщийШаблон);
Параметры.Вставить("СсылкаНаОбъект", СсылкаНаОбъект);
ВывестиРезультатыКомпоновкиВОтчет(Параметры);
ШаблонЛегенда = ОбщийШаблон.ПолучитьОбласть("Легенда");
ТЧОтчета.Вывести(ШаблонЛегенда);
ПоместитьВоВременноеХранилище(ТЧОтчета, АдресРезультата);
КонецПроцедуры
Процедура ВывестиИзмененияРеквизитов(ТЧОтчета, ТаблицаИзмененийРеквизитов, МассивНомеровВерсий, ОбщийШаблон, СсылкаНаОбъект)
ОбластьШапкаРеквизитов = ОбщийШаблон.ПолучитьОбласть("ШапкаРеквизитов");
ТЧОтчета.Вывести(ОбластьШапкаРеквизитов);
ТЧОтчета.НачатьГруппуСтрок("ГруппаРеквизитов");
Для Каждого ЭлементМодРеквизит Из ТаблицаИзмененийРеквизитов Цикл
Если ЭлементМодРеквизит[ИмяКолонкиМодификация()] = Истина Тогда
СтруктураОписанияНаименования = ВерсионированиеОбъектов.НаименованиеВыводимогоРеквизита(СсылкаНаОбъект, ЭлементМодРеквизит.Наименование);
Если Не СтруктураОписанияНаименования.ВыводитьРеквизит Тогда
Продолжить;
КонецЕсли;
ВыводимоеНаименование = СтруктураОписанияНаименования.ВыводимоеНаименование;
ПустаяЯчейка = ОбщийШаблон.ПолучитьОбласть("ПустаяЯчейка");
ТЧОтчета.Вывести(ПустаяЯчейка);
НаименованиеРеквизита = ОбщийШаблон.ПолучитьОбласть("НаименованиеРеквизитаПоля");
НаименованиеРеквизита.Параметры.НаименованиеРеквизитаПоля = ВыводимоеНаименование;
ТЧОтчета.Присоединить(НаименованиеРеквизита);
ИндексПоВерсиямРеквизитов = МассивНомеровВерсий.Количество();
Пока ИндексПоВерсиямРеквизитов >= 1 Цикл
СтруктураХарактеристикаИзменения = ЭлементМодРеквизит["Версия" + Формат(МассивНомеровВерсий[ИндексПоВерсиямРеквизитов-1], "ЧГ=0")];
ПредставлениеЗначенияРеквизита = "";
ЗначениеРеквизита = "";
Изменение = Неопределено;
Если ТипЗнч(СтруктураХарактеристикаИзменения) = Тип("Строка") Тогда
ПредставлениеЗначенияРеквизита = Строка(ЗначениеРеквизита);
ИначеЕсли СтруктураХарактеристикаИзменения <> Неопределено Тогда
Если СтруктураХарактеристикаИзменения.ТипИзменения = "У" Тогда
Иначе
ЗначениеРеквизита = СтруктураХарактеристикаИзменения.Значение.ЗначениеРеквизита;
ПредставлениеЗначенияРеквизита = Строка(ЗначениеРеквизита);
КонецЕсли;
Изменение = СтруктураХарактеристикаИзменения.ТипИзменения;
КонецЕсли;
Если ПредставлениеЗначенияРеквизита = "" Тогда
ПредставлениеЗначенияРеквизита = ЗначениеРеквизита;
Если ПредставлениеЗначенияРеквизита = "" Тогда
ПредставлениеЗначенияРеквизита = " ";
КонецЕсли;
КонецЕсли;
Если Изменение = Неопределено Тогда
ОбластьЗначениеРеквизита = ОбщийШаблон.ПолучитьОбласть("ИсходноеЗначениеРеквизита");
ОбластьЗначениеРеквизита.Параметры.ЗначениеРеквизита = ПредставлениеЗначенияРеквизита;
ИначеЕсли Изменение = "И" Тогда
ОбластьЗначениеРеквизита = ОбщийШаблон.ПолучитьОбласть("ИзмененноеЗначениеРеквизита");
ОбластьЗначениеРеквизита.Параметры.ЗначениеРеквизита = ПредставлениеЗначенияРеквизита;
ИначеЕсли Изменение = "У" Тогда
ОбластьЗначениеРеквизита = ОбщийШаблон.ПолучитьОбласть("УдаленныйРеквизит");
ОбластьЗначениеРеквизита.Параметры.ЗначениеРеквизита = ПредставлениеЗначенияРеквизита;
ИначеЕсли Изменение = "Д" Тогда
ОбластьЗначениеРеквизита = ОбщийШаблон.ПолучитьОбласть("ДобавленныйРеквизит");
ОбластьЗначениеРеквизита.Параметры.ЗначениеРеквизита = ПредставлениеЗначенияРеквизита;
КонецЕсли;
ТЧОтчета.Присоединить(ОбластьЗначениеРеквизита);
ИндексПоВерсиямРеквизитов = ИндексПоВерсиямРеквизитов - 1;
КонецЦикла;
КонецЕсли;
КонецЦикла;
ТЧОтчета.ЗакончитьГруппуСтрок();
КонецПроцедуры
Процедура ВывестиИзмененияТабличныхЧастей(ТЧОтчета, ТаблицаИзмененийТабличныхЧастей, МассивНомеровВерсий,
счетчикУникальныйИд, ОбщийШаблон, СсылкаНаОбъект)
ЗаголовокСекцииТабличныхЧастейВыводился = Ложь;
ШаблонСвободнаяСтрока = ОбщийШаблон.ПолучитьОбласть("СвободнаяСтрока");
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
Для Каждого ЭлементИзмененнаяТЧ Из ТаблицаИзмененийТабличныхЧастей Цикл
ИмяТабличнойЧасти = ЭлементИзмененнаяТЧ.Ключ;
ВерсииТекущейТЧ = ЭлементИзмененнаяТЧ.Значение;
МетаданныеОбъекта = СсылкаНаОбъект.Метаданные();
ПредставлениеТабличнойЧасти = ИмяТабличнойЧасти;
ОписаниеТабличнойЧасти = ВерсионированиеОбъектов.МетаданныеТабличнойЧасти(МетаданныеОбъекта, ИмяТабличнойЧасти);
Если ОписаниеТабличнойЧасти <> Неопределено Тогда
ПредставлениеТабличнойЧасти = ОписаниеТабличнойЧасти.Представление();
КонецЕсли;
ТекущаяТабличнаяЧастьИзменилась = Ложь;
Для ТекСчетчикУникальныйИд = 1 По СчетчикУникальныйИд[ИмяТабличнойЧасти] Цикл
СтрокаУникальныйИдИзменена = Ложь;
ИндексПоВерсиям = МассивНомеровВерсий.Количество();
МодифицированностьСтроки = Ложь;
Пока ИндексПоВерсиям >= 1 Цикл
ТекущаяКолонкаВерсииТЧ = "Версия" + Формат(МассивНомеровВерсий[ИндексПоВерсиям-1], "ЧГ=0");
ТекущаяТЧВерсии = ВерсииТекущейТЧ[ТекущаяКолонкаВерсииТЧ];
НайденнаяСтрока = Неопределено;
Если ТекущаяТЧВерсии.Колонки.Найти(ИмяКолонкиИдСтроки()) <> Неопределено Тогда
НайденнаяСтрока = ТекущаяТЧВерсии.Найти(ТекСчетчикУникальныйИд, ИмяКолонкиИдСтроки());
КонецЕсли;
Если НайденнаяСтрока <> Неопределено Тогда
Если (НайденнаяСтрока[ИмяКолонкиМодификация()] <> Неопределено) Тогда
Если (ТипЗнч(НайденнаяСтрока[ИмяКолонкиМодификация()]) = Тип("Строка")
ИЛИ (ТипЗнч(НайденнаяСтрока[ИмяКолонкиМодификация()]) = Тип("Булево")
И НайденнаяСтрока[ИмяКолонкиМодификация()] = Истина)) Тогда
МодифицированностьСтроки = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
ИндексПоВерсиям = ИндексПоВерсиям - 1;
КонецЦикла;
Если Не МодифицированностьСтроки Тогда
Продолжить;
КонецЕсли;
ИндексПоВерсиям = МассивНомеровВерсий.Количество();
ПромежутокМеждуЗаполнениями = 0;
Пока ИндексПоВерсиям >= 1 Цикл
ПромежутокМеждуЗаполнениями = ПромежутокМеждуЗаполнениями + 1;
ТекущаяКолонкаВерсииТЧ = "Версия" + Формат(МассивНомеровВерсий[ИндексПоВерсиям-1], "ЧГ=0");
ТекущаяТЧВерсии = ВерсииТекущейТЧ[ТекущаяКолонкаВерсииТЧ];
НайденнаяСтрока = ТекущаяТЧВерсии.Найти(ТекСчетчикУникальныйИд, ИмяКолонкиИдСтроки());
Если НайденнаяСтрока <> Неопределено Тогда
Если Не ЗаголовокСекцииТабличныхЧастейВыводился Тогда
ЗаголовокСекцииТабличныхЧастейВыводился = Истина;
ШаблонОбщаяШапкаСекцииТЧ = ОбщийШаблон.ПолучитьОбласть("ШапкаТабличныхЧастей");
ТЧОтчета.Вывести(ШаблонОбщаяШапкаСекцииТЧ);
ТЧОтчета.НачатьГруппуСтрок("ГруппаТабличныхЧастей");
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
КонецЕсли;
Если Не ТекущаяТабличнаяЧастьИзменилась Тогда
ТекущаяТабличнаяЧастьИзменилась = Истина;
ШаблонШапкаТекущейТЧ = ОбщийШаблон.ПолучитьОбласть("ШапкаТабличнойЧасти");
ШаблонШапкаТекущейТЧ.Параметры.НаименованиеТабличнойЧасти = ПредставлениеТабличнойЧасти;
ТЧОтчета.Вывести(ШаблонШапкаТекущейТЧ);
ТЧОтчета.НачатьГруппуСтрок("ТабличнаяЧасть"+ИмяТабличнойЧасти);
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
КонецЕсли;
Модификация = НайденнаяСтрока[ИмяКолонкиМодификация()];
Если СтрокаУникальныйИдИзменена = Ложь Тогда
СтрокаУникальныйИдИзменена = Истина;
ШаблонШапкаСтрокиТЧ = ОбщийШаблон.ПолучитьОбласть("ШапкаСтрокиТабличнойЧасти");
ШаблонШапкаСтрокиТЧ.Параметры.НомерСтрокиТабличнойЧасти = ТекСчетчикУникальныйИд;
ТЧОтчета.Вывести(ШаблонШапкаСтрокиТЧ);
ТЧОтчета.НачатьГруппуСтрок("ГруппаСтрок"+ИмяТабличнойЧасти+ТекСчетчикУникальныйИд);
ТипВывода = "";
Если Модификация = "У" Тогда
ТипВывода = "У"
КонецЕсли;
МассивЗаполнения = Новый Массив;
Для Каждого Колонка Из ТекущаяТЧВерсии.Колонки Цикл
Если СтрНайти(Колонка.Имя, ПрефиксСлужебнойКолонки()) = 1 Тогда
Продолжить;
КонецЕсли;
ПредставлениеРеквизита = Колонка.Имя;
Если ЗначениеЗаполнено(Колонка.Заголовок) Тогда
ПредставлениеРеквизита = Колонка.Заголовок;
Иначе
Если ОписаниеТабличнойЧасти <> Неопределено Тогда
ОписаниеРеквизита = ВерсионированиеОбъектов.МетаданныеРеквизитаТабличнойЧасти(ОписаниеТабличнойЧасти, Колонка.Имя);
Если ОписаниеРеквизита = Неопределено И Метаданные.ПланыСчетов.Содержит(МетаданныеОбъекта) Тогда
ОписаниеРеквизита = МетаданныеОбъекта.ПризнакиУчетаСубконто.Найти(Колонка.Имя);
КонецЕсли;
Если ОписаниеРеквизита <> Неопределено Тогда
ПредставлениеРеквизита = ОписаниеРеквизита.Представление();
КонецЕсли;
КонецЕсли;
КонецЕсли;
МассивЗаполнения.Добавить(ПредставлениеРеквизита);
КонецЦикла;
ПустойСектор = СформироватьПустойСектор(ОбщийШаблон, ТекущаяТЧВерсии.Колонки.Количество()-2);
ПустойСекторЗаполняемый = СформироватьПустойСектор(ОбщийШаблон, ТекущаяТЧВерсии.Колонки.Количество()-2, ТипВывода);
Секция = СформироватьСекторСтрокиТЧ(ОбщийШаблон, МассивЗаполнения, ТипВывода);
ТЧОтчета.Присоединить(ПустойСектор);
ТЧОтчета.Присоединить(Секция);
КонецЕсли;
Пока ПромежутокМеждуЗаполнениями > 1 Цикл
ТЧОтчета.Присоединить(ПустойСекторЗаполняемый);
ПромежутокМеждуЗаполнениями = ПромежутокМеждуЗаполнениями - 1;
КонецЦикла;
ПромежутокМеждуЗаполнениями = 0;
МассивЗаполнения = Новый СписокЗначений;
Для Каждого Колонка Из ТекущаяТЧВерсии.Колонки Цикл
Если СтрНайти(Колонка.Имя, ПрефиксСлужебнойКолонки()) = 1 Тогда
Продолжить;
КонецЕсли;
Представление = Строка(НайденнаяСтрока[Колонка.Имя]);
ИменаКолонокСИзменениями = НайденнаяСтрока[ИмяКолонкиИзменения()];
МассивЗаполнения.Добавить(ИменаКолонокСИзменениями.Найти(Колонка.Имя) <> Неопределено, Представление);
КонецЦикла;
Если ТипЗнч(Модификация) = Тип("Булево") Тогда
ТипВывода = "";
Иначе
ТипВывода = Модификация;
КонецЕсли;
Секция = СформироватьСекторСтрокиТЧ(ОбщийШаблон, МассивЗаполнения, ТипВывода);
ТЧОтчета.Присоединить(Секция);
КонецЕсли;
ИндексПоВерсиям = ИндексПоВерсиям - 1;
КонецЦикла;
Если СтрокаУникальныйИдИзменена Тогда
ТЧОтчета.ЗакончитьГруппуСтрок();
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
КонецЕсли;
КонецЦикла;
Если ТекущаяТабличнаяЧастьИзменилась Тогда
ТЧОтчета.ЗакончитьГруппуСтрок();
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
КонецЕсли;
КонецЦикла;
Если ЗаголовокСекцииТабличныхЧастейВыводился Тогда
ТЧОтчета.ЗакончитьГруппуСтрок();
ТЧОтчета.Вывести(ШаблонСвободнаяСтрока);
КонецЕсли;
КонецПроцедуры
Процедура ВывестиИзмененияТабличныхДокументов(ТЧОтчета, МассивНомеровВерсий, ТаблицаИзмененийТабличныхДокументов, ОбщийШаблон)
Если ТаблицаИзмененийТабличныхДокументов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ШаблонЗаголовокТабличныеДокументы = ОбщийШаблон.ПолучитьОбласть("ШапкаТабличныхДокументов");
ТЧОтчета.Вывести(ШаблонЗаголовокТабличныеДокументы);
ТЧОтчета.НачатьГруппуСтрок("ГруппаТабличныхДокументов");
ШаблонПустаяСтрока = ОбщийШаблон.ПолучитьОбласть("СвободнаяСтрока");
ТЧОтчета.Вывести(ШаблонПустаяСтрока);
ШаблонСтрокаТабличныеДокументы = ОбщийШаблон.ПолучитьОбласть("ШапкаТабличногоДокумента");
ШаблонЯчейкаНеИзменилась = ОбщийШаблон.ПолучитьОбласть("ТабличныеДокументыИдентичны");
ШаблонЯчейкаИзменилась = ОбщийШаблон.ПолучитьОбласть("ТабличныеДокументыРазличаются");
ШаблонЯчейкаДобавлена = ОбщийШаблон.ПолучитьОбласть("ТабличныеДокументыДобавлен");
ШаблонЯчейкаУдалена = ОбщийШаблон.ПолучитьОбласть("ТабличныеДокументыУдален");
Для Каждого текСтрока Из ТаблицаИзмененийТабличныхДокументов Цикл
ШаблонСтрокаТабличныеДокументы.Параметры.НаименованиеТабличногоДокумента = текСтрока.Представление;
ТЧОтчета.Вывести(ШаблонСтрокаТабличныеДокументы);
ВГраница = МассивНомеровВерсий.ВГраница();
Для Индекс = 0 По ВГраница Цикл
ИндексНомераВерсии = ВГраница-Индекс;
НомерВерсии = МассивНомеровВерсий[ИндексНомераВерсии];
ИмяКолонки = "Версия" + Формат(НомерВерсии, "ЧГ=0");
Если ТекСтрока[ИмяКолонки] = "И" Тогда
Область = ТЧОтчета.Присоединить(ШаблонЯчейкаИзменилась);
НомерВерсии0 = Формат(НомерВерсии, "ЧГ=0");
НомерВерсии1 = Формат(МассивНомеровВерсий[ИндексНомераВерсии-1], "ЧГ=0");
ШаблонТекста = НСтр("ru = 'сравнить версию №%1 с версией №%2'");
Область.Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонТекста, НомерВерсии0, НомерВерсии1);
Область.Расшифровка = Новый Структура("Сравнить, Версия0, Версия1",
текСтрока.Наименование, ИндексНомераВерсии, ИндексНомераВерсии-1);
ИначеЕсли текСтрока[ИмяКолонки] = "У" Тогда
Область = ТЧОтчета.Присоединить(ШаблонЯчейкаУдалена);
Область.Текст = НСтр("ru = 'Сохранение изменений табличного документа отключено'");
ИначеЕсли текСтрока[ИмяКолонки] = "Д" Тогда
Область = ТЧОтчета.Присоединить(ШаблонЯчейкаДобавлена);
Область.Текст = НСтр("ru = 'открыть'");
Область.Расшифровка = Новый Структура("Открыть, Версия", текСтрока.Наименование, ИндексНомераВерсии);
Иначе
Область = ТЧОтчета.Присоединить(ШаблонЯчейкаНеИзменилась);
КонецЕсли;
КонецЦикла;
ТЧОтчета.Вывести(ШаблонПустаяСтрока);
КонецЦикла;
ТЧОтчета.ЗакончитьГруппуСтрок();
ТЧОтчета.Вывести(ШаблонПустаяСтрока);
КонецПроцедуры
Процедура ВывестиРезультатыКомпоновкиВОтчет(Параметры)
ТаблицаИзмененийРеквизитов = Параметры.ТаблицаИзмененийРеквизитов;
ТаблицаИзмененийТабличныхЧастей = Параметры.ТаблицаИзмененийТабличныхЧастей;
ТаблицаИзмененийТабличныхДокументов = Параметры.ТаблицаИзмененийТабличныхДокументов;
счетчикУникальныйИд = Параметры.счетчикУникальныйИд;
СписокВерсий = Параметры.СписокВерсий;
ТЧОтчета = Параметры.ТЧОтчета;
ОбщийШаблон = Параметры.ОбщийШаблон;
СсылкаНаОбъект = Параметры.СсылкаНаОбъект;
МассивНомеровВерсий = СписокВерсий.ВыгрузитьЗначения();
ЧислоИзменившихсяРеквизитов = РассчитатьЧислоИзменившихсяРеквизитов(ТаблицаИзмененийРеквизитов, МассивНомеровВерсий);
ЧислоВерсий = МассивНомеровВерсий.Количество();
ТЧОтчета.Очистить();
ВывестиШапку(ТЧОтчета, СписокВерсий, ЧислоВерсий, ОбщийШаблон, СсылкаНаОбъект);
Если ЧислоИзменившихсяРеквизитов = 0 Тогда
ОбластьШапкаРеквизитов = ОбщийШаблон.ПолучитьОбласть("ШапкаРеквизитов");
ТЧОтчета.Вывести(ОбластьШапкаРеквизитов);
ТЧОтчета.НачатьГруппуСтрок("ГруппаРеквизитов");
ОбластьРеквизитыНеИзменялись = ОбщийШаблон.ПолучитьОбласть("РеквизитыНеИзменялись");
ТЧОтчета.Вывести(ОбластьРеквизитыНеИзменялись);
ТЧОтчета.ЗакончитьГруппуСтрок();
Иначе
ВывестиИзмененияРеквизитов(ТЧОтчета, ТаблицаИзмененийРеквизитов, МассивНомеровВерсий, ОбщийШаблон, СсылкаНаОбъект);
КонецЕсли;
ВывестиИзмененияТабличныхЧастей(ТЧОтчета, ТаблицаИзмененийТабличныхЧастей, МассивНомеровВерсий, счетчикУникальныйИд, ОбщийШаблон, СсылкаНаОбъект);
ВывестиИзмененияТабличныхДокументов(ТЧОтчета, МассивНомеровВерсий, ТаблицаИзмененийТабличныхДокументов, ОбщийШаблон);
ТЧОтчета.ИтогиСнизу = Ложь;
ТЧОтчета.ОтображатьСетку = Ложь;
ТЧОтчета.Защита = Ложь;
ТЧОтчета.ТолькоПросмотр = Истина;
КонецПроцедуры
Процедура ВывестиШапку(ТЧОтчета, СписокВерсий, ЧислоВерсий, ОбщийШаблон, СсылкаНаОбъект)
ОбластьШапка = ОбщийШаблон.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.НаименованиеОтчета = НСтр("ru = 'Отчет по изменениям версий объекта'");
ОбластьШапка.Параметры.НаименованиеОбъекта = Строка(СсылкаНаОбъект);
ТЧОтчета.Вывести(ОбластьШапка);
ПустаяЯчейка = ОбщийШаблон.ПолучитьОбласть("ПустаяЯчейка");
ОбластьВерсии = ОбщийШаблон.ПолучитьОбласть("ЗаголовокВерсии");
ТЧОтчета.Присоединить(ПустаяЯчейка);
ТЧОтчета.Присоединить(ОбластьВерсии);
ОбластьВерсии = ОбщийШаблон.ПолучитьОбласть("ПредставлениеВерсии");
КомментарииКВерсиям = Новый Структура;
ЕстьКомментарии = Ложь;
ИндексПоВерсиям = ЧислоВерсий;
Пока ИндексПоВерсиям > 0 Цикл
СведенияОВерсии = ПолучитьОписаниеПоВерсии(СсылкаНаОбъект, СписокВерсий[ИндексПоВерсиям-1]);
ОбластьВерсии.Параметры.ПредставлениеВерсии = СведенияОВерсии.Описание;
КомментарииКВерсиям.Вставить("Комментарий" + ИндексПоВерсиям, СведенияОВерсии.Комментарий);
Если Не ПустаяСтрока(СведенияОВерсии.Комментарий) Тогда
ЕстьКомментарии = Истина;
КонецЕсли;
ТЧОтчета.Присоединить(ОбластьВерсии);
ТЧОтчета.Область("C" + Формат(ИндексПоВерсиям + 2, "ЧГ=0")).ШиринаКолонки = 50;
ИндексПоВерсиям = ИндексПоВерсиям - 1;
КонецЦикла;
Если ЕстьКомментарии Тогда
ОбластьКомментарий = ОбщийШаблон.ПолучитьОбласть("ЗаголовокКомментарий");
ТЧОтчета.Вывести(ПустаяЯчейка);
ТЧОтчета.Присоединить(ОбластьКомментарий);
ОбластьКомментарий = ОбщийШаблон.ПолучитьОбласть("Комментарий");
ИндексПоВерсиям = ЧислоВерсий;
Пока ИндексПоВерсиям > 0 Цикл
ОбластьКомментарий.Параметры.Комментарий = КомментарииКВерсиям["Комментарий" + ИндексПоВерсиям];
ТЧОтчета.Присоединить(ОбластьКомментарий);
ИндексПоВерсиям = ИндексПоВерсиям - 1;
КонецЦикла;
КонецЕсли;
ОбластьСвободнаяСтрока = ОбщийШаблон.ПолучитьОбласть("СвободнаяСтрока");
ТЧОтчета.Вывести(ОбластьСвободнаяСтрока);
КонецПроцедуры
Функция РассчитатьИзменения(НомерВерсии, РезультатРазбораВерсии_0, РезультатРазбораВерсии_1, СсылкаНаОбъект)
Реквизиты_0 = РезультатРазбораВерсии_0.Реквизиты;
ТабличныеЧасти_0 = РезультатРазбораВерсии_0.ТабличныеЧасти;
РезультатРазбораВерсии_1 = ВерсионированиеОбъектов.РазборВерсии(СсылкаНаОбъект, НомерВерсии);
ДобавитьНомераСтрокВТабличныеЧасти(РезультатРазбораВерсии_1.ТабличныеЧасти);
Реквизиты_1 = РезультатРазбораВерсии_1.Реквизиты;
ТабличныеЧасти_1 = РезультатРазбораВерсии_1.ТабличныеЧасти;
СписокТабличныхЧастей_0 = СоздатьТаблицуСравнения();
Для Каждого Элемент Из ТабличныеЧасти_0 Цикл
НоваяСтрока = СписокТабличныхЧастей_0.Добавить();
НоваяСтрока.Установить(0, СокрЛП(Элемент.Ключ));
КонецЦикла;
СписокТабличныхЧастей_1 = СоздатьТаблицуСравнения();
Для Каждого Элемент Из ТабличныеЧасти_1 Цикл
НоваяСтрока = СписокТабличныхЧастей_1.Добавить();
НоваяСтрока.Установить(0, СокрЛП(Элемент.Ключ));
КонецЦикла;
СписокДобавленныхТЧ = ВычестьТаблицу(СписокТабличныхЧастей_1, СписокТабличныхЧастей_0);
СписокУдаленныхТЧ = ВычестьТаблицу(СписокТабличныхЧастей_0, СписокТабличныхЧастей_1);
СписокОставшихсяТЧ = ВычестьТаблицу(СписокТабличныхЧастей_1, СписокДобавленныхТЧ);
СписокИзменившихсяТЧ = НайтиИзменившиесяТабличныеЧасти(СписокОставшихсяТЧ,
ТабличныеЧасти_0,
ТабличныеЧасти_1);
СписокРеквизитов0 = СоздатьТаблицуСравнения();
Для Каждого Реквизит Из РезультатРазбораВерсии_0.Реквизиты Цикл
НоваяСтрока = СписокРеквизитов0.Добавить();
НоваяСтрока.Установить(0, Строка(Реквизит.НаименованиеРеквизита));
КонецЦикла;
СписокРеквизитов1 = СоздатьТаблицуСравнения();
Для Каждого Реквизит Из РезультатРазбораВерсии_1.Реквизиты Цикл
НоваяСтрока = СписокРеквизитов1.Добавить();
НоваяСтрока.Установить(0, Строка(Реквизит.НаименованиеРеквизита));
КонецЦикла;
СписокДобавленныхРеквизитов = ВычестьТаблицу(СписокРеквизитов1, СписокРеквизитов0);
СписокУдаленныхРеквизитов = ВычестьТаблицу(СписокРеквизитов0, СписокРеквизитов1);
СписокОставшихсяРеквизитов = ВычестьТаблицу(СписокРеквизитов1, СписокДобавленныхРеквизитов);
СписокИзменившихсяРеквизитов = СоздатьТаблицуСравнения();
ИзмененияВРеквизитах = Новый Соответствие;
ИзмененияВРеквизитах.Вставить("д", СписокДобавленныхРеквизитов);
ИзмененияВРеквизитах.Вставить("у", СписокУдаленныхРеквизитов);
ИзмененияВРеквизитах.Вставить("и", СписокИзменившихсяРеквизитов);
Для Каждого СтрокаТаблицыЗначений Из СписокОставшихсяРеквизитов Цикл
Реквизит = СтрокаТаблицыЗначений.Значение;
Значение_0 = Реквизиты_0.Найти(Реквизит, "НаименованиеРеквизита").ЗначениеРеквизита;
Значение_1 = Реквизиты_1.Найти(Реквизит, "НаименованиеРеквизита").ЗначениеРеквизита;
Если ТипЗнч(Значение_0) <> Тип("ХранилищеЗначения")
И ТипЗнч(Значение_1) <> Тип("ХранилищеЗначения") Тогда
Если Значение_0 <> Значение_1 Тогда
НоваяСтрока = СписокИзменившихсяРеквизитов.Добавить();
НоваяСтрока.Установить(0, Реквизит);
КонецЕсли;
КонецЕсли;
КонецЦикла;
ИзмененияВТаблицах = РассчитатьИзмененияТабличныхЧастей(
СписокИзменившихсяТЧ,
ТабличныеЧасти_0,
ТабличныеЧасти_1);
ТабличныеДокументы0 = РезультатРазбораВерсии_0.ТабличныеДокументы;
ТабличныеДокументы1 = РезультатРазбораВерсии_1.ТабличныеДокументы;
СписокТабличныхДокументов0 = СоздатьТаблицуСравнения();
СписокТабличныхДокументов0.Колонки.Добавить("Представление");
Если ТабличныеДокументы0 <> Неопределено Тогда
Для Каждого ЭлементСтруктуры Из ТабличныеДокументы0 Цикл
НоваяСтрока = СписокТабличныхДокументов0.Добавить();
НоваяСтрока.Значение = ЭлементСтруктуры.Ключ;
НоваяСтрока.Представление = ЭлементСтруктуры.Значение.Наименование;
КонецЦикла;
КонецЕсли;
СписокТабличныхДокументов1 = СоздатьТаблицуСравнения();
СписокТабличныхДокументов1.Колонки.Добавить("Представление");
Если ТабличныеДокументы1 <> Неопределено Тогда
Для Каждого ЭлементСтруктуры Из ТабличныеДокументы1 Цикл
НоваяСтрока = СписокТабличныхДокументов1.Добавить();
НоваяСтрока.Значение = ЭлементСтруктуры.Ключ;
НоваяСтрока.Представление = ЭлементСтруктуры.Значение.Наименование;
КонецЦикла;
КонецЕсли;
СписокДобавленныхТабличныхДокументов = ВычестьТаблицу(СписокТабличныхДокументов1, СписокТабличныхДокументов0);
СписокУдаленныхТабличныхДокументов = ВычестьТаблицу(СписокТабличныхДокументов0, СписокТабличныхДокументов1);
СписокОставшихсяТабличныхДокументов = ВычестьТаблицу(СписокТабличныхДокументов1,
СписокДобавленныхТабличныхДокументов);
СписокИзменившихсяТабличныхДокументов = СоздатьТаблицуСравнения();
СписокИзменившихсяТабличныхДокументов.Колонки.Добавить("Представление");
ИзмененияВТабличныхДокументах = Новый Соответствие;
ИзмененияВТабличныхДокументах.Вставить("д", СписокДобавленныхТабличныхДокументов);
ИзмененияВТабличныхДокументах.Вставить("у", СписокУдаленныхТабличныхДокументов);
ИзмененияВТабличныхДокументах.Вставить("и", СписокИзменившихсяТабличныхДокументов);
Для Каждого СтрокаТаблицыЗначений Из СписокОставшихсяТабличныхДокументов Цикл
ИмяТабличногоДокумента = СтрокаТаблицыЗначений.Значение;
ТабДокXML = ВерсионированиеОбъектов.СериализоватьОбъект(
Новый ХранилищеЗначения(ТабличныеДокументы0[ИмяТабличногоДокумента].Данные));
КонтрольнаяСумма0 = ВерсионированиеОбъектов.КонтрольнаяСумма(ТабДокXML);
ТабДокXML = ВерсионированиеОбъектов.СериализоватьОбъект(
Новый ХранилищеЗначения(ТабличныеДокументы1[ИмяТабличногоДокумента].Данные));
КонтрольнаяСумма1 = ВерсионированиеОбъектов.КонтрольнаяСумма(ТабДокXML);
Если КонтрольнаяСумма0 <> КонтрольнаяСумма1 Тогда
ЗаполнитьЗначенияСвойств(СписокИзменившихсяТабличныхДокументов.Добавить(), СтрокаТаблицыЗначений);
КонецЕсли;
КонецЦикла;
МодификацииТабличныхЧастей = Новый Структура;
МодификацииТабличныхЧастей.Вставить("д", СписокДобавленныхТЧ);
МодификацииТабличныхЧастей.Вставить("у", СписокУдаленныхТЧ);
МодификацииТабличныхЧастей.Вставить("и", ИзмененияВТаблицах);
КомпоновкаИзменений = Новый Соответствие;
КомпоновкаИзменений.Вставить("Реквизиты", ИзмененияВРеквизитах);
КомпоновкаИзменений.Вставить("ТабличныеЧасти", МодификацииТабличныхЧастей);
КомпоновкаИзменений.Вставить("ТабличныеДокументы", ИзмененияВТабличныхДокументах);
Возврат КомпоновкаИзменений;
КонецФункции
Процедура ПодготовитьКолонкиТаблицИзмененийРеквизитов(ТаблицаЗначений,
МассивНомеровВерсий)
ТаблицаЗначений = Новый ТаблицаЗначений;
ТаблицаЗначений.Колонки.Добавить("Наименование");
ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиМодификация());
ТаблицаЗначений.Колонки.Добавить(ИмяКолонкиТипЗначения());
Для Индекс = 1 По МассивНомеровВерсий.Количество() Цикл
ТаблицаЗначений.Колонки.Добавить("Версия" + Формат(МассивНомеровВерсий[Индекс-1], "ЧГ=0"));
КонецЦикла;
КонецПроцедуры
Функция РассчитатьИзмененияТабличныхЧастей(СписокИзменившихсяТЧ, ТабличныеЧасти_0, ТабличныеЧасти_1)
Для Каждого ТабличнаяЧасть Из ТабличныеЧасти_0 Цикл
Если ТабличныеЧасти_1[ТабличнаяЧасть.Ключ] = Неопределено Тогда
ТабличныеЧасти_1.Вставить(ТабличнаяЧасть.Ключ, Новый ТаблицаЗначений);
УдаленнаяТабличнаяЧасть = СписокИзменившихсяТЧ.Добавить();
УдаленнаяТабличнаяЧасть.Значение = ТабличнаяЧасть.Ключ;
КонецЕсли;
КонецЦикла;
Для Каждого ТабличнаяЧасть Из ТабличныеЧасти_1 Цикл
Если ТабличныеЧасти_0[ТабличнаяЧасть.Ключ] = Неопределено Тогда
ТабличныеЧасти_0.Вставить(ТабличнаяЧасть.Ключ, Новый ТаблицаЗначений);
ДобавленнаяТабличнаяЧасть = СписокИзменившихсяТЧ.Добавить();
ДобавленнаяТабличнаяЧасть.Значение = ТабличнаяЧасть.Ключ;
КонецЕсли;
КонецЦикла;
ИзмененияВТаблицах = Новый Соответствие;
Для Индекс = 1 По СписокИзменившихсяТЧ.Количество() Цикл
ИзмененияВТаблицах.Вставить(СписокИзменившихсяТЧ[Индекс-1].Значение, Новый Соответствие);
ТаблицаДляАнализа = СписокИзменившихсяТЧ[Индекс-1].Значение;
ТЧ0 = ТабличныеЧасти_0[ТаблицаДляАнализа];
ТЧ1 = ТабличныеЧасти_1[ТаблицаДляАнализа];
ТаблицаИзмененныхСтрок = Новый ТаблицаЗначений;
ТаблицаИзмененныхСтрок.Колонки.Добавить("ИндексВТЧ0");
ТаблицаИзмененныхСтрок.Колонки.Добавить("ИндексВТЧ1");
ТаблицаИзмененныхСтрок.Колонки.Добавить("Различия");
СоответствиеСтрокТЧ0СтрокамТЧ1 = СоответствиеСтрокТаблиц(ТЧ0, ТЧ1);
СоответствиеСтрокТЧ1СтрокамТЧ0 = Новый Соответствие;
ПроверяемыеКолонки = НайтиОбщиеКолонки(ТЧ0, ТЧ1);
Для Каждого Соответствие Из СоответствиеСтрокТЧ0СтрокамТЧ1 Цикл
СтрокаТаблицы0 = Соответствие.Ключ;
СтрокаТаблицы1 = Соответствие.Значение;
РазличияСтрок = РазличияСтрок(СтрокаТаблицы0, СтрокаТаблицы1, ПроверяемыеКолонки);
Если РазличияСтрок.Количество() > 0 Тогда
НоваяСтрока = ТаблицаИзмененныхСтрок.Добавить();
НоваяСтрока["ИндексВТЧ0"] = ИндексСтроки(СтрокаТаблицы0) + 1;
НоваяСтрока["ИндексВТЧ1"] = ИндексСтроки(СтрокаТаблицы1) + 1;
НоваяСтрока["Различия"] = РазличияСтрок;
КонецЕсли;
СоответствиеСтрокТЧ1СтрокамТЧ0.Вставить(СтрокаТаблицы1, СтрокаТаблицы0);
КонецЦикла;
ТаблицаДобавленныхСтрок = Новый ТаблицаЗначений;
ТаблицаДобавленныхСтрок.Колонки.Добавить("ИндексВТЧ1");
Для Каждого СтрокаТаблицы Из ТЧ1 Цикл
Если СоответствиеСтрокТЧ1СтрокамТЧ0[СтрокаТаблицы] = Неопределено Тогда
НоваяСтрока = ТаблицаДобавленныхСтрок.Добавить();
НоваяСтрока.ИндексВТЧ1 = ТЧ1.Индекс(СтрокаТаблицы) + 1;
КонецЕсли;
КонецЦикла;
ТаблицаУдаленныхСтрок = Новый ТаблицаЗначений;
ТаблицаУдаленныхСтрок.Колонки.Добавить("ИндексВТЧ0");
Для Каждого СтрокаТаблицы Из ТЧ0 Цикл
Если СоответствиеСтрокТЧ0СтрокамТЧ1[СтрокаТаблицы] = Неопределено Тогда
НоваяСтрока = ТаблицаУдаленныхСтрок.Добавить();
НоваяСтрока.ИндексВТЧ0 = ТЧ0.Индекс(СтрокаТаблицы) + 1;
КонецЕсли;
КонецЦикла;
ИзмененияВТаблицах[СписокИзменившихсяТЧ[Индекс-1].Значение].Вставить("Д", ТаблицаДобавленныхСтрок);
ИзмененияВТаблицах[СписокИзменившихсяТЧ[Индекс-1].Значение].Вставить("У", ТаблицаУдаленныхСтрок);
ИзмененияВТаблицах[СписокИзменившихсяТЧ[Индекс-1].Значение].Вставить("И", ТаблицаИзмененныхСтрок);
КонецЦикла;
Возврат ИзмененияВТаблицах;
КонецФункции
Функция НайтиИзменившиесяТабличныеЧасти(СписокОставшихсяТЧ,
ТабличныеЧасти_0,
ТабличныеЧасти_1)
СписокИзменившихсяТЧ = СоздатьТаблицуСравнения();
Для Каждого Элемент Из СписокОставшихсяТЧ Цикл
ТЧ_0 = ТабличныеЧасти_0[Элемент.Значение];
ТЧ_1 = ТабличныеЧасти_1[Элемент.Значение];
Если ТЧ_0.Количество() = ТЧ_1.Количество() Тогда
НайденоОтличие = Ложь;
Если ТЧЭквиваленты (ТЧ_0.Колонки, ТЧ_1.Колонки) Тогда
Для Индекс = 0 По ТЧ_0.Количество() - 1 Цикл
Строка_0 = ТЧ_0[Индекс];
Строка_1 = ТЧ_1[Индекс];
Если НЕ СтрокиТЧРавны(Строка_0, Строка_1, ТЧ_0.Колонки) Тогда
НайденоОтличие = Истина;
Прервать;
КонецЕсли
КонецЦикла;
Иначе
НайденоОтличие = Истина;
КонецЕсли;
Если НайденоОтличие Тогда
НоваяСтрока = СписокИзменившихсяТЧ.Добавить();
НоваяСтрока.Установить(0, Элемент.Значение);
КонецЕсли;
Иначе
НоваяСтрока = СписокИзменившихсяТЧ.Добавить();
НоваяСтрока.Установить(0, Элемент.Значение);
КонецЕсли;
КонецЦикла;
Возврат СписокИзменившихсяТЧ;
КонецФункции
Функция СчитатьНачальныеЗначенияРеквизитовИТабличныхЧастей(ТаблицаРеквизитов, ТаблицаТЧ, КоличествоВерсий, МассивНомеровВерсий, СсылкаНаОбъект)
МладшаяВерсияОбъекта = МассивНомеровВерсий[0];
ВерсияОбъекта = ВерсионированиеОбъектов.РазборВерсии(СсылкаНаОбъект, МладшаяВерсияОбъекта);
ДобавитьНомераСтрокВТабличныеЧасти(ВерсияОбъекта.ТабличныеЧасти);
Реквизиты = ВерсияОбъекта.Реквизиты;
ТабличныеЧасти = ВерсияОбъекта.ТабличныеЧасти;
Колонка = "Версия" + Формат(МассивНомеровВерсий[0], "ЧГ=0");
Для Каждого СтрокаТаблицыЗначений Из Реквизиты Цикл
НоваяСтрока = ТаблицаРеквизитов.Добавить();
НоваяСтрока[Колонка] = Новый Структура("ТипИзменения, Значение", "И", СтрокаТаблицыЗначений);
НоваяСтрока.Наименование = СтрокаТаблицыЗначений.НаименованиеРеквизита;
НоваяСтрока[ИмяКолонкиМодификация()] = Ложь;
НоваяСтрока[ИмяКолонкиТипЗначения()] = СтрокаТаблицыЗначений.ТипРеквизита;
КонецЦикла;
Для Каждого ЭлементТЧ Из ТабличныеЧасти Цикл
ТаблицаТЧ.Вставить(ЭлементТЧ.Ключ, Новый Соответствие);
ПодготовитьКолонкиТаблицИзмененийДляСоответствия(ТаблицаТЧ[ЭлементТЧ.Ключ], МассивНомеровВерсий);
ТаблицаТЧ[ЭлементТЧ.Ключ]["Версия" + Формат(МладшаяВерсияОбъекта, "ЧГ=0")] = ЭлементТЧ.Значение.Скопировать();
ТекущаяТЗ = ТаблицаТЧ[ЭлементТЧ.Ключ]["Версия" + Формат(МладшаяВерсияОбъекта, "ЧГ=0")];
ТекущаяТЗ.Колонки.Добавить(ИмяКолонкиИдСтроки());
ТекущаяТЗ.Колонки.Добавить(ИмяКолонкиМодификация());
ТекущаяТЗ.Колонки.Добавить(ИмяКолонкиИзменения(), Новый ОписаниеТипов("Массив"));
Для Индекс = 1 По ТекущаяТЗ.Количество() Цикл
ТекущаяТЗ[Индекс-1][ПрефиксСлужебнойКолонки() + "ИдСтроки"] = Индекс;
ТекущаяТЗ[Индекс-1][ПрефиксСлужебнойКолонки() + "Модификация"] = Ложь;
КонецЦикла;
КонецЦикла;
Возврат ВерсияОбъекта;
КонецФункции
Процедура ПодготовитьКолонкиТаблицИзмененийДляСоответствия(Соответствие, МассивНомеровВерсий)
Количество = МассивНомеровВерсий.Количество();
Для Индекс = 1 По Количество Цикл
Соответствие.Вставить("Версия" + Формат(МассивНомеровВерсий[Индекс-1], "ЧГ=0"), Новый ТаблицаЗначений);
КонецЦикла;
КонецПроцедуры
Функция ТЧЭквиваленты(КолонкиПервойТаблицы, КолонкиВторойТаблицы)
Если КолонкиПервойТаблицы.Количество() <> КолонкиВторойТаблицы.Количество() Тогда
Возврат Ложь;
КонецЕсли;
Для Каждого Колонка Из КолонкиПервойТаблицы Цикл
Найденная = КолонкиВторойТаблицы.Найти(Колонка.Имя);
Если Найденная = Неопределено Или Колонка.ТипЗначения <> Найденная.ТипЗначения Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция СтрокиТЧРавны(СтрокаТЧ1, СтрокаТЧ2, Колонки)
Для Каждого Колонка Из Колонки Цикл
ИмяКолонки = Колонка.Имя;
Если СтрокаТЧ2.Владелец().Колонки.Найти(ИмяКолонки) = Неопределено Тогда
Продолжить;
КонецЕсли;
ЗначениеИзТЧ1 = СтрокаТЧ1[ИмяКолонки];
ЗначениеИзТЧ2 = СтрокаТЧ2[ИмяКолонки];
Если ЗначениеИзТЧ1 <> ЗначениеИзТЧ2 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Функция ПолучитьОписаниеПоВерсии(СсылкаНаОбъект, НомерВерсии)
СведенияОВерсии = ВерсионированиеОбъектов.СведенияОВерсииОбъекта(СсылкаНаОбъект, НомерВерсии.Значение);
Описание = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = '№ %1 / (%2) / %3'"), НомерВерсии.Представление,
Строка(СведенияОВерсии.ДатаВерсии), СокрЛП(Строка(СведенияОВерсии.АвторВерсии)));
СведенияОВерсии.Вставить("Описание", Описание);
Возврат СведенияОВерсии;
КонецФункции
Функция РассчитатьЧислоИзменившихсяРеквизитов(ТаблицаИзмененийРеквизитов, МассивНомеровВерсий)
Результат = 0;
Для Каждого ЭлементТЗ Из ТаблицаИзмененийРеквизитов Цикл
Если ЭлементТЗ[ИмяКолонкиМодификация()] <> Неопределено И ЭлементТЗ[ИмяКолонкиМодификация()] = Истина Тогда
Результат = Результат + 1;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция УвеличитьСчетчик(счетчикУникальныйИд, ИмяТаблицы);
счетчикУникальныйИд[ИмяТаблицы] = счетчикУникальныйИд[ИмяТаблицы] + 1;
Возврат счетчикУникальныйИд[ИмяТаблицы];
КонецФункции
Функция ПолучитьУникальныеУникальныйИд(ТаблицаИзмененийТЧ, ИмяКолонкиВерсии)
СоответствиеУникальныйИд = Новый Соответствие;
Для Каждого ЭлементСоотв Из ТаблицаИзмененийТЧ Цикл
СоответствиеУникальныйИд[ЭлементСоотв.Ключ] = Число(ЭлементСоотв.Значение[ИмяКолонкиВерсии].Количество());
КонецЦикла;
Возврат СоответствиеУникальныйИд;
КонецФункции
Процедура ЗаполнитьХарактеристикуИзмененияРеквизита(ТаблицаИзмененийРеквизита,
ПометкаИзменения,
ТаблицаИзмененийРеквизитов,
ИмяКолонкиТекущейВерсии,
ВерсияОбъекта)
Для Каждого Элемент Из ТаблицаИзмененийРеквизита Цикл
Наименование = Элемент.Значение;
ИзменениеРеквизита = ТаблицаИзмененийРеквизитов.Найти (Наименование, "Наименование");
Если ИзменениеРеквизита = Неопределено Тогда
ИзменениеРеквизита = ТаблицаИзмененийРеквизитов.Добавить();
ИзменениеРеквизита.Наименование = Наименование;
КонецЕсли;
ПараметрыИзменения = Новый Структура;
ПараметрыИзменения.Вставить("ТипИзменения", ПометкаИзменения);
Если ПометкаИзменения = "у" Тогда
ПараметрыИзменения.Вставить("Значение", "удалено");
Иначе
ПараметрыИзменения.Вставить("Значение", ВерсияОбъекта.Реквизиты.Найти(Наименование, "НаименованиеРеквизита"));
КонецЕсли;
ИзменениеРеквизита[ИмяКолонкиТекущейВерсии] = ПараметрыИзменения;
ИзменениеРеквизита[ИмяКолонкиМодификация()] = Истина;
КонецЦикла;
КонецПроцедуры
Функция СформироватьСекторСтрокиТЧ(ОбщийШаблон, Знач ЗначенияЗаполнения, Знач ТипВывода = "")
ТабличныйДокумент = Новый ТабличныйДокумент;
Если ТипВывода = "" Тогда
Шаблон = ОбщийШаблон.ПолучитьОбласть("ИсходноеЗначениеРеквизита");
ИначеЕсли ТипВывода = "И" Тогда
Шаблон = ОбщийШаблон.ПолучитьОбласть("ИзмененноеЗначениеРеквизита");
ИначеЕсли ТипВывода = "Д" Тогда
Шаблон = ОбщийШаблон.ПолучитьОбласть("ДобавленныйРеквизит");
ИначеЕсли ТипВывода = "У" Тогда
Шаблон = ОбщийШаблон.ПолучитьОбласть("УдаленныйРеквизит");
КонецЕсли;
ШаблонНетИзменения = ОбщийШаблон.ПолучитьОбласть("ИсходноеЗначениеРеквизита");
ШаблонЕстьИзменение = ОбщийШаблон.ПолучитьОбласть("ИзмененноеЗначениеРеквизита");
ЕстьДетализация = ТипЗнч(ЗначенияЗаполнения) = Тип("СписокЗначений");
Для Каждого Элемент Из ЗначенияЗаполнения Цикл
Значение = Элемент;
Если ЕстьДетализация И ТипВывода = "И" Тогда
Значение = Элемент.Представление;
ЕстьИзменение = Элемент.Значение;
Шаблон = ?(ЕстьИзменение, ШаблонЕстьИзменение, ШаблонНетИзменения);
КонецЕсли;
Шаблон.Параметры.ЗначениеРеквизита = Значение;
ТабличныйДокумент.Вывести(Шаблон);
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Функция СформироватьПустойСектор(ОбщийШаблон, Знач ЧислоСтрок, Знач ТипВывода = "")
ЗначениеЗаполнения = Новый Массив;
Для Индекс = 1 По ЧислоСтрок Цикл
ЗначениеЗаполнения.Добавить(" ");
КонецЦикла;
Возврат СформироватьСекторСтрокиТЧ(ОбщийШаблон, ЗначениеЗаполнения, ТипВывода);
КонецФункции
Функция ВычестьТаблицу(Знач ТаблицаОсновная,
Знач ТаблицаВычитаемая,
Знач КолонкаСравненияОсновнойТаблицы = "",
Знач КолонкаСравненияВычитаемойТаблицы = "")
Если Не ЗначениеЗаполнено(КолонкаСравненияОсновнойТаблицы) Тогда
КолонкаСравненияОсновнойТаблицы = "Значение";
КонецЕсли;
Если Не ЗначениеЗаполнено(КолонкаСравненияВычитаемойТаблицы) Тогда
КолонкаСравненияВычитаемойТаблицы = "Значение";
КонецЕсли;
ТаблицаРезультат = Новый ТаблицаЗначений;
ТаблицаРезультат = ТаблицаОсновная.Скопировать();
Для Каждого Элемент Из ТаблицаВычитаемая Цикл
Значение = Элемент[КолонкаСравненияОсновнойТаблицы];
НайденнаяСтрока = ТаблицаРезультат.Найти(Значение, КолонкаСравненияОсновнойТаблицы);
Если НайденнаяСтрока <> Неопределено Тогда
ТаблицаРезультат.Удалить(НайденнаяСтрока);
КонецЕсли;
КонецЦикла;
Возврат ТаблицаРезультат;
КонецФункции
Функция СоздатьТаблицуСравнения(ТаблицаИнициализации = Неопределено,
ИмяКолонкиСравнения = "Значение")
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить(ИмяКолонкиСравнения);
Если ТаблицаИнициализации <> Неопределено Тогда
Для Каждого Элемент Из ТаблицаИнициализации Цикл
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Установить(0, Элемент[ИмяКолонкиСравнения]);
КонецЦикла;
КонецЕсли;
Возврат Таблица;
КонецФункции
Функция ИндексСтроки(СтрокаТаблицы)
Возврат СтрокаТаблицы.Владелец().Индекс(СтрокаТаблицы);
КонецФункции
Процедура ДобавитьНомераСтрокВТабличныеЧасти(ТабличныеЧасти)
Для Каждого Соответствие Из ТабличныеЧасти Цикл
Таблица = Соответствие.Значение;
Если Таблица.Колонки.Найти("НомерСтроки") <> Неопределено Тогда
Продолжить;
КонецЕсли;
Таблица.Колонки.Вставить(0, "НомерСтроки",,НСтр("ru = '№ строки'"));
Для НомерСтроки = 1 По Таблица.Количество() Цикл
Таблица[НомерСтроки-1].НомерСтроки = НомерСтроки;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Функция НайтиПохожиеСтрокиТаблиц(Знач Таблица1, Знач Таблица2, Знач ТребуемоеКоличествоРазличий = 0, Знач МаксимумРазличий = Неопределено, СоответствиеСтрокТаблицы1СтрокамТаблицы2 = Неопределено)
Пропустить = "Пропустить_";
Если Таблица1.Колонки.Найти(Пропустить) = Неопределено Тогда
Таблица1 = Таблица1.Скопировать();
Таблица1.Колонки.Добавить(Пропустить, Новый ОписаниеТипов("Булево"));
Таблица1.Индексы.Добавить(Пропустить);
КонецЕсли;
Если Таблица2.Колонки.Найти(Пропустить) = Неопределено Тогда
Таблица2 = Таблица2.Скопировать();
Таблица2.Колонки.Добавить(Пропустить, Новый ОписаниеТипов("Булево"));
Таблица2.Индексы.Добавить(Пропустить);
КонецЕсли;
Если СоответствиеСтрокТаблицы1СтрокамТаблицы2 = Неопределено Тогда
СоответствиеСтрокТаблицы1СтрокамТаблицы2 = Новый Соответствие;
КонецЕсли;
Если МаксимумРазличий = Неопределено Тогда
МаксимумРазличий = МаксимальноеКоличествоРазличийМеждуСтрокамиТаблиц(Таблица1, Таблица2);
КонецЕсли;
ОбщиеКолонки = НайтиОбщиеКолонки(Таблица1, Таблица2);
ОстальныеКолонки = НайтиНесовпадающиеКолонки(Таблица1, Таблица2);
Для Каждого СтрокаТаблицы1 Из Таблица1.НайтиСтроки(Новый Структура(Пропустить, Ложь)) Цикл
Для Каждого СтрокаТаблицы2 Из Таблица2.НайтиСтроки(Новый Структура(Пропустить, Ложь)) Цикл
КоличествоРазличий = КоличествоРазличийВСтрокахТаблиц(СтрокаТаблицы1, СтрокаТаблицы2, ОбщиеКолонки, ОстальныеКолонки);
Если КоличествоРазличий = ТребуемоеКоличествоРазличий Тогда
СоответствиеСтрокТаблицы1СтрокамТаблицы2.Вставить(СтрокаТаблицы1.НомерСтроки, СтрокаТаблицы2.НомерСтроки);
СтрокаТаблицы1[Пропустить] = Истина;
СтрокаТаблицы2[Пропустить] = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Если СоответствиеСтрокТаблицы1СтрокамТаблицы2.Количество() < Таблица1.Количество() И Таблица2.НайтиСтроки(Новый Структура(Пропустить, Ложь)).Количество() > 0 Тогда
Если ТребуемоеКоличествоРазличий < МаксимумРазличий Тогда
НайтиПохожиеСтрокиТаблиц(Таблица1, Таблица2, ТребуемоеКоличествоРазличий + 1, МаксимумРазличий, СоответствиеСтрокТаблицы1СтрокамТаблицы2);
КонецЕсли;
КонецЕсли;
Возврат СоответствиеСтрокТаблицы1СтрокамТаблицы2;
КонецФункции
Функция СоответствиеСтрокТаблиц(Таблица1, Таблица2)
СоответствиеНомеровСтрок = НайтиПохожиеСтрокиТаблиц(Таблица1, Таблица2);
Результат = Новый Соответствие;
Для Каждого Элемент Из СоответствиеНомеровСтрок Цикл
Результат.Вставить(Таблица1[Элемент.Ключ - 1], Таблица2[Элемент.Значение - 1]);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция МаксимальноеКоличествоРазличийМеждуСтрокамиТаблиц(Таблица1, Таблица2)
МассивИменКолонокТаблицы1 = ПолучитьИменаКолонок(Таблица1);
МассивИменКолонокТаблицы2 = ПолучитьИменаКолонок(Таблица2);
МассивИменКолонокОбеихТаблиц = ОбъединениеМножеств(МассивИменКолонокТаблицы1, МассивИменКолонокТаблицы2);
ВсегоКолонок = МассивИменКолонокОбеихТаблиц.Количество();
Возврат ?(ВсегоКолонок = 0, 0, ВсегоКолонок - 1);
КонецФункции
Функция ОбъединениеМножеств(Множество1, Множество2)
Результат = Новый Массив;
Для Каждого Элемент Из Множество1 Цикл
Индекс = Результат.Найти(Элемент);
Если Индекс = Неопределено Тогда
Результат.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Для Каждого Элемент Из Множество2 Цикл
Индекс = Результат.Найти(Элемент);
Если Индекс = Неопределено Тогда
Результат.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция ПолучитьИменаКолонок(Таблица)
Результат = Новый Массив;
Для Каждого Колонка Из Таблица.Колонки Цикл
Результат.Добавить(Колонка.Имя);
КонецЦикла;
Возврат Результат;
КонецФункции
Функция КоличествоРазличийВСтрокахТаблиц(СтрокаТаблицы1, СтрокаТаблицы2, ОбщиеКолонки, ОстальныеКолонки)
Результат = ОстальныеКолонки.Количество();
Для Каждого ИмяКолонки Из ОбщиеКолонки Цикл
Если СтрокаТаблицы1[ИмяКолонки] <> СтрокаТаблицы2[ИмяКолонки] Тогда
Результат = Результат + 1;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция НайтиОбщиеКолонки(Таблица1, Таблица2)
МассивИмен1 = ПолучитьИменаКолонок(Таблица1);
МассивИмен2 = ПолучитьИменаКолонок(Таблица2);
Возврат ПересечениеМножеств(МассивИмен1, МассивИмен2);
КонецФункции
Функция НайтиНесовпадающиеКолонки(Таблица1, Таблица2)
МассивИмен1 = ПолучитьИменаКолонок(Таблица1);
МассивИмен2 = ПолучитьИменаКолонок(Таблица2);
Возврат РазностьМножеств(МассивИмен1, МассивИмен2, Истина);
КонецФункции
Функция РазностьМножеств(Множество1, Знач Множество2, СимметричнаяРазность = Ложь)
Результат = Новый Массив;
Множество2 = СкопироватьМассив(Множество2);
Для Каждого Элемент Из Множество1 Цикл
Индекс = Множество2.Найти(Элемент);
Если Индекс = Неопределено Тогда
Результат.Добавить(Элемент);
Иначе
Множество2.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Если СимметричнаяРазность Тогда
Для Каждого Элемент Из Множество2 Цикл
Результат.Добавить(Элемент);
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ПересечениеМножеств(Множество1, Множество2)
Результат = Новый Массив;
Для Каждого Элемент Из Множество1 Цикл
Индекс = Множество2.Найти(Элемент);
Если Индекс <> Неопределено Тогда
Результат.Добавить(Элемент);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Функция СкопироватьМассив(Источник)
Результат = Новый Массив(Источник.Количество());
Для Индекс = 0 По Источник.ВГраница() Цикл
Результат[Индекс] = Источник[Индекс];
КонецЦикла;
Возврат Результат;
КонецФункции
Функция РазличияСтрок(Строка1, Строка2, ПроверяемыеКолонки)
Результат = Новый Массив;
Для Каждого Колонка Из ПроверяемыеКолонки Цикл
Если ТипЗнч(Строка1[Колонка]) = Тип("ХранилищеЗначения") Тогда
Продолжить;
КонецЕсли;
Если Строка1[Колонка] <> Строка2[Колонка] Тогда
Результат.Добавить(Колонка);
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ПрогрессУдалениеПредупрежденийСинхронизации(Знач ТекущийШаг, Максимум, ИтераторВыборки = 0)
ТекущийШаг = ?(ТекущийШаг = 0, 1, ТекущийШаг);
Если ИтераторВыборки = 0 Тогда
Шаблон = НСтр("ru = 'Выполнено итераций %1 из %2'", ОбщегоНазначения.КодОсновногоЯзыка());
ТекстПрогресса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Шаблон, ТекущийШаг, Максимум);
Иначе
Шаблон = НСтр("ru = 'Выполнено итераций %1 из %2 (%3)'", ОбщегоНазначения.КодОсновногоЯзыка());
ТекстПрогресса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
Шаблон, ТекущийШаг, Максимум, ИтераторВыборки);
КонецЕсли;
ПроцентВыполнения = ОКР(ТекущийШаг * 100 / Максимум, 0);
ДлительныеОперации.СообщитьПрогресс(ПроцентВыполнения, ТекстПрогресса);
КонецПроцедуры
Процедура ОчиститьПредупрежденияВерсий(ПараметрыУдаления, ИмяСобытия) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ТипВерсииОбъекта", ПараметрыУдаления.ОтборТипыПредупрежденийВерсий);
Запрос.Текст =
"ВЫБРАТЬ
| РегистрВерсииОбъектов.Объект КАК ОбъектБлокировки,
| РегистрВерсииОбъектов.НомерВерсии КАК НомерВерсии
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК РегистрВерсииОбъектов
|ГДЕ
| РегистрВерсииОбъектов.ТипВерсииОбъекта В(&ТипВерсииОбъекта)
|ИТОГИ ПО
| ОбъектБлокировки";
СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(Запрос.Текст);
ОператорСхемыЗапроса = СхемаЗапроса.ПакетЗапросов[0].Операторы[0];
Если ПараметрыУдаления.ОтборУзловПланаОбмена.Количество() > 0 Тогда
ОператорСхемыЗапроса.Отбор.Добавить("АвторВерсии В(&ОтборУзловПланаОбмена)");
Запрос.УстановитьПараметр("ОтборУзловПланаОбмена", ПараметрыУдаления.ОтборУзловПланаОбмена);
КонецЕсли;
ЗначениеПараметраУдаления = ПараметрыУдаления.ОтборПоДатеВозникновения;
Если ЗначениеЗаполнено(ЗначениеПараметраУдаления) Тогда
ОператорСхемыЗапроса.Отбор.Добавить("ДатаВерсии МЕЖДУ &ДатаНачала И &ДатаОкончания");
Запрос.УстановитьПараметр("ДатаНачала", ЗначениеПараметраУдаления.ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ЗначениеПараметраУдаления.ДатаОкончания);
КонецЕсли;
Если ПараметрыУдаления.ТолькоСкрытыеЗаписи Тогда
ОператорСхемыЗапроса.Отбор.Добавить("ВерсияПроигнорирована = ИСТИНА");
КонецЕсли;
Запрос.Текст = СхемаЗапроса.ПолучитьТекстЗапроса();
ВыборкаОбъекты = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
КоличествоОбъектов = ВыборкаОбъекты.Количество();
Если КоличествоОбъектов < 1 Тогда
Возврат;
КонецЕсли;
Пропорция = ПараметрыУдаления.ОтборТипыПредупрежденийВерсий.Количество() / КоличествоОбъектов;
ИтераторВыборки = 0;
НаборЗаписейРезультаты = РегистрыСведений.ВерсииОбъектов.СоздатьНаборЗаписей();
Пока ВыборкаОбъекты.Следующий() Цикл
НачатьТранзакцию();
Попытка
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить("РегистрСведений.ВерсииОбъектов");
ЭлементБлокировкиДанных.УстановитьЗначение("Объект", ВыборкаОбъекты.ОбъектБлокировки);
БлокировкаДанных.Заблокировать();
НаборЗаписейРезультаты.Отбор.Объект.Установить(ВыборкаОбъекты.ОбъектБлокировки, Истина);
ВыборкаНомераВерсий = ВыборкаОбъекты.Выбрать();
Пока ВыборкаНомераВерсий.Следующий() Цикл
НаборЗаписейРезультаты.Отбор.НомерВерсии.Установить(ВыборкаНомераВерсий.НомерВерсии, Истина);
НаборЗаписейРезультаты.Записать(Истина);
КонецЦикла;
ИтераторВыборки = ИтераторВыборки + 1;
Если ОКР(ИтераторВыборки * Пропорция, 0) <> ОКР((ИтераторВыборки - 1) * Пропорция, 0) Тогда
ПараметрыУдаления.КоличествоОперацийТекущийШаг = ПараметрыУдаления.КоличествоОперацийТекущийШаг + 1;
КонецЕсли;
ПрогрессУдалениеПредупрежденийСинхронизации(ПараметрыУдаления.КоличествоОперацийТекущийШаг, ПараметрыУдаления.КоличествоОперацийМаксимум, ИтераторВыборки);
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение;
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПредыдущиеПредупрежденияОбменов(СведенияОВерсииОбъекта) Экспорт
ДопустимыеТипыПредупреждений = Новый Массив;
ДопустимыеТипыПредупреждений.Добавить(Перечисления.ТипыВерсийОбъекта.ПринятыеДанныеПоКоллизии);
ДопустимыеТипыПредупреждений.Добавить(Перечисления.ТипыВерсийОбъекта.НепринятыеДанныеПоКоллизии);
ДопустимыеТипыПредупреждений.Добавить(Перечисления.ТипыВерсийОбъекта.НепринятыйПоДатеЗапретаОбъектСуществуетВБазе);
ДопустимыеТипыПредупреждений.Добавить(Перечисления.ТипыВерсийОбъекта.НепринятыйПоДатеЗапретаОбъектНеСуществуетВБазе);
Попытка
Если ДопустимыеТипыПредупреждений.Найти(СведенияОВерсииОбъекта.ТипВерсииОбъекта) <> Неопределено Тогда
УдалитьПредыдущиеПредупрежденияОбменовПоТипу(СведенияОВерсииОбъекта, ДопустимыеТипыПредупреждений);
КонецЕсли;
Если НЕ ПустаяСтрока(СведенияОВерсииОбъекта.ПредупреждениеСинхронизации) Тогда
УдалитьПредыдущиеПредупрежденияОбменовПоКомментарию(СведенияОВерсииОбъекта);
КонецЕсли;
Исключение
ИмяСобытия = НСтр("ru = 'Обмен данными'", ОбщегоНазначения.КодОсновногоЯзыка());
ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Процедура УдалитьПредыдущиеПредупрежденияОбменовПоТипу(СведенияОВерсииОбъекта, ДопустимыеТипыПредупреждений)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Объект", СведенияОВерсииОбъекта.Объект);
Запрос.УстановитьПараметр("ТипВерсииОбъекта", СведенияОВерсииОбъекта.ТипВерсииОбъекта);
Если ЗначениеЗаполнено(СведенияОВерсииОбъекта.АвторВерсии)
И ТипЗнч(СведенияОВерсииОбъекта.АвторВерсии) <> Тип("СправочникСсылка.Пользователи") Тогда
Запрос.УстановитьПараметр("АвторВерсииУзел", СведенияОВерсииОбъекта.АвторВерсии);
Иначе
Запрос.УстановитьПараметр("АвторВерсииУзел", Неопределено);
КонецЕсли;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 10
| ВерсииОбъектов.Объект КАК Объект,
| ВерсииОбъектов.НомерВерсии КАК НомерВерсии
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.Объект = &Объект
| И ВерсииОбъектов.ТипВерсииОбъекта = &ТипВерсииОбъекта
| И (ВерсииОбъектов.АвторВерсии = &АвторВерсииУзел
| ИЛИ ВерсииОбъектов.АвторВерсии ССЫЛКА Справочник.Пользователи)
|
|УПОРЯДОЧИТЬ ПО
| ВерсииОбъектов.НомерВерсии";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Количество() > 0 Цикл
Пока Выборка.Следующий() Цикл
МенеджерЗаписи = СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Выборка.Объект;
МенеджерЗаписи.НомерВерсии = Выборка.НомерВерсии;
МенеджерЗаписи.Удалить();
КонецЦикла;
Если ТранзакцияАктивна() Тогда
Прервать;
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПредыдущиеПредупрежденияОбменовПоКомментарию(СведенияОВерсииОбъекта)
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Объект", СведенияОВерсииОбъекта.Объект);
Запрос.УстановитьПараметр("ПредупреждениеСинхронизации", СведенияОВерсииОбъекта.ПредупреждениеСинхронизации);
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 100
| ВерсииОбъектов.Объект КАК Объект,
| ВерсииОбъектов.НомерВерсии КАК НомерВерсии
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.Объект = &Объект
| И (ВЫРАЗИТЬ(ВерсииОбъектов.ПредупреждениеСинхронизации КАК СТРОКА(512))) = &ПредупреждениеСинхронизации
|
|УПОРЯДОЧИТЬ ПО
| ВерсииОбъектов.НомерВерсии";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Количество() > 0 Цикл
Пока Выборка.Следующий() Цикл
МенеджерЗаписи = СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = Выборка.Объект;
МенеджерЗаписи.НомерВерсии = Выборка.НомерВерсии;
МенеджерЗаписи.Удалить();
КонецЦикла;
Если ТранзакцияАктивна() Тогда
Прервать;
КонецЕсли;
Выборка = Запрос.Выполнить().Выбрать();
КонецЦикла;
КонецПроцедуры
Функция ПрефиксСлужебнойКолонки()
Возврат "Версионирование_";
КонецФункции
Функция ИмяКолонкиИдСтроки()
Возврат ПрефиксСлужебнойКолонки() + "ИдСтроки";
КонецФункции
Функция ИмяКолонкиМодификация()
Возврат ПрефиксСлужебнойКолонки() + "Модификация";
КонецФункции
Функция ИмяКолонкиИзменения()
Возврат ПрефиксСлужебнойКолонки() + "Изменения";
КонецФункции
Функция ИмяКолонкиТипЗначения()
Возврат ПрефиксСлужебнойКолонки() + "ТипЗначения";
КонецФункции
#КонецОбласти
#КонецЕсли