• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

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

  • Автор темы Xauren
  • Дата начала
X

Xauren

В номенклатуре из 20к+ позиций есть дублирующие записи (по наименованию). Задача: нужно найти такие дублирущиеся по наименованию записи.

Сделал таким вот образом:

[codebox]
Спр=СоздатьОбъект("Справочник.Номенклатура");
Спр.ВыбратьЭлементы();
Пока Спр.ПолучитьЭлемент()=1 Цикл

Если (Спр.ПометкаУдаления()=1) ИЛИ (Спр.ЭтоГруппа()=1) Тогда
Продолжить;
КонецЕсли;

ТекТовар=Спр.ТекущийЭлемент();

Запрос=СоздатьОбъект("Запрос");
ТекстЗапроса="
|ДубТовар=Справочник.Номенклатура.ТекущийЭлемент;
|Условие (ДубТовар.Наименование=ТекТовар.Наименование);
|Условие (ДубТовар.Код<>ТекТовар.Код);
|Группировка ДубТовар Без Упорядочивания;
|";
...
[/codebox]

Вроде работает, но медленно. Подозреваю, что из-за начальной части, перебор долгий. Кто подскажет, как это можно ускорить, используя один запрос. И можно ли вообще ускорить?

Платформа - 7.7, конечно.
 
P

puh14

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

ТекстЗапроса="
|Товар=Справочник.Номенклатура.ТекущийЭлемент;
|Группировка ДубТовар Без Групп;
|Функция ЧислоВхождений = Счётчик(СокрЛП(Товар.Наименование));
|Условие(Товар.ЭтоГруппа() = 0) и (Товар.ПометкаУдаления() = 0)";

выгрузи в ТЗ и посмотри где счетчик больше 1 - это дубли.
 
X

Xauren

Хм. Спасибо. Что-то про функцию Счётчик() не подумал. Запустил, посмотрим, что быстрее. :)

Первый вариант ещё до сих пор со вчерашнего вечера не закончил работу. :) Правда, результаты показывает в процессе.
 
P

puh14

Попрбовал - гумно этот счетчик, пашет только для объектов БД, для строк и цыферок не пашет.

так пашет


Запрос = СоздатьОбъект("Запрос");

Текст="
|Без Итогов;
|Товар=Справочник.Номенклатура.текущийЭлемент;
|Имя = Справочник.Номенклатура.Наименование;
|Группировка Имя;
|Функция Сч = Счётчик();
|Условие(Товар.ЭтоГруппа() = 0);
|Условие(Товар.ПометкаУдаления() = 0);";

Запрос.Выполнить(Текст);
Запрос.Выгрузить(ТЗ);
Тз.Сортировать("+Сч,+Имя");

115 тыр номенклатуры за 5 минут. прямым запросом на скуле было-бы секунд 10. ;-)


хотя если совсем по честному - то надо ещё на СокрЛП закладываться (мож это и излишне, вроде как строковое поле до конца пробелами добивается, не помню точно). Завтра синтаксис кину.
 
X

Xauren

Угу, уже тоже разобрался. Примерно так и сделал.

Спасибо.
 
U

unknown181538

Еще вариант:
Избавляемся от вложенных циклов вследующим образом:
- делаем простой запрос по всем элементам;
- выгружаем в ТЗ;
- ТЗ Сортируем;
- в цикле по ТЗ сравнивае каждый элемент с предыдущим;

Если попробуете, очень интересно будет знать результаты)
 
V

vbs

Попрбовал - гумно этот счетчик, пашет только для объектов БД, для строк и цыферок не пашет.

так пашет
115 тыр номенклатуры за 5 минут. прямым запросом на скуле было-бы секунд 10. ;-)

Симпатичная идея. Только что у тебя за тачка? Я с секундомером проверил на своей - 24 секунды на справочнике из 50000 элементов -:)
 
P

puh14

Симпатичная идея. Только что у тебя за тачка? Я с секундомером проверил на своей - 24 секунды на справочнике из 50000 элементов

Два ксеона 2,4 ггц, 8 гигов оперативы и около 50 пользователей в терминалке. Наверно из-за пользователей ;-).
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!