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