Таблица значений, быстрое удаление дублей строк

15 Comments

  1. kapustinag

    И какая получилась производительность? С какими вариантами сравнивали?

    Reply
  2. q_i

    Для Каждого Колонка Из БуфернаяТаблицаДанных.Колоники Цикл

    Reply
  3. bulpi

    Нужно пару слов про идею и алгоритм написать, а не только текст процедуры. Чем Ваш вариант лучше того, что я сейчас сяду и напишу за 10 минут на коленке?

    Reply
  4. CagoBHuK

    Алгоритм писателя на 1С 77. Проще всего:

    ВЫБРАТЬ * ПОМЕСТИТЬ ВременнаяТаблица ИЗ &Таблица КАК ВременнаяТаблица;

    ВЫБРАТЬ РАЗЛИЧНЫЕ * ИЗ ВременнаяТаблица

    Reply
  5. Vorobyov

    Можно использовать и запрос, спорить не буду. Таблицу нужно будет подготовить — описать типы колонок, и также добавить колонку, по которой будет происходить суммирование.

    Далее почти по тексту, только нужно будет выбирать не различные, а группировать по нужному списку колонок (строить запрос динимически), и добавить в запрос условие «Имеющие сумма(КолонкаСуммирования) = 1». (просто различные использовать нельзя из-за значений в других колонках таблицы). Далее эту сгруппированную временную таблицу нужно будет джойнить с первоначальной временной таблицей, в условиях связи прописывать равенство по выбранным полям (строить условие динамически), плюс нужно будет в случае если нужно не удалить все дублирующие строки, а оставить по одной из удаляемых тоже это предусмотреть.

    Хотел еще сказать, что этот способ расчитан, на большое количество строк в таблице, и малое количество строк с дублями, для других случаев можно это делать быстрее другим способом.

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

    Reply
  6. abe

    (4) CagoBHuK, нужно иметь в виду, что добавится передача/возврат данных на SQL.

    Reply
  7. abe

    Я бы еще подумал над добавлением индекса(ов) в таблицу значений (по которой выполняется поиск).

    Reply
  8. CagoBHuK

    (6) В данном случае речь шла о таблице значений, которую на клиенте Вы никак не сможете получить. Использование метода «Скопировать» доступно только для универсальных коллекций значений, которые не могут существовать на клиенте. Иными словами сам код обработки предполагает серверный вызов.

    Reply
  9. abe

    (8) CagoBHuK, я и не спорю относительно серверного (сервера 1С) вызова, добавится вызов именно SQL сервера.

    Reply
  10. CagoBHuK

    (9) Вы считаете, что он будет длиться дольше, чем представленный алгоритм пересчета?

    Reply
  11. prodines

    Мой вариант:

    МассивДублей = Новый Массив;

    МассивСотрудников = Новый Массив; // проверяемое на дубль значение

    Для каждого Строка Из ТЗНачисления Цикл

    Если Строка.СпособРасчета = Перечисления.СпособыРасчетаОплатыТруда.СдельныйЗаработок Тогда // критерий сравнения на дубль, может быть любой

    Элем = МассивСотрудников.Найти(Строка.Сотрудник);

    Если Элем = Неопределено Тогда // это первое вхождение проверяемого на дубль сотрудника

    МассивСотрудников.Добавить(Строка.Сотрудник);

    Иначе // а это — уже мы дубль встретили, по данному сотруднику и по данному критерию проверки на дубль

    МассивДублей.Добавить(Строка);

    КонецЕсли;

    КонецЕсли;

    КонецЦикла;

    Если МассивДублей.Количество() > 0 Тогда

    Для каждого Элем Из МассивДублей Цикл

    ТЗНачисления.Удалить(Элем);

    КонецЦикла;

    КонецЕсли;

    Показать

    Вся проверка делается за один проход. Очень просто.

    Reply
  12. CeHbKA

    (4) CagoBHuK, это при условии что все поля строк одинаковые.

    Если, например, в таблице 4 колонки и дубли удалять надо только по 3 колонкам, то вариант стар как мир и даже описан в синтакс-помощнике (осторожно, код в стиле «капитан очевидность»):

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

    Показать

    =)

    Reply
  13. MaiorovYury

    Спасибо, помогло)

    Reply
  14. DJDUH

    Ну как-бы есть и такой метод Таблицы Значений, как Свернуть(«Групп колонки», » сумм колонки») если ничего не нужно суммировать, а только убрать дубли, подходит только групп колонки!

    Слыхал наверное!?

    Reply
  15. logarifm
    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *