Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
3 / 3 / 0
Регистрация: 12.12.2015
Сообщений: 174

Как найти дубликаты объединений столбцов одной строки на одном листе?

26.01.2019, 20:37. Показов 2229. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Уважаемые форумчане, Имею два десятка тысяч строк записей в несколько колонок на одном листе.
В списке есть две сотни записей, где объединение строки третьего и четвертого столбца повторяются. К примеру

Позиция Тип Название Место
991 M Гвоздик Тут-998
992 M Шуруп Тут-17-01-20-87
993 M Шуруп Тут-17-01-20-87
994 M Болт Тут-17-01-20-87
995 M Винт Тут-17-01-99
996 M Саморез Тут-17-01-79-10


Есть код от Hugo121,


Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Sub ttt()
    Dim a(), i&, t$, ind&, x&
 
    ' Отключаем обновление экрана, чтобы код быстрее работал.
    Application.ScreenUpdating = False
    With CreateObject("scripting.dictionary")
        a = Sheets(1).UsedRange.Columns(3).Resize(, 6).Value
        For i = 2 To UBound(a)
            t = a(i, 1) & "|" & a(i, 2) & "|" & a(i, 3) & "|" & a(i, 4) & "|" & a(i, 5) & "|" & a(i, 6)
            .Item(t) = 0&
        Next
 
        a = Sheets(2).UsedRange.Columns(4).Resize(, 6).Value
        ReDim b(1 To UBound(a, 1), 1 To UBound(a, 2))
 
        For i = 2 To UBound(a)
            t = a(i, 1) & "|" & a(i, 2) & "|" & a(i, 3) & "|" & a(i, 4) & "|" & a(i, 5) & "|" & a(i, 6)
            If .exists(t) Then
                ind = ind + 1: For x = 1 To UBound(a, 2): b(ind, x) = a(i, x): Next
            End If
        Next
    End With
 
    If ind > 0 Then Workbooks.Add(1).Sheets(1).[a1].Resize(ind, UBound(b, 2)) = b
    Application.ScreenUpdating = True
 
End Sub
Но он сравнивает два списка на разных листах. Пожалуйста помогите сделать подобное для поиска дубликатов на одном листе?
В принципе мне нужно получить список позиций из первого столбца для повторяющихся объединений столбцов 3 и 4.
Спасибо.
Вложения
Тип файла: xls Книга2.xls (37.0 Кб, 6 просмотров)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
26.01.2019, 20:37
Ответы с готовыми решениями:

Как вставку строки на одном листе повторить на другом листе?
Вопрос из области сбора данных из нескольких листов на один лист. Пример (прототип) представлен в файле Пример 1: на листе №1...

Из одной ячейки на одном листе раскидать данные в другие ячейки в другом листе
Помогите пожалуйста! Экстренная ситуация, вплоть до увольнения:( Надо из одной ячейки на одном листе раскидать данные в другие ячейки в...

2 макроса на одном листе, как сделать?
Доброго времени суток! VBA не знаю. При добавлении второго макроса выдает ошибку - Compile error: ambiguous name detected worksheet_change....

10
15155 / 6428 / 1731
Регистрация: 24.09.2011
Сообщений: 9,999
26.01.2019, 21:58
Цитата Сообщение от Sasanik Посмотреть сообщение
нужно получить список позиций из первого столбца для повторяющихся объединений столбцов 3 и 4
В каком виде?
Можно без макросов: в E2:F2 формулы
Code
1
=C2&"|"&D2  =СЧЁТЕСЛИ(E:E;E2)
, автозаполнить до конца таблицы, отфильтровать по F по >1
Вложения
Тип файла: xls Книга2 (1).xls (40.0 Кб, 1 просмотров)
0
3 / 3 / 0
Регистрация: 12.12.2015
Сообщений: 174
27.01.2019, 07:38  [ТС]
Доброго дня Вам! Казанский,
Цитата Сообщение от Казанский Посмотреть сообщение
В каком виде?
В виде таблицы на отдельном листе.

Формула у мну есть:
Visual Basic
1
=ЕСЛИ(СЧЁТЕСЛИМН($C$2:$C$21141;C2;$D$2:$D$21141;D2)>1;"Повтор";"")
И условное форматирование тоже вариант. Только всё это крайне медленно, к примеру на двадцать тысяч строк, у меня - две минуты на пересчёт и две минуты на фильтрацию, а это уже вечность, так как обработке подлежат несколько сотен тысяч записей минимум по двадцать столбцов.

Ищу решение на VBA Excel. Взор свой обратил на словари, но не знаю как получить и запоминать индекс строки с повтором
Логика примерно такая: - По циклу записываю в keys связку - "C2&D2", в items - "A1". При обнаружении повтора, предыдущую строку, и соответственно "дубль" надо записать в другой лист.
0
 Аватар для Святой НякаЛайк
655 / 247 / 89
Регистрация: 28.10.2015
Сообщений: 526
28.01.2019, 11:48
Цитата Сообщение от Sasanik Посмотреть сообщение
код от Hugo121
можно адаптировать под изменившиеся условия

Не по теме:

Sasanik, потерял форму?:(

Вложения
Тип файла: xls Адаптация для 1 листа.xls (56.5 Кб, 1 просмотров)
0
 Аватар для Святой НякаЛайк
655 / 247 / 89
Регистрация: 28.10.2015
Сообщений: 526
28.01.2019, 12:27
Хмм... Адаптация сия добавляет только найдёныша, а его дубликат - нет.
Вот мой вариант кода. Два массива, UDT и функция. Получилось что-то типа функции Filter, но для двухмерного массива.
Вложения
Тип файла: xls Через массив и UDT-функцию.xls (60.5 Кб, 2 просмотров)
0
 Аватар для Step_UA
1591 / 664 / 225
Регистрация: 09.06.2011
Сообщений: 1,334
28.01.2019, 16:09
Лучший ответ Сообщение было отмечено Sasanik как решение

Решение

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Sub ttt()
  Dim a(), b(), i&, j&, k&, record&, s$
    With Sheets(1)
        a = .Range(.Cells(2,1), .Cells(.Rows.Count, 4).End(xlUp)).Value
    End With
    ReDim b(1 To UBound(a, 1), 1 To 4)
    record = 0
    With CreateObject("scripting.dictionary")
        .comparemode = 1
        For i = 1 To UBound(a, 1)
            s = a(i, 3) & "|" & a(i, 4)
            If .exists(s) Then
                j = .Item(s)
                If j Then
                    record = record + 1
                    For k = 1 To 4: b(record, k) = a(j, k): Next
                    .Item(s) = 0
                End If
                ' убрать следующие две строки, если необходимо копировать только первую запись имеющуюю дубликаты
                record = record + 1
                For k = 1 To 4: b(record, k) = a(i, k): Next
            Else
                .Add s, i
            End If
        Next
    End With
    Sheets(2).UsedRange.Offset(1).Clear
    If record Then Sheets(2).[a2].Resize(record, 4).Value = b
End Sub
1
3 / 3 / 0
Регистрация: 12.12.2015
Сообщений: 174
28.01.2019, 17:37  [ТС]
Нет : (Святой НякаЛайк, Так не годится. В смысле алгоритм не верно построен. Дублирует найденное и добавляет хаотичное количество пустых строк, после каждой выборки. Да и время работы... Вручную, формулами - 4 минуты. Автоматически - 10 минут Это на 39000 строк.

Добавлено через 37 минут
Step_UA, Спасибо! , Это уже нечто. Десятые доли секунды, против 10 минут - Миг! , это на 32000 тысячах строк записей.
Ещё-бы прикрутить сюда счетчик дубликатов. В смысле - два дубля - цифра "2" в конце строки, шесть дублей - "6".
0
 Аватар для Step_UA
1591 / 664 / 225
Регистрация: 09.06.2011
Сообщений: 1,334
28.01.2019, 17:49
Цитата Сообщение от Sasanik Посмотреть сообщение
В смысле - два дубля - цифра "2" в конце строки, шесть дублей - "6".
это без 20 и 21 строки?
Для двух одинаковых значений - значение 2 (общее их количество) или 1 (без учета первой)
0
3 / 3 / 0
Регистрация: 12.12.2015
Сообщений: 174
28.01.2019, 18:40  [ТС]
С учетом 20 и 21 строк.
Надо в каждой выведенной строке поставить количество найденных дубликатов.

Добавлено через 10 минут
Цитата Сообщение от Step_UA Посмотреть сообщение
Для двух одинаковых значений - значение 2 (общее их количество)
. в каждой из двух строк.
0
 Аватар для Step_UA
1591 / 664 / 225
Регистрация: 09.06.2011
Сообщений: 1,334
28.01.2019, 19:24
Лучший ответ Сообщение было отмечено Sasanik как решение

Решение

как то так
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Sub ttt()
  Dim a(), b(), i&, j&, k&, record&, s$
    With Sheets(1)
        a = .Range(.[a2], .Cells(.Rows.Count, 4).End(xlUp)).Value
    End With
    ReDim b(1 To UBound(a, 1), 1 To 5)
    record = 0
    With CreateObject("scripting.dictionary")
        .comparemode = 1
        For i = 1 To UBound(a, 1)
            s = a(i, 3) & "|" & a(i, 4)
            If .exists(s) Then
                j = .Item(s)
                If j < 0 Then
                    record = record + 1
                    For k = 1 To 4: b(record, k) = a(-j, k): Next
                    b(record, 5) = s
                    .Item(s) = 1
                End If
                record = record + 1
                For k = 1 To 4: b(record, k) = a(i, k): Next
                b(record, 5) = s
                .Item(s) = .Item(s) + 1
            Else
                .Add s, -i
            End If
        Next
        For i = 1 To record
            b(i, 5) = .Item(b(i, 5))
        Next
    End With
    Sheets(2).UsedRange.Offset(1).Clear
    If record Then Sheets(2).[a2].Resize(record, 5).Value = b
End Sub
1
3 / 3 / 0
Регистрация: 12.12.2015
Сообщений: 174
28.01.2019, 19:55  [ТС]
Step_UA, Спасибо огромное! Это то, что требовалось.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.01.2019, 19:55
Помогаю со студенческими работами здесь

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

Привязать значение ячейки на одном листе к значению ячейки в другом листе
как привязать значение ячейки на одном листе к значению ячейки в другом листе, чтобы при сортировке другого листа значения не терялись....

Как заполнить ячейку в одном листе при выполнении условий на втором
Всем добрый день. Прошу помочь в решении задачи: проводим турнир, есть сетка. Игроки поделены на группы, в каждой группе есть...

Excel: Как задать ширину столбцов в новом листе
Собственно. Создаю рабочий лист, кидаю данные. using Excel = Microsoft.Office.Interop.Excel; Excel.Application newExcel = new...

Как в Excel печатать на одном листе бумаги сразу несколько листов рабочей книги
Уважаемые программисты, подскажите, пожалуйста, как в Excel печатать на одном листе бумаги сразу несколько листов рабочей книги с помощью...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru