Вход | Регистрация


1С:Предприятие :: 1С:Предприятие 8 общая

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

Поиск дублей в табличной части документа
Я
   RasuLL
 
23.12.12 - 22:35
Документ записан. Как проверить есть ли в табличной части документа дубли, если есть то удалить и сообщить? Обшарила форумы ничего подходящего не нашла. Заранее благодарна за помощь.
 
 
   DrShad
 
1 - 23.12.12 - 22:36
запросом?
   RasuLL
 
2 - 23.12.12 - 22:37
(1) Запрос.Текст = "ВЫБРАТЬ
        |    Товары.Код
        |ИЗ
        |    ДокПоступление.Товары КАК Товары
        |
        |СГРУППИРОВАТЬ ПО
        |    Товары.Код";
?
   H A D G E H O G s
 
3 - 23.12.12 - 22:39
(2) Фотку?
   DrShad
 
4 - 23.12.12 - 22:45
да, без фотки никак
   RasuLL
 
5 - 23.12.12 - 22:46
какая еще фотка?
   H A D G E H O G s
 
6 - 23.12.12 - 22:46
Пол: Женский 

Какая, какая... Твоя.
   Armando
 
7 - 23.12.12 - 22:46
(5) с такими вопросами как (0) только топлес
   ОбычныйЧеловек
 
8 - 23.12.12 - 22:47
(5) месяц на форуме а обычи так и не узнала )
   Torquader
 
9 - 23.12.12 - 22:50
(2) Посчитать количество различных и выбрать те, которые больше 1.
   RasuLL
 
10 - 23.12.12 - 22:50
да тут одни джентльмены!
 
 Рекламное место пустует
   DrShad
 
11 - 23.12.12 - 22:51
(10) что не по-джентельменски?
   RasuLL
 
12 - 23.12.12 - 22:51
(9) можете привести пример?
   alexei366
 
13 - 23.12.12 - 22:53
Модам, вы неверно хотите это проверять перед записью документа?
   RasuLL
 
14 - 23.12.12 - 22:54
(13) нет, после записи
   ERWINS
 
15 - 23.12.12 - 22:55
"ВЫБРАТЬ
    |    Контрагенты.Код,
    |ИЗ
    |    Справочник.Контрагенты КАК Контрагенты
    |
    |СГРУППИРОВАТЬ ПО
    |    Контрагенты.Код
    |
    |ИМЕЮЩИЕ
    |    СУММА(1) > 1"
нечто
   alexei366
 
16 - 23.12.12 - 22:55
это не принципиально, то есть это должно выполняться в интерфейсе и пользователя сразу оповещать?
   RasuLL
 
17 - 23.12.12 - 22:57
(15) мне нужно проверить в таб. части, а это не то
   Torquader
 
18 - 23.12.12 - 22:57
После записи - смысл этой проверки ?
Или это будет проверяться потом, чтобы "зверям отвесить по полной" ?
   ERWINS
 
19 - 23.12.12 - 22:58
(16) думаю что  ОбработкаПроверкиЗаполнения
   Torquader
 
20 - 23.12.12 - 22:58
(17) А что мешает выбирать из табличной части ?
Открыли конструктор запросов и мышкуем по нужным полям.
   Torquader
 
21 - 23.12.12 - 23:00
(19) Если в ОбработкаПроверкаЗаполнения, то выгрузить табличную часть, добавить колонку - проставить единицу в неё, свернуть табличную часть, суммируя по колонке с единицей - ну и перебрать потом, чтобы пользователю сообщить, где он не прав.
   RasuLL
 
22 - 23.12.12 - 23:00
(20) знания, не знаю как это сделать...
   DrShad
 
23 - 23.12.12 - 23:02
(21) какой изврат
   RasuLL
 
24 - 23.12.12 - 23:03
(21)Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ
        |    Товары.Код
        |ИЗ
        |    НовыйДокПоступление.Товары КАК Товары
        |
        |СГРУППИРОВАТЬ ПО
        |    Товары.Код";
        Результат = Запрос.Выполнить();
        ТЗ = Новый ТаблицаЗначений;
        Результат.Выгрузить(ТЗ);
        
        ТЗ.ВыбратьСтроки();
        Пока ТЗ.ПолучитьСтроку()=1 Цикл
        ВыбратьСтроки();
        Пока ПолучитьСтроку()=1 Цикл
            Если (ТЗ.Код = Код)
            И (ТЗ.НомерСтроки<>НомерСтроки) Тогда
                Сообщить ("В строке №"+НомерСтроки+" имеется одинаковый код");
            КонецЕсли;
          КонецЦикла;
        КонецЦикла;
   alexei366
 
25 - 23.12.12 - 23:03
Я так думаю что ей нужно в событии формы "ПередЗаписьюНаСервер" организовать обход строк табличной части, в этом обходе данные текущей строки сравниваются с данными строк где номер строки больше текущего, и при совпадении создавать СообщениеПользователю в котором ссылаться на текущую строку, таким образом мы не только не запишем ошибочный документ, но и тыкнем пользователя носом.
   RasuLL
 
26 - 23.12.12 - 23:04
(25) все верно)
   alexei366
 
27 - 23.12.12 - 23:05
Вот моя умничка, я знал что вы никогда не скажите что хотите
   alexei366
 
28 - 23.12.12 - 23:05
Ну чтож пример кода придумать или сама?
   RasuLL
 
29 - 23.12.12 - 23:06
цель проверять на коды, если в строке имеются одинаковые коды элементов, то удалить их и сообщить об этих строках
   DrShad
 
30 - 23.12.12 - 23:06
(27) а не проще сворачивать по-умолчанию?
   RasuLL
 
31 - 23.12.12 - 23:07
(28) не получается у меня...((
   alexei366
 
32 - 23.12.12 - 23:09
DrShad эт идея, ток надо не сварачивать а в событии таблицы ОкончаниеРедактирования проверять на совпадение с другими строками , если да удалять эту и сообщить пользователю что он дурак
   alexei366
 
33 - 23.12.12 - 23:09
Модмозель, вы определитесь пока с вариантом исполнения, а примеры кода после фотографии (не всёж на халяву)
 
 
   alexei366
 
34 - 23.12.12 - 23:19
Мужики я сделал это!!!!!))))))))))))))
   DrShad
 
35 - 23.12.12 - 23:23
что ты сделал?
   alexei366
 
36 - 23.12.12 - 23:24
DrShad ты опоздал, фотка висела пару минут
   alexei366
 
37 - 23.12.12 - 23:27
Эх походу кто-то обиделся и примеры кода не нужны, ладно ещё 3 минуты посмотрю потом закрою страничку.
   ERWINS
 
38 - 23.12.12 - 23:29
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    ТЗ=Товары.Выгрузить();
    ТЗ.Сортировать("Товар, НомерСтроки");
    тов=неопределено;
    ст="";
    нтов=ложь;
    для каждого стр из ТЗ Цикл
        Если стр.Товар=тов тогда
            ст=ст+","+строка(стр.НомерСтроки);
            нтов=истина;
        Иначе
            Если нтов тогда
                Сообщение = Новый СообщениеПользователю;
                Сообщение.Текст = тов.Наименование+" содержиться в нескольких строках "+ст;
                Сообщение.Сообщить();
                отказ = истина;
            КонецЕсли;
            ст=строка(стр.НомерСтроки);
            нтов=Ложь;
            тов=стр.Товар;
        КонецЕсли;
        
    КонецЦикла;
    
    Если нтов тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = тов.Наименование+" содержиться в нескольких строках "+ст;
        Сообщение.Сообщить();
        отказ = истина;
    КонецЕсли;
    
КонецПроцедуры
   DrShad
 
39 - 23.12.12 - 23:32
(38) за такой код, человек его написавший уже бы не работал у нас, ничего личного, но не стоит учить плохому начинающих
   alexei366
 
40 - 23.12.12 - 23:33
ERWINS есть одно но, небудет подсветки на ошибочную строку если в модуле объекта.
   ОбычныйЧеловек
 
41 - 23.12.12 - 23:34
(38) а не проще выгрузить только колонку товары, добавить числовую колонку - запонить ее единичкой потом свернуть и там гле будет больше единицы вывести на экран...код в 3 строчки.
   ERWINS
 
42 - 23.12.12 - 23:35
(39) и чем плохо кроме имен переменных?
(40) тогда делать по другому, тоже не сложно
   DrShad
 
43 - 23.12.12 - 23:35
(41) зачем!? не проще сделать тоже самое запросом к ТЧ?
   Noroving
 
44 - 23.12.12 - 23:35
(32) Помоему самый верный вариант... зачем писать замудроватые запросы и усложнять запись документа... проще сразу проверять внесенные данные...
   DrShad
 
45 - 23.12.12 - 23:36
(42) например выгрузка в ТЗ и обход по ТЗ, а не сразу же по ТЧ
   alexei366
 
46 - 23.12.12 - 23:36
DrShad а как запрос делать к незаписанному объекту?
   ОбычныйЧеловек
 
47 - 23.12.12 - 23:36
(43) запрос будет работать при условии, что документ уже записан.
   ERWINS
 
48 - 23.12.12 - 23:36
(45) там вообще то сортировка...
сортировать табличную часть????
   DrShad
 
49 - 23.12.12 - 23:42
(48) а ее обязательно сортировать, чтоб найти дубли? имхо клюшечный код в снеговике
 
 Рекламное место пустует
   alexei366
 
50 - 23.12.12 - 23:43
ERWINS а как твой код отработает, если две совпадающие строки будут в конце таблицы?
   ERWINS
 
51 - 23.12.12 - 23:44
(49) что бы найти номера строк обязательно
   alexei366
 
52 - 23.12.12 - 23:44
а всё не посмотрел сначала.
   ERWINS
 
53 - 23.12.12 - 23:44
(50) да, проверил
   DrShad
 
54 - 23.12.12 - 23:45
(53) если уж ты получил ТЗ, то скорми ее запросу и получи все дубли в результат
   ERWINS
 
55 - 23.12.12 - 23:51
(54) зачем?
   kokamoonga
 
56 - 23.12.12 - 23:51
(48) извините за вопрос немного не по теме.
а почему нельзя сортировать табличную часть? судя по количеству вопросительных знаков в конце вашего возмущенного вопроса речь идет о чем-то предельно порочном и некрасивом...
   DrShad
 
57 - 23.12.12 - 23:52
(55) потому что сортировка ТЗ тормознутый метод
потому что дублей может и не быть, а цикл пройдет всю ТЗ и это тоже время
потому что так кошернее
   DrShad
 
58 - 23.12.12 - 23:53
(56) ее потом с оригиналом не удобно сверять, к примеру ввод ПТиУ
   ERWINS
 
59 - 23.12.12 - 23:56
(56) потому что я не знаю, можно ли произвольно в документе менять порядок строк.
Иногда это бывает черевато
   kokamoonga
 
60 - 23.12.12 - 23:57
(58) ну это первое и единственное, что пришло мне в голову да. просто такое количество вопросительных знаков... думал может за этим кроется что-то еще
   ERWINS
 
61 - 23.12.12 - 23:59
(60) просто я один раз так сделал, а потом объяснялся с лдьми из росалкоголя
   kokamoonga
 
62 - 23.12.12 - 23:59
(59) документ в котором нельзя меня порядок строк в табличной части это какой-то плохой документ как мне кажется. что-то есть неправильное в таком документе
   kokamoonga
 
63 - 24.12.12 - 00:02
(61) бред какой-то... но вобщем наши регулирующие органы никогда не были средоточием здравого смысла
   Noroving
 
64 - 24.12.12 - 00:20
модуль формы перед записью на сервере
ТЗДок = ТекущийОбъект.Товары.Выгрузить();

Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ
        |    Товары.Код
        |    КОЛИЧЕСТВО(Товары.Номенклатура) КАК КоличествоДублей
        |ИЗ
        |    &ТабличканяЧастьДок КАК Товары
        |
        |СГРУППИРОВАТЬ ПО
        |    Товары.Код";
 Запрос.УстановитьПараметр("ТабличканяЧастьДок",ТЗДок);
        Результат = Запрос.Выполнить();
       
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
Если Выборка.КоличествоДублей>1 Тогда
    Отбор = Новый Структура("Код", Выборка.Код);
НайденыеСтроки = ТекущийОбъект.Товары.НайтиСтроки(Отбор);
Если НайденыеСтроки.Количество()>0 Тогда
   Для Сч=1 По НайденыеСтроки.Количество()-1 Цикл
   Сообщение = Новый СообщениеПользователю;
   Сообщение.Текст = "Удалена строка с номенклатурой"+НайденыеСтроки[Сч].Номенклатура;
   Сообщение.Сообщить();

ТекущийОбъект.Товары.Удалить(НайденыеСтроки[Сч]);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
   Snovy
 
65 - 24.12.12 - 00:27
(0) Выгрузить ТЧ в ТЗ, свернуть ТЗ по колонкам, где могут быть дубли, сравнить количество строк свернутой ТЗ и оригинальной ТЧ. Если разошлись количества строк - значит есть дубли. А вот уже потом искать любыми производительными способами дубли и сообщать о них пользователю.

А то часто видел код проверки на дубли, который очень долго ищет их там, где их нет...
   Max Street
 
66 - 24.12.12 - 00:30
(0) Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Для Каждого ТекСтрока Из ТЧ Цикл
        ТекНоменклатура = ТекСтрока.Номенклатура;
        НомерСтрк = ТекСтрока.НомерСтроки;
        Для Каждого Стрк ИЗ ТЧ Цикл
            Если Стрк.Номенклатура = ТекНоменклатура И Стрк.НомерСтроки <> НомерСтрк Тогда 
                ТЧ.Удалить(Стрк);
                Сообщение = Новый СообщениеПользователю;
                Сообщение.Текст = "дубли строк очищены";
                Сообщение.Сообщить();
            КонецЕсли;    
        КонецЦикла;        
    КонецЦикла;
КонецПроцедуры
   ERWINS
 
67 - 24.12.12 - 00:34
&НаКлиенте
перем ЕстьДубликаты;

&НаКлиенте
Функция ПроверкаДубликатов()

    для каждого стр из Объект.Товары цикл
        стр.ДублирующаяСтрока=ложь;
    конецЦикла;
    
    МассивПервый=новый Массив;
    МассивВторой=новый Массив;
    
    для каждого стр из Объект.Товары цикл
        Если МассивПервый.Найти(стр.Товар)=неопределено тогда
            МассивПервый.Добавить(стр.Товар);
        иначеЕсли МассивВторой.Найти(стр.Товар)=неопределено тогда
            МассивВторой.Добавить(стр.Товар);
        КонецЕсли
    конецЦикла;
    
    для каждого стр из Объект.Товары цикл
        стр.ДублирующаяСтрока=не (МассивВторой.Найти(стр.Товар)=неопределено);
    КонецЦикла;
    
    ЕстьДубликаты=МассивВторой.Количество()>0;
    возврат ЕстьДубликаты;
КонецФункции// ПроверкаДубликатов()
 


&НаКлиенте
Процедура ТоварыПриИзменении(Элемент)
    ПроверкаДубликатов()
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ПроверкаДубликатов()
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
    Если ЕстьДубликаты тогда
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "В табличной части Товары есть дубликаты";
        Сообщение.Сообщить();
        отказ=истина;
    КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПриПовторномОткрытии()
    ПроверкаДубликатов()
КонецПроцедуры
   DrShad
 
68 - 24.12.12 - 00:34
(66) больше никому это не показывай
   ERWINS
 
69 - 24.12.12 - 00:35
(68) почему?
   Noroving
 
70 - 24.12.12 - 00:36
(66) Представляю что будет с таб частью в 50 строк... Можно записать документ и пойти пообедать)))
   DrShad
 
71 - 24.12.12 - 00:40
(69) во-первых двойной цикл
во-вторых удаление строк с нарушением выборки
   ERWINS
 
72 - 24.12.12 - 00:41
(71) где ты видишь удаление строк????
какой двойной цикл?
   Noroving
 
73 - 24.12.12 - 00:44
(71) Таки да, если это и будет работать, то только при обратном обходе.
(72) Не тупи, мы коментируем не твой код.
   ERWINS
 
74 - 24.12.12 - 00:46
(73) понял, извини
удаление строк в двойном цикле это минное поле
   DrShad
 
75 - 24.12.12 - 00:46
(74) иди уже отдыхать :)
   Dethmont
 
76 - 24.12.12 - 03:47
(64) Пока самый близкий вариант... Но опять же обход всей Табличной части (а если нету дублей?)
   Dethmont
 
77 - 24.12.12 - 03:50
Тоже самое но с условием в запросе
ТЗДок = ТекущийОбъект.Товары.Выгрузить();

Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ
        |    Товары.Код
        |    КОЛИЧЕСТВО(Товары.Номенклатура) КАК КоличествоДублей
        | Поместить ВТ
        |ИЗ
        |    &ТабличканяЧастьДок КАК Товары
        |
        |СГРУППИРОВАТЬ ПО
        |    Товары.Код";
        |;
        | Выбрать ВТ.Код
        |ИЗ ВТ КАК ВТ
        |ГДЕ ВТ.КоличествоДублей > 1
 Запрос.УстановитьПараметр("ТабличканяЧастьДок",ТЗДок);
        Результат = Запрос.Выполнить();
       
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
    Отбор = Новый Структура("Код", Выборка.Код);
    НайденыеСтроки = ТекущийОбъект.Товары.НайтиСтроки(Отбор);
Если НайденыеСтроки.Количество()>0 Тогда
   Для Сч=1 По НайденыеСтроки.Количество()-1 Цикл
   Сообщение = Новый СообщениеПользователю;
   Сообщение.Текст = "Удалена строка с номенклатурой"+НайденыеСтроки[Сч].Номенклатура;
   Сообщение.Сообщить();

ТекущийОбъект.Товары.Удалить(НайденыеСтроки[Сч]);
КонецЦикла;
КонецЕсли;
КонецЦикла;
   Dethmont
 
78 - 24.12.12 - 03:59
Или же примитив:
ТЗДок = ТекущийОбъект.Товары.Выгрузить();
ТЗДок.Колонки.Добавить("КоличествоДублей");
ТЗДок.ЗаполнитьЗначения(1,"КоличествоДублей");

ТЗДок.Свернуть("Номенклатура","КоличествоДублей");
Для каждого Стр Из ТЗДок Цикл
   Если Стр.КоличествоДублей > 1 тогда
      Отбор = Новый Структура("Номенклатура", Стр.Номенклатура);
    НайденыеСтроки = ТекущийОбъект.Товары.НайтиСтроки(Отбор);
Если НайденыеСтроки.Количество()>0 Тогда
   Для Сч=1 По НайденыеСтроки.Количество()-1 Цикл
   Сообщение = Новый СообщениеПользователю;
   Сообщение.Текст = "Удалена строка с номенклатурой"+НайденыеСтроки[Сч].Номенклатура;
   Сообщение.Сообщить();

ТекущийОбъект.Товары.Удалить(НайденыеСтроки[Сч]);
КонецЦикла;
КонецЕсли;
КонецЦикла;
   Infsams654
 
79 - 24.12.12 - 09:14
В типовой БГУ в ОбщегоНазначения есть Функция ЭтоСтрокаДубль(ТабЧасть, СтрокаТабЧасти, СтруктураРеквизитов)
   Serg_1960
 
80 - 24.12.12 - 09:40
(64) и (78) Прежде чем искать чёрную кошку в тёмной комнате хотелось бы убедиться, что она там есть.

ТЗ = ЭтотОбъект.Товары.Выгрузить();
ТЗ.ЗаполнитьЗначения(1,"НомерСтроки");
ТЗ.Свернуть("Номенклатура","НомерСтроки");

Если ЭтотОбъект.Товары.Количество() <> ТЗ.Количество() Тогда
   Собщить("Мадам, я дико извеняюсь, но у вас таки всё-таки есть проблема с дублями строк");
   Отказ = Истина;
   ...
КонецЕсли;
   Noroving
 
81 - 24.12.12 - 09:48
(77) Писал на ходу без отладок... так что уж извините...
А нащет этого  |ГДЕ ВТ.КоличествоДублей > 1
может я и ошибаюсь, но помоему сначало срабатывает отбор, а потом групировка, не???
   Ns33
 
82 - 24.12.12 - 10:58
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ПоступлениеТоваровТовары.НомерСтроки КАК НомерСтроки,
    ПоступлениеТоваровТовары.Номенклатура
ИЗ
    Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары1
        ПО ПоступлениеТоваровТовары.Номенклатура = ПоступлениеТоваровТовары1.Номенклатура
ГДЕ
    ПоступлениеТоваровТовары.Ссылка = &Ссылка
    И ПоступлениеТоваровТовары1.Ссылка = &Ссылка
    И ПоступлениеТоваровТовары.НомерСтроки <> ПоступлениеТоваровТовары1.НомерСтроки

УПОРЯДОЧИТЬ ПО
    НомерСтроки

Единственно, нужно сначала ТЧ во временную таблицу кинуть, чтобы 2 раза не читать, но для краткости пока без ВТ.
   ERWINS
 
83 - 24.12.12 - 11:20
(82) квадратичная зависимость... жесть, так нельзя
   ERWINS
 
84 - 24.12.12 - 11:23
Каждый раз гонять данные на скл и обратно не есть гуд, это дополнительная нагрузка и значительные задержки, правда практически константные, лучше уж делать только на одном уровне трехзвенки (случай ошибок особый)
   Ns33
 
85 - 24.12.12 - 11:26
(83) Конечно нельзя, ведь правильно это делать циклами и без запросов, и для полного счастья всё это на клиенте.
   ERWINS
 
86 - 24.12.12 - 11:32
(85) смотри (67)
   Ns33
 
87 - 24.12.12 - 11:35
(86) Так я про это и писал.
   ERWINS
 
88 - 24.12.12 - 11:36
(87) на мой взгляд лучший  вариант....
   Ns33
 
89 - 24.12.12 - 11:43
(88) А вот давай попросим знающих людей выбрать наилучший вариант из предложенных в данной теме. Если они сюда зайдут, конечно.
   ERWINS
 
90 - 24.12.12 - 11:45
(89) хотелось бы
   МихаилМ
 
91 - 24.12.12 - 12:11
(0)
вот эффективный алгоритм поиска дублей
Задача на поиск в массиве


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Тема не обновлялась длительное время, и была помечена как архивная. Добавление сообщений невозможно.
Но вы можете создать новую ветку и вам обязательно ответят!
Каждый час на Волшебном форуме бывает более 2000 человек.
Рекламное место пустует