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