Excel vba - Сравните два диапазона и найдите несоответствия - PullRequest
3 голосов
/ 12 октября 2011

У меня есть два листа Excel, один из которых состоит из списка пользователей.А другой список содержит те же данные, только один и тот же пользователь указан несколько раз.Теперь мне нужно как-то сравнить второй список с первым и удалить строки, содержащие пользователя, которого нет в первом списке.

Первый список выглядит следующим образом:

  • Пол Маккартни
  • Джон Леннон
  • Джордж Харрисон
  • Ринго Старр

Второй список может выглядеть следующим образом:

  • Пол Маккартни
  • Пол Маккартни
  • Пол Маккартни
  • Джон Леннон
  • Джон Леннон
  • Джон Леннон
  • Джордж Харрисон
  • Джордж Харрисон
  • Джордж Харрисон
  • Ринго Старр
  • Ринго Старр
  • Ринго Старр
  • Ринго Стар
  • Ринго Стар
  • Ринго Стар

Итак, сравнениеВ этих двух списках вы видите, что имя Ринго Стар не в первом списке, и я хочу удалить эти строки.Я пробовал с несколькими циклами, но я не могу заставить это работать.Думаю, я мог бы добавить эти элементы в какой-то массив и запустить его через функцию.Но есть ли простой способ сделать это без такого большого количества кода?

Ответы [ 3 ]

3 голосов
/ 12 октября 2011

На этот раз вы можете использовать коллекцию.

Вот попытка на основе вашего предыдущего файла:

Option Explicit

Sub test()
Dim i As Long
Dim arrSum As Variant, arrUsers As Variant
Dim cUnique As New Collection

'Put the name range from "Summary" in an array
With ThisWorkbook.Sheets("Summary")
    arrSum = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With

'"Convert" the array to a collection (unique items)
For i = 1 To UBound(arrSum, 1)
    On Error Resume Next
    cUnique.Add arrSum(i, 1), CStr(arrSum(i, 1))
Next i

'Get the users array
With ThisWorkbook.Sheets("Users")
    arrUsers = .Range("A2", .Range("A" & Rows.Count).End(xlUp))
End With

'Check if the value exists in the Users sheet
For i = 1 To cUnique.Count
    'if can't find the value in the users range, delete the rows
    If Application.WorksheetFunction.VLookup(cUnique(i), arrUsers, 1, False) = "#N/A" Then
        With ThisWorkbook.Sheets("Summary").Cells
            .AutoFilter Field:=1, Criteria1:=cUnique(i)
            .Range("A2", .Range("A" & Rows.Count).End(xlUp)).EntireRow.Delete
        End With
    End If
Next i
'removes AutoFilter if one remains
ThisWorkbook.Sheets("Summary").AutoFilterMode = False
End Sub
2 голосов
/ 12 октября 2011

Вы можете использовать простую формулу MATCH, чтобы обнаружить любые несоответствия, а затем удалить их с помощью автофильтра.

Если ваш первый список был в колонке листа 1, второй - в колонке листа 2, а затем в B1 листа2 положить = ISNA (MATCH (A1, Sheet1! A: A, 0)) и скопировать

, что возвращает TRUE, когда второй список не может быть сопоставлен с первым.Затем вы можете удалить эти ИСТИННЫЕ строки с помощью автофильтра

Обратите внимание, что вы также можете использовать = COUNTIF (Sheet1! A: A, A1) = 0 для того же эффекта, чтобы идентифицировать несоответствия (как ИСТИНА)

xl2010 фото, показанное здесь

enter image description here [VBA добавлено]

Sub QuickKill()
    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Dim rng1 As Range
    Set ws1 = Sheets(1)
    Set ws2 = Sheets(2)
    ws2.Columns(2).Insert
    Set rng1 = ws2.Range(ws2.[a1], ws2.Cells(Rows.Count, "A").End(xlUp))
    Rows(1).Insert
    With rng1.Offset(0, 1)
        .FormulaR1C1 = "=COUNTIF('" & ws1.Name & "'!C1,RC[-1])=0"
        .AutoFilter Field:=1, Criteria1:="TRUE"
        .EntireRow.Delete
        .EntireColumn.Delete
    End With
End Sub
1 голос
/ 12 октября 2011

См. этот вопрос . Используя эту технику, вы можете легко запросить SELECT * FROM [Sheet2$] WHERE columnX NOT IN (SELECT columnY FROM [Sheet1$]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...