我有一个excel电子表格的值。我正在尝试构建一个值的字符串,它将查看工作表中的所有记录并确定哪些是相同的(基于序列)。
如图所示,有三列(E,F,G)包含源数据。 (源ID,目标ID和连接ID)..基本上只有源到目标关系的一种组合,所以我需要合并任何重复的连接。
到目前为止,我已经设法找到它们重复的时间: 连接源和目标(Col H) 使用公式
寻找重复项(并对它们进行排序)=IF(COUNTIF(H:H,H2)>1,COUNTIF(H$2: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等)
答案 0 :(得分:2)
前段时间我为我的一个朋友写了一个相当广泛的UDF来处理这个问题。它应该看起来像一个VLookup,除了一个额外的参数UniqueOnly和一个分隔符。
它的作用是基于不同的单元格查找一个值,就像VLookup一样,但与Vlookup不同,它会返回所有可能的值,而不仅仅是一个。
它的用法如下:
= 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,“〜”)
答案 1 :(得分:1)
因此,如果您想在没有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)
这将给出以下最终结果: