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

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

1С: как найти дубли в табличной части документа

Практические способы найти одинаковые строки в табличной части документа 1С: визуальный поиск, отбор, запрос и обработка кода. Примеры и типичные ошибки.

Дубли в табличной части документа 1С — это повторяющиеся строки с одинаковой номенклатурой, контрагентом или другим ключевым реквизитом. Такие повторы приводят к завышенным суммам, двойному списанию со склада и ошибкам в отчётности. Найти их можно как стандартными средствами интерфейса, так и запросом или небольшой обработкой.

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

Что считать дублем и откуда они берутся

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

Типичные причины появления повторов: двойное нажатие кнопки «Добавить», копирование строк, загрузка из Excel или обмена, где один и тот же товар встречается в файле дважды, а также подбор товара без контроля уже добавленных позиций. В документах с большим числом строк (инвентаризация, перемещение) заметить повтор глазами почти невозможно.

Быстрый поиск дублей без программирования

Самый простой способ, доступный любому пользователю, — сортировка табличной части. Кликните правой кнопкой по таблице, выберите «Сортировать по возрастанию» для колонки «Номенклатура» (или другой ключевой). Одинаковые позиции встанут рядом, и повторы станут видны.

Второй вариант — отбор строк. Через меню таблицы выберите «Установить отбор и сортировку списка» (в типовых конфигурациях на управляемых формах эта команда есть в меню «Ещё» табличной части). Задайте конкретное значение номенклатуры: если после отбора видно больше одной строки — это дубль.

Для документов с сотнями строк удобно выгрузить табличную часть в табличный документ или Excel (через «Вывести список») и там применить условное форматирование повторяющихся значений. Это не требует прав и не меняет данные в базе.

Порядок действий в интерфейсе
  1. 1
    Откройте документ и перейдите на вкладку с табличной частью
  2. 2
    Отсортируйте таблицу по колонке с ключевым реквизитом (номенклатура, сотрудник)
  3. 3
    Проверьте соседние строки с одинаковым значением
  4. 4
    При необходимости установите отбор по конкретному значению
  5. 5
    Удалите лишние строки и перепроведите документ

Поиск дублей запросом

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

ВЫБРАТЬ

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

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

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

ИЗ

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

ГДЕ

Товары.Ссылка.Дата МЕЖДУ &НачПериода И &КонПериода

И Товары.Ссылка.Проведен

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

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

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

ИМЕЮЩИЕ

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

Запрос вернёт список документов и позиций, которые встречаются в табличной части более одного раза. Его можно выполнить в консоли запросов (внешней обработке) или встроить в отчёт. Условие по периоду и проведённости сокращает объём проверки и ускоряет выполнение.

Если дублем считается совпадение нескольких колонок (например, номенклатура + склад + серия), добавьте все эти поля в секцию СГРУППИРОВАТЬ ПО — тогда запрос будет искать именно полные совпадения по набору реквизитов.

Программная проверка через Свернуть() и перебор

Разработчику часто нужно проверить дубли в момент записи документа — например, в обработчике ПередЗаписью или ПриПроведении. Есть два рабочих приёма.

Первый — метод Свернуть(). Скопируйте табличную часть в таблицу значений, сверните по ключевой колонке с суммированием количества строк и сравните число строк до и после свёртки:

ТЗ = Объект.Товары.Выгрузить();

ТЗ.Колонки.Добавить("Счётчик");

ТЗ.ЗаполнитьЗначения(1, "Счётчик");

ТЗ.Свернуть("Номенклатура", "Счётчик");

Для Каждого СтрокаТЗ Из ТЗ Цикл

Если СтрокаТЗ.Счётчик > 1 Тогда

Сообщить("Дубль: " + СтрокаТЗ.Номенклатура);

КонецЕсли;

КонецЦикла;

Второй приём — соответствие для подсчёта вхождений. Оно работает быстрее на больших таблицах, потому что не копирует данные:

Счётчик = Новый Соответствие;

Для Каждого Строка Из Объект.Товары Цикл

Ключ = Строка(Строка.Номенклатура.УникальныйИдентификатор());

Счётчик[Ключ] = ?(Счётчик[Ключ] = Неопределено, 1, Счётчик[Ключ] + 1);

КонецЦикла;

Если проверка должна блокировать запись, вызывайте её в обработчике ОбработкаПроверкиЗаполнения и при обнаружении дублей устанавливайте Отказ = Истина с понятным сообщением пользователю, в какой строке проблема.

1c
ТЗ = Объект.Товары.Выгрузить(); ТЗ.Свернуть("Номенклатура", "Количество"); Если ТЗ.Количество() < Объект.Товары.Количество() Тогда Сообщить("Есть дубли"); КонецЕсли;

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

Если документ ещё не проведён, просто удалите лишние строки: выделите их и нажмите Delete или кнопку «Удалить». Это самый безопасный сценарий — движения по регистрам ещё не сформированы.

Если документ проведён, удаление строки изменит движения по регистрам: остатки склада, взаиморасчёты, проводки. Перед правкой проверьте, не попадает ли документ в закрытый период и не используется ли он в последующих документах (списаниях, корректировках, отчётах комитента). После правки перепроведите документ и проконтролируйте остатки.

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

Профилактика: как не допустить дубли

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

При загрузке из внешних файлов добавьте в обработку загрузки проверку: перед добавлением строки искать номенклатуру в уже загруженных строках методом Найти() по выгруженной таблице. Это дешевле, чем потом разбирать последствия двойного списания.

Для самописных документов реализуйте контроль в модуле объекта, как показано выше, и добавьте его в подписку на событие ОбработкаПроверкиЗаполнения — тогда проверка будет работать для всех документов нужного вида без доработки каждого.

Типичные ошибки
01
Проверка дублей только по наименованию строки: одинаковый товар под разными ссылками (дубли самого справочника) не будет найден — сравнивайте по ссылке, а не по представлению
02
Свертка исходной табличной части вместо копии: метод Свернуть() меняет данные, поэтому всегда работайте с Выгрузить()
03
Удаление дублей в проведённом документе без анализа связанных документов — ломаются корректировки и отчёты
04
Запрос без ограничения периода на большой базе — долгое выполнение и блокировки

Проверка результата

После устранения дублей убедитесь, что проблема решена полностью. Повторите запрос с группировкой — он должен вернуть пустой результат. Сверьте итоговую сумму документа с ожидаемой: если строки объединялись, сумма не должна измениться.

Для проведённых документов дополнительно проверьте регистры: сформируйте отчёт по остаткам склада или взаиморасчётам до и после правки на контрольном примере. Расхождение должно объясняться именно удалёнными строками, а не посторонними изменениями.

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

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

Повторный запрос с группировкой
Норма

Пустой результат — дублей нет

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

Остались строки с ЧислоСтрок > 1

Сумма документа
Норма

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

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

Сумма изменилась необъяснимо

Движения по регистрам
Норма

Изменились только по удалённым строкам

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

Затронуты другие документы или периоды

Итог

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

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

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

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

Добавьте все ключевые колонки в секцию СГРУППИРОВАТЬ ПО запроса (например, Номенклатура, Характеристика, Серия). В коде — сформируйте составной ключ, соединив значения колонок в строку, и считайте вхождения через соответствие.

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

Да. Сортировка, отбор и выгрузка списка в табличный документ требуют только права чтения документа. Запрос в консоли запросов также выполняется с правами на чтение.

Чем опасны дубли в табличной части?

При проведении каждая строка формирует движения: товар спишется дважды, задолженность покупателя удвоится, НДС исказится. В отчётах это проявится как расхождение остатков и сумм с первичными документами.

Как найти дубли сразу во всех документах базы?

Используйте запрос к табличной части конкретного вида документа с группировкой по ссылке и ключевому реквизиту. Для нескольких видов документов выполните запрос для каждого вида по очереди — объединить разные табличные части в одном запросе можно через ОБЪЕДИНИТЬ ВСЕ.

Почему Свернуть() не находит дубли, хотя строки одинаковые?

Метод сравнивает значения строго. Если в одной строке реквизит заполнен, а в другой пуст, или отличается хотя бы одна колонка из сворачиваемых, строки не объединятся. Проверьте, что сворачиваете именно по тем колонкам, которые определяют дубль.

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

Да, в обработчике ПередЗаписью выгрузите табличную часть, примените Свернуть() с суммированием количества и сумм, затем загрузите результат обратно методом Загрузить(). Учтите: это изменит состав строк без предупреждения пользователя, поэтому добавьте сообщение о выполненном объединении.