Excel макрос для удаления дубликатов

Удаление повторяющихся значений (дубликатов) в диапазоне ячеек с помощью кода VBA Excel. Метод Range.RemoveDuplicates — синтаксис, параметры, примеры.

Метод Range.RemoveDuplicates

Метод Range.RemoveDuplicates предназначен в VBA Excel для удаления повторяющихся значений по столбцам в заданном диапазоне ячеек рабочего листа. Строки с обнаруженными дубликатами удаляются целиком.

Синтаксис метода Range.RemoveDuplicates

expression. RemoveDuplicates (Columns , Header),

где expression — переменная или выражение, возвращающее объект Range.

Параметры метода Range.RemoveDuplicates

Наименование Описание
Columns Массив индексов столбцов, содержащих ячейки с повторяющимися значениями. Обязательный параметр. Тип данных – Variant.
Header Указывает, содержит ли первая строка диапазона заголовок, который не участвует в поиске дубликатов:

  • xlNo — первая строка списка не содержит заголовок (значение по умолчанию);
  • xlYes — первая строка диапазона содержит заголовок;
  • xlGuess — VBA Excel решает сам, есть ли у списка заголовок.

Необязательный параметр. Тип данных – XlYesNoGuess.

Метод работает как с круглыми скобками, в которые заключены параметры, так и без них. Если требуется указать несколько столбцов в параметре Columns, следует использовать функцию Array, например, Array(2, 3).

Примеры удаления дубликатов

Исходная таблица для всех примеров

Исходная таблица для удаления дубликатов

По третьей колонке легко определить, какие строки были удалены.

Пример 1
Удаление повторяющихся значений по первому столбцу:

Range("A1:C10").RemoveDuplicates 1

или

Range(Cells(1, 1), Cells(10, 3)).RemoveDuplicates (1)

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

Результат:

Пример 2
Удаление дубликатов по первому столбцу с указанием, что первая строка содержит заголовок:

Range("A1:C10").RemoveDuplicates 1, xlYes

Результат:

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

Пример 3
Удаление дубликатов по первому и второму столбцам:

Range("A1:C10").RemoveDuplicates Array(1, 2)

Результат:

Обратите внимание, что при удалении повторяющихся значений по нескольким столбцам, будут удалены дубли только тех строк, в которых во всех указанных столбцах содержатся одинаковые значения. В третьем примере удалены «лишние» строки с дублями значений по двум первым столбцам: Корова+Лягушка, Свинья+Бурундук и Овца+Собака.


Смотрите, как отобрать уникальные значения из списка в VBA Excel с помощью объекта Collection и объекта Dictionary.

Студворк — интернет-сервис помощи студентам

Добрый день, вчера весь день искал себе подходящий способ решения своей задачи, но так и не нашел подходящий.
Прошу Вас помочь мне.

В приложенном Excel файле 2 таблицы:

Левая — исходные данные
Правая — какой должен получиться результат

Задача — сразу в нескольких колонках, удалить все дубликаты находящиеся только в одном столбце.

То есть если в одном столбце дважды (или несколько раз) попадается цифра «4» — то именно в этом столбце должна остаться только одна цифра «4».

Например: У нас в одном столбце восемь цифр: 1 2 3 4 1 2 3 4
Мы видим, что здесь последние четыре цифры 1 2 3 4 — дублируются, то есть на выходе должны остаться только первые четыре цифры 1 2 3 4

Я нашел пару макросов, как удалить дубликаты во всех столбцах, а не только в одном — и это не подходит.

Например: У нас есть два столбца:

1….5
2….6
3….5
4….6
1….1
2….2
3….3
4….4

То есть, на выходе должно получиться:

1…..5
2…..6
3…..1
4…..2
…….3
…….4

То есть, в первом столбце были удалены дублирующиеся последние четыре цифры (1 2 3 4), а во втором столбце дублирующиеся вторая и третья цифры (5 6).

Вот тут важно то, что во втором столбце последние цифры 1 2 3 4 — не дубликаты потому, что во втором столбце нет повторяющихся цифр 1 2 3 4.
Во втором столбце дублируются лишь 5 и 6.

А мои макросы оказывается удаляют дубликаты не в отдельном одном столбце из всей массы столбцов, а во всех столбцах сразу — виртуально объединив их в один.

Где в результате из нашего примера получается следующее:

1….5
2….6
3
4

Хотя, мне не нужно было, чтобы макрос удалял во втором столбце последние четыре цифры 1 2 3 4.

Excel VBA code to remove duplicates from a given range of cells. In the below data set we have given a list of 15 numbers in “Column A” range A1:A15.  Need to remove duplicates and place unique numbers in column B.

Sample Data: Cells A1:A15

Sample Data

Final Output:

VBA Code to remove duplicates and place into next column (B)

Declare Variables:

Variables Data Type Comments
nonDuplicate Boolean It is a Boolean value (True/False).
uNo Integer Count no of Unique items in column B
colA Integer Iteration column A cells
colB Integer Iteration column B cells
'Variable Declarations
Dim nonDuplicate As Boolean, uNo As Integer, colA As Integer, colB As Integer

Always first value will be unique, So A1 place to cell B1

'Place first value to B1
Cells(1, 2).Value = Cells(1, 1).Value

Initialize variables:

'Initialize uNo = 1 since first number is already placed in column B; Assign True to the variable nonDuplicate

uNo = 1

nonDuplicate= True

Since the first number is already placed in cell B1, Loop starts from A2 to A15.  Take each number from Column A and check with Column B (unique range)

'Use for loop to check each number from A2 to A15 
For colA = 2 To 15
    For colB = 1 To uNo

if the number is already placed in column B.  Assign False to the “nonDuplicate” variable.

        If Cells(colA, 1).Value = Cells(colB, 2).Value Then
            nonDuplicate= False
        End If

“nonDuplicate” is True then place to column B and increase uNo by 1

    'if nonDuplicate is true, place cell value in column B and increase uNo = uNo + 1
    If nonDuplicate = True Then
        Cells(uNo + 1, 2).Value = Cells(colA, 1).Value
        uNo = uNo + 1
    End If

Reset “nonDuplicate” variable 

'reset nonDuplicate to True
nonDuplicate = True

Close for loop

Next colA

Implementation:

Follow the below steps to remove duplicates using Excel VBA:

Step 1: Add a shape (VBA Remove Duplicates) to your worksheet  

Step 2: Right-click on “VBA Remove Duplicates” and “Assign Macro..”

Step 3: Select “removeDuplicates”, you can see a list of macros available in your workbook

Step 4: Save your excel file as “Excel Macro-Enabled Workbook” *.xlsm

Step 5: Click “VBA Remove Duplicates” to execute VBA code and see the output

Необходим макрос для удаления дубликатов

Black_Storm

Дата: Понедельник, 03.03.2014, 15:49 |
Сообщение № 1

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

Прошу прощения за оплошность, допущенную в первый раз.
Название темы переименовал. Раздел сменил. (Очень сложно по сайту ориентироваться, впервой в целом).
Добрый день всем!
Правила прочитал, поиском пользовался, в гугле не забанили. Везде искал — ничего толком не нашел.
Возможно (и скорее всего) проблема во мне — и я не понимаю, что смотрю, так как кодами пользоваться не умею.
В целом ситуация следующая: нужно написать макрос (код) и именно его, в котором удалялись бы дубликаты. Причем необходимо, чтобы удалялись ранние версии и всегда оставалась более поздняя.
Объясню ситуацию: есть большой массив и поставщики в него будут каждый день загружать информацию. В одной колонке номер договора, в другой статус. Статус может соответственно меняться и соответственно всегда более интересен последний. Поэтому нужно чтобы поздняя версия оставалась, а ранняя удалялась.
Для этого нужно прикрутить кнопку или автоматом как-то тоже будет работать?
Прикладываю примерный файл.
Буду безумно признателен!
Ах да, я не студент :) Пересмотрел кучу кодов, но я в них просто не разбираюсь…

По поводу файла — очень долго шел код активации, а гости не могут прикладывать документ. За сим тоже прошу прощения!

К сообщению приложен файл:

5290752.xls
(24.0 Kb)

Сообщение отредактировал Black_StormПонедельник, 03.03.2014, 15:50

 

Ответить

igrtsk

Дата: Понедельник, 03.03.2014, 15:58 |
Сообщение № 2

Группа: Проверенные

Ранг: Обитатель

Сообщений: 307


Репутация:

50

±

Замечаний:
0% ±


Excel 2016

Что-то в вашем примере не стыкуется с вашим пояснением.
Если столбец А — номер договора, а столбец D — статус, то совпадений нет. Нет ни одного повторяющегося номера договора с различными статусами. Или номер договора безразличен, а важен только номер статуса.
Или я вас не понял!?


Инструктор по применению лосей в кавалерийских частях РККА

 

Ответить

Black_Storm

Дата: Понедельник, 03.03.2014, 16:01 |
Сообщение № 3

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

igrtsk, Номер Договора будет как раз в столбце D. До этого дата и прочая не интересная штука.
Ах да, возможно в примере не корректно прорисовал ячейки. Нужно чтобы удалялась вся строка…
Моя ошибка, признаю.

Сообщение отредактировал Black_StormПонедельник, 03.03.2014, 16:05

 

Ответить

nilem

Дата: Понедельник, 03.03.2014, 19:07 |
Сообщение № 4

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

например, так:
[vba]

Код

Sub ertert()
Dim x, i&
x = Range(«A1:D» & Cells(Rows.Count, 1).End(xlUp).Row).Value
With CreateObject(«Scripting.Dictionary»)
     .CompareMode = 1
     For i = 1 To UBound(x)
         If .Exists(x(i, 4)) Then x(.Item(x(i, 4)), 1) = Empty
         .Item(x(i, 4)) = i
     Next i
End With
On Error Resume Next
With Range(«A1», Cells(Rows.Count, 1).End(xlUp))
     .Value = x: .SpecialCells(4).EntireRow.Delete
End With
End Sub

[/vba]


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 11:36 |
Сообщение № 5

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, Огромное спасибо! Работает.
Сижу чешу репу, хочу усложнить себе задачу. Возможно додумаюсь сам, но и сюда кину свои мысли:
Хочу сделать, чтобы при обнаружении дубликатов выдавалось сообщение в message box и появлялись две кнопки — «Удалить» и «Оставить как есть» соответственно.
Ну и далее все понятно — если удалить — удалить и скрыть сообщение с кнопками, если оставить как есть — энд саб и скрытие соответственно.

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 12:06 |
Сообщение № 6

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

Господа, рано я радовался.
Не могу понять в чем беда, привязав формулу к необходимому файлу.
К сожалению файл не могу приложить :(
В общем ситуация такая. По макросу указанному выше я так понимаю информация берется в диапазоне от А до Д, а в оригинале от A до Z, где А — п/п.
Сама таблица начинается с 5 строки.
Номер договора по прежнему находится в D.
Изменил формулу следующим образом:
[vba]

Код

Private Sub CommandButton1_Click()
Dim x, i&
x = Range(«B5:Z» & Cells(Rows.Count, 1).End(xlUp).Row).Value
With CreateObject(«Scripting.Dictionary»)
.CompareMode = 1
For i = 1 To UBound(x)
If .Exists(x(i, 4)) Then x(.Item(x(i, 4)), 1) = Empty
.Item(x(i, 4)) = i
Next i
End With
On Error Resume Next
With Range(«B5», Cells(Rows.Count, 1).End(xlUp))
.Value = x: .SpecialCells(4).EntireRow.Delete
End With
End Sub

[/vba]
Не могу понять почему при клике удаляется вся информация… :(

Строк может быть бесконечное множество в документе…
Буду признателен!

Сообщение отредактировал Black_StormВторник, 04.03.2014, 12:10

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 12:26 |
Сообщение № 7

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

приложите кусочек (несколько строк) из вашего файла


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 12:29 |
Сообщение № 8

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, Приложу целый файл.
В общем и целом по уже нормальному файлу — когда будет вбиваться две одинаковых строки с номером договора хочется оставить только последний нормальный. Ни с каким другим столбцом сравнивать необходимости нет. Повторяется — предыдущая не нужна.
Как-то так.
Огромное Вам спасибо!

К сообщению приложен файл:

2312352.xlsm
(31.3 Kb)

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 12:55 |
Сообщение № 9

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

вот так попробуйте:
[vba]

Код

Sub ertert()
Dim x, i&
With Range(«D4», Cells(Rows.Count, 4).End(xlUp))
     x = .Value
     With CreateObject(«Scripting.Dictionary»)
         .CompareMode = 1
         For i = 1 To UBound(x)
             If .Exists(x(i, 1)) Then x(.Item(x(i, 1)), 1) = Empty
             .Item(x(i, 1)) = i
         Next i
     End With
     .Value = x
     On Error Resume Next
     If MsgBox(«Удалить повторы?», 36) = vbYes Then .SpecialCells(4).EntireRow.Delete
End With
End Sub

[/vba]


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 13:13 |
Сообщение № 10

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, Не удаляет дубликаты на данный момент.
Если мсгбокс сложно реализовать — не нужно. Это, так сказать, фетиш.
Вы мне очень сильно помогаете! Безумно признателен!

Уже начинаю понимать этот язык)
вроде мсгбокс реализовать вообще не сложно.
Не могу понять почему не ищет дубликаты по Вашему коду…

Сообщение отредактировал Black_StormВторник, 04.03.2014, 13:20

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 13:26 |
Сообщение № 11

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

попробуйте еще раз в файле

Если номера договоров — просто числа, то нужно подправить словарь. А если договоры как обычно (что-то вроде «СР25-456/45-2014»), то должно работать.


Яндекс.Деньги 4100159601573

Сообщение отредактировал nilemВторник, 04.03.2014, 13:29

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 13:32 |
Сообщение № 12

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, в файле все работает.
Договоры могут быть как числами, так и буквы+числа. Но в файле удаляет и просто числа.
Спасибо огромное!

Снова рано радовался :)
Не могу перенести к себе файл и почему-то иногда не удаляет.
В чем причина не могу понять. Сломал голову уже…

Сообщение отредактировал Black_StormВторник, 04.03.2014, 14:33

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 14:49 |
Сообщение № 13

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

[vba]

Код

Private Sub CommandButton1_Click()
Dim x, i&
With Range(«D5», Cells(Rows.Count, 5).End(xlUp))
x = .Value
With CreateObject(«Scripting.Dictionary»)
.CompareMode = 1
For i = 1 To UBound(x)
If .Exists(x(i, 1)) Then x(.Item(x(i, 1)), 1) = Empty
.Item(x(i, 1)) = i
Next i
End With
On Error Resume Next
If MsgBox(«Удалить повторы?», 36) = vbYes Then .Value = x: .SpecialCells(5).EntireRow.Delete
End With
End Sub

[/vba]

Мне кажется ошибка в
[vba]

Код

With Range(«D5», Cells(Rows.Count, 4).End(xlUp))

[/vba]
этой строке…
Но я особо не разбираюсь во всем этом…(

Сообщение отредактировал Serge_007Вторник, 04.03.2014, 22:51

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 16:52 |
Сообщение № 14

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

With Range(«D5», Cells(Rows.Count, 5).End(xlUp))

[vba]

Код

With Range(«D5», Cells(Rows.Count, 4).End(xlUp))

[/vba]
д.б. 4 вместо 5, столбец Д — это 4-й по порядку
ну или пришлите мне на почту свой реальный файл


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 17:14 |
Сообщение № 15

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, У Вас скрыт адрес электронной почты. Готов отправить.

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 19:54 |
Сообщение № 16

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

написал в личку


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Вторник, 04.03.2014, 20:07 |
Сообщение № 17

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

nilem, сейчас отправлю.

 

Ответить

nilem

Дата: Вторник, 04.03.2014, 22:44 |
Сообщение № 18

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

вот такой получился код:
[vba]

Код

Sub ertert()
Dim x, i&
With Application
     .ScreenUpdating = False: .Calculation = xlCalculationManual
End With
With ActiveSheet
     If .FilterMode Then .ShowAllData
     x = .Range(«E3», .Cells(Rows.Count, 5).End(xlUp)).Value
End With
With CreateObject(«Scripting.Dictionary»)
     .CompareMode = 1
     For i = 1 To UBound(x)
         If .Exists(CStr(x(i, 1))) Then x(.Item(CStr(x(i, 1))), 1) = Empty
         .Item(CStr(x(i, 1))) = i
     Next i
End With
On Error Resume Next
If MsgBox(«Óäàëèòü ïîâòîðû?», 36) = vbYes Then
     With Range(«E3», Cells(Rows.Count, 5).End(xlUp))
         .Value = x
         .SpecialCells(4).EntireRow.Delete
         .Offset(1, -4).Value = Evaluate(«=row(» & .Address & «)-2»)
     End With
End If
With Application
     .ScreenUpdating = True: .Calculation = xlCalculationAutomatic
End With
End Sub

[/vba]


Яндекс.Деньги 4100159601573

 

Ответить

Black_Storm

Дата: Среда, 05.03.2014, 10:43 |
Сообщение № 19

Группа: Пользователи

Ранг: Участник

Сообщений: 55


Репутация:

1

±

Замечаний:
100% ±


Excel 2007

Еще раз всем привет!
В коде выше все начинается с третьей строки, в моем файле с 5-ой.
Изменил значение Е3 на Е5 везде и строку
.Offset(1, -4).Value = Evaluate(«=row(» & .Address & «)-2»)
на
.Offset(1, -4).Value = Evaluate(«=row(» & .Address & «)-4»)
Однако, нумерация в первой колонке начинается теперь с 4.
Вместо -4 перепробовал все значение от 0 до -6 — результата нуль :(
Логикой понимаю, что с -4 должно работать, на практике не пониманию почему не работает…

 

Ответить

nilem

Дата: Среда, 05.03.2014, 11:36 |
Сообщение № 20

Группа: Авторы

Ранг: Старожил

Сообщений: 1612


Репутация:

563

±

Замечаний:
0% ±


Excel 2013, 2016

наверное, что-то пропустили. Вот полный код для случая, если начало в 5-й строке (5-я строка — заголовки)
[vba]

Код

Sub ertert()
Dim x, i&
With Application
     .ScreenUpdating = False: .Calculation = xlCalculationManual
End With
With ActiveSheet
     If .FilterMode Then .ShowAllData
     x = .Range(«E5», .Cells(Rows.Count, 5).End(xlUp)).Value
End With
With CreateObject(«Scripting.Dictionary»)
     .CompareMode = 1
     For i = 1 To UBound(x)
         If .Exists(CStr(x(i, 1))) Then x(.Item(CStr(x(i, 1))), 1) = Empty
         .Item(CStr(x(i, 1))) = i
     Next i
End With
On Error Resume Next
If MsgBox(«Удалить повторы?», 36) = vbYes Then
     With Range(«E5», Cells(Rows.Count, 5).End(xlUp))
         .Value = x
         .SpecialCells(4).EntireRow.Delete
         .Offset(1, -4).Value = Evaluate(«=row(» & .Address & «)-4»)
     End With
End If
With Application
     .ScreenUpdating = True: .Calculation = xlCalculationAutomatic
End With
End Sub

[/vba]


Яндекс.Деньги 4100159601573

 

Ответить

I have a worksheet with two columns: Date and Name. I want to delete all rows that are exact duplicates, leaving only unique values.

Here is my code (which doesn’t work):

Sub DeleteRows()

Dim rng As Range
Dim counter As Long, numRows As Long

With ActiveSheet
    Set rng = ActiveSheet.Range("A1:B" & LastRowB)
End With
numRows = rng.Rows.Count

For counter = numRows To 1 Step -1
    If rng.Cells(counter) Like rng.Cells(counter) - 1 Then
        rng.Cells(counter).EntireRow.Delete
    End If
Next

End Sub

It’s «Like rng.Cells(counter)-1» that seems to be the cause- I get «Type Mismatch».

Community's user avatar

asked Jun 7, 2013 at 16:25

4

There’s a RemoveDuplicates method that you could use:

Sub DeleteRows()

    With ActiveSheet
        Set Rng = Range("A1", Range("B1").End(xlDown))
        Rng.RemoveDuplicates Columns:=Array(1, 2), Header:=xlYes
    End With

End Sub

answered Jun 7, 2013 at 16:40

fbonetti's user avatar

fbonettifbonetti

6,5823 gold badges33 silver badges32 bronze badges

5

The duplicate values in any column can be deleted with a simple for loop.

Sub remove()
Dim a As Long
For a = Cells(Rows.Count, 1).End(xlUp).Row To 1 Step -1
If WorksheetFunction.CountIf(Range("A1:A" & a), Cells(a, 1)) > 1 Then Rows(a).Delete
Next
End Sub

Martijn Pieters's user avatar

answered Nov 23, 2016 at 17:04

kadrleyn's user avatar

kadrleynkadrleyn

3341 silver badge5 bronze badges

Понравилась статья? Поделить с друзьями:
  • Excel макрос для транслитерации
  • Excel макрос для сравнения таблица
  • Excel макрос для сортировки таблицы
  • Excel макрос для сбора в одну книгу
  • Excel макрос для рисунка