Compare columns & display what's unique in a separate column?

curls100

New Member
Joined
Oct 9, 2014
Messages
10
I'm comparing two columns, then displaying what's unique in Col A and not in Col B, in a 3rd column.

I found this google function to do it (it works):
=FILTER( AA2:AA , ISERROR( MATCH( AA2:AA , BB2:BB , 0 ) ) )

I need to do it in Excel. Preferably in Excel 97, but if not then in a more recent Excel.
97 includes Match, VLookup, Lookup, but not Compare.

-----
For a separate task, I'd like to compare two cols and if Col B is also in Col A then put a text string (non varied) into Col C on the same row.

Thanks for ideas!!!
 
..........
Looking up the frequency function, so far it doesn't seem like it will apply, since I'm comparing to a range of 1 text string, not to a numeric range. There are a bunch of other formulas I can look at too. I've found this site has some good explanations of the forumlas: https://www.ablebits.com/office-addins-blog/2014/07/29/vlookup-formula-examples/
.......!

.. well spotted - it is a good site. I went there myself sometime after using VLOOKUP extensively. ..
.. some time later I got into the Index with Match alternative, explained quite well there
https://www.ablebits.com/office-addins-blog/2014/08/13/excel-index-match-function-vlookup/
.. I contributed a small bit there, based on some of what I have learnt at MrExcel

.. always worth considering if you are using VLOOKUP to consider the Index with Match Alternative instead at an early stage.

Index and Match themselves are certainly parallel to , if not abit more important to master, I think, then VLOOKUP.
. For some reason people often use the VLOOKUP first / extensively, as I did, missing out on the advantages of the Index with Match alternative.

Alan
 
Upvote 0

Excel Facts

Highlight Duplicates
Home, Conditional Formatting, Highlight Cells, Duplicate records, OK to add pink formatting to any duplicates in selected range.
I've read through this thread and you think i would be able to come up with a solution but I've already wasted hours so hopefully someone can point me in the right direction

Have 3 columns (Field 1, Field 2, Field 3)...they are different information, but combined together make a unique record. I need a list of unique 'records' and how many times they appear...see below for example and solution

Field1Field2Field3UniqueRecord1UniqueRecord2UniqueRecord3Occurances
dogAJandogAJan2
catBFebcatBFeb1
birdCMarbirdCMar1
dogBJandogBJan1
catCFebcatCFeb1
catAMarcatAMar1
dogAJandogAFeb1
dogAFeb
 
Upvote 0
Let A:C of Sheet1 house the data.

Row\Col
A​
B​
C​
D​
E​
F​
G​
H​
1​
Field1Field2Field3
7
2​
dogAJanField1Field2Field3Count
3​
catBFebdogAJan
2​
4​
birdCMarcatBFeb
1​
5​
dogBJanbirdCMar
1​
6​
catCFebdogBJan
1​
7​
catAMarcatCFeb
1​
8​
dogAJancatAMar
1​
9​
dogAFebdogAFeb
2​
10​

<tbody>
</tbody>


Define first Ivec by means of Formulas | Name Manager as referring to:
Rich (BB code):

=ROW(Sheet1!$A$2:$A$9)-ROW(Sheet1!$A$2)+1<strike></strike>

E1, control+shift+enter, not just enter:
Rich (BB code):

=SUM(IF(FREQUENCY(IF($A$2:$A$9<>"",IF($B$2:$B$9<>"",IF($C$2:$C$9<>"",
    MATCH($A$2:$A$9&"|"&$B$2:$B$9&"|"&$C$2:$C$9,
    $A$2:$A$9&"|"&$B$2:$B$9&"|"&$C$2:$C$9,0)))),Ivec),1))<strike></strike>

E3, control+shift+enter, copy across to G3, and down:
Rich (BB code):

=IF(ROWS(E$3:E3)<=$E$1,INDEX(A$2:A$9,SMALL(IF(FREQUENCY(IF($A$2:$A$9<>"",
    IF($B$2:$B$9<>"",IF($C$2:$C$9<>"",MATCH($A$2:$A$9&"|"&$B$2:$B$9&"|"&$C$2:$C$9,
    $A$2:$A$9&"|"&$B$2:$B$9&"|"&$C$2:$C$9,0)))),Ivec),Ivec),ROWS(E$3:E3))),"")<strike></strike>

H3, just enter and copy down:
Rich (BB code):

=COUNTIFS($A$2:$A$9,E3,$B$2:$B$9,F3,$C$2:$C$9,C2)<strike></strike>
 
Upvote 0
Hi tech retard
I just got notified of your reply to this old Thread......
My memory of this thread is fading as is all my memory of my two weeks spent trying to understand the world of Excel CSE Stuff. I seem to remember almost loosing the will to live after Aladin Akyurek slagged off my attempt to understand and explain his Formulas which took me a day just for a bit of them!!.... your requirement Looks by his standards dead easy. ( EDIT: He did it while I was preparing my Reply!!! ) In the meantime I personally have decided to take some other MrExcel Expert’s advice and treat CSE “array formulas” like tourniquets...only to be used in life or death situation........
If Yous want a VBA solution alternative... it is dead easy even for me.....There are infinite ways, here is just one:

I will take this as your start point ( Input Data) somewhere in a spreadsheet in a sheet called “CurlyAladinVBA”, say Top left corner cell A10
Using Excel 2007
Row\Col
A
B
C
10
Field1Field2Field3
11
dogAJan
12
catBFeb
13
birdCMar
14
dogBJan
15
catCFeb
16
catAMar
17
dogAJan
18
dogAFeb
CurlyAladinVBA

And for no Special reason I will Paste out the results you want with the Top left corner being cell E10

.. here is the code: ( Unnecessary bits and explaining messy ‘green comments included! )

Rich (BB code):
Sub CurlyAladinsEunuchstechretardRevisitedSept2015FTangFTangOLEBiscuitBarrel() '---o00o---`(_)`---o00o---
'http://www.mrexcel.com/forum/excel-questions/857924-compare-columns-display-whats-unique-separate-column-3.html
Rem 1) Get Some Worksheet data
        '    Dim vTemp As Variant'Just used sometimes for Debugging
Dim wsdbc As Worksheet 'Give variables Method, Properties etc, of Worksheets Object.
Set wsdbc = ThisWorkbook.Worksheets("CurlyAladinVBA") 'Assign the actual Worksheet to the Object. These two lines allow us to get at the Methods, properites etc by using the .Dot
Dim ldbc As Long, dbc As Long 'Variables for last "rows" and "rows" of interest. ( Long is a Big whole Number limit (-2,147,483,648 to 2,147,483,647) If you need some sort of validation the value should only be within the range of a Byte/Integer otherwise there's no point using anything but Long.--upon/after 32-bit, Integers (Short) need converted internally anyways, so a Long is actually faster. )
Let ldbc = wsdbc.Cells(Rows.Count, 1).End(xlUp).Row 'The Range Object ( cell ) that is the last cell  in the column of interest has the property .End ( argument Xl up ) appisd to it. This returns a new range ( cell ) which is that of the first Range ( cell ) with something in it "looking up" the XL spreadsheet from the last cell. Then the .Row Property is applied to return a long number equal to the row number of that cell
Dim arrIn() As Variant 'Variables for Dynamic Arrays for the Input Data including Headings
Let arrIn() = wsdbc.Range("A10:C" & ldbc & "").Value2 'The Property .value 2 applied to a range of more than 1 cell returns a colllection ( Array )  of the undelying values all the cells in that range. VBA allows a "one liner" to then assign these value to a dynamic Array. The Elements of the collection are defined initially as variant by VBA. So that is why we had Array() = Variant

Rem 2) Unique values of Animal Stuff. Prepare Microsoft Scripting Runtime Dictionary
'Using Microsoft Scripting Runtime Dictionary for a unique Key or referrence or heading value
'-needs library referrence MS Scripting Runtime ( Early Binding ) -
'Tools>>References>>scrolldown and check the box next to Microsoft Scripting Runtime
'... or crashes at next two lines
'    Dim dicOb As Scripting.Dictionary ' Daten hier hat einem eindeutigen "Schlüssel" oder Teilenummer
'    Set dicOb = New Scripting.Dictionary
'Alternative called Late binding. (But note some Dictionary methods and properties will not work with it  - in those cases Early Binding must be used.)
Dim dicOb As Object
Set dicOb = CreateObject("Scripting.Dictionary") '' Late Binding is better when sharing files as I am here. Early Binding has the advantage that Excel intellisense
' will then work for the Microsoft Scripting Runtime stuff and give you suggestions after you type the .dot thing

'2a) Use a simple "one liner" to get unique Stuff
Dim z As Variant, Keys() As Variant 'For use with building of the unique referrences. Keys will be given by direct assignment to collection Field Of variant Types so must be Dimed as Variant. Similar to the .Range.Value thing
Dim j As Long 'Loop Bound variable Count for each Input "row"
    For j = 2 To UBound(arrIn(), 1) '... look at each "row" starting at second, where the data starts
                            'Let vTemp = arrIn(j, 1)
    'The method here =.Item() is a simple way to get unique Key ( referrence) values without actually assigning / putting anything in the dictionary   http://www.snb-vba.eu/VBA_Dictionary_en.html       '   -- Normallerweise .Item() verwendet man, um ein Element von eine eindeutiger Schlüssel, .Item, zu einem vaiable zuweisen, bzw.  z = dicLookupTable.Item(x(i))   Wenn der Schlüssel aber nicht existiert, dann wird es gemacht - Cool oder ? --- ( Und kein Wert wird in die Variable angegeben werden ( aber das braucht auch Variable typ Variant) )
    If arrIn(j, 1) <> "" And arrIn(j, 1) <> "Ignor this row" Then Let z = dicOb.Item(arrIn(j, 1) & "|" & arrIn(j, 2) & "||" & arrIn(j, 3)) 'use the concatenated first 3 columns in row as a Uniue stuff.  you never see anything in z: Post #7 # 12 #14  http://www.excelforum.com/excel-programming-vba-macros/1083899-copy-and-paste-entire-row-to-second-sheet-based-on-cell-value.html
    Next j
Let Keys() = dicOb.Keys 'This non Duplicate Key word / Heading / dictionary referrence / part number ( your unique stuff ) are obtainable from the Keys Property applied The Dictioary Object

Rem 3)Looping to get occurances=======
Dim y As Long 'Loop Bound variable Count
Dim arrOut() As Variant 'This is our Output Array. It is of known size and content type ( Long and strings , so need variant )  will be filled by looping so we can give it a type....
Dim pos1 As Long, pos11 As Long 'Positions of separators |  ||  inn  Keys(y) Concatenated String
ReDim arrOut(1 To UBound(Keys()) + 1 + 1, 1 To 4) '...we must use ReDim as Dim only takes numbers  (First +1 makes space for headings, second +1 is because-***)
    For y = 0 To UBound(Keys()) Step 1 'Take each Unique stuff in turn and....(-*** Internally Array type things tend to start by default at 0 - Keys(0) is first Key)
        Let pos1 = InStr(1, Keys(y), "|"): Let pos11 = InStr(1, Keys(y), "||")
        Let arrOut(y + 1 + 1, 1) = Left(Keys(y), (pos1 - 1)) 'Bit of mucking about to get..
        Let arrOut(y + 1 + 1, 3) = Right(Keys(y), (Len(Keys(y)) - pos11) - 1) '.. at each of the 3 concatenated bits
        Let arrOut(y + 1 + 1, 2) = Mid(Keys(y), (pos1 + 1), ((pos11 - pos1) - 1)) '.. and put them in the Output Array
        For j = 2 To UBound(arrIn(), 1) Step 1 '.....consider each data "row" and ....
        If Keys(y) = (arrIn(j, 1) & "|" & arrIn(j, 2) & "||" & arrIn(j, 3)) Then Let arrOut(y + 1 + 1, 4) = arrOut(y + 1 + 1, 4) + 1
        Next j
    Next y '===========================
Rem 4)Put headings in Output Array
Let arrOut(1, 1) = "UniqueRecord1": Let arrOut(1, 2) = "UniqueRecord2": Let arrOut(1, 3) = "UniqueRecord3": Let arrOut(1, 4) = "Occurances"
Rem 5)Output of Final Array values
Let wsdbc.Range("E10").Resize(UBound(arrOut(), 1), UBound(arrOut(), 2)).Value2 = arrOut() 'The Resize Property Applied to this new Range Object Returns a new range object that of the last increased to the specified Row and Column size. This is a Neat way to paste out in one go: Shift then Resize the Range ( cell ) at top left of where output data should go to size of output array, then use the allowed VBA "One liner" to assign the values of an array to a spreadsheet range.

End Sub

..when you run it with the input data you get this ( i checked it..! ):
Using Excel 2007
Row\Col
E
F
G
H
10
UniqueRecord1UniqueRecord2UniqueRecord3Occurances
11
dogAJan
2​
12
catBFeb
1​
13
birdCMar
1​
14
dogBJan
1​
15
catCFeb
1​
16
catAMar
1​
17
dogAFeb
1​
CurlyAladinVBA

( Have Fun with the CSE Stuff!!!! )

Alan
 
Upvote 0
@ tech retard and Aladin Akyurek,
_ Out of interest I tried to follow through the Formula solution given and have successfully implemented it in a spreadsheet. And sorry i could not resist to post my notes, in case it could help any novice like me who in the future stumbles on the Thread.

I Applied to a slightly different range

Using Excel 2007
Row\Col
A
B
C
20
Field1Field2Field3
21
dogAJan
22
catBFeb
23
birdCMar
24
dogBJan
25
catCFeb
26
catAMar
27
dogAJan
28
dogAFeb

........
My output:

Using Excel 2007
Row\Col
E
F
G
H
20
7​
21
UniqueRecord1UniqueRecord2UniqueRecord3Occurances
22
dogAJan
2​
23
catBFeb
1​
24
birdCMar
1​
25
dogBJan
1​
26
catCFeb
1​
27
catAMar
1​
28
dogAFeb
1​
29
Should be "" gone too far downShould be "" gone too far downShould be "" gone too far down
0​
..................................................................................

Formula in E2 (my E20)
Using Excel 2007
Row\Col
E
20
=SUM(IF(FREQUENCY(IF(A21:A28<>"",IF(B21:B28<>"",IF(C21:C28<>"",
MATCH(A21:A28&"|"&B21:B28&"|"&C21:C28,
A21:A28&"|"&B21:B28&"|"&C21:C28,0
)
)
)
),ROW(A21:A28)-ROW($A$21)+1
),1
)
)​
............................................................................
_ Formula in E2 ( my E20 ) I explained along with ivec in my Post #14. It returns the count of the unique numbers
............................................................................

Formula In E3 ( my E22)
Using Excel 2007
Row\Col
E
22
=IF(ROWS(E$22:E22)<=$E$20,INDEX(A$21:A$28,SMALL(IF(FREQUENCY(
MATCH($A$21:$A$28&"|"&$B$21:$B$28&"|"&$C$21:$C$28,
$A$21:$A$28&"|"&$B$21:$B$28&"|"&$C$21:$C$28,0
),ROW($A$21:$A$28)-ROW($A$21)+1
),ROW($A$21:$A$28)-ROW($A$21)+1
),ROWS(E$22:E22)
),1
),"Should be """" gone too far down"
)

_ This time I can just about understand the main Formula which is dragged across and down:

I start “In the middle”:

Match Bit
The Match Bit compares itself with itself, but as it finds the first occurrence it will return an Array of numbers like this
{1;2;3;4;5;6;1;8}
So the second occurrence of the 1 shows it found the first occurrence rather than the duplicated 7Th Line.

(_ The three nested Ifs take care of returning nothing if the whole Row is empty . Just to help see and demonstrate I took them out, and in your case the formula will still work, as you have no empty rows. )

Frequency Bit
_ The frequency of each of the first argument of the Frequency Function ( which is that last array above ) is checked against the Frequency Function second argument
{1;2;3;4;5;6;7;8}
Or “bins” ( approx )
_0-1__1-2__2-3__3-4__4-5__5-6__6-7__7-8__>8

giving finally
__{2; __1; __1; __1; __1; __1; __0; __1; __0}

If ( on the Frequency )
The first ( only ) argument here returns us
{1;2;3;4;5;6;FALSCH;8;FALSCH}

Small Bit
_ The final Array above is the first argument Array ( or range of numerical data) for which the second argument determine the kth position along.. Dragging down the formula and looking at that second argument gives simply
__1__ 2__ 3 __4__ 5__ 6 __7 for the position along that the next from the above should be given
Applying then that logic will give us
__1__ 2__ 3 __4__ 5__ 6 __8
These final co ordinates are the second argument “row” in the column which I have included in my formula as the default 1 for the Index first argument fixed Array
A$21:A$28 ( or when dragging across the other two columns B$21:B$28 and C$21:C$28 )

Hence the correct output is selected.
..............................

Formula in H3 ( my H 22 )
Using Excel 2007
Row\Col
E
22
=IF(ROWS(E$22:E22)<=$E$20,INDEX(A$21:A$28,SMALL(IF(FREQUENCY(
MATCH($A$21:$A$28&"|"&$B$21:$B$28&"|"&$C$21:$C$28,
$A$21:$A$28&"|"&$B$21:$B$28&"|"&$C$21:$C$28,0
),ROW($A$21:$A$28)-ROW($A$21)+1
),ROW($A$21:$A$28)-ROW($A$21)+1
),ROWS(E$22:E22)
),1
),"Should be """" gone too far down"
)

Formula in column H is a simple Count S if returning the number of times the complete 3 columns from the output table in the row are to be found in the fixed Arrays for the Initial Input Table
Note : There is a very minor typo in Aladin Akyurek’s formula . I believe he has a C2 where he means a C3


Hope I have not waffled a bit too much here ( again )

Alan
 
Upvote 0
@ tech retard and Aladin Akyurek,
_ Out of interest I tried to follow through the Formula solution given and have successfully implemented it in a spreadsheet. And sorry i could not resist to post my notes, in case it could help any novice like me who in the future stumbles on the Thread.
[...]

You should resist... and not sicken the thread.
 
Upvote 0
Hi
You should resist... and not sicken the thread.

_ Like any sane person I can only have amazing respect for you and your amazing efforts at MrExcel. I have learnt an amazing amount of stuff from you , Gold worth, never to be found in Books.
_ I did however find your comments here slightly harsh on me.

_ I have tried to make some worthwhile additions to this Thread, including a complete alternative VBA Solution and have attempted to add to your solution, detailing an alternative implementation and noting ( an admittedly extremely minor ) error in your solution.

_ Like everyone I am just trying to help.
_ I did myself, before your Post here, make a Post with a suggestion that could improve the issue which I think you may have, at least partly, be been referring to.
http://www.mrexcel.com/forum/about-board/830361-board-wish-list.html#post4285667

Alan
 
Upvote 0
Hi, hope this does not cause a stomach ache..
You should resist... and not sicken the thread.

_ one thing I really did not explain well was how the Small Function is working here. I could not find any published explanations that I could Understand at the first reading. So I experimented a bit and came up with my own.
_ Looking at the specific example.

_ The first argument of the Small Function here was a fixed Array
Using Excel 2007
1​
2​
3​
4​
5​
6​
false​
8​
false​

_ This syntaxly should be numbers. ( It can however have Text which then appears to be ignored. )

_ In the example the second argument was a single number that in dragging the Formula down the rows looked like this:

Using Excel 2007
1​
2​
3​
4​
5​
6​
7​

_ I would put in words the definition of the Small Function as the following. The first argument Array can have any jumbled mixture of numbers and text, even duplicate numbers. It can be thought of then as if Excel just takes the numbers and holds them somewhere in an internal memory that we do not see in ascending sorted order. ( Duplicated numbers are just held alongside each other). For our case

1__2__ 3__ 4__ 5__ 6__ 8

_ The second argument should be a whole number ( If it is not then Excel appears Internally to round it down **** ). This number represents the position along that the Small Function goes to and picks put the number there. Looking for example at the formula in the last of our rows. – The second argument says go to the 7th number along and return it. So it picks out the 8.

( _ **** Note an exception to the rounding Down: If the number exceeds the number of elements in the Array then it crashes. In our example 6.99 rounds down to 6, but 7.99 or even 7.000001 crashes. Presumably Excel checks first if the number exceeds the number of Elements and then if not it rounds down if necessary )

Alan
 
Last edited:
Upvote 0
For once, I have the PERFECT Solution, if this topic is still open.
I have Column A, thousands of rows, some dups, some unique
I have Column B, Thousands of rows, some dups, some unique, some that may or may not be in Column A.
I need to know unique values of part in both columns.

I have a macro, that
1. takes all the values in Col A and puts unique values in Col C
2. takes all the values in Col B and puts unique values in Col D
3. takes values that are in BOTH columns C and D and puts them in Col E.

Bullet proof, been using it for years,
let me know if you still need it.
 
Upvote 0

Forum statistics

Threads
1,216,176
Messages
6,129,321
Members
449,501
Latest member
Amriddin

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top