[英]Finding if a column cell equals another in a different sheet
I want to find out if a particular group of cells match another group of cells in a different sheet using VBA. 我想找出特定的一组单元格是否使用VBA与另一张工作表中的另一组单元格匹配。 In my case, I need to find out if the lastName, firstName
cells match. 就我而言,我需要找出lastName, firstName
单元格是否匹配。 In my solution that I came up with, I'm looping through the first table, getting the employee name. 在我想出的解决方案中,我遍历第一个表,获取员工姓名。 Then looping through the second table, getting the employee name. 然后遍历第二个表,获取员工姓名。 Then seeing if the two match up. 然后看看两者是否匹配。 This method is too costly and takes too long. 该方法太昂贵并且花费太长时间。 Is there any better way to do this? 有什么更好的方法吗?
My first table contains 6 rows, my second table can contain 100+ rows. 我的第一张表包含6行,我的第二张表可以包含100多行。 Too much time is wasted. 浪费太多时间。
I was thinking about just searching down the entire column to see if the last name matches first, if it does, then go and see if the first name matches... but then again, there could be some people with the same last name.. 我正在考虑只搜索整个列,以查看姓氏是否首先匹配,如果匹配,然后再去查看该名字是否匹配...但是,同样地,可能会有一些人使用相同的姓氏。 。
Here is what I have so far. 这是我到目前为止所拥有的。
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
I know I have no conditional statement, I didn't bother writing it because I knew this approach is not the best one. 我知道我没有条件声明,我也不必费心编写它,因为我知道这种方法不是最好的方法。
I cannot add another column to concatenate the second sheets names because they are read from a database and kept in separate columns and last name and first name. 我无法添加另一列来连接第二个工作表名称,因为它们是从数据库中读取的,并保存在单独的列中以及姓氏和名字。 Anyways, is there a way that I can concatenate the names without adding another column to the second sheet and try to find them that way? 无论如何,有没有一种方法可以连接名称, 而无需在第二张工作表中添加另一列并尝试以这种方式查找它们? Does that make sense? 那有意义吗?
Find
will only look in one column if I'm not mistaken. 如果我没有记错的话, Find
只会查找一列。 Can it look in two? 能看成两半吗?
UPDATE UPDATE
I'm able to get the first occurrence of the last name, but not the others. 我能够获得姓氏的第一个出现,而其他人则没有。 I've added another field to match. 我添加了另一个字段进行匹配。 So there are three fields to match now. 因此,现在要匹配三个字段。 Last Name
, First Name
, and Project Name
. Last Name
, First Name
和Project Name
。 So far, my code will only find the first occurrence and stay there. 到目前为止,我的代码只会找到第一个匹配项并停留在那里。 I think my order of the looping is wrong. 我认为我的循环顺序是错误的。
Here is what I have so far. 这是我到目前为止所拥有的。
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
Take a look at 'Is this in the wrong place?
看看'Is this in the wrong place?
for my new loop. 为我的新循环。
UPDATE 2: Solved 更新2:解决
I have successfully filtered on three columns using find
and findNext
. 我已经使用find
和findNext
成功过滤了三列。 With the help of some good answers. 在一些好的答案的帮助下。 I will post the completed version. 我将发布完整版本。 I had to add extra else statement into my filters in order to go to the next ling found. 我不得不在过滤器中添加其他else语句,以转到找到的下一个ling。 Hopefully others can learn from this, as there is no clear answer for filtering on three columns using find
. 希望其他人可以从中学习,因为对于使用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
Instead of using two loops, you can use just the first one and utilize the find
function. 除了使用两个循环,您还可以只使用第一个循环并使用find
函数。 I believe it'll be faster for you. 我相信这对您会更快。
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
For more information on find
, look here . 有关find
更多信息,请单击此处 。
you only need to know if it is there... then use COUNTIFS like: 您只需要知道它是否在那里...然后使用COUNTIFS就像:
=COUNTIFS(A:A,"Name",B:B,"Lastname"....)
and if it is not 0 then there is a match. 如果不为0,则表示匹配。
For VBA it is 对于VBA
Application.Countifs(Range("A:A"),"Name",Range("B:B"),"Lastname"....)
If you have any questions left, just ask ;) 如果您还有任何疑问,请问;)
EDIT 编辑
... I need the row number that they exist in ... ...我需要它们存在的行号...
You never said that! 你从来没有说过! *angry face*... still, it is possible to do in a more or less fast way: *生气的脸* ...仍然可以或多或少地快速进行:
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
I usually use a dictionary or collection when looking for duplicates. 寻找重复项时,我通常会使用字典或收藏集。 In this way I only have to loop through each list one time. 这样,我只需要遍历每个列表一次。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.