我想知道一组特定的单元格是否与使用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 Name
,First Name
和Project 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:已解决
我已使用find
和findNext
成功过滤了三列。在一些好的答案的帮助下。我将发布完成的版本。我必须在我的过滤器中添加额外的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
答案 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