К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как найти дубли в запросе 1С

Практические способы найти дубли в запросе 1С: группировка с HAVING КОЛИЧЕСТВО, соединение таблицы с самой собой, поиск дублей в справочниках и регистрах с примерами кода.

Дубли в данных 1С — частая проблема: одинаковые контрагенты, повторные элементы справочников, задвоенные строки в регистрах. Язык запросов 1С позволяет находить такие повторы несколькими способами, и выбор конкретного зависит от задачи: нужен список дублирующихся значений, полные записи-дубли или вариант «оставить одну, показать остальные».

Базовый инструмент — группировка с агрегатной функцией КОЛИЧЕСТВО и отбором по секции ИМЕЮЩИЕ (HAVING). Для сложных случаев применяют соединение таблицы с самой собой, временные таблицы и различие строк по уникальному идентификатору.

Ниже разобраны рабочие приёмы с примерами кода, которые можно адаптировать под любую конфигурацию — от поиска дублей контрагентов по ИНН до контроля задвоенных движений в регистрах.

Поиск дублирующихся значений через группировку и ИМЕЮЩИЕ

Самый простой сценарий — определить, какие значения встречаются в таблице больше одного раза. Для этого поля, образующие «ключ дубля», перечисляют в секции СГРУППИРОВАТЬ ПО, а в секции ИМЕЮЩИЕ ставят условие на количество строк в группе.

ВЫБРАТЬ

Контрагенты.ИНН КАК ИНН,

КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ИНН <> ""

СГРУППИРОВАТЬ ПО

Контрагенты.ИНН

ИМЕЮЩИЕ

КОЛИЧЕСТВО(*) > 1

Результат покажет только сами дублирующиеся значения и число повторов, но не конкретные элементы справочника. Обратите внимание на отбор по непустому ИНН: без него все элементы с пустым реквизитом сгруппируются в одну большую «дубль-группу» и исказят картину.

Ключ дубля может быть составным: например, ИНН + КПП или Наименование + ИНН. Чем больше полей в группировке, тем строже критерий совпадения и тем меньше ложных срабатываний, но выше риск пропустить реальные дубли с опечатками в одном из полей.

Как получить сами записи-дубли, а не только значения

Группировка теряет ссылки на конкретные элементы. Чтобы вывести полный список записей-дублей (например, всех контрагентов с повторяющимся ИНН), результат группировки помещают во временную таблицу и соединяют её с исходной таблицей по ключу дубля.

ВЫБРАТЬ

Контрагенты.ИНН КАК ИНН

ПОМЕСТИТЬ ДублирующиесяИНН

ИЗ

Справочник.Контрагенты КАК Контрагенты

ГДЕ

Контрагенты.ИНН <> ""

СГРУППИРОВАТЬ ПО

Контрагенты.ИНН

ИМЕЮЩИЕ

КОЛИЧЕСТВО(*) > 1

;

ВЫБРАТЬ

Контрагенты.Ссылка КАК Ссылка,

Контрагенты.Наименование КАК Наименование,

Контрагенты.ИНН КАК ИНН

ИЗ

Справочник.Контрагенты КАК Контрагенты

ВНУТРЕННЕЕ СОЕДИНЕНИЕ ДублирующиесяИНН КАК Дубли

ПО Контрагенты.ИНН = Дубли.ИНН

УПОРЯДОЧИТЬ ПО

ИНН, Наименование

Такой пакетный запрос возвращает все элементы, у которых есть «близнецы», сгруппированные по значению дубля благодаря сортировке. Это удобно для последующей ручной обработки или выгрузки в табличный документ.

Временная таблица живёт в пределах одного пакета запроса. Если менеджер временных таблиц не нужен дальше, после использования её можно удалить командой УНИЧТОЖИТЬ, чтобы не расходовать память сервера СУБД.

Порядок действий
  1. 1
    Определите ключ дубля: одно поле или комбинацию полей
  2. 2
    Напишите запрос с группировкой и ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1, исключив пустые значения
  3. 3
    Поместите ключи дублей во временную таблицу
  4. 4
    Соедините временную таблицу с исходной и выведите ссылки и нужные реквизиты
  5. 5
    Проверьте результат на копии базы или в консоли запросов

Поиск дублей через соединение таблицы с самой собой

Альтернативный приём — самосоединение: таблица соединяется сама с собой по совпадению ключа дубля и неравенству ссылок. Это позволяет сразу получать пары «элемент — его дубль».

ВЫБРАТЬ

Таб1.Ссылка КАК Элемент,

Таб2.Ссылка КАК Дубль,

Таб1.ИНН КАК ИНН

ИЗ

Справочник.Контрагенты КАК Таб1

ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Таб2

ПО Таб1.ИНН = Таб2.ИНН

И Таб1.Ссылка < Таб2.Ссылка

ГДЕ

Таб1.ИНН <> ""

Условие «Таб1.Ссылка < Таб2.Ссылка» выполняет две функции: исключает соединение строки с самой собой и убирает зеркальные пары (А–Б и Б–А). Сравнение ссылок оператором «меньше» в запросах 1С допустимо и работает по внутреннему представлению ссылки.

Минус подхода — декартово произведение внутри групп дублей: при трёх одинаковых элементах получится три пары, при десяти — сорок пять. На больших таблицах с массовыми дублями это заметно нагружает СУБД, поэтому для первичной оценки масштаба проблемы лучше сначала выполнить группировку с подсчётом.

Сравнение вариантов

Группировка + ИМЕЮЩИЕ

Быстро и дёшево по ресурсам, но возвращает только ключи дублей без ссылок. Подходит для оценки масштаба.

Временная таблица + соединение

Даёт полные записи-дубли, требует пакетного запроса. Оптимальный вариант для обработок исправления данных.

Самосоединение по парам

Удобно для попарного сопоставления, но порождает много строк при множественных дублях и тяжелее для СУБД.

Дубли в табличных частях и регистрах

В табличных частях документов дубль обычно означает повтор строки с одинаковым набором ключевых реквизитов — например, одна и та же номенклатура дважды в одном документе. Ключ группировки строится из ссылки на документ и реквизитов строки.

ВЫБРАТЬ

Товары.Ссылка КАК Документ,

Товары.Номенклатура КАК Номенклатура,

КОЛИЧЕСТВО(*) КАК ЧислоСтрок

ИЗ

Документ.РеализацияТоваровУслуг.Товары КАК Товары

СГРУППИРОВАТЬ ПО

Товары.Ссылка,

Товары.Номенклатура

ИМЕЮЩИЕ

КОЛИЧЕСТВО(*) > 1

В регистрах сведений с режимом «Периодический» или «Непериодический» дубли по измерениям технически невозможны на уровне платформы — уникальность обеспечивается ключом записи. А вот в регистрах накопления и бухгалтерии «дубль» — понятие прикладное: например, два одинаковых движения от разных документов там, где ожидалось одно. Такие ситуации ищут группировкой по набору аналитик с подсчётом суммы или количества записей.

При анализе движений учитывайте отбор по периоду и организации: полный оборот регистра за всё время на крупной базе — тяжёлая операция. Всегда ограничивайте выборку условием ГДЕ по периоду и, если возможно, по регистратору.

Нечёткие дубли и типичные ошибки

Точное совпадение по реквизитам не находит дубли с опечатками: «ООО Ромашка» и «ООО "Ромашка"» для запроса — разные значения. Для нечёткого поиска в запросе доступны только грубые приёмы: сравнение по ИНН/КПП, по нормализованному наименованию (без пробелов и кавычек, подготовленному заранее в отдельном реквизите) или по подстроке через ПОДОБНО. Полноценный нечёткий поиск обычно делают в коде встроенного языка или штатной обработкой «Поиск и удаление дублей» из состава БСП.

Частые ошибки при написании таких запросов: забытый отбор пустых значений ключа, сравнение наименований с учётом регистра и лишних пробелов, использование КОЛИЧЕСТВО(Поле) вместо КОЛИЧЕСТВО(*) — если поле может быть NULL, счётчик занизится. Ещё одна ошибка — попытка найти дубли по полям, которые различаются по типу данных в разных строках виртуальной таблицы.

Типичные ошибки
01
Не отфильтрованы пустые значения ключа — тысячи элементов без ИНН схлопываются в одну группу дублей
02
Сравнение наименований как есть — дубли с опечатками и лишними пробелами не находятся
03
КОЛИЧЕСТВО(Поле) вместо КОЛИЧЕСТВО(*) — строки с NULL в поле не учитываются
04
Самосоединение без условия неравенства ссылок — каждая строка соединяется сама с собой, результат удваивается
05
Запуск тяжёлого запроса на рабочей базе без ограничения периода — блокировки и жалобы пользователей

Проверка результата и дальнейшие действия

После выполнения запроса убедитесь, что найденные пары — действительно дубли, а не разные сущности с совпадающим признаком. Например, одинаковый ИНН у обособленных подразделений — норма, а вот у независимых контрагентов — повод для разбора. Выборочно откройте несколько элементов из результата и сравните их карточки и связанные документы.

Для исправления данных не удаляйте дубли прямым запросом — в 1С это невозможно штатно и опасно концептуально: на элементы ссылаются документы и регистры. Правильный путь — обработка замены ссылок (в типовых конфигурациях на БСП это «Поиск и удаление дублей»), которая переносит ссылки на выбранный «правильный» элемент и помечает дубли на удаление.

Контрольные точки

Как проверить результат

Число групп дублей
Норма

Соответствует ожиданиям по предметной области

Тревожный признак

Подозрительно много групп — вероятно, в ключ попали пустые или служебные значения

Состав пар
Норма

Элементы пары действительно описывают один объект

Тревожный признак

В паре разные сущности с совпадающим реквизитом — ключ дубля выбран неверно

Ссылки на элементы
Норма

По дублям есть документы, ссылки переносимы

Тревожный признак

Дубль используется в закрытых периодах — замена ссылок потребует корректировки учёта

Итог

Что важно запомнить

Дубли ищут группировкой с ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1, полные записи получают через временную таблицу и соединение, пары — самосоединением. Всегда исключайте пустые ключи, проверяйте запрос на копии базы, а исправляйте дубли штатной заменой ссылок, а не удалением.

Частые вопросы

Можно ли найти дубли без программирования?

Да. В типовых конфигурациях на базе Библиотеки стандартных подсистем есть обработка «Поиск и удаление дублей» (раздел «Администрирование» — «Обслуживание»). Она ищет дубли справочников по настраиваемым правилам, включая нечёткое сравнение наименований, и умеет автоматически заменять ссылки.

Как найти дубли сразу по нескольким полям?

Перечислите все поля ключа в секции СГРУППИРОВАТЬ ПО через запятую — группа будет образована комбинацией значений. Условие ИМЕЮЩИЕ КОЛИЧЕСТВО(*) > 1 останется тем же. Помните: совпадение должно быть по всем полям одновременно.

Почему запрос находит дубли, которых «нет» в списке справочника?

Чаще всего причина в помеченных на удаление элементах — запрос видит их наравне с обычными. Добавьте в условие ГДЕ отбор «НЕ ПометкаУдаления», если помеченные элементы не интересуют. Также проверьте, не включены ли в выборку предопределённые или недействующие элементы.

Как оставить один элемент, а остальные показать как лишние?

Определите «главный» элемент группы агрегатом — например, МИНИМУМ(Ссылка) или МАКСИМУМ(ДатаСоздания) — во временной таблице с группировкой по ключу дубля. Затем соедините её с исходной таблицей по ключу и условием неравенства ссылки главному элементу: в результат попадут только «лишние» записи.

Работает ли ПОДОБНО для поиска похожих наименований?

Оператор ПОДОБНО поддерживает шаблоны с символом «%» и позволяет находить вхождения подстроки, но это не нечёткий поиск: перестановки слов, опечатки и сокращения он не ловит. Для таких задач предварительно нормализуйте наименования в отдельном реквизите или используйте обработку с алгоритмами сравнения строк во встроенном языке.

Можно ли искать дубли в динамическом списке формы?

Напрямую динамический список не группирует с ИМЕЮЩИЕ в произвольном режиме так, как пакетный запрос. Практичнее выполнить запрос программно, поместить результат в таблицу значений и показать её на форме, либо использовать отбор динамического списка по списку ссылок, полученному заранее.