What is the best way to sync up two lists each of which may contain items not in the other? As shown the lists are not sorted - although if necessary sorting them first would not be an issue.
List 1 = a,b,c,e
List 2 = b,e,c,d
Using the lists above, I'm looking for a solution that will write out to a spreadsheet in two columns:
a
b b
c c
d
e e
Here are some notes on using a disconnected recordset.
Const adVarChar = 200 'the SQL datatype is varchar
'Create arrays fron the lists
asL1 = Split("a,b,c,", ",")
asL2 = Split("b,e,c,d", ",")
'Create a disconnected recordset
Set rs = CreateObject("ADODB.RECORDSET")
rs.Fields.append "Srt", adVarChar, 25
rs.Fields.append "L1", adVarChar, 25
rs.Fields.append "L2", adVarChar, 25
rs.CursorType = adOpenStatic
rs.Open
'Add list 1 to the recordset
For i = 0 To UBound(asL1)
rs.AddNew Array("Srt", "L1"), Array(asL1(i), asL1(i))
rs.Update
Next
'Add list 2
For i = 0 To UBound(asL2)
rs.MoveFirst
rs.Find "L1='" & asL2(i) & "'"
If rs.EOF Then
rs.AddNew Array("Srt", "L2"), Array(asL2(i), asL2(i))
Else
rs.Fields("L2") = asL2(i)
End If
rs.Update
Next
rs.Sort = "Srt"
'Add the data to the active sheet
Set wks = Application.ActiveWorkbook.ActiveSheet
rs.MoveFirst
intRow = 1
Do
For intField = 1 To rs.Fields.Count - 1
wks.Cells(intRow, intField + 1) = rs.Fields(intField).Value
Next intField
rs.MoveNext
intRow = intRow + 1
Loop Until rs.EOF = True
Here's another option, this time using Dictionaries (add a reference to Microsoft Scripting Runtime, which also has several other hugely useful objects - don't start VBA coding without it!)
As written, the output isn't sorted - that could be a bit of a showstopper. Anyway, there are a couple of nice little tricks here:
Option Explicit
Public Sub OutputLists()
Dim list1, list2
Dim dict1 As Dictionary, dict2 As Dictionary
Dim ky
Dim cel As Range
Set dict1 = DictionaryFromArray(Array("a", "b", "c", "e"))
Set dict2 = DictionaryFromArray(Array("b", "e", "c", "d"))
Set cel = ActiveSheet.Range("A1")
For Each ky In dict1.Keys
PutRow cel, ky, True, dict2.Exists(ky)
If dict2.Exists(ky) Then
dict2.Remove ky
End If
Set cel = cel.Offset(1, 0)
Next
For Each ky In dict2
PutRow cel, ky, False, True
Set cel = cel.Offset(1, 0)
Next
End Sub
Private Sub PutRow(cel As Range, val As Variant, in1 As Boolean, in2 As Boolean)
Dim arr(1 To 2)
If in1 Then arr(1) = val
If in2 Then arr(2) = val
cel.Resize(1, 2) = arr
End Sub
Private Function DictionaryFromArray(arr) As Dictionary
Dim val
Set DictionaryFromArray = New Dictionary
For Each val In arr
DictionaryFromArray.Add val, Nothing
Next
End Function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With