Please help to solve my problem.
I use below script but result nothing on activesheet..
Sub Dutylist()
Dim dutyTable(1 To 2, 1 To 4) As String
Dim Cyc As Integer, Team As Integer
Dim Svalue As Range, Srange As Range
Dim Result() As String
//Cycle 1
dutyTable(1, 1) = "A,B,C,D,E,F,G"
dutyTable(1, 2) = "D,C,A,B,A,E,D"
dutyTable(1, 3) = "B,A,E,C,B,D,E"
dutyTable(1, 4) = "C,B,C,D,C,A,A"
//Cycle 2
dutyTable(2, 1) = "B,E,D,A,D,B,A"
dutyTable(2, 2) = "B,A,E,C,C,D,B"
dutyTable(2, 3) = "D,C,A,B,B,E,B"
dutyTable(2, 4) = "E,A,B,D,A,C,D"
Cyc = 1
Set Srange = ActiveSheet.Range("a:a")
For Team = 1 To 4
Result = Split(dutyTable(Cyc, Team), ",")
For Each Svalue In Srange
If Svalue = "Team " & CStr(Team) Then
Svalue.Offset(0, 1).Resize(, UBound(Result) + 1).Value = Result
End If
Next Svalue
Next Team
End Sub
Any problem of my code above?
My understanding for your code execution should be as following, what I have changed is rearrange the Looping with some modification and also you should set range by reference to last used row instead of A:A to speed up the execution.
Basically the code will match the value on Col A for the Team, if found then return dutyTable1 value based on the cycle give by you,
Sub Dutylist()
Dim dutyTable(1 To 2, 1 To 4) As String
Dim Cyc As Integer, Team As Integer
Dim Svalue As Range, Srange As Range
Dim Result() As String
Dim i As Long
dutyTable(1, 1) = "A,B,C,D,E,F,G"
dutyTable(1, 2) = "D,C,A,B,A,E,D"
dutyTable(1, 3) = "B,A,E,C,B,D,E"
dutyTable(1, 4) = "C,B,C,D,C,A,A"
dutyTable(2, 1) = "B,E,D,A,D,B,A"
dutyTable(2, 2) = "B,A,E,C,C,D,B"
dutyTable(2, 3) = "D,C,A,B,B,E,B"
dutyTable(2, 4) = "E,A,B,D,A,C,D"
Cyc = 1
Set Srange = ActiveSheet.Range("a1:a20")
For Each Svalue In Srange
For Team = 1 To 4
Result = Split(dutyTable(Cyc, Team), ",")
If InStr(Svalue.Value, Team) > 0 Then
Svalue.Offset(0, 1).Resize(, UBound(Result) + 1).Value = Result
End If
Next Team
Next Svalue
End Sub
Output (Only 3 Team are tested, can be extended)
Related
giving the below code, how can I check if "outArr" value is Yes or No and replace them respectively with 1 and 0?
Sub IndexMatchFirm1()
Dim destinationWs As Worksheet
Set destinationWs = ThisWorkbook.Worksheets("Master")
Dim destinationLastRow As Long
destinationLastRow = destinationWs.Range("A" & Rows.Count).End(xlUp).Row
Dim lkpArr As Variant
lkpArr = destinationWs.Range("A5:A" & destinationLastRow).Value
With Worksheets("MyData")
Dim retval As Variant
retval = Intersect(.Range("E:E"), .UsedRange)
Dim mtch As Variant
mtch = Intersect(.Range("B:D"), .UsedRange)
End With
Dim outArr As Variant
ReDim outArr(1 To UBound(lkpArr, 1), 1 To 1)
Dim i As Long
For i = 1 To UBound(lkpArr, 1)
Dim j As Long
For j = 1 To UBound(retval, 1)
If mtch(j, 3) = "FirmA" Then
Dim v
If mtch(j, 1) = lkpArr(i, 1) Then
v = retval(j, 1)
outArr(i, 1) = IIf(v = "Yes", 1, IIf(v = "No", 0, v))
End If
'If mtch(j, 1) = lkpArr(i, 1) Then
'outArr(i, 1) = retval(j, 1)
'Exit For
'End If
End If
Next j
Next i
destinationWs.Range("L5").Resize(UBound(outArr, 1), 1).Value = outArr
End Sub
I tried in many ways but none of them seems to be working. I also would like not to use the "For each cell in myrange" approach because it slows down a lot the workbook. Any suggestion?
Thanks
Simplest fix:
Dim v
'...
'...
If mtch(j, 1) = lkpArr(i, 1) Then
v = retval(j, 1)
outArr(i, 1) = IIf(v = "Yes", 1, IIf(v="No", 0, v)
Exit For 'Edit - I forgot to add this....
End If
'...
'...
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 am trying to copy data from one workbook to another based on the values contained in cells in the source workbook that matches the same values in the target workbook. For example, I have a table (Table1) that has four columns say, A1:D5. One of these columns (column A) contains account numbers that match similar account numbers located on another workbook (also in column A). I am trying to find a code that looks through the table (Table1) in the source workbook via the account number column, and if the account number matches the account number in the target workbook, copy and paste the cells on that row in specific locations to the target workbook. Is this possible?
I hope that makes sense. I have looked all over on how to structure such a code, and I was not able to find anything to start the process for this logic.
Any help will be very appreciative.
Thank you
Even if your question is about doing this in VBA, I'm just going to mention that what you are trying to do seems like it could also be done with Power Query.
That being said, if you were to use VBA for this, you would have to use the Match function to find where your rows match and then copy the data from the source to the destination table.
I've adapted the code I provided to this question to better serve your specific needs. One of the things I've done is to add an optional argument called DoOverwrite and set it to false. This will make sure that the information from one row won't be overwritten by another row later down the road.
Sub TableJoinTest()
'Those table columns will have to match for the 2 lines to be a match
Dim MandatoryHeaders() As Variant
MandatoryHeaders = Array("Account Number")
Dim SourceTableAnchor As Range
Set SourceTableAnchor = Workbooks("SourceWorkbook.xlsx").Sheets("Sheet1").Range("A1")
Dim TargetTableAnchor As Range
Set TargetTableAnchor = Workbooks("TargetWorkbook.xlsx").Sheets("Sheet1").Range("A1")
TableJoin _
SourceTableAnchor:=SourceTableAnchor, _
TargetTableAnchor:=TargetTableAnchor, _
MandatoryHeaders:=MandatoryHeaders, _
AddIfMissing:=False, _
IsLogging:=False, _
DoOverwrite:=False
End Sub
Sub TableJoin( _
SourceTableAnchor As Range, _
TargetTableAnchor As Range, _
MandatoryHeaders As Variant, _
Optional OtherHeaders As Variant, _
Optional AddIfMissing As Boolean = False, _
Optional IsLogging As Boolean = False, _
Optional DoOverwrite As Boolean = True)
'''''''''''''''''''''''''''''''''''''''
'Definitions
'''''''''''''''''''''''''''''''''''''''
Dim srng As Range, trng As Range
Set srng = SourceTableAnchor.CurrentRegion
Set trng = TargetTableAnchor.CurrentRegion
Dim sHeaders As Range, tHeaders As Range
Set sHeaders = srng.Rows(1)
Set tHeaders = trng.Rows(1)
'Store in Arrays
Dim sArray() As Variant 'prefix s is for Source
sArray = ExcludeRows(srng, 1).Value2
Dim tArray() As Variant 'prefix t is for Target
tArray = ExcludeRows(trng, 1).Value2
Dim sArrayHeader As Variant
sArrayHeader = sHeaders.Value2
Dim tArrayHeader As Variant
tArrayHeader = tHeaders.Value2
'Find Column correspondance
Dim sMandatoryHeadersColumn As Variant
ReDim sMandatoryHeadersColumn(LBound(MandatoryHeaders) To UBound(MandatoryHeaders))
Dim tMandatoryHeadersColumn As Variant
ReDim tMandatoryHeadersColumn(LBound(MandatoryHeaders) To UBound(MandatoryHeaders))
Dim k As Long
For k = LBound(MandatoryHeaders) To UBound(MandatoryHeaders)
sMandatoryHeadersColumn(k) = Application.Match(MandatoryHeaders(k), sArrayHeader, 0)
tMandatoryHeadersColumn(k) = Application.Match(MandatoryHeaders(k), tArrayHeader, 0)
Next k
Dim sOtherHeadersColumn As Variant
ReDim sOtherHeadersColumn(LBound(OtherHeaders) To UBound(OtherHeaders))
Dim tOtherHeadersColumn As Variant
ReDim tOtherHeadersColumn(LBound(OtherHeaders) To UBound(OtherHeaders))
For k = LBound(OtherHeaders) To UBound(OtherHeaders)
sOtherHeadersColumn(k) = Application.Match(OtherHeaders(k), sArrayHeader, 0)
tOtherHeadersColumn(k) = Application.Match(OtherHeaders(k), tArrayHeader, 0)
Next k
'Merge mandatory headers into one column (aka the helper column method)
Dim i As Long, j As Long
Dim sHelperColumn() As Variant
ReDim sHelperColumn(LBound(sArray, 1) To UBound(sArray, 1), 1 To 1)
For i = LBound(sArray, 1) To UBound(sArray, 1)
For j = LBound(MandatoryHeaders) To UBound(MandatoryHeaders)
sHelperColumn(i, 1) = sHelperColumn(i, 1) & sArray(i, sMandatoryHeadersColumn(j))
Next j
Next i
Dim tHelperColumn() As Variant
ReDim tHelperColumn(LBound(tArray, 1) To UBound(tArray, 1), 1 To 1)
For i = LBound(tArray, 1) To UBound(tArray, 1)
For j = LBound(MandatoryHeaders) To UBound(MandatoryHeaders)
tHelperColumn(i, 1) = tHelperColumn(i, 1) & tArray(i, tMandatoryHeadersColumn(j))
Next j
Next i
'Find all matches
Dim MatchList() As Variant
Dim LoggingColumn() As String
ReDim LoggingColumn(LBound(tArray, 1) To UBound(tArray, 1), 1 To 1)
For i = LBound(sArray, 1) To UBound(sArray, 1)
ReDim MatchList(LBound(tArray, 1) To UBound(tArray, 1))
For j = LBound(tArray, 1) To UBound(tArray, 1)
If sHelperColumn(i, 1) = tHelperColumn(j, 1) Then
MatchList(j) = 1
End If
Next j
'Get the row number for the match
Dim MatchRow As Long
Select Case Application.Sum(MatchList)
Case Is > 1
'Need to do more matching
Dim MatchingScoresList() As Long
ReDim MatchingScoresList(1 To UBound(tArray, 1))
Dim m As Long
For k = LBound(OtherHeaders) To UBound(OtherHeaders)
For m = LBound(tArray, 1) To UBound(tArray, 1)
If tArray(m, sOtherHeadersColumn(k)) = sArray(i, sOtherHeadersColumn(k)) Then
MatchingScoresList(m) = MatchingScoresList(m) + 2 ^ (UBound(OtherHeaders) - k)
End If
Next m
Next k
'Get the max score position
Dim MyMax As Long
MyMax = Application.Max(MatchingScoresList)
If Application.Count(Application.Match(MatchingScoresList(), Array(MyMax), 0)) > 1 Then
MsgBox "Error: can't determine how to match row " & i & " in source table"
Exit Sub
Else
MatchRow = Application.Match(MyMax, MatchingScoresList, 0)
End If
Case Is = 1
MatchRow = Application.Match(1, MatchList, 0)
Case Else
Dim nArray() As Variant, Counter As Long
If AddIfMissing Then
MatchRow = 0
Counter = Counter + 1
ReDim nArray(1 To Counter, 1 To UBound(tArray, 2))
For k = LBound(MandatoryHeaders) To UBound(MandatoryHeaders)
nArray(Counter, tMandatoryHeadersColumn(k)) = sArray(i, sMandatoryHeadersColumn(k))
Next k
For k = LBound(OtherHeaders) To UBound(OtherHeaders)
nArray(Counter, tOtherHeadersColumn(k)) = sArray(i, sOtherHeadersColumn(k))
Next k
Else
MsgBox "Error: Couldn't find a match for data row #" & i
Exit Sub
End If
End Select
'Logging and assigning values
If MatchRow > 0 Then
For k = LBound(OtherHeaders) To UBound(OtherHeaders)
If tArray(MatchRow, tOtherHeadersColumn(k)) <> sArray(i, sOtherHeadersColumn(k)) Then
'Logging
If IsLogging And DoOverwrite Then LoggingColumn(MatchRow, 1) = LoggingColumn(MatchRow, 1) & _
IIf(LoggingColumn(MatchRow, 1) <> "", ", ", "") & _
tHeaders.Cells(1, tOtherHeadersColumn(k)) & " : " & _
tArray(MatchRow, tOtherHeadersColumn(k)) & _
" -> " & sArray(i, sOtherHeadersColumn(k))
'Assign new value
If DoOverwrite Or tArray(MatchRow, tOtherHeadersColumn(k)) = VbNullString Then
tArray(MatchRow, tOtherHeadersColumn(k)) = sArray(i, sOtherHeadersColumn(k))
End If
End If
Next k
End If
Next i
'Write arrays to sheet
ExcludeRows(trng, 1).Value2 = tArray
With trng.Parent
If IsArrayInitialised(nArray) And AddIfMissing Then
.Cells(trng.Cells(1, 1).Row + trng.Rows.Count, trng.Cells(1, 1).Column).Resize(UBound(nArray, 1), UBound(nArray, 2)).Value2 = nArray
End If
If IsLogging Then
.Cells(trng.Cells(1, 1).Row, trng.Cells(1, 1).Column + trng.Columns.Count) = "Changes"
.Cells(trng.Cells(2, 1).Row, trng.Cells(1, 1).Column + trng.Columns.Count).Resize(UBound(LoggingColumn, 1), 1).Value2 = LoggingColumn
End If
End With
End Sub
And also add these functions inside your VBA project to as they are used in the procedure above.
Function IsArrayInitialised(ByRef A() As Variant) As Boolean
On Error Resume Next
IsArrayInitialised = IsNumeric(UBound(A))
On Error GoTo 0
End Function
Function ExcludeRows(MyRng As Range, StartRow As Long, Optional EndRow As Long = -1) As Range
'PURPOSE: Exclude one or more consecutives rows from an existing range
Dim Afterpart As Range, BeforePart As Range
If StartRow < 1 Or EndRow > MyRng.Rows.Count Then Set ExcludeRows = Nothing
If StartRow = 1 And EndRow = MyRng.Rows.Count Then Set ExcludeRows = Nothing
If EndRow = -1 Then EndRow = StartRow
If EndRow < MyRng.Rows.Count Then
With MyRng.Parent
Set Afterpart = .Range(MyRng.Cells(EndRow + 1, 1), MyRng.Cells(MyRng.Rows.Count, MyRng.Columns.Count))
End With
End If
If StartRow > 1 Then
With MyRng.Parent
Set BeforePart = .Range(MyRng.Cells(1, MyRng.Cells(1, 1).Column), MyRng.Cells(StartRow - 1, MyRng.Columns.Count))
End With
End If
Set ExcludeRows = Union2(True, BeforePart, Afterpart)
End Function
Public Function Union2(IgnoreEmptyRange As Boolean, ParamArray RangeArray() As Variant) As Range
'PURPOSE: Samae as Application.Union but allows some range object to be Empty
Dim V As Variant
Dim Rng As Range
For Each V In RangeArray
Do
If VarType(V) = vbEmpty Then Exit Do
Set Rng = V
If Not Union2 Is Nothing Then
Set Union2 = Union(Union2, Rng)
ElseIf Not Rng Is Nothing Then
Set Union2 = Rng
End If
Loop While False
Next
End Function
I read data I stored in a worksheet table into a VBA array. I need the first "column" of this array to be in lowercase. (The purpose of this array is to allow quicker calculations with the data contained in the table without referring to the table itself.)
I do this with the "LCase()" function, and I used the "Debug.print()" function to verify that they are being stored as lowercase.
However, later on in the code when I refer to this array, the values have reverted to their original case. I haven't added/edited the array beyond the point that I read the table data into it.
Simplified code:
Dim wb as Workbook
Dim ws as Worksheet
Dim tbl_Data as ListObject
Dim arr(1 to 10, 1 to 2) as Variant
Dim i as Integer
Dim calcValue as Single
Dim stringMatch as String
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet 1")
Set tbl_Data = ws.ListObjects("Table1")
For i = 1 to tbl_Data.ListRows.Count
arr(i, 1) = LCase(tbl_Data.DataBodyRange(i, 1))
arr(i, 2) = tbl_Data.DataBodyRange(i, 2))
Debug.Print(arr(i, 1)) 'Returns lowercase values normally
Next i
'---Insert calculations here
'- Returns calcValue (ex. calcValue = 10.12)
For i = 1 to UBound(arr, 1)
If calcValue = arr(i, 2) Then
Debug.Print(arr(i, 1)) 'Returns strings with original case values
stringMatch = arr(i, 1)
End If
Next i
I do not see an issue with the code that would cause the values stored to revert back to the original.
The original code. I hope that it makes sense, without the context of the data itself.
Option Explicit
Sub updateInventory()
Dim wb As Workbook
Dim sh_NewInventory As Worksheet
Dim sh_MasterInventory As Worksheet
Dim tbl_MasterInventory As ListObject
Dim cell_NewIngredient As Range
Dim arr_NewIngredients(1 To 30, 1 To 4) As Variant
Dim arr_MasterInventory(1 To 60, 1 To 6) As Variant
Dim i As Integer, j As Integer
Dim bool_isCellBlank As Boolean
Dim bool_isIngredientMatch As Boolean
Set wb = ThisWorkbook
Set sh_NewInventory = wb.Worksheets("Update Inventory")
Set sh_MasterInventory = wb.Worksheets("Food Inventory")
Set tbl_MasterInventory = sh_MasterInventory.ListObjects("MasterInventory")
Set cell_NewIngredient = sh_NewInventory.Range("B3")
bool_isCellBlank = False
bool_isIngredientMatch = False
i = 1
Do While Not bool_isCellBlank
arr_NewIngredients(i, 1) = LCase(cell_NewIngredient)
arr_NewIngredients(i, 2) = LCase(cell_NewIngredient.Offset(0, 1))
arr_NewIngredients(i, 3) = cell_NewIngredient.Offset(0, 2)
arr_NewIngredients(i, 4) = cell_NewIngredient.Offset(0, 3)
i = i + 1
Set cell_NewIngredient = cell_NewIngredient.Offset(1, 0)
bool_isCellBlank = (cell_NewIngredient = "")
Loop
For i = 1 To tbl_MasterInventory.ListRows.Count
arr_MasterInventory(i, 1) = LCase(tbl_MasterInventory.DataBodyRange(i, 1))
arr_MasterInventory(i, 2) = LCase(tbl_MasterInventory.DataBodyRange(i, 2))
For j = 1 To tbl_MasterInventory.ListColumns.Count - 2
arr_MasterInventory(i, j) = tbl_MasterInventory.DataBodyRange(i, j)
Next j
Next i
For i = 1 To UBound(arr_NewIngredients, 1)
j = 0
bool_isIngredientMatch = False
Do While Not bool_isIngredientMatch
j = j + 1
If arr_NewIngredients(i, 1) = LCase(arr_MasterInventory(j, 1)) Then
bool_isIngredientMatch = True
Debug.Print (arr_NewIngredients(i, 1) & " : " & arr_MasterInventory(j, 1))
End If
Loop
Next i
End Sub
RESULTS: Immediate Window
I figured it out!
See the following code (reading data into the array):
For i = 1 To tbl_MasterInventory.ListRows.Count
arr_MasterInventory(i, 1) = LCase(tbl_MasterInventory.DataBodyRange(i, 1))
arr_MasterInventory(i, 2) = LCase(tbl_MasterInventory.DataBodyRange(i, 2))
For j = 1 To tbl_MasterInventory.ListColumns.Count - 2
arr_MasterInventory(i, j) = tbl_MasterInventory.DataBodyRange(i, j)
Next j
Next i
I made a mistake in the loop using the "j" index. By starting at "j=1", I was replacing what I had done prior to the "j" For loop, which was what caused the data to be re-entered as the original version.
I feel real dumb for making the mistake, but I'm glad y'all looked at it for me! Thanks again!
I have a current code that compares the first two sheets and then outputs the differences in another. I am now trying to figure out how to also output the similarities into another worksheet.
Here is my current code:
Option Explicit
Sub CompareIt()
Dim ar As Variant
Dim arr As Variant
Dim Var As Variant
Dim v()
Dim i As Long
Dim n As Long
Dim j As Long
Dim str As String
ar = Sheet1.Cells(10, 1).CurrentRegion.Value
With CreateObject("Scripting.Dictionary")
.CompareMode = 1
ReDim v(1 To UBound(ar, 2))
For i = 2 To UBound(ar, 1)
For n = 1 To UBound(ar, 2)
str = str & Chr(2) & ar(i, n)
v(n) = ar(i, n)
Next
.Item(str) = v: str = ""
Next
ar = Sheet2.Cells(10, 1).CurrentRegion.Resize(, UBound(v)).Value
For i = 2 To UBound(ar, 1)
For n = 1 To UBound(ar, 2)
str = str & Chr(2) & ar(i, n)
v(n) = ar(i, n)
Next
If .exists(str) Then
.Item(str) = Empty
Else
.Item(str) = v
End If
str = ""
Next
For Each arr In .keys
If IsEmpty(.Item(arr)) Then .Remove arr
Next
Var = .items: j = .Count
End With
With Sheet3.Range("a10").Resize(, UBound(ar, 2))
.CurrentRegion.ClearContents
.Value = ar
If j > 0 Then
.Offset(1).Resize(j).Value = Application.Transpose(Application.Transpose(Var))
End If
End With
Sheet3.Activate
End Sub
Any ideas?
Since your question is:
Any ideas?
I do have an idea that does rely on:
Your excel license (TEXTJOIN function is available if you have Office 2019, or if you have an Office 365 subscription)
Your data size (If the resulting string exceeds 32767 characters (cell limit), TEXTJOIN returns the #VALUE! error.)
But it's an idea :)
Sheet1 & Sheet2
Run this code:
Sub Test()
Dim Var() As String
With ThisWorkbook.Sheets("Sheet3")
Var() = Split(Evaluate("=TEXTJOIN("","",TRUE,IF(Sheet1!A1:A6=TRANSPOSE(Sheet2!A1:A5),Sheet1!A1:A6,""""))"), ",")
.Cells(1, 1).Resize(UBound(Var) + 1).Value = Application.Transpose(Var)
End With
End Sub
Output on sheet3:
Obviously it's simplified, but you can add variables in the EVALUATE.