Имя: Пароль:
1C
1C 7.7
v7: Выбрать элементы справочника с одинаковым наименованием
0 Dimon1C
 
04.09.15
13:45
ТекстЗапроса = "
        |Номенклатура = Справочник.Номенклатура.ТекущийЭлемент;
        |НаименованиеНоменклатуры = Справочник.Номенклатура.Наименование;
        |Условие (НаименованиеНоменклатуры = ВыбНоменкратура);
        |Группировка Номенклатура без групп;
        |";    

Работает оооочень медленно, что делаю не так, надо быстро выбрать одинаковые значения?
1 Фокусник
 
04.09.15
14:00

////////////////////////////////////////////////////
//Поиск дублей (по наименованию) для текущего элемента справочника
//
Процедура глПроверкаДубликатаСправочника(Конт) Экспорт
    
    ТекКод=Конт.Код;
    ТекНаим=Конт.Наименование;
    
    Спр=СоздатьОбъект("Справочник."+Конт.Вид());
    
    ИспользоватьМедленныйВариант = 0;
    
    НачатьТранзакцию();
    Пока Спр.НайтиПоНаименованию(ТекНаим,0,1)=1 Цикл
        //если найден
        
        Если (СокрЛП(Спр.Наименование)=СокрЛП(ТекНаим))
        и    (СокрЛП(Спр.Код)<>СокрЛП(ТекКод)) Тогда
            Сообщить("Найден дубль: Код "+Спр.Код+", Наименование: '"+СокрЛП(Спр.Наименование)+"' в группе '"+СтрЗаменить(Спр.ПолноеНаименование(),"/"+СокрЛП(Спр.Наименование),"")+"'","!");
        КонецЕсли;                          
        
        Попытка
            Спр.Удалить(1);
        Исключение                
            //не повезло, заблокирован
            ИспользоватьМедленныйВариант = 1;
            Прервать;
        КонецПопытки;
        
        
    КонецЦикла;      
    
    Если ИспользоватьМедленныйВариант = 1 Тогда
        Спр=СоздатьОбъект("Справочник."+Конт.Вид());
        Если Спр.НайтиПоНаименованию(ТекНаим,0,1)=1 Тогда
            //если найден
            Спр.ВыбратьЭлементы();
            Пока Спр.ПолучитьЭлемент()=1 Цикл
                Если (СокрЛП(Спр.Наименование)=СокрЛП(ТекНаим))
                и    (СокрЛП(Спр.Код)<>СокрЛП(ТекКод)) Тогда
                    Сообщить("Найден дубль: Код "+Спр.Код+", Наименование: '"+СокрЛП(Спр.Наименование)+"' в группе '"+СтрЗаменить(Спр.ПолноеНаименование(),"/"+СокрЛП(Спр.Наименование),"")+"'","!");
                КонецЕсли;                          
            КонецЦикла;
        КонецЕсли;                          
    КонецЕсли;
    
    
    ОтменитьТранзакцию();
    
КонецПроцедуры      
2 ДенисЧ
 
04.09.15
14:02
select descr, count(*)
from $справочник.Номенклатура
group by desc
having count(*) > 1
3 Dimon1C
 
04.09.15
14:09
(1) Перебор двойной, сложность n в квадрате.
(2) А это как, я только по русски умею...
4 Dimon1C
 
04.09.15
14:13
Пока склоняюсь к методу - запихнуть в ТЗ в отсортированном виде по наименованию, а там уже искать.
5 Dimon1C
 
04.09.15
14:13
Просто странно почему запрос в (0) не работает по индексируемому полю Наименование, он должен вообще моментом выполняться.
6 ДенисЧ
 
04.09.15
14:16
(5) потому что он сравнение по наименованию делает...
7 PuhUfa
 
04.09.15
14:18
Зачем вообще условие в (0)?
8 lera01
 
04.09.15
14:26
Вывести в таблицу значений, добавить колонку, записать туда 1 и свернуть по наименованию с подсчетом итогов по этой колонке. Где>1 там дубли
9 akaBrr
 
04.09.15
14:33
10 Фокусник
 
04.09.15
16:09
(3) "Перебор двойной"

Посмотри внимательнее...
Выполняется поиск по наименованию (потом найденный элемент "удаляется" далее отмена транзации, т.е. удаления не будет, и поиск еще раз по наименованию).

Работает быстро. Это рабочий код из реальной базы, которой уже лет 10...

А перебор будет только в том случае, если элемент "удалить" нельзя - заблокирован каким-либо пользователем


Если ИспользоватьМедленныйВариант = 1 Тогда


;)

PS конечно, вариант из (1) не идет в сравнение с "прямыми запросами", но с прямыми запросами и вопроса в (0) не было бы ;)