2011-10-12 13 views
3

J'ai deux feuilles Excel où une feuille se compose d'une liste d'utilisateurs. Et l'autre liste contient les mêmes données, seul le même utilisateur est listé plusieurs fois. Maintenant, j'ai besoin d'un moyen de comparer la deuxième liste avec le premier et supprimer les lignes qui contient un utilisateur qui ne se trouve pas dans la première liste.Excel vba - Comparer deux plages et trouver des non-correspondances

La première liste ressemble à ceci:

  • Paul Mccartney
  • John Lennon
  • George Harrison
  • Ringo Starr

La deuxième liste pourrait ressembler à ceci:

  • Paul Mccartney
  • Paul Mccartney
  • Paul Mccartney
  • John Lennon
  • John Lennon
  • John Lennon
  • George Harrison
  • George Harrison
  • George Harrison
  • Ringo Starr
  • Ringo Starr
  • Ringo Starr
  • Ringo Starr
  • Ringo Starr
  • Ringo Starr

Ainsi, en comparant ces deux listes, vous voyez que le nom Ringo Star est pas dans la première liste, et je veux supprimer ces lignes. J'ai essayé avec plusieurs boucles, mais je n'arrive pas à faire fonctionner ça. Je suppose que je pourrais ajouter ces éléments à un tableau de quelque sorte, et l'exécuter si une fonction. Mais y a-t-il un moyen facile de le faire sans trop de code?

Répondre

3

Cette fois, vous pourriez utiliser une collection.

Voici un essai basé sur votre fichier précédent:

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 
+0

Encore une fois merci! Cela fonctionne très bien :) Je vois qu'il y a quelques concepts qui sont nouveaux pour moi, en particulier les parties comparatives. Je vais étudier et décomposer votre code pour m'assurer que je vais comprendre tous les aspects :) –

+0

+1 de moi ainsi qu'une variante/collection est très efficace – brettdj

2

Vous pouvez utiliser une formule simple MATCH pour détecter les correspondances non, puis les supprimer avec AutoFiltre

Si votre première liste était dans la feuille 1 colonne A, votre deuxième feuille 2 colonne A puis dans B1 de la feuille 2 mettre = ISNA (MATCH (A1, feuille1! A: A, 0)) et copier

0 renvoie à VRAI où la deuxième liste ne peut pas correspondre à la première. Vous pouvez ensuite supprimer ces lignes TRUE avec autofiltre

Notez que vous pouvez également utiliser = COUNTIF (Sheet1!A: A, A1) = 0 pour le même effet d'identifier non matchs (TRUE)

xl2010 pic montré ici

enter image description here [VBA ajouté]

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 
+0

Ah, je vois cela fonctionne :) Mais j'en ai besoin via VBA je pense. Parce que je veux que cette liste soit aussi pure que possible, comment est-ce que je ferais cela en utilisant VBA? Puis-je ajouter cette formule à une colonne vide, de haut en bas. Et puis faire une boucle dans chaque cellule, trouver la valeur TRUE, puis supprimer ces lignes en utilisant le code vba? Ou pourrais-je lancer un IF avec cette formule et vérifier la valeur directement? –

+0

Je pensais que vba était très peu VB :). Le VBA ci-dessus fait automatiquement la même chose, à savoir une suppression très rapide en utilisant une colonne de formule de travail plutôt qu'une boucle. – brettdj

+0

Ceci est une réponse très claire. Et vous avez probablement raison, en utilisant la formule sera plus rapide qu'une boucle. +1 btw – JMax

1

Voir this question. En utilisant cette technique, vous pouvez facilement interroger SELECT * FROM [Sheet2$] WHERE columnX NOT IN (SELECT columnY FROM [Sheet1$]

Questions connexes