2016-06-29 12 views
1

Ich möchte herausfinden, ob eine bestimmte Gruppe von Zellen mit einer anderen Gruppe von Zellen in einem anderen Blatt mit VBA übereinstimmen. In meinem Fall muss ich herausfinden, ob die lastName, firstName Zellen übereinstimmen. In meiner Lösung, die ich gefunden habe, durchlaufe ich die erste Tabelle und erhalte den Namen des Mitarbeiters. Durchlaufen Sie dann die zweite Tabelle, um den Namen des Mitarbeiters zu erhalten. Dann sehen, ob die beiden zusammenpassen. Diese Methode ist zu teuer und dauert zu lange. Gibt es einen besseren Weg, dies zu tun?Finden, ob eine Spalte Zelle gleich einem anderen in einem anderen Blatt

Meine erste Tabelle enthält 6 Zeilen, meine zweite Tabelle kann mehr als 100 Zeilen enthalten. Zu viel Zeit ist verschwendet.

Ich dachte daran, nur die gesamte Spalte zu durchsuchen, um zu sehen, ob der Nachname zuerst passt, wenn ja, dann geh und sieh nach, ob der Vorname passt ... aber andererseits könnte es auch Leute geben selbe Nachname ..

Hier ist was ich bisher habe.

Ich weiß, ich habe keine bedingte Aussage, ich habe nicht die Mühe zu schreiben, weil ich wusste, dass dieser Ansatz nicht der beste ist.

Ich kann keine weitere Spalte hinzufügen, um die Namen der zweiten Blätter zu verketten, weil sie aus einer Datenbank gelesen und in separaten Spalten und Nachnamen und Vornamen geführt werden. Wie auch immer, gibt es einen Weg, dass ich die Namen verketten kann, ohne eine weitere Spalte auf dem zweiten Blatt hinzuzufügen und versuche, sie so zu finden? Ist das sinnvoll?

Find wird nur in einer Spalte aussehen, wenn ich mich nicht irre. Kann es in zwei aussehen?

UPDATE

Ich bin in der Lage das erste Vorkommen des Nachnamens zu bekommen, aber nicht die anderen. Ich habe ein anderes Feld hinzugefügt. Es gibt also drei Felder, die jetzt zusammenpassen. Last Name, First Name und Project Name. Bis jetzt wird mein Code nur das erste Vorkommen finden und dort bleiben. Ich denke, meine Reihenfolge der Schleifen ist falsch.

Hier ist was ich bisher habe.

For i = 2 To managerRows 'Looping through the Managers Table 
     empLast = managerSheet.Cells(i, 1) 
     empFirst = managerSheet.Cells(i, 2) 
     empName = (empLast & ", " & empFirst) 
     projectName = managerSheet.Cells(i, 3) 
     managerLast = managerSheet.Cells(i, 4) 
     managerFirst = managerSheet.Cells(i, 5) 
     managerName = (managerLast & ", " & managerFirst) 

     Set findRow = assignSheet.Range(assignSheet.Cells(3, 4), assignSheet.Cells(assignRows, 4)) 'Set a range to look for Last Name 
     Set c = findRow.Find(empLast, LookIn:=xlValues) 'Find matching Last Name if it exists 
     If Not c Is Nothing Then 'Last Name found 
      Do Until c Is Nothing 'Is this in the wrong place? 
       If Cells(c.Row, 5) = empFirst Then 'If first name matches 
        If Cells(c.Row, 10) = projectName Then 'If project name matches. We found them 
         MsgBox ("Found: " & empLast & ", " & empFirst & ": Project: " & projectName & " : in: " & c.Row) 
        End If 
       End If 
       Set c = findRow.FindNext(c) 'Is this is the wrong place? 
      Loop 
     End If 
     Set c = Nothing 'Is this in the wrong place? 
    Next i 

Werfen Sie einen Blick auf 'Is this in the wrong place? für meine neue Schleife.

UPDATE 2:

ich erfolgreich auf drei Säulen gefiltert haben Gelöst find und findNext verwenden. Mit Hilfe einiger guter Antworten. Ich werde die fertige Version veröffentlichen. Ich musste extra else-Anweisungen in meine Filter einfügen, um zum nächsten gefundenen Ling zu gelangen. Hoffentlich können andere davon lernen, da es keine klare Antwort für das Filtern auf drei Spalten unter Verwendung find gibt.

For i = 2 To managerRows 'Looping through the Managers Table 
     empLast = managerSheet.Cells(i, 1) 
     empFirst = managerSheet.Cells(i, 2) 
     empName = (empLast & ", " & empFirst) 
     projectName = managerSheet.Cells(i, 3) 
     managerLast = managerSheet.Cells(i, 4) 
     managerFirst = managerSheet.Cells(i, 5) 
     managerName = (managerLast & ", " & managerFirst) 
     'Focus Below this 
     Set findRow = assignSheet.Range(assignSheet.Cells(3, 4), assignSheet.Cells(assignRows, 4)) 'Set a range to look for Last Name 
     Set c = findRow.Find(empLast, LookIn:=xlValues) 'Find matching Last Name if it exists 
     If Not c Is Nothing Then 'Last Name found 
      Do Until c Is Nothing 
       If Cells(c.Row, 5) = empFirst Then 'If first name matches 
        If Cells(c.Row, 10) = projectName Then 'If project name matches. We found them 
         MsgBox ("Found: " & empLast & ", " & empFirst & ": Project: " & projectName & " : in: " & c.Row) 
         Set c = Nothing 
        Else 
         Set c = findRow.FindNext(c) 
        End If 
       Else 
        Set c = findRow.FindNext(c) 
       End If 
      Loop 
     End If 
    Next i 
+0

Sie könnten versuchen, 'WorksheetFunction.Vlookup' – JamesFaix

+0

Können Sie Daten in der "großen" Blatt sortieren? (BTW: 100+ Zeilen ist überhaupt keine große Zeilennummer!) – user3598756

Antwort

1

Statt zwei Schleifen zu verwenden, können Sie nur die ersten verwenden und die find Funktion nutzen. Ich glaube, es wird schneller für dich sein.

For i = 2 To managerRows 'Looping through the Managers Table 
    empFirst = managerSheet.Cells(i, 1) 
    empLast = managerSheet.Cells(i, 2) 
    empName = (empLast & ", " & empFirst) 
    managerLast = managerSheet.Cells(i, 3) 
    managerFirst = managerSheet.Cells(i, 4) 
    managerName = (managerLast & ", " & managerFirst) 

    MsgBox (empName & ", " & managerName) 

    Set myRng = assignSheet.Range(assignSheet.Cells(3, 4), assignSheet.Cells(assignRows, 4) 
    Set c = myRng.Find(empName, lookin:=xlValues) 
    if Not c is Nothing Then 'you found last name, no look to see if first is a match 
     if assignSheet.cells(c.row, 5) = empFirst then 'if it is, do something 
      'do whatever you need to do here 
     else 
      firstAddress = c.Address 
      Do 
       Set c = myRng.FindNext(c) 

       if Not c is Nothing Then 'you found last name, no look to see if first is a match 
        if assignSheet.cells(c.row, 5) = empFirst then 'if it is, do something 
         'do whatever you need to do here 
        end if 
       end if 
      Loop While Not c Is Nothing And c.Address <> firstAddress 
     end if 
    end if 
Next i 

Für weitere Informationen über find, schauen here.

+0

War gerade in diesem, meine Frage aktualisiert. Ich denke, du hast es falsch verstanden. Gerade geklärt es ein wenig –

+0

OK. Ja, ich würde Vor- und Zunamen mehr oder weniger verketten, wie ich es in meiner Antwort angegeben habe, und Sie haben in Ihrer aktualisierten Frage angegeben, dass Sie dann die von mir erwähnte Suchfunktion verwenden und dabei nur eine Schleife brauchen, nicht zwei. –

+0

Oh, ich sehe, Sie wollen nicht in der Tabelle verketten. Warum verketten Sie dann nicht in Ihrem Code und speichern das Ergebnis in einem Array? –

1

Sie müssen nur wissen, ob es da ist ... dann COUNTIFS wie verwenden:

=COUNTIFS(A:A,"Name",B:B,"Lastname"....) 

und wenn es nicht 0 ist, dann ist es eine Übereinstimmung.

Für VBA ist es

Application.Countifs(Range("A:A"),"Name",Range("B:B"),"Lastname"....) 

Wenn Sie Fragen haben, links, fragen Sie einfach;)

EDIT

... Ich brauche die Zeilennummer, die sie existieren in ...

Du hast ne ver sagte das! * Wütendes Gesicht * ... noch ist es möglich, in einer mehr oder weniger schnelle Weise zu tun:

Sub test() 
    Dim val As Variant, rowNum As Variant 
    With Sheets("Sheet1") 
    val = Evaluate(Intersect(.Columns(1), .UsedRange).Address & "&"" --- ""&" & Intersect(.Columns(2), .UsedRange).Address) 
    rowNum = Application.Match("name" & " --- " & "firstname", val, 0) 
    If IsNumeric(rowNum) Then Debug.Print "Found at Row: " & rowNum Else Debug.Print "Nothing was found" 
    End With 
End Sub 
+0

Ja, das funktioniert nur, um herauszufinden, ob sie existieren, aber ich brauche auch die Zeilennummer, in der sie existieren. Suche ist besser für mein Problem, weil ich die Zeilennummer finden kann. –

+0

überprüfe bitte meinen Schnitt ... es sollte ziemlich schnell laufen;) –

+0

Das klappte auch nach ein paar Optimierungen. Ich wünschte, ich könnte zwei richtige Antworten wählen. Danke –

0

ich in der Regel ein Wörterbuch verwenden oder eine Sammlung, wenn Sie nach Duplikaten suchen. Auf diese Weise muss ich jede Liste nur einmal durchlaufen.

Sub FindDuplicates() 
    Dim empFirst As String, empLast As String, empName As String 
    Dim assignSheet As Worksheet, managerSheet As Worksheet 
    Dim i As Long, lastRow As Long 
    Dim d 
    Set assignSheet = Sheet2 
    Set managerSheet = Sheet1 

    Set d = CreateObject("Scripting.Dictionary") 
    With managerSheet 
     lastRow = .Range("A" & Rows.Count).End(xlUp).Row 

     For i = 2 To lastRow 'Looping through the Managers Table 
      empFirst = .Cells(i, 1) 
      empLast = .Cells(i, 2) 
      empName = (empLast & ", " & empFirst) 
      If Not d.exists(empName) Then d.Add empName, i 
     Next 
    End With 


    With assignSheet 
     lastRow = .Range("A" & Rows.Count).End(xlUp).Row 

     For i = 2 To lastRow 'Looping through the Managers Table 
      empFirst = .Cells(i, 4) 
      empLast = .Cells(i, 5) 
      empName = (empLast & ", " & empFirst) 
      If d.exists(empName) Then 

       Debug.Print "Match Found", empName, "assignSheet Row:" & i, "managerSheet Row:" & d(empName) 

      End If 

     Next 
    End With 

End Sub 

enter image description here

Verwandte Themen