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

Тема в разделе "1C и всё что с ней связано", создана пользователем Xauren, 29 окт 2009.

  1. Xauren

    Xauren Гость

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

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

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

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

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

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

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

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

    puh14 Well-Known Member
    1C Team

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

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

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

    Xauren Гость

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

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

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Попрбовал - гумно этот счетчик, пашет только для объектов БД, для строк и цыферок не пашет.

    так пашет


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

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

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

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


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

    Xauren Гость

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

    Спасибо.
     
  6. unknown181538

    unknown181538 НеГуру
    1C Team

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

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

    vbs Well-Known Member

    Регистрация:
    18 фев 2007
    Сообщения:
    1.708
    Симпатии:
    3
    Симпатичная идея. Только что у тебя за тачка? Я с секундомером проверил на своей - 24 секунды на справочнике из 50000 элементов -:)
     
  8. puh14

    puh14 Well-Known Member
    1C Team

    Регистрация:
    11 июл 2008
    Сообщения:
    1.412
    Симпатии:
    0
    Два ксеона 2,4 ггц, 8 гигов оперативы и около 50 пользователей в терминалке. Наверно из-за пользователей ;-).
     
Загрузка...

Поделиться этой страницей