I'm trying to transpose data based on the cell information from another column.
I can fairly quickly with the macro below when I only have two data that are the same. My problem is when I hit more than one data that are the same.
For example:
Clients What they want
20 B
20 C
33 B
33 C
202 A
202 B
202 C
55 A
55 C
The macro I have is this
Sub TransposeDuplciateData()
Sheets("Duplicate").Select
While Range("A2") <> ""
Range("B2").Select
ActiveCell.Resize(2, 1).Select
Selection.Copy
Sheets("Clients").Select
Range("B1").Select
Selection.End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Sheets("Duplicate").Select
Selection.EntireRow.Delete Shift:=xlUp
Wend
End Sub
The problem is when I hit client number 202, he wants three different things not only two.
I'm therefore looking for a macro that it would first recognize how many times the clients appear and from there copy the relevant information from column B and transpose it into my Clients sheet, then delete the entire rows from my Duplicate sheet (since I dealt with it) and move to the next clients information and do the same thing until there is no more clients information.
Here is the end results I would like it too look like
Clients Option 1 Option 2 Option 3 Option 4
20 B C
33 B C
202 A B C
55 B C
a possible way to achieve your desired outcome is to use a pivot table.
If you set Column A as Row, Column B as Column and values as count of Column B, you get the following output.
A B C
20 1 1
33 1 1
55 1 1
202 1 1 1
Would that help?
For a macro based solution, try the following code. It may need to be adapted to your exact need. Make also sure, column A is sorted in some kind of a way (this can also be done within the macro)
Sub remove_dub()
With Sheets("Dublicate")
Dim row_dubl As Integer
Dim row_clie As Integer
Dim col_clie As Integer
row_dubl = 1
row_clie = 1
col_clie = 2
While .Cells(row_dubl, "A") <> ""
Sheets("Clients").Cells(row_clie, "A") = .Cells(row_dubl, "A")
Sheets("Clients").Cells(row_clie, col_clie) = .Cells(row_dubl, "B")
If .Cells(row_dubl, "A") = .Cells(row_dubl + 1, "A") Then
row_clie = row_clie
col_clie = col_clie + 1
Else
row_clie = row_clie + 1
col_clie = 2
End If
row_dubl = row_dubl + 1
Wend
End With
End Sub
Best regards
A bit "simplified" version:
Dim c As Range
Set c = [a2]
While c > ""
While c = c(2) ' while c equals the cell below it
c.End(xlToRight)(, 2) = c(2, 2) ' get the second value below c
c(2).Resize(, 2).Delete xlShiftUp ' delete the 2 cells below c
Wend
Set c = c(2)
Wend
Here is a macro which creates a user defined object as a class, which has the properties of Client and a dictionary of Opts (for Option). You can easily add other properties, if you want to extend this.
Set reference to Microsoft Scripting Runtime
EDIT: Rename the class module cClient
Class Module
Option Explicit
Private pClient As String
Private pOpt As String
Private pOpts As Dictionary
Public Property Get Client() As String
Client = pClient
End Property
Public Property Let Client(Value As String)
pClient = Value
End Property
Public Property Get Opt() As String
Opt = pOpt
End Property
Public Property Let Opt(Value As String)
pOpt = Value
End Property
Public Property Get Opts() As Dictionary
Set Opts = pOpts
End Property
Public Function ADDOpt(Value As String)
If Not pOpts.Exists(Value) Then
pOpts.Add Key:=Value, Item:=Value
End If
End Function
Private Sub Class_Initialize()
Set pOpts = New Dictionary
pOpts.CompareMode = TextCompare
End Sub
Regular Module
Option Explicit
'Set reference to Microsoft Scripting Runtime
Sub OrganizeClientOptions()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes As Variant
Dim cC As cClient, dC As Dictionary
Dim I As Long, J As Long
Dim V As Variant, W As Variant
'Set worksheets
Set wsSrc = Worksheets("sheet1")
On Error Resume Next
Set wsRes = Worksheets("Results")
If Err.Number = 9 Then
Worksheets.Add.Name = "Results"
End If
On Error GoTo 0
Set wsRes = Worksheets("Results")
Set rRes = wsRes.Cells(1, 1)
With wsSrc
vSrc = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)).Resize(columnsize:=2)
End With
'collect the data
Set dC = New Dictionary
For I = 2 To UBound(vSrc, 1)
Set cC = New cClient
With cC
.Client = vSrc(I, 1)
.Opt = vSrc(I, 2)
.ADDOpt .Opt
If Not dC.Exists(.Client) Then
dC.Add Key:=.Client, Item:=cC
Else
dC(.Client).ADDOpt .Opt
End If
End With
Next I
'Size vRes
J = 0
For Each V In dC.Keys
I = dC(V).Opts.Count
J = IIf(J > I, J, I)
Next V
ReDim vRes(0 To dC.Count + 1, 1 To J + 1)
'headers
vRes(0, 1) = "Client"
For J = 2 To UBound(vRes, 2)
vRes(0, J) = "Option " & J - 1
Next J
'Data
I = 0
For Each V In dC.Keys
I = I + 1
vRes(I, 1) = V
J = 1
For Each W In dC(V).Opts
J = J + 1
vRes(I, J) = W
Next W
Next V
'Write the results
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.Value = vRes
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
End With
End Sub
Results
Related
Looking for a little more help please. I was here a month ago a RiskyPenguin gave me a great bit of code. I would like to add to this.
This is the part that works:
So if the "invoice" spreadsheet (sheet 5), if cell G4 (for example is I111) matches any of the data in the first column of the "income" spreadsheet (sheet 1) (starting at row 6) then the corresponding data in columns 2 3, 8 & 9 will copy over to the "invoice" spreadsheet in columns 2, 3, 4 & 5 (starting at row 13).
Sub FindAndCopyData2()
Dim shData As Worksheet, shReport As Worksheet
Set shData = Sheet1
Set shReport = Sheet6
Dim strInvoceNumber As String
strInvoceNumber = shReport.Cells(4, "E").Value
Dim intLastRow As Integer
intLastRow = shData.Cells(Rows.Count, 1).End(xlUp).Row
Dim intReportRow As Integer
intReportRow = 13
shReport.Range("B13:E20").ClearContents
Dim i As Integer
For i = 1 To intLastRow
If shData.Cells(i, 1).Value2 = strInvoceNumber Then
shReport.Cells(intReportRow, 2).Value2 = shData.Cells(i, 3).Value2
shReport.Cells(intReportRow, 3).Value2 = shData.Cells(i, 4).Value2
shReport.Cells(intReportRow, 4).Value2 = shData.Cells(i, 8).Value2
shReport.Cells(intReportRow, 5).Value2 = shData.Cells(i, 9).Value2
intReportRow = intReportRow + 1
End If
Next i
End Sub
I would then like to (hopefully using the same search)
Take the "invoice" spreadsheet (sheet 5), if cell G4 (for example is I111) matches any of the data in the second column of the "expenses" spreadsheet (sheet 2) (starting at row 11) then the corresponding data in columns 3, 5, & 7 will copy over to the "invoice" spreadsheet in columns 2, 4 & 6 (starting at row 13).
Is this possible or does it have to be a separate piece of programming?
Many Thanks for any advise.
Assuming this could be useful for others I made a function out of it and refactored the initial code to handle the copy in memory. I setup your first lookup so you just need to edit the variables to get your second lookup:
Option Explicit
''''''''''''''''''''''''''''''''''''''
''Main Sub
''''''''''''''''''''''''''''''''''''''''''''''''''
Sub main()
'Set some vars
Dim sourceArr, targetArr, sourceCls, targetCls, sourceStartRw As Long, targetStartRw As Long, dict As Object, j As Long, sourceLookupCl As Long, Matchkey As Long
''''''''''''''''''''''''''''''''''''''
''Lookup 1
''''''''''''''''''''''''''''''''''''''''''''''''''
Matchkey = Sheet5.Range("G4").Value2 'lookupKey
sourceCls = Split("2,3,8,9 ", ",") 'Columns to copy from
targetCls = Split("2,3,4,5", ",") 'Columns to copy to
sourceStartRw = 6
targetStartRw = 13
sourceLookupCl = 1 'matching column
'get data in memory = array
sourceArr = Sheet1.Range("A1").CurrentRegion.Value2
'call our function
targetArr = reorder(sourceArr, sourceCls, targetCls, sourceStartRw, sourceLookupCl, Matchkey)
'dump to sheet
With Sheet5
.Range(.Cells(targetStartRw, 1), .Cells(UBound(targetArr) + targetStartRw - 1, UBound(targetArr, 2))).Value2 = targetArr
End With
''''''''''''''''''''''''''''''''''''''
''Lookup 2 => change source and target cols to your need
''''''''''''''''''''''''''''''''''''''''''''''''''
Matchkey = Sheet5.Range("G4").Value2
sourceCls = Split("2,3,8,9 ", ",")
targetCls = Split("2,3,4,5", ",")
sourceStartRw = 6
targetStartRw = 13 'must be the same as previous lookup if you want to keep the targetArr from previous lookups
sourceLookupCl = 1
'get data in memory = array
sourceArr = Sheet1.Range("A1").CurrentRegion.Value2
'call our function keeping the data from the first lookup
targetArr = reorder(sourceArr, sourceCls, targetCls, sourceStartRw, sourceLookupCl, Matchkey, targetArr)
'dump to sheet
With Sheet5
.Range(.Cells(targetStartRw, 1), .Cells(UBound(targetArr) + targetStartRw - 1, UBound(targetArr, 2))).Value2 = targetArr
End With
End Sub
''''''''''''''''''''''''''''''''''''''
''Supporting function
''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function reorder(sourceArr, sourceCls, targetCls, sourceStartRw As Long, sourceLookupCl As Long, Matchkey As Long, Optional targetArr) As Variant
Dim dict As Object, j As Long
'if the target array overlaps the previous lookups pass it to the function
If IsMissing(targetArr) Then
ReDim targetArr(1 To UBound(sourceArr), 1 To UBound(sourceArr, 2))
End If
'build a dict to compare quickly
Set dict = CreateObject("Scripting.Dictionary") 'create dictionary lateB
For j = 1 To UBound(sourceArr) 'traverse source
dict(sourceArr(j, sourceLookupCl)) = Empty
Next j
'check if key exists in dict and copy data
Dim i As Long, ii As Long ': ii = 1
If dict.Exists(Matchkey) Then
For j = sourceStartRw To UBound(sourceArr)
For i = 1 To UBound(sourceArr, 2)
If i = sourceCls(ii) Then
targetArr(j - sourceStartRw + 1, targetCls(ii)) = sourceArr(j, i)
ii = IIf(ii < UBound(sourceCls), ii + 1, ii)
End If
Next i
ii = 0
Next j
End If
reorder = targetArr
End Function
On the left is the hypothetical database. On the right is the result I would like to obtain.
I would like to print all of the items of type B, as well as the sum and the count.
I'm stuck and I'm not able to go ahead. Could you please help me out? Thanks.
Private Sub CommandButton1_Click()
Dim dicDistincts As Scripting.Dictionary, _
dicDuplicates As Scripting.Dictionary
Set dicDistincts = New Scripting.Dictionary
Set dicDuplicates = New Scripting.Dictionary
Dim i As Integer
For i = 2 To 10
If Cells(i, 1).Value = "B" Then
If Not dicDistincts.Exists(Cells(i, 2).Value) Then
dicDistincts.Add Key:=Cells(i, 2).Value, Item:=Cells(i, 2).Value
Else
dicDuplicates.Add Key:=Cells(i, 2).Value, Item:=Cells(i, 2).Value
End If
End If
Next i
For i = 0 To dicDuplicates.Count - 1
Cells(i + 1, 9).Value = WorksheetFunction.CountIfs(Range("a2:a10"), "B", Range("b2:b10"), dicDistincts.keys(i))
Next i
End Sub
EDIT: I tried with countifs but it return 0 for banana, apple and strawberry
EDIT 2: I corrected the countifs. Now it works.
If you must use dictionaries then you could do this with a single dictionary, storing the counts and quantities as array as the values in the dictionary.
Private Sub CommandButton1_Click()
Dim dic As Scripting.Dictionary
Dim arrData()
Dim i As Long
Dim ky As Variant
Set dic = New Dictionary
For i = 2 To 10
If Cells(i, 1).Value = "B" Then
ky = Cells(i, 2).Value
If Not dic.Exists(ky) Then
arrData = Array(1, Cells(i, 3).Value)
Else
arrData = dic(ky)
arrData = Array(arrData(0) + 1, arrData(1) + Cells(i, 3).Value)
End If
dic(ky) = arrData
End If
Next i
Range("A1:C1").Copy Range("E1:G1")
For i = 0 To dic.Count - 1
Range("E" & i + 2) = dic.Keys(i)
Range("F" & i + 2).Resize(, 2) = dic.Items(i)
Next i
End Sub
Unique Sum and Unique Count with Double Dictionary
Option Explicit
Private Sub CommandButton1_Click()
Dim rg As Range
With Range("A1").CurrentRegion
Set rg = .Resize(.Rows.Count - 1).Offset(1)
End With
Dim Data As Variant: Data = rg.Value
Dim cDict As Object: Set cDict = CreateObject("Scripting.Dictionary")
Dim sDict As Object: Set sDict = CreateObject("Scripting.Dictionary")
Dim i As Long
For i = 1 To UBound(Data, 1)
If Data(i, 1) = "B" Then
cDict(Data(i, 2)) = cDict(Data(i, 2)) + 1 ' Count
sDict(Data(i, 2)) = sDict(Data(i, 2)) + Data(i, 3) ' Sum
End If
Next i
ReDim Data(1 To cDict.Count, 1 To 3)
i = 0
Dim Key As Variant
For Each Key In cDict.Keys
i = i + 1
Data(i, 1) = Key
Data(i, 2) = sDict(Key)
Data(i, 3) = cDict(Key)
Next Key
With Range("E2").Resize(, 3)
.Resize(i).Value = Data
.Resize(.Worksheet.Rows.Count - .Row - i + 1).Offset(i).ClearContents
End With
End Sub
This should work it uses loops through all bs and addes them if to the other list
Sub countBs()
Dim Bs As Range 'list of the line of all Bs
Dim B As Range 'each indiviual b in the B list
Dim Item As Range 'each indivual item
Dim adder As Range 'resturns nothing if b not fond in times
Set Bs = Range("a2", Range("a2").End(xlDown)) 'you can also change this ofcourse to a specifici range or user selected
For Each B In Bs
If B = "B" Then
Set adder = Range("g2", Range("g2").End(xlDown)).Find(B.Offset(0, 1))
If adder Is Nothing Then
If Range("g2") = "" Then
Set Item = Range("g2")
Else
Set Item = Range("g1").End(xlDown).Offset(1, 0)
End If
Item.Resize(1, 2).Value = B.Offset(0, 1).Resize(1, 2).Value
Item.Offset(0, 2) = 1
Else
adder.Offset(0, 1).Value = adder.Offset(0, 1).Value + B.Offset(0, 2).Value
adder.Offset(0, 2).Value = adder.Offset(0, 2).Value + 1
End If
End If
Next B
End Sub
I read many post on this forum regarding my problem, but cant find solutions.
I have a table with different number of cells, with duplicate value.
I would like to count duplicates and show in another columns.
Source table where I mark a few cell:
I would like to receive such output
A have a part of code, but whatever I select, it counts the last cell
Dim rng, rngTarget, rngTargetName As Range
Set rngTarget = Range("D7")
Set items = CreateObject("Scripting.Dictionary")
For Each rng In Selection
If Not items.exists(rng.Value) Then
items.Add rng.Value, 1
rngTarget.Value = items(rng.Value)
rngTargetName = rng
Else
items(rng.Value) = items(rng.Value) + 1
rngTarget.Value = items(rng.Value)
rngTargetName = rng
End If
Next
What i missing?
First enter this in a Standard Module:
Public Function unikue(rng As Range)
Dim arr, c As Collection, r As Range
Dim nCall As Long, nColl As Long
Dim i As Long
Set c = New Collection
nCall = Application.Caller.Count
On Error Resume Next
For Each r In rng
If r.Value <> "" Then
c.Add r.Text, CStr(r.Text)
End If
Next r
On Error GoTo 0
nColl = c.Count
If nCall > nColl Then
ReDim arr(1 To nCall, 1 To 1)
For i = 1 To nCall
arr(i, 1) = ""
Next i
Else
ReDim arr(1 To nColl, 1 To 1)
End If
For i = 1 To nColl
arr(i, 1) = c.Item(i)
Next i
unikue = arr
End Function
The above UDF() will return a list of the unique, non-blank, items in a block of cells.
Then in a set of cells in column, say F starting at F5 , array-enter:
=unikue(A1:D3)
In G5 enter:
=COUNTIF($A$1:$D$3,F5)
and copy downward:
With Excel 365, there is a no-VBA solution.
Thanks Gary's for help, but ...
i completed my version of code and now works as expected - i can select few cell and count duplicates.
My working code:
Dim rng As Range
Dim var As Variant
Dim i As Integer
i = 0
Set D = CreateObject("Scripting.Dictionary")
For Each rng In Selection
If rng <> "" Then
If D.exists(rng.Value) Then
D(rng.Value) = D(rng.Value) + 1
Else
D.Add rng.Value, 1
End If
End If
Next
For Each var In D.Keys
Range("C" & (i + 18)) = var
Range("E" & (i + 18)) = D(var)
i = i + 1
Next
Set D = Nothing
I have the following situation. In an Excel worksheet, I have a column which contains values that are separated by "|".
e.g.
Option Column
Option 1 | Option 3
Option 4 | Option 7
Option 2 | Option 3 | Option 6
I want to
1. Insert 10 columns to the right, name them "Option 1", "Option 2", "Option 3" ..... "Option 10"
2. In each cell of the first column, if "Option x" exists, split/copy/move to the column named "Option x" (Where x can be 1, 2 .... 10)
This is the code that I use currently to achieve it:
Sub Insert_10_columns()
Columns("B:K").Insert Shift:=xlToRight, _
CopyOrigin:=xlFormatFromLeftOrAbove
For i = 2 To 11
ActiveSheet.Cells(1, i).Value = "Option " & i - 1
Next i
End Sub
Sub Look_For_Text()
Dim LastRow As Long
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To LastRow + 1
For k = 1 To 10
If InStr(1, (Cells(i, 1).Value), "Option " & k) > 0 Then
ActiveSheet.Cells(i, k + 1).Value = "Option " & k
End If
Next k
Next i
End Sub
I was just wondering if loops are the best way to go about it, especially because when I start using it, I would be operating on 20,000+ rows and 15+ columns.
Variant using System.Collections.ArrayList and Scripting.Dictionary, I guess that should be faster than your solution)
Sub test()
Dim data As Range, cl As Range, i&, x As Variant
Dim arrList As Object, Dic As Object
Set arrList = CreateObject("System.Collections.ArrayList")
Set Dic = CreateObject("Scripting.Dictionary")
Set data = Range([A2], Cells(Rows.Count, "A").End(xlUp))
'get unique values from split
For Each cl In data
For Each x In Split(cl, "|"): x = Trim(x)
If Not Dic.exists(x) Then
Dic.Add x, Nothing
arrList.Add x
End If
Next x, cl
Dic.RemoveAll 'clear dictionary
arrList.Sort 'sort values
If sortorder = xlDescending Then
arrList.Reverse
End If
'add headers
i = 2
For Each x In arrList
Cells(1, i).Value2 = x
Dic.Add x, i: i = i + 1
Next x
'split values against headers
For Each cl In data
For Each x In Split(cl, "|"): x = Trim(x)
Cells(cl.Row, Dic(x)).Value2 = x
Next x, cl
End Sub
test here
You will need a loop to walk through while you split the cell contents. Looping through an array is faster than looping through the worksheet. After splitting, populate a target array with matching columns before putting the target array values into the worksheet.
Option Explicit
Sub InsertOptions()
Dim i As Long, j As Long, mx As Long, dlm As String
Dim hdrs As Variant, opts As Variant, vals As Variant, tmp As Variant, m As Variant
dlm = " | " 'column A delimiter; might be " | "
mx = 15 'maximum number of options
With Worksheets("sheet9")
'create an independent array of header labels
ReDim hdrs(1 To 1, 1 To mx)
For i = LBound(hdrs, 2) To UBound(hdrs, 2)
hdrs(1, i) = "Option " & i
Next i
'collect the delimited options from column A
opts = Range(.Cells(2, "A"), .Cells(.Rows.Count, "A").End(xlUp)).Value2
'make room for all options in expanded form
ReDim vals(LBound(opts, 1) To UBound(opts, 1), _
LBound(hdrs, 2) To UBound(hdrs, 2))
'loop through delimited options, split them and look for matches in hdrs
For i = LBound(opts, 1) To UBound(opts, 1)
tmp = Split(opts(i, 1), dlm)
For j = LBound(tmp) To UBound(tmp)
m = Application.Match(tmp(j), hdrs, 0)
If Not IsError(m) Then
vals(i, m) = tmp(j)
End If
Next j
Next i
'insert ten new columns
.Cells(1, "B").Resize(1, UBound(hdrs, 2)).EntireColumn.Insert
'put arrays into new columns
With .Cells(1, "B").Resize(1, UBound(hdrs, 2)).EntireColumn
.ColumnWidth = 9
.Cells(1, 1).Resize(UBound(hdrs, 1), UBound(hdrs, 2)) = hdrs
.Cells(2, 1).Resize(UBound(vals, 1), UBound(vals, 2)) = vals
End With
End With
End Sub
I use this to see which clients have been added to our client list and which have left, month to month.
It takes two lists, then outputs the unique and common members of the two lists. There may be better ways of doing this, but the logic is simple and easy to follow and it seems to work. e.g.
A
B
A
B
AB
1
3
1
5
3
2
4
2
6
4
3
5
4
6
Option Base 1
Sub UniqueMembersOfTwoLists()
Dim arrOne() As Variant
Dim arrTwo() As Variant
Dim AB() As Variant
ReDim AB(0 To 0) As Variant
Dim A_Only() As Variant
ReDim A_Only(0 To 0) As Variant
Dim OnlyInListB() As Variant
ReDim OnlyInListB(0 To 0) As Variant
Dim lrOne As Long
Dim lrTwo As Long
Dim r1 As Range
Dim r2 As Range
Dim i As Long
Dim test As Variant
Dim g As Boolean
‘Dim ms As String
‘ if needed
‘ms = "Put list 1 in column A starting in A1, put list 2 in column B staring B1"
‘MsgBox ms
lrOne = Range("A65336").End(xlUp).Row
lrTwo = Range("B65336").End(xlUp).Row
Set r1 = Range((Cells(1, 1)), (Cells(lrOne, 1)))
Set r2 = Range((Cells(1, 2)), (Cells(lrTwo, 2)))
arrOne = r1
arrTwo = r2
‘simple check to see if each member of list B is in List A
For Each Element In arrTwo
test = Element
g = contained(arrOne, test)
If g = True Then
' means is a member of both lists, add to common members list
ReDim Preserve AB(0 To UBound(AB) + 1)
AB(UBound(AB)) = test
Else
‘means only in list A, so add to A only
ReDim Preserve A_Only(0 To UBound(A_Only) + 1)
A_Only(UBound(A_Only)) = test
End If
Next Element
‘ then repeat the other way round to find only in list B
For Each w In arrOne
test = w
g = contained(arrTwo, test)
If g = True Then
' means is a member of both lists, already added so do nothing
Else
ReDim Preserve OnlyInListB(0 To UBound(OnlyInListB) + 1)
OnlyInListB(UBound(OnlyInListB)) = test
End If
Next w
' out put to sheet
For i = 1 To UBound(AB)
Cells(i, 5).Value = AB(i)
Next i
i = 1
For i = 1 To UBound(A_Only)
Cells(i, 4).Value = A_Only(i)
Next i
i = 1
For i = 1 To UBound(OnlyInListB)
Cells(i, 3).Value = OnlyInListB(i)
Next i
i = 1
‘ tidy up
Rows("1:1").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").Select
ActiveCell.FormulaR1C1 = "List A"
Range("B1").Select
ActiveCell.FormulaR1C1 = "List B"
Range("C1").Select
ActiveCell.FormulaR1C1 = "Only in List A"
Range("D1").Select
ActiveCell.FormulaR1C1 = "Only in List B"
Range("E1").Select
ActiveCell.FormulaR1C1 = "In both A & B"
Rows("1:1").Select
Selection.Font.Bold = True
Cells.Select
Cells.EntireColumn.AutoFit
End Sub
Function contained(arr() As Variant, test As Variant)
Dim i As Long
Dim a As Variant
Dim g As Boolean
g = False
For i = 1 To UBound(arr)
a = arr(i, 1)
If a = test Then
g = True
Exit For
Else
End If
Next i
contained = g
End Function
Is there a more efficient way of achieving the same, possibly using a dictionary?