I have below code in which i want to create a loop for multiple values that are available in Sheet1.Range(A2:A100) code will pick one by one each value and match then paste result in Column B.
thisvalue = Sheet1.Range("A2:A100"). Can someone please help me to create the loop. Your help will be appreciated.
Sub Macro1()
Dim thisvalue As Double, sh As Worksheet, lastR As Long, arr, arrFin, i As Long
thisvalue = 3.61
Set sh = Worksheets("Sheet1")
lastR = sh.Range("J" & sh.rows.count).End(xlUp).row
arr = sh.Range("E7:J" & lastR).Value
ReDim arrFin(1 To UBound(arr), 1 To 1)
For i = 1 To UBound(arr)
If arr(i, 1) < thisvalue And arr(i, 2) > thisvalue Then arrFin(i, 1) = arr(i, 6)
Next i
sh.Range("B2").Resize(UBound(arrFin), 1).Value = arrFin
End Sub
Please, try the next code:
Sub Macro1__2()
Dim thisvalue As Double, sh As Worksheet, lastR As Long
Dim arrVal, arr, arrFin, i As Long, j As Long
Set sh = Worksheets("Sheet2")
arrVal = Worksheets("Sheet1").Range("Q2:Q100").Value
Worksheets("Sheet1").Range("R2:R200").ClearContents
lastR = sh.Range("J" & sh.Rows.Count).End(xlUp).Row
arr = sh.Range("E7:J" & lastR).Value
For j = 1 To UBound(arrVal)
thisvalue = arrVal(j, 1)
If CStr(thisvalue) <> "" Then 'excluding the cases of empty cells. I didn't know that they may exist
arrFin = Worksheets("Sheet1").Range("R2:R200").Value 'firstly input the existing range in the array
For i = 1 To UBound(arr)
If arr(i, 1) < thisvalue And arr(i, 2) > thisvalue Then arrFin(j, 1) = arr(i, 6)
Next i
Worksheets("Sheet1").Range("R2").Resize(UBound(arrFin), 1).Value = arrFin
End If
Next j
MsgBox "Ready..."
End Sub
Ranges and Arrays
Option Explicit
Sub Macro1()
' Source
Const sName As String = "Sheet1"
Const slrCol As String = "J"
Const sCols As String = "E:J"
Const sfRow As Long = 7
Const scColLess As Long = 1
Const scColGreater As Long = 2
Const srCol As Long = 6
Const sCriteria As Double = 3.61
' Destination
Const dName As String = "Sheet1"
Const dFirst As String = "B2"
' Create a reference to the Workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Create a reference to the Source Worksheet ('sws').
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
' Create a reference to the Source Range ('srg').
If sws.Columns(sCols).Columns.Count < srCol Then Exit Sub ' too few columns
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, slrCol).End(xlUp).Row
If slRow < sfRow Then Exit Sub ' no data
Dim rCount As Long: rCount = slRow - sfRow + 1 ' for source and destination
Dim srg As Range
Set srg = sws.Rows(sfRow).Columns(sCols).Resize(rCount)
' Write the values from the Source Range
' to the Source Array ('sData').
Dim sData As Variant: sData = srg.Value
' Define the Destination Array ('dData').
Dim dData As Variant: ReDim dData(1 To rCount, 1 To 1)
' Write the appropriate values from the Source Array
' to the Destination Array.
Dim cValue As Variant
Dim r As Long
For r = 1 To rCount
cValue = sData(r, scColLess)
If IsNumeric(cValue) Then
If cValue < sCriteria Then
cValue = sData(r, scColGreater)
If IsNumeric(cValue) Then
If cValue > sCriteria Then
dData(r, 1) = sData(r, srCol)
End If
End If
End If
End If
Next r
' Create a reference to the Destination Worksheet ('dws').
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
' Create a reference to the Destination Range ('drg').
Dim dfCell As Range: Set dfCell = dws.Range(dFirst)
Dim drg As Range: Set drg = dfCell.Resize(rCount)
' Write the values from the Destination Array
' to the Destination Range ('drg').
drg.Value = dData
' Clear the Destination Clear Range ('dcrg'),
' the range below the Destination Range.
Dim dcrg As Range
Set dcrg = drg.Resize(dws.Rows.Count - drg.Row - rCount + 1).Offset(rCount)
dcrg.Clear ' or maybe rather 'dcrg.ClearContents'
' Format the Destination Range.
'drg.Font.Bold = True
'drg.EntireColumn.AutoFit
'drg.Interior.Color = 14348258
' Save the workbook.
'wb.Save
End Sub
Related
I use this VBA code which works very well. It searches in column A of an external Excel file for all the terms in column D, and replaces the matches, with the content of column B of the external file in the found row. So for instance:
if D5 matches A11 of the external file, then B11 from external file is written to D5.
I am now trying to modify it so that it still searches in column 4 for matches in column A of external file, but for any matches found, replaces the column E with column B of the external file. So:
If D5 matches A11, then B11 from external file is written to E5.
Well, I've tried many changes in the replace loop but it throws errors every time. I suppose I don't use the correct command!
Private Sub CommandButton1_Click()
Dim NameListWB As Workbook, thisWb As Workbook
Dim NameListWS As Worksheet, thisWs As Worksheet
Dim i As Long, lRow As Long
'This is the workbook from where code runs
Set thisWb = ThisWorkbook
Set thisWs = thisWb.Sheets("Sheet1")
'External file
Set NameListWB = Workbooks.Open("E:\Data.xlsx")
Set NameListWS = NameListWB.Worksheets("Sheet1")
With NameListWS
'Detect end row in Col A of Data.xlsx
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
'Loop though Column A
For i = 1 To lRow
'... and perform replace action
thisWs.Columns(4).Replace What:=.Range("A" & i).Value, _
Replacement:=.Range("B" & i).Value, _
SearchOrder:=xlByColumns, _
MatchCase:=False
Next i
End With
End Sub ```
Untested:
Private Sub CommandButton1_Click()
Dim NameListWB As Workbook
Dim NameListWS As Worksheet, thisWs As Worksheet, n As Long
Dim i As Long, arrList, arrD, rngD As Range
Set thisWs = ThisWorkbook.Sheets("Sheet1") 'This is the workbook from where code runs
'get an array from the column to be searched
Set rngD = thisWs.Range("D1:D" & thisWs.Cells(Rows.Count, "D").End(xlUp).Row)
arrD = rngD.Value
'Open external file and get the terms and replacements as an array
Set NameListWB = Workbooks.Open("E:\Data.xlsx")
With NameListWB.Worksheets("Sheet1")
arrList = .Range("A1:B" & .Cells(Rows.Count, "A").End(xlUp).Row).Value
End With
For n = 1 To UBound(arrD, 1) 'check each value from ColD
For i = 1 To UBound(arrList, 1) 'loop over the array of terms to search for
If arrD(n, 1) = arrList(i, 1) Then 'exact match ?
'If InStr(1, arrD(n, 1), arr(i, 1)) > 0 Then 'partial match ?
rngD.Cells(n).Offset(0, 1).Value = arrList(i, 2) 'populate value from ColB into ColE
Exit For 'got a match so stop searching
End If
Next i
Next n
End Sub
A VBA Lookup (Application.Match)
Adjust (play with) the values in the constants section.
Compact
Sub VBALookup()
' Source
Const sPath As String = "E:\Data.xlsx"
Const sName As String = "Sheet1"
Const slCol As String = "A" ' lookup
Const svCol As String = "B" ' value
Const sfRow As Long = 2
' Destination
Const dName As String = "Sheet1"
Const dlCol As String = "D" ' lookup
Const dvCol As String = "E" ' value
Const dfRow As Long = 2
Application.ScreenUpdating = False
' Source
Dim swb As Workbook: Set swb = Workbooks.Open(sPath)
Dim sws As Worksheet: Set sws = swb.Worksheets(sName)
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, slCol).End(xlUp).Row
If slRow < sfRow Then Exit Sub ' no data in lookup column range
Dim srCount As Long: srCount = slRow - sfRow + 1
Dim slrg As Range: Set slrg = sws.Cells(sfRow, slCol).Resize(srCount)
Dim svData As Variant
With slrg.EntireRow.Columns(svCol)
If srCount = 1 Then ' one cell
ReDim svData(1 To 1, 1 To 1): svData(1, 1) = .Value
Else ' multiple cells
svData = .Value
End If
End With
' Destination
Dim dwb As Workbook: Set dwb = ThisWorkbook ' workbook containing this code
Dim dws As Worksheet: Set dws = dwb.Worksheets(dName)
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, dlCol).End(xlUp).Row
If dlRow < dfRow Then Exit Sub ' no data in lookup column range
Dim drCount As Long: drCount = dlRow - dfRow + 1
Dim dlrg As Range: Set dlrg = dws.Cells(dfRow, dlCol).Resize(drCount)
Dim dData As Variant
If drCount = 1 Then ' one cell
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = dlrg.Value
Else ' multiple cells
dData = dlrg.Value
End If
' Loop.
Dim srIndex As Variant
Dim dValue As Variant
Dim dr As Long
Dim MatchFound As Boolean
For dr = 1 To drCount
dValue = dData(dr, 1)
If Not IsError(dValue) Then
If Len(dValue) > 0 Then
srIndex = Application.Match(dValue, slrg, 0)
If IsNumeric(srIndex) Then MatchFound = True
End If
End If
If MatchFound Then
dData(dr, 1) = svData(srIndex, 1)
MatchFound = False
Else
dData(dr, 1) = Empty
End If
Next dr
' Close the source workbook.
swb.Close SaveChanges:=False
' Write result.
dlrg.EntireRow.Columns(dvCol).Value = dData
' Inform.
Application.ScreenUpdating = True
MsgBox "VBA lookup has finished.", vbInformation
End Sub
I have two macros that I would like to combine but somehow its not going well...
I want a macro that will get only unique values from a range and input them into another sheet every second row starting from row no 3
Could anyone tell me how should I combine those two macros?
I have tried to change .Font.Size = 20 with Application.Transpose(objDict.keys) but it didn't work.
Sub UniqueValue()
Dim X
Dim objDict As Object
Dim lngRow As Long
Set objDict = CreateObject("Scripting.Dictionary")
X = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp)))
For lngRow = 1 To UBound(X, 1)
objDict(X(lngRow)) = 1
Next
Range("F1:F" & objDict.Count) = Application.Transpose(objDict.keys)
End Sub
Sub EverySecond()
Dim EndRow As Long
EndRow = Range("A" & Rows.Count).End(xlUp).Row
For ColNum = 5 To EndRow Step 2
Range(Cells(ColNum, 2), Cells(ColNum, 2)).Font.Size = 20
Next ColNum
End Sub
Copy Unique Values to Every Other Row
Option Explicit
Sub UniqueEveryOther()
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "A2"
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "A2"
Dim wb As Workbook: Set wb = ThisWorkbook
' Reference the source range.
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim srg As Range
Dim srCount As Long
With sws.Range(sFirstCellAddress)
Dim lCell As Range: Set lCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub
srCount = lCell.Row - .Row + 1
Set srg = .Resize(srCount)
End With
' Write the values from the source range to an array.
1
Dim Data As Variant
If srCount = 1 Then ' one cell
ReDim Data(1 To 1, 1 To 1): Data(1, 1) = srg.Value
Else ' multiple cells
Data = srg.Value
End If
' Write the unqiue values from the array to a dictionary.
Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")
dict.CompareMode = vbTextCompare
Dim Key As Variant
Dim r As Long
For r = 1 To srCount
Key = Data(r, 1)
If Not IsError(Key) Then
If Len(Key) > 0 Then
dict(Key) = Empty
End If
End If
Next r
If dict.Count = 0 Then Exit Sub
' Write the unqiue values from the dictionary to the array.
ReDim Data(1 To 2 * dict.Count - 1, 1 To 1)
r = -1
For Each Key In dict.Keys
r = r + 2
Data(r, 1) = Key
Next Key
' Write the unique values from the array to the destination range.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dFirstCellAddress)
.Resize(r).Value = Data
.Resize(dws.Rows.Count - .Row - r + 1).Offset(r).Clear
'.EntireColumn = AutoFit
End With
'wb.Save
MsgBox "Uniques populated.", vbInformation
End Sub
My idea is to get the data that I have on "A4" ("Data" worksheet) and paste it 4 times on "B4" ("Forecast" worksheet). After that, take the data from "A5" and do the same (starting from the first blank cell) until there is no more data on the "A" column. After there is no more data, the process should stop.
How do I tell excel to paste the value in the first blank cell in column B ("Forecast" worksheet)?
Sub Test()
Dim wsSource As Worksheet, wsTarget As Worksheet
Dim i As Integer, k As Integer
Set wsSource = ThisWorkbook.Worksheets("Data")
Set wsTarget = ThisWorkbook.Worksheets("Forecast")
k = wsSource.Range("A4", wsSource.Range("A4").End(xlDown)).Rows.Count
For i = 1 To k
wsTarget.Range("B4", "B7").Value = wsSource.Range("A" & 3 + i).Value
Next
End Sub
Copy Repetitions
A Quick Fix
Sub Test()
Dim wsSource As Worksheet, wsTarget As Worksheet
Dim sCell As Range, tCell As Range
Dim i As Long, j As Long, k As Long
Set wsSource = ThisWorkbook.Worksheets("Data")
Set wsTarget = ThisWorkbook.Worksheets("Forecast")
k = wsSource.Range("A4", wsSource.Range("A4").End(xlDown)).Rows.Count
Set sCell = wsSource.Range("A4")
Set tCell = wsTarget.Range("B4")
For i = 1 To k
For j = 1 To 4
tCell.Value = sCell.Value
Set tCell = tCell.Offset(1)
Next j
Set sCell = sCell.Offset(1)
Next i
End Sub
My Choice
Sub CopyRepetitions()
' Source
Const sName As String = "Data"
Const sfCellAddress As String = "A4"
' Destination
Const dName As String = "Forecast"
Const dfCellAddress As String = "B4"
Const Repetitions As Long = 4
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source (one-column) range ('srg').
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim srg As Range
Dim srCount As Long
With sws.Range(sfCellAddress)
Dim lCell As Range: Set lCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Sub ' no data
srCount = lCell.Row - .Row + 1
Set srg = .Resize(srCount)
End With
' Write values from the source range the source array ('sData')
Dim sData As Variant
If srCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
Else
sData = srg.Value
End If
' Define the destination array ('dData').
Dim drCount As Long: drCount = srCount * Repetitions
Dim dData As Variant: ReDim dData(1 To drCount, 1 To 1)
' Write the repeating values from the source- to the destination array.
Dim sr As Long
Dim rep As Long
Dim dr As Long
For sr = 1 To srCount
For rep = 1 To Repetitions
dr = dr + 1
dData(dr, 1) = sData(sr, 1)
Next rep
Next sr
' Write the values from the destination array to the destination
' one-column range and clear the data below.
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dfCellAddress)
.Resize(drCount).Value = dData
.Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
End With
' Inform.
MsgBox "Repetitions copied.", vbInformation
End Sub
I have some code that works okay on a small data set, however, I'm looking for the most efficient way to handle this over in 100k+ rows.
The data is in two columns. In column B, wherever "Orange" is listed, I would like to copy/paste "Orange" into column A and replace "Citrus" for that row.
Here is my current code. I think it has some unnecessary bits in it now since I was trying to find a way to copy and paste all of the found cells at once.
SearchStr = "Orange"
Set SearchRng = Range("b2:b11)
With SearchRng
Set FoundCell = .Find(SearchStr, LookIn:=xlValues, LookAt:=xlPart)
If Not FoundCell Is Nothing Then
FirstAdd = FoundCell.Address
Do
If Not AllFoundCells Is Nothing Then
Set AllFoundCells = Union(AllFoundCells, FoundCell)
Else
Set AllFoundCells = FoundCell
End If
FoundCell.Copy Destination:=FoundCell.Offset(0, -1)
Set FoundCell = .FindNext(FoundCell)
Loop While FoundCell.Address <> FirstAdd
End If
End With
Replace If Match in Column
If a string (sString) is found in a column (sCol), then write another string (dString (in this case dString = sString)) to another column (dCol).
On my sample data of 1M rows (>200k of matches), it took less than 2s for the 'AutoFilter' solution and it took about 4s for the 'Array Loop' solution (3s for writing back to the range: drg.Value = dData).
Option Explicit
Sub UsingAutoFilter()
' Source
Const sCol As String = "B"
Const sString As String = "Orange"
' Destination
Const dCol As String = "A"
Const dString As String = "Orange"
' Both
Const hRow As Long = 1 ' Header Row
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
If ws.AutoFilterMode Then ws.AutoFilterMode = False
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, sCol).End(xlUp).Row
If lRow < hRow + 1 Then Exit Sub ' no data or just headers
Dim rCount As Long: rCount = lRow - hRow + 1
Dim srg As Range: Set srg = ws.Cells(hRow, sCol).Resize(rCount)
Dim sdrg As Range: Set sdrg = srg.Resize(srg.Rows.Count - 1).Offset(1)
srg.AutoFilter 1, sString
Dim sdvrg As Range
On Error Resume Next
Set sdvrg = sdrg.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
ws.AutoFilterMode = False
If sdvrg Is Nothing Then Exit Sub ' no match found
Dim ddvrg As Range
Set ddvrg = sdvrg.Offset(, ws.Columns(dCol).Column - srg.Column)
ddvrg.Value = dString
End Sub
Sub UsingArrayLoop()
' Source
Const sCol As String = "B"
Const sString As String = "Orange"
' Destination
Const dCol As String = "A"
Const dString As String = "Orange"
' Both
Const fRow As Long = 2 ' First Data Row
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim lRow As Long: lRow = ws.Cells(ws.Rows.Count, sCol).End(xlUp).Row
If lRow < fRow Then Exit Sub ' no data
Dim rCount As Long: rCount = lRow - fRow + 1
Dim srg As Range: Set srg = ws.Cells(fRow, sCol).Resize(rCount)
Dim drg As Range: Set drg = srg.EntireRow.Columns(dCol)
Dim sData As Variant
Dim dData As Variant
If rCount = 1 Then
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = srg.Value
ReDim dData(1 To 1, 1 To 1): dData(1, 1) = drg.Value
Else
sData = srg.Value
dData = drg.Value
End If
Dim r As Long
For r = 1 To rCount
If StrComp(CStr(sData(r, 1)), sString, vbTextCompare) = 0 Then
dData(r, 1) = dString
End If
Next r
Erase sData
drg.Value = dData
End Sub
Should be quicker than copy-paste:
Sub Tester()
Dim rw As Long, f As String
With ActiveSheet
rw = .Cells(.Rows.Count, "B").End(xlUp).Row
f = Replace("=IF(B2:B<rw>=""Orange"",B2:B<rw>,A2:A<rw>)", "<rw>", rw)
.Range("A2:A" & rw).value = .Evaluate(f) 'edited to remove `Application`
End With
End Sub
About 0.2sec for 100k rows
Evaluate() takes a worksheet function and evaluates it in the context of either the ActiveSheet (if you use the Application.Evaluate form) or a specific worksheet (if you use the WorkSheet.Evaluate form). It handles array formulas (no need to add the {}), and can return an array as the result (which here we just assign directly to the ColA range)
I am using below code which is comparing three columns values and copy pasting the 4th column data into other column.
My code is working fine but it is slow to perform the processing and takes much time and sometimes Not Responding window appears.
Any help to fix the problem will be appreciated
Sub rowMatch()
Dim ws As Worksheet
Dim ws2 As Worksheet
Set ws = Worksheets("Sheet3")
Set ws2 = Worksheets("Sheet2")
Dim a As String, b As String, c As Date
For i = 3 To ws.Cells(ws.Rows.Count, 14).End(xlUp).Row
a = ws.Cells(i, 14).Value
b = ws.Cells(i, 15).Value
c = ws.Cells(i, 16).Value
For j = 3 To ws2.Cells(ws2.Rows.Count, 98).End(xlUp).Row
If ws2.Cells(j, 98).Value = a _
And ws2.Cells(j, 103).Value = b _
And ws2.Cells(j, 114).Value = c _
Then
ws2.Cells(j, 120).Value = ws.Cells(j, 18).Value
End If
Next j
Next i
End Sub
A 'Triple' Lookup
When in a loop a condition 1. is not met or 2. is met, use Exit For to stop looping (to exit the loop).
Option Explicit
Sub TripleLookup()
' Source
Const sName As String = "Sheet3" ' Worksheet Name
Const sfRow As Long = 3 ' First Row
Const slColsList As String = "N,O,P" ' Lookup Columns
Const slrCol As String = "N" ' Last Row Column
Const svCol As String = "R" ' Value Column
' Destination
Const dName As String = "Sheet2" ' Worksheet Name
Const dfRow As Long = 3 ' First Row
Const dlColsList As String = "CT,CY,DJ" ' Lookup Columns
Const dlrcol As String = "CT" ' Last Row Column
Const dvCol As String = "DP" ' Value Column
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, slrCol).End(xlUp).Row
If slRow < sfRow Then Exit Sub ' no data
Dim srCount As Long: srCount = slRow - sfRow + 1
Dim slrrg As Range: Set slrrg = sws.Cells(sfRow, slrCol).Resize(srCount)
Dim slCols() As String: slCols = Split(slColsList, ",")
Dim cUpper As Long: cUpper = UBound(slCols)
Dim sData As Variant: ReDim sData(0 To cUpper)
Dim srg As Range
Dim n As Long
For n = 0 To cUpper
Set srg = slrrg.EntireRow.Columns(slCols(n))
sData(n) = srg.Value
Next n
Set srg = slrrg.EntireRow.Columns(svCol)
Dim svData As Variant: svData = srg.Value
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, dlrcol).End(xlUp).Row
If dlRow < dfRow Then Exit Sub ' no data
Dim drCount As Long: drCount = dlRow - dfRow + 1
Dim dlrrg As Range: Set dlrrg = dws.Cells(dfRow, dlrcol).Resize(drCount)
Dim dlCols() As String: dlCols = Split(dlColsList, ",")
Dim dData As Variant: ReDim dData(0 To cUpper)
Dim drg As Range
For n = 0 To cUpper
Set drg = dlrrg.EntireRow.Columns(dlCols(n))
dData(n) = drg.Value
Next n
Dim dvData As Variant: ReDim dvData(1 To drCount, 1 To 1)
' Loop
Dim tUpper As Long: tUpper = cUpper + 1
Dim sr As Long
Dim dr As Long
For dr = 1 To drCount
For sr = 1 To srCount
For n = 0 To cUpper
If StrComp(CStr(sData(n)(sr, 1)), CStr(dData(n)(dr, 1)), _
vbTextCompare) <> 0 Then ' ignoring case
Exit For ' 1. mismatch found, no need to loop anymore
End If
Next n
If n = tUpper Then ' no mismatch, all are equal
dvData(dr, 1) = svData(sr, 1)
Exit For ' 2. value written, no need to loop anymore
End If
Next sr
Next dr
' Result
Set drg = dlrrg.EntireRow.Columns(dvCol)
drg.Value = dvData
End Sub
Looking at the code you have two nested For loops, which depending on the size of the dataset you're working with, it will likely continue to be an issue on the time it takes to complete the task. The more rows you have, the longer it will take to complete the tasks.
One possible solution that you might want to consider looking into is using power query to blend/merge/append and clean data. Then use VBA to do what Power Query doesn't do very well.
I've spent many years avoiding looking at PQ as a solution to these problems and was a VBA guy all the way, but now when I come across these types of problems,I would look at PQ first over VBA.