【问题标题】:VBA Excel - How to display non equal values in an excel arrayVBA Excel - 如何在excel数组中显示不相等的值
【发布时间】:2020-02-28 19:15:17
【问题描述】:

所以目前我在 excel 中有两个 DATA 输入 数据 1 和数据 2 我需要一个公式或某种形式来显示结果 *目前这是一个手动过程。

【问题讨论】:

  • 我知道我们必须使用Split下的一个函数,然后将它们两者进行比较,然后将其恢复为123、124、125序列形式
  • 这是否意味着这是一个有限制的家庭作业问题?
  • @RonRosenfeld 不,只是我在工作中加班

标签: arrays excel vba


【解决方案1】:

使用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

【讨论】:

  • 非常感谢。变体 a) 最适合我的情况
【解决方案2】:

如果您将 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 函数
  • 删除空格。 如果所有分隔符都是&lt;comma&gt;&lt;space&gt;,我们可以稍微简化一下公式。
  • 使用&lt;comma&gt; 创建一个XML 来定义节点。
  • xPath 表示返回所有不跟随或不跟随重复的节点。
  • TEXTJOIN 结果数组

【讨论】:

  • 我使用的是 Office 2016
  • @Bamuel 如果你有TEXTJOIN 函数,那么公式应该可以工作。
  • 您在FilterXML 函数中的XPath 表达式不仅棘手,而且证明在这一行公式+1 中非常有效。 - BTW 是否有使用相同标签的函数节点命名的通用帮助源,即&lt;t&gt;&lt;s&gt;? .. 参考recent post using FILTERXML ? - @RonRosenfeld
  • @T.M.节点的命名方式没有任何区别,只要您对所有兄弟节点使用相同的名称,而为 wrapper 使用不同的名称。当然,可以创建更复杂的 xml,但由于我们真正要做的是拆分分隔字符串,然后对其应用 xPath,因此没有必要。
  • @T.M.我不知道。我注意到另一个人正在使用该命名约定,我认为您引用的参考文献中的海报注意到了我对它的使用。
【解决方案3】:
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,只需将最后一个分隔符替换为 ""。(不要忘记将 array1array2 声明为 Variant;~> Option Explicit!) - / / 仅供参考 通往罗马的方法有很多,也许您会发现我使用 Filter() 函数的方法很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 2016-07-08
  • 1970-01-01
相关资源
最近更新 更多