如果在列中找到重复的单元格值,则返回值
Posted
技术标签:
【中文标题】如果在列中找到重复的单元格值,则返回值【英文标题】:IF duplicate cell value found in column then return value 【发布时间】:2015-08-10 02:59:47 【问题描述】:我需要在数据表中跟踪一个人,以确定该人从哪个位置移动到哪个位置。
如果一个人在 J 列中出现超过一次,这意味着该人已更改位置,并且位置值在 L 列中。为此,我有以下代码:
=IF(J18=J19;IF(COUNTIF(J:J;J18)>1; "From "&L18 &" to "& IF(J18=J19;L19;"");"");"")
问题是如果此人更改位置超过两次。在 O 列到 AA 列中,我有一年中的月份,它决定了这个人的位置。
如何修改此代码以执行上述操作:
=IF(J18=J19;IF(COUNTIF(J:J;J18)>1; "From "&L18 &" to "& IF(J18=J19;L19;"");"");"")
【问题讨论】:
@Byron 这里是图片link 【参考方案1】:这是一个用户定义函数(又名UDF)来完成任务。
Function my_Travels(nm As Range, loc As Range, cal As Range)
Dim n As Long, cnt As Long, v As Long, vLOCs As Variant, vTMPs As Variant
Dim iLOC As Long, sTMP As String
my_Travels = vbNullString '"no travels"
cnt = Application.CountIf(nm.EntireColumn, nm(1))
If Application.CountIf(nm, nm(1)) = cnt And cnt > 1 Then
Set loc = loc.Rows(1).Resize(nm.Rows.Count, loc.Columns.Count)
Set cal = cal.Rows(1).Resize(nm.Rows.Count, cal.Columns.Count)
'seed the array
ReDim vLOCs(1 To cnt, 1 To cnt)
For v = LBound(vLOCs, 1) To UBound(vLOCs, 1)
vLOCs(v, 1) = cal.Columns.Count + 1
vLOCs(v, 2) = cal.Columns.Count + 1
Next v
'collect the values into the array
For n = 1 To nm.Rows.Count
If nm.Cells(n, 1).Value2 = nm.Cells(1, 1).Value2 Then
iLOC = Application.Match(1, Application.Index(cal, n, 0), 0)
For v = LBound(vLOCs, 1) To UBound(vLOCs, 1)
If vLOCs(v, 1) = cal.Columns.Count + 1 Then
vLOCs(v, 1) = iLOC
vLOCs(v, 2) = n
Exit For
End If
Next v
End If
Next n
'sort the values in the array
For v = LBound(vLOCs, 1) To (UBound(vLOCs, 1) - 1)
For n = (v + 1) To UBound(vLOCs, 1)
If vLOCs(v, 1) > vLOCs(n, 1) Then
vTMPs = Array(vLOCs(v, 1), vLOCs(v, 2))
vLOCs(v, 1) = vLOCs(n, 1)
vLOCs(v, 2) = vLOCs(n, 2)
vLOCs(n, 1) = vTMPs(0)
vLOCs(n, 2) = vTMPs(1)
Exit For
End If
Next n
Next v
'concatenate the locations from the array
For v = LBound(vLOCs) To (UBound(vLOCs) - 1)
sTMP = sTMP & "From " & loc.Cells(vLOCs(v, 2), 1) & " to " & loc.Cells(vLOCs(v + 1, 2), 1) & "; "
Next v
'truncate the string and return it
sTMP = Left(sTMP, Len(sTMP) - 2)
my_Travels = sTMP
End If
End Function
Locations 和 Calendar 单元格只需要由第一行定义。每个都重新定义了其高度(即行)以保持与名称列表的一致性。
在 AB2(如上)中,公式为,
=my_Travels(J2:J$8, L2, O2:AA2)
根据需要填写。
【讨论】:
亲爱的@Jeeped 非常感谢您!效果很好 :) 我有两个问题: 1. 如果没有 VBA,这可能吗? 2. 在日历单元格中,值可以从 0,1 到 1,因此是否可以更改代码以“计数”所有大于 0,1 的单元格?再次感谢你:) 1) 勉强可以,但计算量会很大。迭代未知数量的行来连接字符串意味着您必须“涵盖所有可能性”²。 VBA 可以动态定义其循环的大小。 2)听起来这会改变原来的条件,以至于这不再是一个有效的答案。如果是这样的话,那应该是另一个问题了。简而言之,很难击中移动的目标。 好的,听起来很公平。还有一件事:有时一个人的位置相同,即使这个名字出现了不止一次。如果在出现人名的每一行中位置都相同,是否可以不在 AB 列中显示位置?谢谢你:) 一切皆有可能。听起来您可能需要删除重复的数据,但是如果将相同的位置记录为不同的日期,那么就会设置一个完全不同的场景。与预期结果捆绑在一起的样本数据是确定这一点的唯一方法。同样,您不断更改测试条件。 FWIW,我发现您的原始问题很有趣,一旦您将问题的参数定义为某种程度的清晰,我将其视为一项智力练习,尽管我认为没有人会再次有同样的问题。虽然您的头脑可能正在与新的可能性赛跑,但回复您询问的人确实非常坚忍,并期望解决一组有限的参数。如果您确实发布了新问题,请提供足够的数据(和预期结果)来说明问题。您自己寻找答案的努力应该放在首位。以上是关于如果在列中找到重复的单元格值,则返回值的主要内容,如果未能解决你的问题,请参考以下文章