Excel 如果在列中找到重复的单元格值,则返回值

Excel 如果在列中找到重复的单元格值,则返回值,excel,if-statement,indexing,match,countif,Excel,If Statement,Indexing,Match,Countif,我需要在数据表中跟踪一个人,以确定此人从哪个位置移动到哪个位置 如果某个人在第J列中出现多次,则表示该人已更改位置,且位置值在第L列中。为此,我有以下代码: =IF(J18=J19;IF(COUNTIF(J:J;J18)>1; "From "&L18 &" to "& IF(J18=J19;L19;"");"");"") 问题是,如果此人更改位置超过两次。在O列至AA列中,我有一年中确定此人所在位置的月份 如何修改此代码以执行上述操作: =IF(J18=J19;I

我需要在数据表中跟踪一个人,以确定此人从哪个位置移动到哪个位置

如果某个人在第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;"");"");"")
这里有一个用户定义的函数(也称为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
位置和日历单元格只需要由第一行定义。每个都重新定义了其高度(即行),以保持与名称列表的一致性

在AB2(如上)中,公式为

=my_Travels(J2:J$8, L2, O2:AA2)

根据需要填写。

@Byron这是照片亲爱的@Jeeped非常感谢!我有两个问题:1。如果没有VBA,这可能吗?2.在日历单元格中,值可以从0,1到1,因此是否可以将代码更改为“计数”大于0,1的所有单元格?再次感谢:)1)可能性不大,但计算量会很大。迭代未知数量的行以连接字符串意味着您必须“覆盖所有可能性”。VBA可以动态定义其循环的大小。2) 它会改变原来的条件,使之不再是一个有效的答案。如果是这样,那应该是另一个问题。简而言之,很难击中移动的目标。好吧,听起来很公平。还有一件事:有时一个人有相同的位置,即使这个名字出现了不止一次。如果姓名出现的每一行中的位置都相同,是否可以不在AB列中显示位置?谢谢:)一切皆有可能。听起来您可能需要删除重复的数据,但如果将同一位置记录为不同的日期,则会设置一个完全不同的场景。将样本数据与预期结果捆绑在一起是确定这一点的唯一方法。同样,你不断地改变测试条件。FWIW,我发现你原来的问题很有趣。一旦你把问题的参数定义得很清楚,我就把它当作一种智力练习,尽管我认为没有人会再遇到同样的问题。虽然你的头脑中可能充满了新的可能性,但回应你询问的人实际上相当坚忍,他们希望能够解决一组有限的参数。如果您确实发布了一个新问题,请提供足够的数据(和预期结果)来说明该问题。你自己寻找答案的努力应该是最重要的。