v8: Функция сравнения двух объектов одного типа Ключевые слова: сравнение,справочник,документ,различия
Функция пока работает только со справочниками и документами.
Но этого более чем достаточно.
Результат возвращается в виде таблицы значений с колонками:
* Реквизит - имя реквизита
* ТабличнаяЧасть - имя табличной части
* НомерСтроки - номер строки табличной части
* Значение1, Значение2 - различающиеся значения реквизитов
* Разница - есть ли различия.
Указав параметр Разница=ложь, можно добиться, чтобы выдавался список всех реквизитов, даже одинаковых. Такая вариация может использоваться для разложения объекта в плоскую таблицу, если сравнивать его с самим собой.
Код:
Функция СравнитьДваОбъекта(О1, О2, Разница=истина) Экспорт
Перем Т;
Т=Новый ТаблицаЗначений();
Т.Колонки.Добавить("Реквизит");
Т.Колонки.Добавить("Значение1");
Т.Колонки.Добавить("Значение2");
Т.Колонки.Добавить("НомерСтроки");
Т.Колонки.Добавить("ТабличнаяЧасть");
Т.Колонки.Добавить("Разница");
Если ТипЗнч(О1)<>ТипЗнч(О2) Тогда
Возврат Неопределено;
КонецЕсли;
Ссылка1=О1.Ссылка;
Ссылка2=О2.Ссылка;
ЭтоСправочник=Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка1));
ЭтоДокумент=Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Ссылка1));
Если
ЭтоДокумент ИЛИ ЭтоСправочник
Тогда
МДО=Метаданные.НайтиПоТипу(ТипЗнч(Ссылка1));
СписокРеквизитов=Новый Массив();
Если ЭтоСправочник Тогда
СписокРеквизитов.Добавить("Наименование");
СписокРеквизитов.Добавить("ПометкаУдаления");
СписокРеквизитов.Добавить("Код");
Если МДО.Иерархический Тогда
СписокРеквизитов.Добавить("Родитель");
Если МДО.ВидИерархии = Метаданные.СвойстваОбъектов.ВидИерархии.ИерархияГруппИЭлементов Тогда
СписокРеквизитов.Добавить("ЭтоГруппа");
КонецЕсли;
КонецЕсли;
Если МДО.Владельцы.Количество() <> 0 Тогда
СписокРеквизитов.Добавить("Владелец");
КонецЕсли;
КонецЕсли;
Если ЭтоДокумент Тогда
СписокРеквизитов.Добавить("Дата");
СписокРеквизитов.Добавить("Номер");
СписокРеквизитов.Добавить("Проведен");
СписокРеквизитов.Добавить("ПометкаУдаления");
КонецЕсли;
Для Каждого МДР ИЗ МДО.Реквизиты Цикл
Реквизит=МДР.Имя;
СписокРеквизитов.Добавить(Реквизит);
КонецЦикла;
Для Каждого Реквизит Из СписокРеквизитов Цикл
Значение1=О1[Реквизит];
Значение2=О2[Реквизит];
Если Значение1<>Значение2 ИЛИ НЕ Разница Тогда
Стр=Т.Добавить();
Стр.Реквизит=Реквизит;
Стр.Значение1=Значение1;
Стр.Значение2=Значение2;
Стр.Разница=Значение1<>Значение2;
КонецЕсли;
КонецЦикла;
Для Каждого МДТЧ ИЗ МДО.ТабличныеЧасти Цикл
ИмяТЧ=МДТЧ.Имя;
ТЧ1=О1[ИмяТЧ];
ТЧ2=О2[ИмяТЧ];
Для Инд=0 По Макс(ТЧ1.Количество()-1,ТЧ2.Количество()-1) Цикл
Для Каждого МДРТЧ ИЗ МДТЧ.Реквизиты Цикл
Реквизит=МДРТЧ.Имя;
Если Инд>=ТЧ1.Количество() Тогда
Значение1=Неопределено;
Иначе
Значение1=ТЧ1[Инд][Реквизит];
КонецЕсли;
Если Инд>=ТЧ2.Количество() Тогда
Значение2=Неопределено;
Иначе
Значение2=ТЧ2[Инд][Реквизит];
КонецЕсли;
Если Значение1<>Значение2 ИЛИ НЕ Разница Тогда
Стр=Т.Добавить();
Стр.Реквизит=Реквизит;
Стр.Значение1=Значение1;
Стр.Значение2=Значение2;
Стр.НомерСтроки=Инд;
Стр.ТабличнаяЧасть=ИмяТч;
Стр.Разница=Значение1<>Значение2;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЕсли;
Возврат Т;
КонецФункции
Благодарен Плотнику, который дописал этот код для проверки наличия владельца и родителя у справочников |