Skip to content
Как найти дубли в справочнике (элементы совпадающие по названию) при помощи запроса в 1С?
Для этого необходимо получить выборку из этого справочника с названием и ссылкой.
Следующим шагом Вы группируете данную выборку по названию, а к полю «Ссылка» применяете функцию «Количество».
Тем самым вы узнаете, сколько с таким названием элементов справочника.
Но нас не интересуют «одиночные» элементы, т.е. те названия у которых одна ссылка. Поэтому необходимо использовать оператор «Имеющие», который применяем к функции «Количество», ставя условие что результат этой функции больше одного.
Например, как в этом запросе:
ВЫБРАТЬ
Товары.Наименование КАК Наименование,
КОЛИЧЕСТВО(Товары.Ссылка) КАК КоличествоДублей
ИЗ
Справочник.Товары КАК Товары
СГРУППИРОВАТЬ ПО
Товары.Наименование
ИМЕЮЩИЕ КОЛИЧЕСТВО(Товары.Ссылка) > 1
Результат его выполнения можно посмотреть на картинке ниже
Если Вы всё еще «плаваете» в конструкциях языка запросов, и у Вас вызывают трудности даже самые простые запросы, то рекомендую вам мой курс «Запросы в 1С от новичка до профи». Где эти и многие другие вопросы рассматриваются более подробно.
В чем особенность этого курса:
• Курс рассчитан на тех, кто не знаком с языком запросов в 1С;
• Учебный материал грамотно скомпонован и прост в освоении;
• Несколько десятков уроков;
• Полезные практические примеры;
• Все уроки изложены понятным и простым языком
Для моих читателей, купон на скидку 25%: hrW0rl9Nnx
Я стараюсь как можно чаще выпускать различные интересные бесплатные статьи и видеоуроки. Поэтому буду очень рад, если Вы поддержите мой проект перечислив любую сумму:
Можете перечислить любую сумму напрямую:
Яндекс.Деньги — 410012882996301
Web Money — R955262494655
Вступайте в мои группы:
Вконтакте: https://vk.com/1c_prosto
Фейсбуке: https://www.facebook.com/groups/922972144448119/
ОК: http://ok.ru/group/52970839015518
Твиттер: https://twitter.com/signum2009
Содержание:
1. Процесс поиска дублей в 1С, используя группировку
2. Поиск соединением таблиц в 1С
3. Поиск дублей как к4омбинации реквизитов
4. Использование библиотеки стандартных подсистем в типовых решениях 1С
Данная тема не нова, но подобные вопросы периодически возникают у начинающих программистов. Здесь приведены примеры работающих запросов в 1С.
1. Процесс поиска дублей в 1С, используя группировку
Первый запрос выбирает ИНН, которые встречаются более 1 раза и помещает их в виртуальную таблицу 1С.
Во втором запросе находим тех контрагентов, ИНН которых входит в виртуальную таблицу 1С, и готовим вывод с удобной группировкой.
2. Поиск соединением таблиц в 1С
Несмотря на изящность решения, такой запрос выполняется гораздо дольше, чем с группировкой в 1С 8,3.
Даже вариация первого варианта с соединением таблиц 1С выполняется дольше.
Тем не менее, это работает.
3. Поиск дублей как комбинации реквизитов
Например, ищем контрагентов, имеющих одинаковые ИНН и КПП.
Идея, аналогична первому варианту. Создаем виртуальную таблицу, содержащую повторяющиеся пары ИНН/КПП. Отбираем Контрагентов, у которых пара значений ИНН/КПП встречается в виртуальной таблице 1С. Готовим удобный вывод, добавляя ИТОГИ. Поле Ключ создано для удобства вывода итоговых строк.
4. Использование библиотеки стандартных подсистем в типовых решениях 1С
В типовых решениях используется Библиотека стандартных подсистем, в которой присутствует подсистема «Поиск и удаление дублей 1С».
Чаще всего пользователи используют одноименную обработку данной подсистемы, которая размещена в «Администрирование» (или «НСИ и Администрирование») → Обслуживание → Корректировка данных → Поиск и удаление дублей 1С».
Кстати, обработка работает, если найдено не более 1500 дублей. Если дублей слишком много, то придется подправить код обработки 1С.
К функциям подсистемы можно обращаться и программно. Они расположены в общем модуле ПоискИУдалениеДублей . Например:
Специалист компании ООО «Кодерлайн» Иван Горбунов.
Содержание:
1. Работа с консолью запросов
2. Добавление поиска по производителю
1. Работа с консолью запросов
Цель данной статьи – помочь начинающим разработчикам немного лучше разобраться с таким важным аспектом программирования на платформе 1С 8.3 как запросы.
Разберем на простом примере, как с помощью такого инструмента как консоль запросов найти дублирующие друг друга записи в справочнике 1С 8.3. Согласитесь, ведь зачем перегружать справочник лишними элементами, если у нас уже есть элемент с такими реквизитами.
Пример будет показан на самой простой конфигурации 1С 8.3. За основу была взята учебная конфигурация, с помощью которой специалисты сдают экзамен. После чего в справочнике номенклатура был добавлен дополнительный реквизит «Производитель». Теперь откроем режим предприятия, добавим в справочник «Номенклатура» по три дубля двух наименований (причем у двух из них будет также совпадать и производитель).
Откроем консоль запросов и для начала напишем следующий текст:
В данном запросе происходит группировка выборки по названию, а к полю «Ссылка» применяете функцию «Количество» 1С.
Тем самым узнаем, сколько с таким названием элементов справочника.
Но нас не интересуют «одиночные» элементы, т.е. те названия у которых одна ссылка. Поэтому необходимо использовать оператор «Имеющие», который применяем к функции «Количество», ставя условие что результат и вывод функции больше одного. Таким образом мы получили по три номенклатуры с одинаковым наименованием.
2. Добавление поиска по производителю
Теперь попробуем немного усложнить запрос. Добавили поиск и по производителю. Все что нужно сделать, это добавить в выборку поле «Производитель», и так же как и с наименованием сгруппировать по этому полю. В итоге запрос 1С 8.3 будет выглядеть следующим образом:
Теперь выполним его и проверим полученный результат:
Таким образом можно построить и гораздо более сложные запросы для поиска дублей. Нужно всего лишь добавить в выборку новое поле и сгруппировать.
Специалист компании «Кодерлайн»
Айдар Фархутдинов
Запрос на поиск дублей |
Я |
29.08.17 – 07:44
Добрый день!
Помогите пожалуйста разобраться с запросом.
Задача состоит в следующем. Мне надо проверить элементы выбранного справочника на наличие дублей по какому-нибудь конкретному полю (поле определяется из правил конвертации). Например – справочник “Номенклатура” синхронизация идет по полю “Код”. Мне нужно в виде дерева вывести все элементы справочника, у которых совпадает код. Пишу запрос, чтобы найти дубли по этому полю.
ВЫБРАТЬ СУММА(1) КАК КоличествоДублей, Номенклатура.Код ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.ЭтоГруппа = Ложь СГРУППИРОВАТЬ ПО Номенклатура.Код ИМЕЮЩИЕ СУММА(1) > 1
Выводит дублируемые элементы (их код).Как прицепить туда еще наименование, а лучше ссылку? И еще вопрос, как мне вывести запрос в виде дерева? Чтобы выглядело вот-так
Неуникальный код 1
Элемент1 КодЭлемента1
Элемент2 КодЭлемента2
Элемент3 КодЭлемента3
На примере:
0000001
Соль 0000001
Сахар 0000001
0000002
Мука 0000002
Хлеб 0000002
1 – 29.08.17 – 07:46
выбрать различные с группировкой код/наименование
2 – 29.08.17 – 07:51
Ой, запрос начальный выложил
ВЫБРАТЬ СУММА(1) КАК КоличествоДублей, Номенклатура.Код КАК Код ПОМЕСТИТЬ ВТ_дубли ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.ЭтоГруппа = ЛОЖЬ СГРУППИРОВАТЬ ПО Номенклатура.Код ИМЕЮЩИЕ СУММА(1) > 1 ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ Номенклатура.Код КАК Код, Номенклатура.Ссылка ИЗ ВТ_дубли КАК ВТ_дубли ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура ПО ВТ_дубли.Код = Номенклатура.Код СГРУППИРОВАТЬ ПО Номенклатура.Ссылка, Номенклатура.Код УПОРЯДОЧИТЬ ПО Номенклатура.Код
3 – 29.08.17 – 07:54
(2) Результат запроса выводит
Соль 0000001 Сахар 0000001
А как сделать, чтобы было так:
0000001 Соль 0000001 Сахар 0000001
4 – 29.08.17 – 07:55
ВЫБРАТЬ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Номенклатура.Ссылка) КАК КоличествоДублей,
Номенклатура.Код КАК Код
……
ИТОГИ ПО
Номенклатура.Код
5 – 29.08.17 – 07:56
(4) вот он сча скопирует и ничему не научится
6 – 29.08.17 – 07:56
=)
7 – 29.08.17 – 07:58
Посмотри в УТ11 или БП3.0 обработку Поиск и замена дублей
8 – 29.08.17 – 08:27
(4)
Не понял что это даст, это же просто выведет список кодов с их количеством в справочнике?
9 – 29.08.17 – 08:44
Виноват, неправильно понял вначале, исправил
10 – 29.08.17 – 08:46
Выбрать ВСЕДУБЛИ(Номенклатура.Ссылка)
из
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.ЭтоГруппа = Ложь
ничего придумывать не нужно
11 – 29.08.17 – 08:53
Ему в дереве нужно, тогда так ВСЕДУБЛИВДЕРЕВО(Номенклатура.Ссылка)
12 – 29.08.17 – 08:58
(2) тебе только добавить нужно
ИТОГИ ПО
Номенклатура.Код
И все.
13 – 29.08.17 – 09:00
(11) Ты забыл добавить
ВСЕДУБЛИВДЕРЕВОИМЕНЕМНУРАОИЕВА(Номенклатура.Ссылка)
14 – 29.08.17 – 09:01
(13) +очипятка
ВСЕДУБЛИВДЕРЕВОИМЕНЕМНУРАЛИЕВА
15 – 29.08.17 – 09:32
Эээ, стесняюсь спросить, а чем типовая обработка не подходит? Там очень хороший функционал.
16 – 29.08.17 – 09:40
(15) дык ему просто запрос нужно, как я понял.
и дерево постоить
ИМХО правильный ответ – ключевое слово “итоги”
и параметры метода “Выгрузить” результата запроса.
AlexeyVM
17 – 29.08.17 – 12:08
(15) Потому что это в дальнейшем там придется все усложнить. В итоге должна получиться обработка, которая проверит сразу все справочники на наличие дублей по полям, по которым идет синхронизация справочника в правилах обмена. И далее в виде дерева покажет все неуникальные элементы справочников. Ну и там в дальнейшем еще некоторые мелочи
Проверка на наличие дублирующихся строк в табличных частях
Время прочтения – 7 мин.
Получить бесплатную консультацию
Думаю, каждый программист рано или поздно сталкивался с подобной задачей: как реализовать проверку на наличие дублирующихся строк в табличных частях. Кому-то просто нужно проверить: есть, или нет, дубли. Кому-то нужно известить пользователя, и сообщить ему номера строк с дублями. Это вопросы будут рассмотрены в данной статье. Но давайте сразу определимся с терминологией: поля, по которым будет осуществляться контроль, назовем «ключевые».
Итак, предположим, что у нас стоит задача проверить наличие дублей строк табличной части по ключевым полям. Пусть это будет документ «Реализация товаров, услуг», дубли строк мы будем искать в табличной части «Товары», а в качестве ключевых полей будем использовать следующие реквизиты табличной части: Качество, Номенклатура, Склад, СерияНоменклатуры и ХарактеристикаНоменклатуры.
Рассмотрим следующие ситуации:
1) Проверка на наличие дублирующихся строк на уровне есть/нет.
Реализация ее будет выглядеть следующим образом:
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.Текст =
“ВЫБРАТЬ
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) КАК КоличествоДублей
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) > 1″;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Сообщить(“Имеются дубли строк!!!”);
КонецЕсли;
Здесь все достаточно просто. Обращаемся к данным табличной части документа, группируем по ключевым полям с использование агрегатной функции для подсчета количества номеров строк. Накладываем условие по вычисленному значению агрегатной функции. Все.
2) Классика жанра. Выведем в сообщении пользователю номера всех тех строк табличной части, которые являются дублями.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.Текст =
“ВЫБРАТЬ
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|;
| |////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.Качество КАК Качество,
| ТабЧасть.Номенклатура КАК Номенклатура,
| ТабЧасть.СерияНоменклатуры КАК СерияНоменклатуры,
| ТабЧасть.Склад КАК Склад,
| ТабЧасть.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ИЗ
| ВТ_ТабЧасть КАК ТабЧасть
|ГДЕ
| (ТабЧасть.Качество, ТабЧасть.Номенклатура, ТабЧасть.СерияНоменклатуры, ТабЧасть.Склад, ТабЧасть.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад”;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Выб_Качество = РезЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Качество.Следующий() Цикл
Выб_Номенклатура = Выб_Качество.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Номенклатура.Следующий() Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_СерияНоменклатуры.Следующий() Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Склад.Следующий() Цикл
Выборка = Выб_Склад.Выбрать();
ТекстСообщения = “”;
Пока Выборка.Следующий() Цикл
ТекстСообщения = ТекстСообщения + ?(ПустаяСтрока(ТекстСообщения), “”, “, “) + Выборка.НомерСтроки;
КонецЦикла;
ТекстСообщения = “Обнаружено дублирование строк: ” + ТекстСообщения; Сообщить(ТекстСообщения);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;КонецЕсли
Здесь все тоже не слишком сложно. Обратились к данным табличной части документа, поместили их во временную таблицу. Далее работаем со временной таблицей. Обращаемся к ней, отбираем те данные, по которым есть дубли (условие с использованием вложенного запроса). А далее, для того, чтобы сохранить все множество значений номеров строк, нам необходимо по ключевым полям объявить итоги. В таком случае в результате запроса, при использовании механизма итогов, появляются дополнительные строки, в которых хранится итог для того, или иного поля, а сам результат принимает иерархический вид, или вид дерева. Для того, чтобы вывести пользователю сообщение, нам нужно обойти результат запроса, и по каждому набору ключевых полей скомпоновать текст сообщения, и выдать его пользователю.
А теперь попробуем оценить перспективу доработки. Допустим, у нас изменился состав ключевых полей в сторону увеличения их количества: добавились ЕдиницаИзмерения и ЗаказПокупателя. Чтобы контроль дублей строк не перестал работать, нам нужно доработать запрос и обход результата запроса следующим образом:
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Ссылка);
Запрос.Текст =
“ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя КАК ЗаказПокупателя,
| ТабЧасть.Качество КАК Качество,
| ТабЧасть.Номенклатура КАК Номенклатура,
| ТабЧасть.СерияНоменклатуры КАК СерияНоменклатуры,
| ТабЧасть.Склад КАК Склад,
| ТабЧасть.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ИЗ
| ВТ_ТабЧасть КАК ТабЧасть
|ГДЕ
| (ТабЧасть.ЕдиницаИзмерения, ТабЧасть.ЗаказПокупателя, ТабЧасть.Качество, ТабЧасть.Номенклатура, ТабЧасть.СерияНоменклатуры, ТабЧасть.Склад, ТабЧасть.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры,
| ЕдиницаИзмерения”;
РезЗапроса = Запрос.Выполнить();
Если Не РезЗапроса.Пустой() Тогда
Выб_Качество = РезЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Качество.Следующий() Цикл
Выб_Номенклатура = Выб_Качество.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Номенклатура.Следующий() Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_СерияНоменклатуры.Следующий() Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_Склад.Следующий() Цикл
Выб_ХарактеристикаНоменклатуры = Выб_Склад.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_ХарактеристикаНоменклатуры.Следующий() Цикл
Выб_ЕдиницаИзмерения=Выб_ХарактеристикаНоменклатуры.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выб_ЕдиницаИзмерения.Следующий() Цикл
ТекстСообщения = “”;
Выборка = Выб_ЕдиницаИзмерения.Выбрать();
Пока
Подпишитесь на дайджест!
Подпишитесь на дайджест, и получайте ежемесячно подборку полезных статей.
3) Альтернативный вариант.
Реализация предыдущего варианта другим способом. Предлагаю использовать особенность запросов 1С, позволяющих обращаться к данным табличных частей, как к обычным полям выборки. Ну все-таки не совсем обычным, но все же полям выборки. Кроме того, нам придётся использовать не самый оптимальный способ соединения данных – декартово произведение. Почему так – опишу ниже.
ШаблонОшибки = “Табличная часть ‘Товары’: по реквизитам ‘Качество, Номенклатура, СерияНоменклатуры, Склад, ХарактеристикаНоменклатуры’ обнаружено дублирование строк ‘%1′”;
Запрос = Новый Запрос;
Запрос.УстановитьПараметр(“Ссылка”, Объект.Ссылка);
Запрос.Текст =
“ВЫБРАТЬ
| ТабЧасть.Ссылка,
| МИНИМУМ(ТабЧасть.НомерСтроки) КАК МинНомерСтроки,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ТабЧасть.Ссылка,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
| |ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) > 1
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.Ссылка,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| Док.Товары.(
| НомерСтроки,
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры
| ) КАК ДублиСтрок
|ИЗ
| (ВЫБРАТЬ
| Док.Товары.(
| НомерСтроки,
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры
| ) КАК Товары
| ИЗ
| Документ.РеализацияТоваровУслуг КАК Док
| ГДЕ
| Док.Ссылка = &Ссылка
| И (Док.Товары.Качество, Док.Товары.Номенклатура, Док.Товары.СерияНоменклатуры, Док.Товары.Склад, Док.Товары.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ)) КАК Док
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_ТабЧасть КАК ТабЧасть
| ПО (ИСТИНА)
|ГДЕ
| Док.Товары.Качество = ТабЧасть.Качество
| И Док.Товары.Номенклатура = ТабЧасть.Номенклатура
| И Док.Товары.СерияНоменклатуры = ТабЧасть.СерияНоменклатуры
| И Док.Товары.Склад = ТабЧасть.Склад
| И Док.Товары.ХарактеристикаНоменклатуры = ТабЧасть.ХарактеристикаНоменклатуры
|
|УПОРЯДОЧИТЬ ПО
| ТабЧасть.МинНомерСтроки,
| Док.Товары.НомерСтроки”;
ТЗ_Результат = Запрос.Выполнить().Выгрузить();
Для Каждого СтрТЗ Из ТЗ_Результат Цикл
Сообщить(СтрШаблон(ШаблонОшибки, СтрСоединить(СтрТЗ.ДублиСтрок.ВыгрузитьКолонку(“НомерСтроки”), “, “)));
КонецЦикла;
Главное отличие от предыдущего варианта: обход результата запроса осуществляется линейным способом. Т.е. при изменении состава ключевых полей меняется только текст запроса.
Несколько комментариев по поводу запроса.
Работа с табличными частями в качестве полей выборки накладывает ряд ограничений на выполнение запросов. Во-первых, это работа с временными таблицами. Т.е. нельзя помещать такие объекты во временные таблицы, но никто не мешает использовать вложенные запросы. Во-вторых, это соединения таблиц. Мне требовалось написать такой запрос, который бы возвратил мне наборы ключевых полей по которым имеются дубли, и многострочный объект, содержащий все строки с таким же набором ключевых полей. Обычные соединения (ВНУТРЕННЕЕ, ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ) возвращают всю табличную часть, что, в общем, правильно – для части объекта условие соединения же выполняется? Выполняется. Ну тогда и получите всю табличную часть. Искомый результат, как оказалось, достигается декартовым произведением. Мне как-то претит видеть в тексте запроса перечисление таблиц через запятую, поэтому я все декартовы произведения всегда реализую через «… СОЕДИНЕНИЕ … ПО (ИСТИНА)». Чтобы ограничить мсье Декарта в аппетитах (и повысить производительность), применяются дополнительные ограничения.
Теперь о производительности. Производились тестовые замеры каждого из вариантов на документе с большим количеством строк в табличной части. Количество строк в тестируемом документе: 47 817, 4 комбинации ключевых полей с дублями по 2, 2, 3 и 4 строки. Результаты замеров:
Вариант 1) 0:00:00.078 сек.
Вариант 2) 0:00:00.265 сек.
Вариант 3) 0:00:01.513 сек.
Как видим, третий вариант, как и ожидалось, самый медленный, но он же является самым удобным в перспективе модификации.
Прилагаемая обработка является демонстратором третьего варианта. Работает она и в обычном, и в управляемом режимах. Внешний вид и функционал полностью одинаков.
1) Выбираем вид объекта: Документ или Справочник.
2) Выбираем тип объекта: Какой именно документ или справочник.
3) Выбираем табличную часть объекта.
4) Определяем состав ключевых полей в специальном диалоге
5) Если мы хотим, то можем указать ссылку на объект, чтобы проверить его на наличие дублей.
6) Если активен флажок «Сгенерировать и показать код для проверки на дубли», то будет сгенерирован программный код для выполнения проверки на дубли строк с имеющимися настройками.
Автор статьи:
Эксперт по технологическим вопросам ИнфоСофт