Страницы: 1 2 След.
RSS
Найти в таблице дубли данных физических лиц и копировать их на новый лист
 
Часто в работе приходится использовать поочередно 3 формулы для поиска значений или определенной информации, после выполнения одной процедуры длящейся часами прописывать вторую дожидаться ее окончания, и сравнить между собой
полученные результаты.
На практике это выглядит так:
1) =СЧЁТЕСЛИМН(D:D;D4;E:E;E4;F:F;F4;G:G;G4)
(где D– фамилия, Е – Имя, F – отчество, G-дата рождения);
2) = СЧЁТЕСЛИ(C:C;C4)  ( где С –  физ. лицо. идентификатор)
3) =I4=J4 (где I - результаты первой формулы, J – результаты второй формулы) отображаются как ЛОЖЬ или ИСТИНА.

Можете помочь с макросом, который будет выполнять алгоритм, завершив первую процедуру,
самостоятельно приступить ко второй, потом к третьей? И в завершении скопировать все данные со значениями ЛОЖЬ на отдельный лист.
 
Может как-то так, см. файл (таблица всегда должна начинаться с А1)
P.S. Столбцы с формулами можно вообще удалить из файла
Изменено: New - 11.02.2021 15:37:40
 
New, все четко работает на тестовом примере, огромное Вам спасибо. Проверю на большом массиве данных, обязательно отпишусь.
 
да, мне тоже будет интересно, как на больших объёмах будет, отпишитесь потом
 
New, почему-то не могу скачать Ваш файл, открывает новую вкладку и пишет, что файл отсутствует. :cry:  
 
я его сейчас заменил, попробуйте ещё раз скачать. Вы видно пытались скачать файл, когда я его заменял. Просто чуть поправил код и дописал пару комментариев в самом коде
Изменено: New - 11.02.2021 15:50:42
 
Цитата
Камиль Гусейнов написал: помочь с макросом, который будет выполнять алгоритм, завершив первую процедуру,
Т.е. это какая-то конкретная задача (что-то найти, посчитать, определить...)? Предложите название темы, отражающее эту задачу. Заменят модераторы
 
Возможная тема: Найти дубли данных физических лиц в таблице и скопировать их на новый лист
Изменено: New - 11.02.2021 16:02:16
 
New, в общем использовал для теста небольшой массив данных, 42 713 строк (427 222 заполненные ячейки) сначала протестировал формулами:
=СЧЁТЕСЛИМН(D:D;D4;E:E;E4;F:F;F4;G:G;G4) - 2 минуты;
= СЧЁТЕСЛИ(C:C;C4)  - чуть больше 1 минуты;
=I4=J4 меньше минуты  (одним словом 4 - 5 минут) определил все дубли (294 штуки). Во время работы процессор I7 3770 - нагрузка в основном 100%

На счет макроса, убрал лишние колонки массив данных получился  42 713 строк (но 341 757 заполненные ячейки) запустил 18:25, недожался окончания,  сам  принудительно остановил 18:59  - длительность 34 минуты. Нагрузка на процессор была от 15 до 26%. Большой массив на который уходит формулами до 2,5-3,5 часов, думаю при таком предварительном сравнении, затянется как минимум в 3-4 раза дольше.
Я в любом случае протестирую  работу макроса до конца напишу за сколько он по времени завершил  и отличались ли результаты.

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

ячейка В (или 2) - Идентификатор физ/лица  (вместо С (или 3) как раньше)
ячейки  F,G,H,I (или 6,7,8,9) - Фамилия, Имя, Отчество, Рождение. (вместо D,E,F,G или 4,5,6,7)
копируем на новый лист - диапазон  от А по J (или 1 по 10).
 
Цитата
Камиль Гусейнов написал: его можно как то ускорить?
Подумаю

Цитата
...подправить диапазон, чтобы не удалять лишние столбцы таблицы.
Какие вы столбцы удаляете? Ваши формулы? Можете не удалять их. Макросу без разницы

Цитата
ячейка В (или 2) - Идентификатор физ/лица
Разные столбцы - выложите снова корректный файл, я поправлю код
 
Спасибо.
 
Камиль Гусейнов, я получил ваши сообщения. Да, верю-верю, что долго работает макрос... Надо подумать, как увеличить его скорость... может ещё кто с форума подскажет варианты... (я тоже подумаю)
 
New, ок спасибо.
 
Ну, раз больше никто не предлагает вариантов, то я остановлюсь на ваших формулах. Вставлять их макросом в ячейки и переносить результат на новый лист. Мой тест 50.000 строк 2:50 мин
P.S. Файл сохранил в формате XLSB, он так меньше занимает места
Изменено: New - 12.02.2021 00:07:33
 
вариант на pq, время работы на ~ 100 тыс. строках около 15 сек
Код
let
    z = Table.Buffer(Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content]),
    a = Table.Group(z, {"Фамилия ", "Имя ", "Отчество ", "Дата рождения "}, {"q", each Table.RowCount(_)}),
    b = Table.Group(z[[Физ. Лицо идентификатор]], {"Физ. Лицо идентификатор"}, {"w", each Table.RowCount(_)}),
    c = Table.Join(z, "Физ. Лицо идентификатор", b, "Физ. Лицо идентификатор"),
    d = Table.Join(c, {"Фамилия ", "Имя ", "Отчество ", "Дата рождения "}, a, {"Фамилия ", "Имя ", "Отчество ", "Дата рождения "}),
    f = Table.AddColumn(d, "q1", each [w]=[q]),
    e = Table.SelectRows(f, each ([q1] = false)),
    q = Table.SelectColumns(e,Table.ColumnNames(z))
in
    q
Изменено: Антон - 12.02.2021 00:42:08
 
Цитата
New написал:
Ну, раз больше никто не предлагает вариантов, то я остановлюсь на ваших формулах.
Уф, зарекался же на ночь задачки брать посмотреть..
Попробовал вот так, 200 тысяч строк обрабатывает где-то полторы минуты. Понятно что PQ всяко быстрее будет, но чисто академический интерес заел. Тут вся работа пока в рамках одного листа, вынос результата с ЛОЖЬ на другой лист не делал - в 4 утра пока неохота :)
Код
Sub fast_count()

Dim ws As Worksheet
Dim EndRow As Long

Set ws = ThisWorkbook.Worksheets("Дубли физ лиц")
Set ID_Dict = CreateObject("Scripting.Dictionary")
Set Identity_Dict = CreateObject("Scripting.Dictionary")

StartTime = Timer
IDColumn = 3
IdentityColumn = 9

EndRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
StartRow = 2

ws.Range("I2:I" & EndRow).Formula = "=CONCAT(D2:G2)"


For i = StartRow To EndRow Step 1
    Identity = Cells(i, IdentityColumn).Value
    If Identity_Dict.Exists(Identity) Then
        Identity_Dict(Identity) = Identity_Dict(Identity) + 1
    Else
        Identity_Dict.Add Identity, 1
    End If
    
    ID = Cells(i, IDColumn).Value
    If ID_Dict.Exists(ID) Then
        ID_Dict(ID) = ID_Dict(ID) + 1
    Else
        ID_Dict.Add ID, 1
    End If
    
Next
          
IDKeys = ID_Dict.keys
IDCount = ID_Dict.items

IdentityKeys = Identity_Dict.keys
IdentityCount = Identity_Dict.items
                    
For j = 2 To EndRow

For i = LBound(IdentityKeys) To UBound(IdentityKeys)

If ws.Cells(j, IdentityColumn).Value = IdentityKeys(i) Then
ws.Cells(j, 10).Value = IdentityCount(i)
Else
End If

Next i

For p = LBound(IDKeys) To UBound(IDKeys)

If ws.Cells(j, IDColumn).Value = IDKeys(p) Then
ws.Cells(j, 11).Value = IDCount(p)
Else
End If
Next p

If ws.Cells(j, 10).Value = ws.Cells(j, 11).Value Then
ws.Cells(j, 12).Value = True
Else
ws.Cells(j, 12).Value = False
End If

Next j
Columns(9).EntireColumn.Delete
MsgBox "Done. ", , Round(Timer - StartTime, 2) & "s"

End Sub

Изменено: Alex T. - 12.02.2021 05:09:50
 
Цитата
New написал: ...раз больше никто не предлагает вариантов, то я остановлюсь на ваших формулах.
Просто волшебство, спасибо большое, 0 ошибок, найдены все 294 дубля, время не запомнил на сообщении примерно 1,5 минуты. Быстрее как минимум в 2-2,5 раза моего предыдущего результата.

Цитата
Камиль Гусейнов написал: (одним словом 4 - 5 минут) определил все дубли (294 штуки).
Сегодня проверю и другие предложенные способы и обязательно напишу, я всем очень благодарен  за оказанную помощь!!!
 
Alex T., Попробовал Ваш вариант, просчет идет до 25 строки, столько же строк было в тестовом файле, к сожалению не нашел в макросе, что подправить, чтобы он прошел до конца.
Антон, Сам код не понял если честно как применить отдельно, так как приложенный Вами тестовый файл ругается, что браузер нужен старее чем у меня установлен. Поэтому протестировать не смог. В любом случае Ваше внимание к моей проблеме,  Вы  все мне помогли, огромное Вам всем спасибо.
 
Камиль Гусейнов, здравствуйте
Если я правильно понял,то задача сводится к тому, чтобы проверить, что по каждому идетификатору сцепка "ФИО+дата" — одна и та же
Протестируйте на реальных данных - должно быть очень шустро
Изменено: Jack Famous - 12.02.2021 10:19:42
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Цитата
Камиль Гусейнов написал:
Сам код не понял если честно как применить отдельно
почитайте Что такое Power Query / Pivot / Map / View / BI и зачем они пользователю Excel, будет интересно
Цитата
Камиль Гусейнов написал:
файл ругается, что браузер нужен старее чем у меня установлен
что-то я сомневаюсь, покажите скрин
 
Цитата
Камиль Гусейнов написал:
Попробовал Ваш вариант, просчет идет до 25 строки, столько же строк было в тестовом файле, к сожалению не нашел в макросе, что подправить, чтобы он прошел до конца.
Хм, действительно, забавно.
Переменная EndRow определяется по первой колонке и возвращает 25 строк, надо потом глянуть почему
Пока можно заменить
EndRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row на EndRow = ws.UsedRange.Rows.Count
 
Антон, Возможно, что то не так делал. Я на другом компьтере дома тоже попробую, отпишусь.

Картинки удалены - превышение допустимого размера вложения [МОДЕРАТОР]
 
Цитата
Alex T.: EndRow = ws.UsedRange.Rows.Count
некорректно отработает, если данные начинаются НЕ с 1ой строки. Тогда уж
Код
EndRow = ws.UsedRange.Row + ws.UsedRange.Rows.Count-1
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Камиль Гусейнов, скрины увиден, но в моем файле нет ни одного макроса
 
 Антон, Я если чесно сильнее запутался, а как нужно было его применять? Тот код, что Вы написали.
 
Камиль Гусейнов, по файлу от Антона - нужно добавить данные на лист "Лист1" (допустим 100.000 строк), а на листе "Таблица2" нажать правой клавишей мыши на таблице и выбрать "Обновить"
P.S. Решение от Антона сделано через Power Query - это надстройка встроенная в Excel. Там на языке "М" Антон сделал запрос к таблице на Лист1, которая обрабатывает эти данные и выгружает их на лист "Таблица2"
Чтобы открыть в файле окно Power Query - вам надо перейти в меню Данные, нажать "Запросы и подключения", справа откроется окно "запросы и подключения", там ниже будет запрос с названием "Таблица" - щёлкнуть по нему правой клавишей мыши и выбрать "Изменить", откроется окно "Power Query"
Изменено: New - 12.02.2021 16:33:00
 
New, Спасибо впредь буду знать!!!
 
Камиль Гусейнов, проверьте на моём файле - интересно быстродействие
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, обязательно, сегодня вечером сделаю и отпишусь, как раз файл есть 247 308 строк.
 
Jack Famous,  не как не могу запустить макрос, немного подкорректировал
= Range("A2:J247308").Value  (вместо = Range("A2:J25").Value)
изменил столбцы как в моей таблице не тестовой:
colKey = 2  ' номер столбца с идентификатором
colF = 6    ' фамилия
colI = 7    ' имя
colO = 8    ' отчество
colDate = 9 ' ДР

Желтым подсвечивается Sub FindDuples()  название макроса и ошибка.
Страницы: 1 2 След.
Наверх