Удаление дублей запросом

03.04.14

Разработка - Запросы

Удаляем дубли запросом (из его временной таблицы). Дубли определяем по набору полей сверки. Процедура для обычных форм.

Иногда возникает необходимость убрать дубли из результата запроса. Причём делать это хочется при помощи запроса - так быстрее (критично на больших объёмах данных).

Дубли имеются в виду частичные - т.е. это такие записи, где значения, скажем, по 3 полям совпадают (у двух или более записей), а по остальным полям - нет. Я назвал такие совпадающие поля условно "поля сверки дублей". В общем-то, их может быть сколько угодно - не обязательно именно 3.

Я написал процедуру, убирающую дубли запросом. Она принимает на входе временную таблицу запроса, из которой надо удалить дубли, список полей сверки дублей. Результат помещается в новую временную таблицу того же запроса. Опционально она может показать найденные дубли (и даже вывести их на экран в печатной таблице). Вот код этой процедуры:

Она проверена в 1С:Бухгалтерия 2.5, в ЗУП, возможно, потребуется исправить "ОбщегоНазначения" на "ОбщегоНазначенияЗК".

// Процедура удаления дублей из временной таблице запроса (только для обычных форм).

// Параметры:

// "Запрос" - запрос, содержащий временную таблицу, из которой надо удалить дубли.

// "ИмяВТВход" - имя временной таблицы запроса, из которой надо удалить дубли. Удаляется после проработки процедуры (как более не нужная).

// "ПоляСверкиДубля" - строка вида "Поле1,Поле2,Поле3", содержащая имена тех полей из "ИмяВТВход", по которым мы будем искать дубли.

// "ИмяВТВыход" - имя временной таблицы запроса, в которую помещается результат работы процедуры - т.е. "ИмяВТВход", откуда убрали все дубли.

// "ОставитьВТДубли" - оставить или нет временную таблицу с обнаруженными дублями после проработки процедуры. 

// "ПоказыватьДубли" - выводить или нет печатную таблицу с обнаруженными дублями.

// "ЗаголовокТаблицыДублей" - заголовок для печатной таблицы "ПоказыватьДубли".

Процедура УдалитьДублиВТ(Запрос, ИмяВТВход, ПоляСверкиДубля, ИмяВТВыход, ОставитьВТДубли = Ложь, ПоказыватьДубли = Ложь, ЗаголовокТаблицыДублей = "Таблица найденных дублей")
	//Прототип: http://www.forum.mista.ru/topic.php?id=550537
	
	МПСД = ОбщегоНазначения.РазложитьСтрокуВМассивПодстрок(ПоляСверкиДубля,",");
	
	ПоляЗапроса = "";
	
	ПоляСоединения = "";
	
	Для каждого Элем Из МПСД Цикл
		
		ПоляЗапроса = ПоляЗапроса + ИмяВТВход + "." + Элем + ", ";
		
		ПоляСоединения = ПоляСоединения + "(" + ИмяВТВход + "." + Элем + " = " + "ВТ_ДУБЛИ1." + Элем + ") И ";
	
	КонецЦикла;
	
	ПоляЗапроса = Лев(ПоляЗапроса, СтрДлина(ПоляЗапроса)-2);
	
	ПоляСоединения = Лев(ПоляСоединения, СтрДлина(ПоляСоединения)-3);
	
	Запрос.Текст = "ВЫБРАТЬ СУММА(1) КАК КоличествоДублей, " + ПоляЗапроса + " ПОМЕСТИТЬ ВТ_ДУБЛИ ИЗ " + ИмяВТВход + " КАК " + ИмяВТВход + 
	" СГРУППИРОВАТЬ ПО " + ПоляЗапроса + " ИМЕЮЩИЕ СУММА(1) > 1 ; ВЫБРАТЬ ВТ_ДУБЛИ.*, 1 КАК СтрокаДубля ПОМЕСТИТЬ ВТ_ДУБЛИ1 ИЗ ВТ_ДУБЛИ КАК ВТ_ДУБЛИ; ";
	
	Запрос.Текст = Запрос.Текст + "ВЫБРАТЬ " + ИмяВТВход + ".*, ЕСТЬNULL(ВТ_ДУБЛИ1.СтрокаДубля,0) КАК СтрокаДубля ПОМЕСТИТЬ ВТ_ВЫХОД ИЗ " + ИмяВТВход + " КАК " + ИмяВТВход +
	" ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДУБЛИ1 КАК ВТ_ДУБЛИ1 ПО " + ПоляСоединения + " ГДЕ ВТ_ДУБЛИ1.СтрокаДубля ЕСТЬ NULL";
	
	Запрос.Выполнить();
	
	Если ПоказыватьДубли Тогда
		
		ДанныеТаблицы = Новый Запрос;
		ДанныеТаблицы.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
		ДанныеТаблицы.Текст =
		"Выбрать 0 КАК НомерСтроки, *
		|    Из ВТ_ДУБЛИ
		|";
		
		ТЗДубли = ДанныеТаблицы.Выполнить().Выгрузить();
		
		Для Сч = 0 По ТЗДубли.Количество()-1 Цикл
			
			ТЗДубли[Сч].НомерСтроки = Сч + 1;
		
		КонецЦикла;
		
		Построитель=Новый ПостроительОтчета(); 
		Построитель.ИсточникДанных=Новый ОписаниеИсточникаДанных(ТЗДубли); 
		Построитель.ТекстЗаголовка = ЗаголовокТаблицыДублей;
		Построитель.Вывести();
		
	КонецЕсли; 
	
	ДанныеТаблицы = Новый Запрос;
	ДанныеТаблицы.МенеджерВременныхТаблиц = Запрос.МенеджерВременныхТаблиц;
	ДанныеТаблицы.Текст =
	"Выбрать ПЕРВЫЕ 1 *
	|    Из ВТ_ВЫХОД
	|";
	
	ТЗВыход = ДанныеТаблицы.Выполнить().Выгрузить();	
	
	ПоляЗапроса = "";
	
	Для каждого Колонка Из ТЗВыход.Колонки Цикл
		
		Если Колонка.Имя <> "СтрокаДубля" Тогда
			
			ПоляЗапроса = ПоляЗапроса + Колонка.Имя + ", ";
		
		КонецЕсли;
	
	КонецЦикла; 
	
	ПоляЗапроса = Лев(ПоляЗапроса, СтрДлина(ПоляЗапроса)-2);
	
	Запрос.Текст = "ВЫБРАТЬ " + ПоляЗапроса + " ПОМЕСТИТЬ " + ИмяВТВыход + " ИЗ ВТ_ВЫХОД; УНИЧТОЖИТЬ " + ИмяВТВход + 
	"; УНИЧТОЖИТЬ ВТ_ВЫХОД; УНИЧТОЖИТЬ ВТ_ДУБЛИ1";
	
	Если НЕ ОставитьВТДубли Тогда
		
		Запрос.Текст = Запрос.Текст + "; УНИЧТОЖИТЬ ВТ_ДУБЛИ";
	
	КонецЕсли;
	
	Запрос.Выполнить();	
	
КонецПроцедуры

Вступайте в нашу телеграмм-группу Инфостарт

Удаление дублей запросом

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

10000 руб.

02.09.2020    268170    1495    421    

1179

Инструментарий разработчика Запросы Программист 1С 8.3 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Структура запроса. Обработка визуально показывает, из какого количества подзапросов состоит запрос.

2 стартмани

06.07.2026    3374    45    XSlava    20    

44

Запросы Программист 1С 8.3 Россия Бесплатно (free)

Визуальный «Конструктор запроса» 1С, встроенный прямо в VS Code, — аналог конструктора из Конфигуратора и EDT, но без запуска платформы. Расширение читает конфигурацию, выгруженную в файлы, позволяет собрать запрос мышью и генерирует корректный текст на языке запросов 1С (SDBL). Открывает уже существующий текст запроса из кода для правки и — что особенно ценно — сохраняет комментарии при цикле «открыть - править - сохранить». Подходит тем, кто пишет код 1С в VS Code, держит под рукой множество проектов и не хочет ради одного запроса запускать тяжёлый Конфигуратор или EDT.

26.06.2026    7264    Alex_YAM    5    

33

WEB-интеграция Запросы Программист 1С 8.3 Абонемент ($m)

Post1C - это внешняя обработка, которая превращает 1С в полноценный инструмент для тестирования REST API. Всё управление сосредоточено в одном окне: настройка запроса, выполнение, просмотр ответа и генерация кода - без переключения между формами. Аналог Postman, но работающий в привычной среде 1С.

1 стартмани

02.04.2026    2981    82    priem_nv    24    

66

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    12069    155    zup_dev    32    

86

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

05.03.2025    6863    24    XilDen    12    

29

Обновление 1С Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

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

3 стартмани

06.02.2025    6132    37    XilDen    26    

42
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. mikhailovaew 127 14.04.14 16:27 Сейчас в теме
зачем так сложно? если дубли не нужны, пишем ВЫБРАТЬ РАЗЛИЧНЫЕ
Alex Star; +1 Ответить
2. prodines 107 17.04.14 15:41 Сейчас в теме
(1) mikhailovaew, в этом случае будут убраны лишь дублирующиеся записи, а дубли - нет. Это разные вещи.

Дубль - это множество записей с одинаковыми полями сверки, всегда содержащее как минимум 2 элемента (на то они и есть дубли, что их больше одного). Дублей в выборке может быть сколько угодно.

Ваш вариант в каждом дубле оставит одну запись, а остальные (дублирующиеся) уберёт. Мой вариант в каждом дубле не оставит ни одной записи.
Для отправки сообщения требуется регистрация/авторизация