Часто перед разработчиками 1С встает задача сравнить однотипные данные (например, справочники номенклатуры или контрагентов) из нескольких разных информационных баз. Сложность заключается в том, что количество этих баз может меняться: сегодня их три, а завтра — восемь. Создавать отчет в системе компоновки данных (СКД) с жестко прописанными соединениями для каждой таблицы — негибкий и трудоемкий путь.
В этой статье мы разберем универсальный и масштабируемый подход, который позволит создать в СКД отчет для сравнения данных из любого количества источников без необходимости переписывать запрос каждый раз.
Первая мысль, которая приходит в голову, — это соединить все таблицы в одном запросе с помощью ЛЕВОЕ СОЕДИНЕНИЕ. Однако при количестве таблиц больше двух условия соединения становятся очень громоздкими, особенно если сопоставление должно идти по нескольким полям (например, по ГУИДу, Коду или Наименованию). Такой запрос сложно читать, поддерживать, и он может работать неэффективно.
Правильный подход заключается в изменении самой структуры данных, подаваемых на вход СКД. Вместо нескольких таблиц мы подготовим одну общую таблицу, в которую соберем данные из всех источников. Главное — добавить в эту таблицу дополнительное поле-идентификатор, которое будет указывать, из какой именно базы пришла та или иная запись.
После такой подготовки задача сравнения сводится к простой группировке и подсчету с помощью агрегатных функций в СКД.
Этот этап выполняется до того, как СКД начнет строить отчет. Наша цель — создать `ТаблицуЗначений` или временную таблицу, которая будет содержать данные из всех сравниваемых баз. Эту таблицу мы затем передадим в СКД как Набор данных - объект.
Структура итоговой таблицы должна быть следующей:
Процесс заполнения этой таблицы выглядит так:
В результате у нас получится "длинная" таблица, где собраны все записи из всех баз. Эту таблицу и нужно передать в схему компоновки данных.
Теперь, когда у нас есть единый источник данных, вся логика сравнения реализуется в настройках СКД без сложных запросов. Запрос к набору данных-объекту будет предельно простым:
ВЫБРАТЬ
ИсходныеДанные.ГУИД,
ИсходныеДанные.Код,
ИсходныеДанные.Наименование,
ИсходныеДанные.ИмяБазы
ИЗ
&НашаИтоговаяТаблица КАК ИсходныеДанные
Дальнейшую магию сделаем в настройках отчета.
Чтобы сгруппировать записи, которые мы считаем идентичными, создадим вычисляемое поле. Оно будет служить уникальным ключом для сравнения.
Выразить(Код КАК Строка(50)) + Выразить(Наименование КАК Строка(150)) + Выразить(ГУИД КАК Строка(36))
Теперь все записи, у которых совпадают Код, Наименование и ГУИД, будут иметь одинаковое значение в поле УникальнаяКомбинация и попадут в одну группу.
Это ключевой момент нашего решения. Нам нужно посчитать, в скольких базах встречается каждая уникальная комбинация полей.
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ИмяБазы)
Эта агрегатная функция для каждой группы (сгруппированной по УникальнаяКомбинация) посчитает количество уникальных имен баз, в которых эта комбинация была найдена.
Осталось собрать все вместе на вкладке "Настройки".
Код, Наименование, ГУИД и наш ресурс КоличествоСовпадений.
ВЫБОР
КОГДА КоличествоСовпадений = &ОбщееКоличествоБаз
ТОГДА "Нет различий (данные совпадают во всех базах)"
ИНАЧЕ "Есть различия (данные отсутствуют или отличаются в некоторых базах)"
КОНЕЦ
Как это работает:
Если для какой-то уникальной комбинации кода, наименования и ГУИДа наш ресурс КоличествоСовпадений равен общему числу баз, это означает, что эта запись с абсолютно идентичными реквизитами присутствует во всех базах. Если же значение ресурса меньше, значит, в одной или нескольких базах эта запись либо отсутствует, либо имеет другие реквизиты (и, следовательно, попала в другую группу).
Таким образом, мы получили гибкий и универсальный отчет, который не зависит от количества источников данных. Вся логика реализована на уровне настроек СКД, а самая сложная часть — подготовка единой таблицы — вынесена в код и выполняется один раз перед формированием отчета.