2016-06-29 3 views
1

VBA를 사용하여 특정 시트 그룹이 다른 시트의 다른 셀 그룹과 일치하는지 확인하고 싶습니다. 내 경우에는 lastName, firstName 세포가 일치하는지 알아야합니다. 필자가 생각해 낸 솔루션에서 첫 번째 테이블을 반복하여 직원 이름을 얻었습니다. 그런 다음 두 번째 테이블을 반복하면서 직원 이름을 가져옵니다. 그런 다음 두 사람이 일치하는지 확인합니다. 이 방법은 비용이 너무 많이 들고 너무 오래 걸립니다. 이 작업을 수행하는 더 좋은 방법이 있습니까?다른 시트의 열 셀이 다른 셀과 동일한 지 찾기

내 첫 번째 테이블에는 6 개의 행이 있고 두 번째 테이블에는 100 개 이상의 행이 포함될 수 있습니다. 너무 많은 시간이 낭비됩니다.

전체 열을 검색하여 성이 먼저 일치하는지 확인하고, 일치하면 첫 번째 이름이 일치하는지 확인하려고했지만 다시 한 번 동일한 성 ...

여기까지 내가 지금까지 가지고있는 것입니다. 내가 더 조건문이없는 알고

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

     For j = 3 To assignRows 'Looping through the Assignments table 
      empLastAssign = assignSheet.Cells(i, 4) 
      empFirstAssign = assignSheet.Cells(i, 5) 
      empNameAssign = (empLastAssign & ", " & empFirstAssign) 
      'MsgBox (empNameAssign) 
      ... 
      Conditional statement comparing names 
      ... 
     Next j 
    Next i 

, 난이 방법이 최선이 아니다 알고 있기 때문에 그것을 쓰는 귀찮게하지 않았다.

두 번째 시트 이름을 데이터베이스에서 읽고 다른 열과 성 및 이름으로 유지하기 때문에 두 번째 시트 이름을 연결하는 다른 열을 추가 할 수 없습니다. 어쨌든, 두 번째 시트에 다른 열을 추가하지 않고 이라는 이름을 연결할 수있는 방법이 있습니까? 그런 식으로 찾으시겠습니까? 말이 돼?

Find 내가 잘못하지 않으면 한 열만 보입니다. 두 가지로 볼 수 있습니까?

UPDATE 내가 마지막 이름의 첫 번째 발생을 얻을 수있어

아닌 다른 사람. 일치시킬 다른 입력란을 추가했습니다. 이제는 일치시킬 세 개의 필드가 있습니다. Last Name, First NameProject Name. 지금까지, 내 ​​코드는 첫 번째 발생 만 찾아서 거기에 머물러 있습니다. 루핑 순서가 잘못되었다고 생각합니다.

여기까지 제가 지금까지 있습니다.

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 

내 새 루프는 'Is this in the wrong place?입니다.

업데이트 2 :

해결 나는 성공적으로 findfindNext를 사용하여 세 개의 열을 필터링했다. 좋은 대답 덕분에. 완성 된 버전을 게시합니다. 나는 발견 된 다음 링으로 가기 위해서 다른 필터를 추가해야했다. find을 사용하여 세 개의 열에서 필터링에 대한 명확한 답이 없기 때문에 다른 사람들도이 정보를 얻을 수 있기를 바랍니다.

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

당신은'WorksheetFunction.Vlookup' – JamesFaix

+0

당신이 "큰"시트에 데이터를 정렬 할 수 있겠지? (BTW : 100+ 행은 큰 행 번호가 전혀 없습니다!) – user3598756

답변

1

대신 두 개의 루프를 사용, 당신은 단지 첫 번째를 사용하고 find 기능을 활용할 수 있습니다. 나는 그것이 당신을 위해 더 빠를 것이라고 믿습니다. find에 대한 자세한 내용은

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 

, here을 찾습니다.

+0

그냥 내 질문을 업데이 트이 찾고 있었어요. 나는 당신이 그것을 오해했다고 생각합니다. 그냥 조금 명확하게 –

+0

OK. 예, 저는 답안에 명시된대로 성과 이름을 더 많이 또는 더 적게 연결하고, 업데이트 된 질문에 언급 한 다음 언급 한 찾기 기능을 사용하여 두 개가 아닌 하나의 루프 만 필요로합니다. –

+0

오, 알겠습니다. 스프레드 시트에서 연결하지 않으려합니다. 그런 다음 코드에서 연결하여 배열에 결과를 저장하지 않는 이유는 무엇입니까? –

1

당신은 다음과 같은 COUNTIFS 사용 ... 거기 있는지 알고해야합니다

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

을하고 0이 아닌 경우 다음 경기가있다.

VBA를 들어 당신이 질문이 남아있는 경우

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

, 그냥 물어이며,

편집

) ... 나는 그들이 존재하는 행 번호가 필요합니다 ...

ver는 그것을 말했다! * 화난 얼굴 * ... 아직도, 그것은 다소 빠른 방법으로 할 수 있습니다 : 중복 찾을 때

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

그래, 그냥 존재하는 경우 찾는 데 사용할 수 있지만 그들도 존재하는 행 번호가 필요합니다. 행 번호를 찾을 수 있기 때문에 찾기가 내 문제에 더 좋습니다. –

+0

내 편집을 확인하십시오 ... 꽤 빨리 실행해야합니다;) –

+0

이것은 약간의 조정 후에도 효과가있었습니다. 나는 두 가지 정답을 선택할 수 있었으면 좋겠다. 감사합니다 –

0

나는 보통 사전 또는 모음을 사용합니다. 이 방법으로 각 목록을 한 번만 반복하면됩니다.

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

관련 문제