我们如何在 MS Excel 中执行常见的集合操作(​​并集、交集、减号)?

Gau*_*are 8 statistics excel analytics

例如,我有一个 xls,其中:

  • A 列包含具有属性 A 的项目列表
  • B 列包含具有属性 B 的项目列表

我需要以下内容:

  • C列是A联合B(A和B的唯一项目)
  • D 列是 A 交点 B(A 和 B 的公共项)
  • E 列是 A 减去 B(A 中的项目但 B 中没有的项目)
  • F 列是 B 减去 A(B 中的项目但 A 中没有的项目)

使用 SQL 或 Python 对元素列表进行设置操作似乎很容易。但是如何在 xls 中做到这一点?

注意:它应该是一个自动化,复制粘贴和点击次数最少。例如,我不想将 A 复制粘贴到 B 下方,然后“消除重复项”以获得 A 联合 B。

Ben*_*ggs 5

交叉点(在 A 和 B 中): =IFNA(VLOOKUP(B2,$A$2:$B$42,1,FALSE),"")

联合(在 A 或 B 中):=IFS(A2,A2,B2,B2)请注意,IFS仅适用于 Office 2019 和更新版本。

A - B(仅在 A 中): =IF(NOT(IFNA(MATCH(A2,$B$2:$B$42,0),FALSE)),IF(A2,A2,""),"")

B - A(仅在 B 中):(=IF(NOT(IFNA(MATCH(B2,$A$2:$A$42,0),FALSE)),IF(B2,B2,""),"")交换字母)

正在运行的公式的屏幕截图,带有颜色编码。


小智 2

嗯,Microsoft Excel 不处理内置的集合运算。但是您可以使用MATCH函数和错误处理通过 VBA 进行模拟。

这是对我有用的代码(我假设您的标题位于第一行):

Sub set_operations()
    Dim i, j, rangeA, rangeB, rowC, rowD, rowE, rowF As Long
    Dim test1, test2 As Boolean

    rangeA = ActiveSheet.Range("A" & CStr(ActiveSheet.Rows.Count)).End(xlUp).Row()
    rangeB = ActiveSheet.Range("B" & CStr(ActiveSheet.Rows.Count)).End(xlUp).Row()
    rowC = 2
    rowD = 2
    rowE = 2
    rowF = 2
    test1 = False
    test2 = False
    test2 = False

    'A union B
    On Error GoTo errHandler1
    For i = 2 To rangeA
        If Application.Match(ActiveSheet.Cells(i, 1), ActiveSheet.Range("C:C"), 0) > 0 Then
            If test1 = True Then
                ActiveSheet.Cells(rowC, 3) = ActiveSheet.Cells(i, 1)
                rowC = rowC + 1
            End If
        End If
        test1 = False
    Next i
    For j = 2 To rangeB
        If Application.Match(ActiveSheet.Cells(j, 2), ActiveSheet.Range("C:C"), 0) > 0 Then
            If test1 = True Then
                ActiveSheet.Cells(rowC, 3) = ActiveSheet.Cells(j, 2)
                rowC = rowC + 1
            End If
        End If
        test1 = False
    Next j

    'A intersection B
    For i = 2 To rangeA
        On Error GoTo errHandler2
        If Application.Match(ActiveSheet.Cells(i, 1), ActiveSheet.Range("B:B"), 0) > 0 Then
            On Error GoTo errHandler1
            If Application.Match(ActiveSheet.Cells(i, 1), ActiveSheet.Range("D:D"), 0) > 0 Then
                If test1 = True And test2 = False Then
                    ActiveSheet.Cells(rowD, 4) = ActiveSheet.Cells(i, 1)
                    rowD = rowD + 1
                End If
            End If
        End If
        test1 = False
        test2 = False
    Next i

    'A minus B
    For i = 2 To rangeA
        On Error GoTo errHandler2
        If Application.Match(ActiveSheet.Cells(i, 1), ActiveSheet.Range("B:B"), 0) > 0 Then
            On Error GoTo errHandler1
            If Application.Match(ActiveSheet.Cells(i, 1), ActiveSheet.Range("E:E"), 0) > 0 Then
                If test1 = True And test2 = True Then
                    ActiveSheet.Cells(rowE, 5) = ActiveSheet.Cells(i, 1)
                    rowE = rowE + 1
                End If
            End If
        End If
        test1 = False
        test2 = False
    Next i

    'B minus A
    For i = 2 To rangeB
        On Error GoTo errHandler2
        If Application.Match(ActiveSheet.Cells(i, 2), ActiveSheet.Range("A:A"), 0) > 0 Then
            On Error GoTo errHandler1
            If Application.Match(ActiveSheet.Cells(i, 2), ActiveSheet.Range("F:F"), 0) > 0 Then
                If test1 = True And test2 = True Then
                    ActiveSheet.Cells(rowF, 6) = ActiveSheet.Cells(i, 2)
                    rowF = rowF + 1
                End If
            End If
        End If
        test1 = False
        test2 = False
    Next i


errHandler1:
    test1 = True
    Resume Next

errHandler2:
    test2 = True
    Resume Next
End Sub
Run Code Online (Sandbox Code Playgroud)