查找列单元格是否等于另一个工作表中的另一个列单元格

时间:2016-06-29 15:09:33

标签: excel vba excel-vba

我想知道一组特定的单元格是否与使用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只会查看一列。可以看两个吗?

更新

我能够获得姓氏的第一次出现,但不能获得其他姓氏。我添加了另一个匹配的字段。所以现在有三个字段要匹配。 Last NameFirst 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成功过滤了三列。在一些好的答案的帮助下。我将发布完成的版本。我必须在我的过滤器中添加额外的else语句才能转到下一个找到的语句。希望其他人可以从中学习,因为使用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

3 个答案:

答案 0 :(得分:1)

您可以只使用第一个循环并使用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

有关find的详细信息,请查看here

答案 1 :(得分:1)

你只需要知道它是否在那里......然后使用COUNTIFS之类的:

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

如果它不是0,则匹配。

对于VBA,它是

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

如果您还有任何疑问,请询问;)

修改

  

...我需要它们中存在的行号...

你从来没有这么说过! *生气的脸* ......仍然可以用或多或少的方式做:

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

答案 2 :(得分: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