【发布时间】:2020-02-28 19:15:17
【问题描述】:
【问题讨论】:
-
我知道我们必须使用Split下的一个函数,然后将它们两者进行比较,然后将其恢复为123、124、125序列形式
-
这是否意味着这是一个有限制的家庭作业问题?
-
@RonRosenfeld 不,只是我在工作中加班
【问题讨论】:
使用Filter()函数的方法
Function test(ByVal a, ByVal b, Optional Delim$ = ",") As String
'Purpose: return non unique values by comparing two comma separated string lists a vs. b
a = Split(a, Delim): b = Split(b, Delim)
Dim elem
For Each elem In b
a = Filter(a, elem, False) ' Include:=False, i.e. exclude non uniques
Next elem
test = Join(a, Delim & " ")
End Function
论据 a: 668,669,777,778,779,780,781,782,891,893,894,895
论据 b: 668,777,779,778,780,892,891,782
结果字符串 669、781、893、894、895
顺便说一句,结果不应包含 782 (c.f. OP),因为这不是一个独特的项目。
警告/编辑
上述方法仅假设三个数字。因为基本上Filter 函数执行部分字符串搜索,如果您要搜索例如,这将导致不需要的结果。 7 因此也排除了任何包含 7 的数字。 ~~> 查看修改后的代码
修改后的代码
只允许完整的字符串匹配:
变体 a) 第二个列表包含双峰,但只是第一个列表的子集
Function test(ByVal a, ByVal b, Optional Delim$ = ",") As String
'Purpose: return non unique values by comparing two comma separated string lists a vs. b
a = "$" & Replace(a, Delim, "$" & Delim & "$") & "$"
a = Split(a, Delim): b = Split(b, Delim)
Dim elem
For Each elem In b
a = Filter(a, "$" & elem & "$", False) ' Include:=False, i.e. exclude non uniques
Next elem
test = Replace(Join(a, Delim & " "), "$", vbNullString)
End Function
变体 b) 第二个列表还包含与第一个列表不同的新数字
这可能是您问题的防水解决方案(结果对应于@RonRosenfeld 的精细解决方案)。
Function test(ByVal a, ByVal b, Optional Delim$ = ",", Optional ByVal cnt% = 1) As String
'Purpose: return non unique values by comparing two comma separated string lists a vs. b
If cnt = 1 Then ' recursive call to check 2nd string against 1st one
test = test(b, a, Delim, 2)
If Len(test) > 1 Then test = Mid(test, 1, Len(test) - 1)
End If
a = "$" & Replace(a, Delim, "$" & Delim & "$") & "$"
a = Split(a, Delim): b = Split(b, Delim)
Dim elem
For Each elem In b
a = Filter(a, "$" & elem & "$", False) ' Include:=False, i.e. exclude non uniques
Next elem
test = Replace(Join(a, Delim), "$", vbNullString) & Delim & test
If cnt = 0 Then test = Replace(test, Delim, Delim & " ") ' add blank after delimiters
End Function
【讨论】:
如果您将 Excel 2016 或 Office 365 与 TEXTJOIN 函数一起使用,则可以使用 数组公式
=TEXTJOIN(", ",,FILTERXML("<t><s>" & SUBSTITUTE(SUBSTITUTE(TEXTJOIN(",",TRUE,Data_1,Data_2)," ",""),",","</s><s>") & "</s></t>","//s[not( .=preceding::*) and not(.=following::*)]"))
由于这是一个数组公式,您需要通过按住 ctrl + shift 的同时点击 enter 来“确认”它。如果您正确执行此操作,Excel 将在公式周围放置大括号 {...},如公式栏中所示
TEXTJOIN 使用逗号分隔符的字符串
TEXTJOIN 函数,但您仍然需要 Excel 2013+ 才能拥有 FILTERXML 函数
<comma><space>,我们可以稍微简化一下公式。
<comma> 创建一个XML 来定义节点。xPath 表示返回所有不跟随或不跟随重复的节点。TEXTJOIN 结果数组【讨论】:
TEXTJOIN 函数,那么公式应该可以工作。
FilterXML 函数中的XPath 表达式不仅棘手,而且证明在这一行公式+1 中非常有效。 - BTW 是否有使用相同标签的函数节点命名的通用帮助源,即<t> 和<s>? .. 参考recent post using FILTERXML ? - @RonRosenfeld
Function TEST(aString As String, aString2 As String, Optional Delimiter As String = ",") As String
array1 = Split(aString, Delimiter)
array2 = Split(aString2, Delimiter)
Dim i 'As Integer
Dim j 'As Integer
Dim isFound 'As Boolean
Dim output
For i = 0 To UBound(array1)
isFound = False
For j = 0 To UBound(array2) - 1
If array1(i) = array2(j) Then
isFound = True
End If
Next 'j
If Not isFound Then
output = output + array1(i) & ", "
End If
Next 'i
TEST = output
End Function
【讨论】:
782 项目不是唯一的,不应出现在您的列表中。原因:为了避免结果字符串中出现最终分隔符,您的 j 循环忘记仅在计数到 UBound(array2) - 1 instead to UBound(array2)` 时要比较的最后一个 array2 项。如果输出 len(gth) 大于 0,只需将最后一个分隔符替换为 ""。(不要忘记将 array1 和 array2 声明为 Variant;~> Option Explicit!) - / / 仅供参考 通往罗马的方法有很多,也许您会发现我使用 Filter() 函数的方法很有帮助。