如何检查Excel中的上一条和下一条记录是否连续
How to check if the previous and next records are sequential in Excel
我有一个 excel 价差sheet 值。我正在尝试构建一串值,这些值将查看 sheet 中的所有记录并确定哪些是相同的(基于序列)..
如图所示,源数据分为三列(E、F、G)。 (源 ID、目标 ID 和连接 ID).. 基本上源到目标关系只能有一种组合,因此我需要合并任何重复的连接。
到目前为止,我已经设法通过以下方式找到它们何时重复:
连接源和目标(Col H)
使用公式
查找重复项(并对其进行排序)
=IF(COUNTIF(H:H,H2)>1,COUNTIF(H:H2,H2),1)
现在我正在尝试构建一个将用于合并记录的字符串。
本质上,我正在尝试构建一个函数,它在 Col H 中查找所有确切的字符串,然后查看序列 (I) 并构建一个如下所示的字符串:
34~62~65(这告诉我连接 34 必须与 62 合并,然后与 65 合并)
问题是我没有设法做到这一点。
Col J 中的当前公式是:
=IF(H2=H3,IF(I3=I2+1,G3&"~"&G2,""))
但如您所见,它只是成对的,实际上并不是按顺序查找重复项(即 1 然后 2 然后 3 等)
前段时间我为我的一个朋友写了一个相当广泛的UDF来处理这个问题。它应该看起来与 VLookup 完全一样,除了一个额外的参数 UniqueOnly 和一个分隔符。
它的作用是像 VLookup 一样根据不同的单元格查找值,但与 Vlookup 不同的是它 returns 结果是所有可能的值,而不仅仅是一个。
它是这样使用的:
=LookupConcatenate(LookupValue,LookupRange,LookupColumn, [Optional UniqueOnly = 0], [Optional Separator = ", "])
代码是:
Public Function LookupConcatenate(LookupValue As Range, LookupRange As Range, Column As Integer, Optional UniqueOnly As Boolean = False, Optional Separator As String = ", ") As String
' by Marek Stejskal
Dim rngMatch As Range
Dim rngLookup As Range
Dim varMatch As Variant
Dim varIndex As Variant
Dim intFoundAll As Integer
Dim strFoundAll() As String
Dim intFoundUnique As Integer
Dim strFoundUnique() As String
Dim blnFound As Boolean
Dim strResult As String
Dim i As Integer
On Error GoTo ErrHandler:
Set rngLookup = LookupRange
Set rngMatch = rngLookup.Columns(1)
Do While 1 = 1
' Match function
varMatch = Application.Match(LookupValue, rngMatch, 0)
' Exit checking if MATCH returned no value
If IsError(varMatch) Then Exit Do
' Index function
varIndex = Application.Index(rngLookup, varMatch, Column)
intFoundAll = intFoundAll + 1
' Adding space to ALL array
ReDim Preserve strFoundAll(1 To intFoundAll)
' Checking if the new result is in ALL array
blnFound = False
For i = 1 To UBound(strFoundAll)
If strFoundAll(i) = CStr(varIndex) Then
blnFound = True
Exit For
End If
Next
' If new result is unique add it to UNIQUE array
If blnFound = False Then
intFoundUnique = intFoundUnique + 1
ReDim Preserve strFoundUnique(1 To intFoundUnique)
strFoundUnique(intFoundUnique) = CStr(varIndex)
End If
' Add the new result to ALL array
strFoundAll(intFoundAll) = CStr(varIndex)
' Shortening ranges
Set rngLookup = rngLookup.Resize(rngLookup.Rows.Count - varMatch).Offset(varMatch)
Set rngMatch = rngLookup.Columns(1)
Loop
' Creating result string
If UniqueOnly = True Then
If intFoundUnique = 0 Then
strResult = ""
Else
For i = 1 To UBound(strFoundUnique)
strResult = strResult & IIf(strResult = "", "", Separator) & strFoundUnique(i)
Next i
End If
Else
If intFoundAll = 0 Then
strResult = ""
Else
For i = 1 To UBound(strFoundAll)
strResult = strResult & IIf(strResult = "", "", Separator) & strFoundAll(i)
Next i
End If
End If
LookupConcatenate = strResult
Exit Function
ErrHandler:
LookupConcatenate = Err.Description
End Function
为了使这项工作适合您,您首先需要调换 Connection
和 ID
的顺序,然后您可以将公式放在第 2 行,如下所示:
=LookupConcatenate(G2, G2:J100, 2, 0, "~")
因此,如果您想在没有 VBA 的情况下执行此操作,唯一的方法是在逐行向下构建字符串。我的意思是最终数据看起来像:
这不符合包含完整串联字符串的所有列 "F" 的完整要求。但 ID 的最后一行将包含最终字符串。
F 列中的公式(假设您的数据与此处的图片对齐)
=IF(ISERROR(MATCH($D2,INDIRECT("D1:D"&ROW()-1),0)),""&$C2,IFERROR(INDEX(F:F,MATCH($D2,INDIRECT("D1:D"&ROW()-1),1)),INDEX(F:F,MATCH($D2,INDIRECT("D1:D"&ROW()-1),0)))&"~"&$C2)
即使行未排序,它也能工作(实际上它根本不使用序列列)。这是一张添加了额外行作为测试数据的图片:
您实际上可以通过添加包含以下内容的列来创建您正在搜索的列:
=IF(COUNTIF($F:$F,SUBSTITUTE($F2,"~","*")&"*")=1,$F2,FALSE)
最终结果如下:
我有一个 excel 价差sheet 值。我正在尝试构建一串值,这些值将查看 sheet 中的所有记录并确定哪些是相同的(基于序列)..
如图所示,源数据分为三列(E、F、G)。 (源 ID、目标 ID 和连接 ID).. 基本上源到目标关系只能有一种组合,因此我需要合并任何重复的连接。
到目前为止,我已经设法通过以下方式找到它们何时重复: 连接源和目标(Col H) 使用公式
查找重复项(并对其进行排序)=IF(COUNTIF(H:H,H2)>1,COUNTIF(H:H2,H2),1)
现在我正在尝试构建一个将用于合并记录的字符串。
本质上,我正在尝试构建一个函数,它在 Col H 中查找所有确切的字符串,然后查看序列 (I) 并构建一个如下所示的字符串:
34~62~65(这告诉我连接 34 必须与 62 合并,然后与 65 合并) 问题是我没有设法做到这一点。 Col J 中的当前公式是:
=IF(H2=H3,IF(I3=I2+1,G3&"~"&G2,""))
但如您所见,它只是成对的,实际上并不是按顺序查找重复项(即 1 然后 2 然后 3 等)
前段时间我为我的一个朋友写了一个相当广泛的UDF来处理这个问题。它应该看起来与 VLookup 完全一样,除了一个额外的参数 UniqueOnly 和一个分隔符。
它的作用是像 VLookup 一样根据不同的单元格查找值,但与 Vlookup 不同的是它 returns 结果是所有可能的值,而不仅仅是一个。
它是这样使用的:
=LookupConcatenate(LookupValue,LookupRange,LookupColumn, [Optional UniqueOnly = 0], [Optional Separator = ", "])
代码是:
Public Function LookupConcatenate(LookupValue As Range, LookupRange As Range, Column As Integer, Optional UniqueOnly As Boolean = False, Optional Separator As String = ", ") As String
' by Marek Stejskal
Dim rngMatch As Range
Dim rngLookup As Range
Dim varMatch As Variant
Dim varIndex As Variant
Dim intFoundAll As Integer
Dim strFoundAll() As String
Dim intFoundUnique As Integer
Dim strFoundUnique() As String
Dim blnFound As Boolean
Dim strResult As String
Dim i As Integer
On Error GoTo ErrHandler:
Set rngLookup = LookupRange
Set rngMatch = rngLookup.Columns(1)
Do While 1 = 1
' Match function
varMatch = Application.Match(LookupValue, rngMatch, 0)
' Exit checking if MATCH returned no value
If IsError(varMatch) Then Exit Do
' Index function
varIndex = Application.Index(rngLookup, varMatch, Column)
intFoundAll = intFoundAll + 1
' Adding space to ALL array
ReDim Preserve strFoundAll(1 To intFoundAll)
' Checking if the new result is in ALL array
blnFound = False
For i = 1 To UBound(strFoundAll)
If strFoundAll(i) = CStr(varIndex) Then
blnFound = True
Exit For
End If
Next
' If new result is unique add it to UNIQUE array
If blnFound = False Then
intFoundUnique = intFoundUnique + 1
ReDim Preserve strFoundUnique(1 To intFoundUnique)
strFoundUnique(intFoundUnique) = CStr(varIndex)
End If
' Add the new result to ALL array
strFoundAll(intFoundAll) = CStr(varIndex)
' Shortening ranges
Set rngLookup = rngLookup.Resize(rngLookup.Rows.Count - varMatch).Offset(varMatch)
Set rngMatch = rngLookup.Columns(1)
Loop
' Creating result string
If UniqueOnly = True Then
If intFoundUnique = 0 Then
strResult = ""
Else
For i = 1 To UBound(strFoundUnique)
strResult = strResult & IIf(strResult = "", "", Separator) & strFoundUnique(i)
Next i
End If
Else
If intFoundAll = 0 Then
strResult = ""
Else
For i = 1 To UBound(strFoundAll)
strResult = strResult & IIf(strResult = "", "", Separator) & strFoundAll(i)
Next i
End If
End If
LookupConcatenate = strResult
Exit Function
ErrHandler:
LookupConcatenate = Err.Description
End Function
为了使这项工作适合您,您首先需要调换 Connection
和 ID
的顺序,然后您可以将公式放在第 2 行,如下所示:
=LookupConcatenate(G2, G2:J100, 2, 0, "~")
因此,如果您想在没有 VBA 的情况下执行此操作,唯一的方法是在逐行向下构建字符串。我的意思是最终数据看起来像:
这不符合包含完整串联字符串的所有列 "F" 的完整要求。但 ID 的最后一行将包含最终字符串。
F 列中的公式(假设您的数据与此处的图片对齐)
=IF(ISERROR(MATCH($D2,INDIRECT("D1:D"&ROW()-1),0)),""&$C2,IFERROR(INDEX(F:F,MATCH($D2,INDIRECT("D1:D"&ROW()-1),1)),INDEX(F:F,MATCH($D2,INDIRECT("D1:D"&ROW()-1),0)))&"~"&$C2)
即使行未排序,它也能工作(实际上它根本不使用序列列)。这是一张添加了额外行作为测试数据的图片:
您实际上可以通过添加包含以下内容的列来创建您正在搜索的列:
=IF(COUNTIF($F:$F,SUBSTITUTE($F2,"~","*")&"*")=1,$F2,FALSE)
最终结果如下: