问题
For example, I have an xls where :
- column A has list of items with property A
- column B has list of items with property B
I need the following :
- column C which is A union B (unique items of both A & B)
- column D which is A intersection B (common items of A & B)
- column E which is A minus B (items in A but not in B)
- column F which is B minus A (items in B but not in A)
Set operations on a list of elements seem to be easy with SQL or Python. But how to do it in xls?
Note : It should be an automation with minimal copy-pastes and clicks. For example, I dont want to copy-paste A below B, then "eliminate duplicates" to get A union B.
回答1:
Intersection (In A & B): =IFNA(VLOOKUP(B2,$A$2:$B$42,1,FALSE),"")
Union (In A or B): =IFS(A2,A2,B2,B2)
Note that IFS
is only in recent (as of 2018) versions.
A - B (Only in A): =IF(NOT(IFNA(MATCH(A2,$B$2:$B$42,0),FALSE)),IF(A2,A2,""),"")
B - A (Only in B): =IF(NOT(IFNA(MATCH(B2,$A$2:$A$42,0),FALSE)),IF(B2,B2,""),"")
(Swap the letters)
回答2:
Well, Microsoft Excel does not handle built-in set operations. But you can emulate then by VBA using MATCH function and error handling.
Here is the code that worked for me (I presume that you have heading on the first line):
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
回答3:
you can simple use below formula to get result
=IF(LOWER(A4)=LOWER(B4),"",A4)
来源:https://stackoverflow.com/questions/31186547/how-can-we-perform-common-set-operations-union-intersection-minus-in-ms-exce