Excel 查找匹配范围的地址

Excel 查找匹配范围的地址,excel,excel-formula,Excel,Excel Formula,在下图中,我试图找到所有匹配单元格的地址。也就是说,如果在3行中找到一个源(例如),那么我需要显示类似于F2:F4的地址 正如你在图片中看到的,我创建了一个公式,它给出了匹配的第一个实例的地址,但不是完整的范围 =单元格(“地址”,索引($F$2:$F$12,匹配(A2,$F$2:$F$12,0),1)) 如何获取完整范围的地址?假设数据已排序,则公式需要两部分,第一部分获取第一个单元格的地址,第二部分获取最后一个单元格的地址。你已经得到了第一部分。对于第二部分,您可以使用类似的公式,但请注意

在下图中,我试图找到所有匹配单元格的地址。也就是说,如果在3行中找到一个源(例如),那么我需要显示类似于F2:F4的地址

正如你在图片中看到的,我创建了一个公式,它给出了匹配的第一个实例的地址,但不是完整的范围

=单元格(“地址”,索引($F$2:$F$12,匹配(A2,$F$2:$F$12,0),1))


如何获取完整范围的地址?

假设数据已排序,则公式需要两部分,第一部分获取第一个单元格的地址,第二部分获取最后一个单元格的地址。你已经得到了第一部分。对于第二部分,您可以使用类似的公式,但请注意
MATCH
是如何不同的:

=CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,0)))&":"&CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,1)))


编辑:我错过了前面第二部分的更简单的
匹配解决方案。如果您仍然对前面的数组公式感兴趣,请使用以下公式:

=CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,0)))&":"&CELL("address",INDEX($F$2:$F$16,MAX(IF($F$2:$F$16=A2,ROW($F$2:$F$16)-1))))

假设数据已排序,公式将需要两部分,第一部分获取第一个单元格的地址,第二部分获取最后一个单元格的地址。你已经得到了第一部分。对于第二部分,您可以使用类似的公式,但请注意
MATCH
是如何不同的:

=CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,0)))&":"&CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,1)))


编辑:我错过了前面第二部分的更简单的
匹配解决方案。如果您仍然对前面的数组公式感兴趣,请使用以下公式:

=CELL("address",INDEX($F$2:$F$16,MATCH(A2,$F$2:$F$16,0)))&":"&CELL("address",INDEX($F$2:$F$16,MAX(IF($F$2:$F$16=A2,ROW($F$2:$F$16)-1))))

如果您对使用VBA更改事件感兴趣,可以尝试:

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim LastrowA As Long, LastrowF As Long, i As Long, y As Long
    Dim Source As String, strAddress As String
    Dim ws As Worksheet

    'Set the sheet which you will use
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    With ws
        'Find Last rows for Column A & F
        LastrowA = .Cells(.Rows.Count, "A").End(xlUp).Row
        LastrowF = .Cells(.Rows.Count, "F").End(xlUp).Row
    End With

    'Chek if the changes intersect our ranges

    If Not Intersect(Target, Range("A:A", "F:F")) Is Nothing Then

        For i = 2 To LastrowA

            Source = ws.Range("A" & i).Value

            Application.EnableEvents = False
                'Count Times
                ws.Range("B" & i).Value = Application.WorksheetFunction.CountIf(ws.Range("F2:F" & LastrowF), Source)

                strAddress = ""
                'Import Address
                For y = 2 To LastrowF
                    If ws.Range("F" & y).Value = Source Then
                        If strAddress = "" Then
                            strAddress = ws.Range("F" & y).Address
                        Else
                            strAddress = strAddress & "," & ws.Range("F" & y).Address
                        End If
                    End If
                Next y

                ws.Range("C" & i).Value = strAddress

            Application.EnableEvents = True

        Next i

    End If

End Sub
结果:


如果您对使用VBA更改事件感兴趣,可以尝试:

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim LastrowA As Long, LastrowF As Long, i As Long, y As Long
    Dim Source As String, strAddress As String
    Dim ws As Worksheet

    'Set the sheet which you will use
    Set ws = ThisWorkbook.Worksheets("Sheet1")

    With ws
        'Find Last rows for Column A & F
        LastrowA = .Cells(.Rows.Count, "A").End(xlUp).Row
        LastrowF = .Cells(.Rows.Count, "F").End(xlUp).Row
    End With

    'Chek if the changes intersect our ranges

    If Not Intersect(Target, Range("A:A", "F:F")) Is Nothing Then

        For i = 2 To LastrowA

            Source = ws.Range("A" & i).Value

            Application.EnableEvents = False
                'Count Times
                ws.Range("B" & i).Value = Application.WorksheetFunction.CountIf(ws.Range("F2:F" & LastrowF), Source)

                strAddress = ""
                'Import Address
                For y = 2 To LastrowF
                    If ws.Range("F" & y).Value = Source Then
                        If strAddress = "" Then
                            strAddress = ws.Range("F" & y).Address
                        Else
                            strAddress = strAddress & "," & ws.Range("F" & y).Address
                        End If
                    End If
                Next y

                ws.Range("C" & i).Value = strAddress

            Application.EnableEvents = True

        Next i

    End If

End Sub
结果:


排序数据允许您利用二进制查找匹配。它们编写简单,功能上比未排序的查找更快

=ADDRESS(MATCH(A2, E:E, 0), 5, 4)&":"&ADDRESS(MATCH(A2&" ", E:E), 5, 4)
第一个地址是传统的精确匹配。第二个地址是通过在排序列表中添加后缀空格字符来查找最后一个地址来实现的

因为您处理的是一个已知的列,所以我放弃了CELL函数,转而使用ADDRESS构造函数


这种对排序数据进行二进制匹配的方法将对未排序的数据产生不可靠的结果(结果,而不是错误,可能是正确的,也可能是不正确的)。

排序数据允许您利用二进制查找匹配。它们编写简单,功能上比未排序的查找更快

=ADDRESS(MATCH(A2, E:E, 0), 5, 4)&":"&ADDRESS(MATCH(A2&" ", E:E), 5, 4)
第一个地址是传统的精确匹配。第二个地址是通过在排序列表中添加后缀空格字符来查找最后一个地址来实现的

因为您处理的是一个已知的列,所以我放弃了CELL函数,转而使用ADDRESS构造函数


这种对已排序数据进行二进制匹配的方法将对未排序的数据产生不可靠的结果(结果,而不是错误,可能是正确的,也可能是不正确的)。

问题在于
CELL()
返回一个单元格地址。您必须执行一些字符串操作才能获得范围。F列是否已排序?在实际数据中,F列是否已排序?@user11087823-现在我查看了真实数据,是的,它已排序。问题是
CELL()
返回一个单元格地址。您必须执行一些字符串操作才能获得范围。F列是否已排序?在您的实际数据中,F列是否已排序?@user11087823-现在我查看了我的真实数据,是的,它已排序。谢谢。我确实尝试过使用max方法,但没有得到预期的结果,因为我没有将其作为数组公式。现在它可以工作了,但我仍然不明白数组公式在这种情况下是如何工作的。如果数据被实际排序,那么我相信MATCH可以很容易地返回最后一行,而不需要数组公式。问题中的样本数据未排序。@user11087823如果未排序,则范围将不准确。说
A
在范围
F2:F7
内,而
F3
处有A
B
在我看来是有问题的。哦,排序,我的意思是更像所有相似的元素被分组在一起;排序可以确保这一点。每组元素的实际顺序不相关。a)这是分组而不是排序。排序意味着在升序排序中,三个源位于两个源之前,其中一个源位于两个源之前。b) “。。。获取上一次出现的行号“错误”。它获取包含最后一次出现的*单元格。只有
MAX(如果($F$2:$F$16=A2,行($F$2:$F$16)-1))部分才能获得行号。谢谢。我确实尝试过使用max方法,但没有得到预期的结果,因为我没有将其作为数组公式。现在它可以工作了,但我仍然不明白数组公式在这种情况下是如何工作的。如果数据被实际排序,那么我相信MATCH可以很容易地返回最后一行,而不需要数组公式。问题中的样本数据未排序。@user11087823如果未排序,则范围将不准确。说
A
在范围
F2:F7
内,而
F3
处有A
B
在我看来是有问题的。哦,排序,我的意思是更像所有相似的元素被分组在一起;排序可以确保这一点。每组元素的实际顺序不相关。a)这是分组而不是排序。排序意味着在升序排序中,三个源位于两个源之前,其中一个源位于两个源之前。b) “。。。获取上一次出现的行号“错误”。它获取包含最后一次出现的*单元格。只有
MAX(如果($F$2:$F$16=A2,行($F$2:$F$16)-1))部分才能获得行号。谢谢。这也是可行的(不过我将使用公认的答案,因为我不太确定数据是否被排序)。请您解释一下第二部分是如何工作的
MATCH(A2&“
”?上面的开始匹配公式和停止匹配公式之间有什么区别?@asd123添加空格就像告诉
MATCH
寻找一些