Consolidating Dynamic Named Ranges from Separate Sheets - excel

My initial understanding is that I may be able to use Union to solve this:
I have different dynamic named ranges for various product types on separate pages in a workbook. All carry the same start cell and column properties, but vary in length based on input data. Is there an easy way to automatically pool these entries into a consolidated list? These are not formatted tables, and I'd prefer to avoid making them into charts.
Ex: Worksheet 1 carries a list of two products (B2:B3) with associated revenue and cost figures in columns C and D. Worksheet 2 carries a list of three products (B2:B4) with... I'd like to have worksheet 3 automatically update with (B2:B6) and columns C and D with data from the original 2 worksheets. This data will grow and will be changed periodically.

Here's one method to emulate UNION
=LET(
data1,FILTER('Worksheet 1'!B:D,'Worksheet 1'!B:B<>""),
data2,FILTER('Worksheet 2'!B:D,'Worksheet 2'!B:B<>""),
rows1,ROWS(data1),
rows2,ROWS(data2),
cols1,COLUMNS(data1),
rowindex,SEQUENCE(rows1+rows2),
colindex,SEQUENCE(1,cols1),
IF(
rowindex<=rows1,
INDEX(data1,rowindex,colindex),
INDEX(data2,rowindex-rows1,colindex))
)

I know my code is probably wildly inefficient - I'm still at the beginning of my learning... Since I couldn't figure out this "union" thing, I ended up running the following code:
Sub dynamicRangeCons()
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim startCell As Range, lastRow As Long, lastCol As Long, ws0 As Worksheet, ws1 As Worksheet
Dim ConsItem As String
Set ws = Worksheets("Cons Ingredients Listing")
ws.Activate
Set startCell = ws.Range("B3")
Set ws0 = ThisWorkbook.Sheets("Cons Ingredients Listing")
Set ws1 = ThisWorkbook.Sheets("Spirits Ingredients Listing")
Set ws2 = ThisWorkbook.Sheets("Beer Ingredients Listing")
Set ws3 = ThisWorkbook.Sheets("Misc Ingredients Listing")
Set ws4 = ThisWorkbook.Sheets("Wine Ingredients Listing")
Set ws5 = ThisWorkbook.Sheets("NA Ingredients Listing")
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).End(xlToRight).Column
ws.Range(startCell, ws.Cells(lastRow, lastCol)).Clear
ws1.Range("SpiritsItem").Copy ws0.Range("B3")
ws1.Range("Spirits").Copy ws0.Range("C3")
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).Column
ws2.Range("BeerItem").Copy ws.Cells(lastRow + 1, lastCol)
ws2.Range("Beer").Copy ws.Cells(lastRow + 1, lastCol + 1)
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).Column
ws3.Range("MiscItem").Copy ws.Cells(lastRow + 1, lastCol)
ws3.Range("Misc").Copy ws.Cells(lastRow + 1, lastCol + 1)
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).Column
ws4.Range("WineItem").Copy ws.Cells(lastRow + 1, lastCol)
ws4.Range("Wine").Copy ws.Cells(lastRow + 1, lastCol + 1)
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).Column
ws5.Range("NAItem").Copy ws.Cells(lastRow + 1, lastCol)
ws5.Range("NA").Copy ws.Cells(lastRow + 1, lastCol + 1)
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).Column
ws.Range(startCell, ws.Cells(lastRow, lastCol)).Select
ThisWorkbook.Names.Add Name:="ConsItem", RefersTo:=Selection
lastRow = ws.Cells(ws.Rows.Count, startCell.Column).End(xlUp).Row
lastCol = ws.Cells(startCell.Row, startCell.Column).End(xlToRight).Column
ws.Range(ws.Cells(startCell.Row, startCell.Column + 1), ws.Cells(lastRow, lastCol)).Select
ThisWorkbook.Names.Add Name:="Cons", RefersTo:=Selection
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub

Consolidate Worksheets
Copy the following into a standard module, e.g. Module1.
Adjust the values in the constants section.
Option Explicit
Sub ConsolidateProducts()
Const sNamesList As String = "Sheet1,Sheet2"
Const sFirst As String = "B2:D2"
Const dName As String = "Sheet3"
Const dFirst As String = "B2"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sNames() As String: sNames = Split(sNamesList, ",")
Dim nUpper As Long: nUpper = UBound(sNames)
Dim nCount As Long: nCount = -1
Dim sData As Variant: ReDim sData(0 To nUpper)
Dim rData() As Long: ReDim rData(0 To nUpper)
Dim sws As Worksheet
Dim srg As Range
Dim sfrrg As Range
Dim slCell As Range
Dim srCount As Long
Dim drCount As Long
Dim n As Long
For n = 0 To nUpper
Set sws = wb.Worksheets(sNames(n))
Set sfrrg = sws.Range(sFirst)
Set slCell = Nothing
Set slCell = sfrrg.Resize(sws.Rows.Count - sfrrg.Row + 1) _
.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not slCell Is Nothing Then
nCount = nCount + 1
srCount = slCell.Row - sfrrg.Row + 1
Set srg = sfrrg.Resize(srCount)
sData(nCount) = srg.Value
rData(nCount) = srCount
drCount = drCount + srCount
End If
Next n
If nCount = -1 Then Exit Sub
Dim cCount As Long: cCount = sfrrg.Columns.Count
Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
Dim s As Long, d As Long, c As Long
For n = 0 To nCount
For s = 1 To rData(n)
d = d + 1
For c = 1 To cCount
dData(d, c) = sData(n)(s, c)
Next c
Next s
Next n
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirst)
Dim dfrrg As Range: Set dfrrg = dfCell.Resize(, cCount)
Dim drg As Range: Set drg = dfrrg.Resize(drCount)
drg.Value = dData
Dim dcrg As Range: Set dcrg = dfrrg _
.Resize(dws.Rows.Count - dfrrg.Row - drCount - 1).Offset(drCount)
dcrg.ClearContents
End Sub
If all the data are values then to automate the previous, copy the following into each source module (not the destination (resulting) worksheet).
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const sFirst As String = "B2:D2"
Dim srg As Range
With Range(sFirst)
Set srg = .Resize(Rows.Count - .Row + 1)
End With
Dim irg As Range
Set irg = Intersect(srg, Target)
If Not srg Is Nothing Then
ConsolidateProducts
End If
End Sub

Related

Extract data separated by multiple dots from a single cell

The cells contain different lengths of data. I tried text to column. It does not work because of the number of dots.
How can I populate each text or number in separate cells by ignoring the number of dots than delete the line anywhere there is an empty cell in column A and B?
Data exemple:
Split Data
Associated
Sub SplitAssociated()
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "A1"
Const dName As String = "Sheet1"
Const dFirstCellAddress As String = "B1"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sfCell As Range: Set sfCell = sws.Range(sFirstCellAddress)
Dim srg As Range
Dim rCount As Long
With sfCell.Resize(sws.Rows.Count - sfCell.Row + 1)
Dim slCell As Range
Set slCell = .Find("*", , xlFormulas, , , xlPrevious)
rCount = slCell.Row - .Row + 1
Set srg = .Resize(rCount)
End With
Dim Data As Variant
Data = sws.Evaluate("TRIM(SUBSTITUTE(" & srg.Address & ",""."","" ""))")
Dim SubStrings() As Variant: ReDim SubStrings(1 To rCount)
Dim Lens() As Long: ReDim Lens(1 To rCount)
Dim r As Long
Dim cCount As Long
Dim cString As String
For r = 1 To rCount
cString = Data(r, 1)
If Len(cString) > 0 Then
SubStrings(r) = Split(cString)
Lens(r) = UBound(SubStrings(r)) + 1
If Lens(r) > cCount Then cCount = Lens(r)
End If
Next r
ReDim Data(1 To rCount, 1 To cCount)
Dim c As Long
For r = 1 To rCount
For c = 1 To Lens(r)
Data(r, c) = SubStrings(r)(c - 1)
Next c
Next r
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim drg As Range: Set drg = dfCell.Resize(rCount, cCount)
drg.Value = Data
drg.Resize(dws.Rows.Count - drg.Row - rCount + 1).Offset(rCount).Clear
End Sub
Remove Blanks
Sub SplitRemoveBlanks()
Const sName As String = "Sheet1"
Const sFirstCellAddress As String = "A1"
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "C1"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sfCell As Range: Set sfCell = sws.Range(sFirstCellAddress)
Dim srg As Range
Dim srCount As Long
With sfCell.Resize(sws.Rows.Count - sfCell.Row + 1)
Dim slCell As Range
Set slCell = .Find("*", , xlFormulas, , , xlPrevious)
srCount = slCell.Row - .Row + 1
Set srg = .Resize(srCount)
End With
Dim Data As Variant
Data = sws.Evaluate("TRIM(SUBSTITUTE(" & srg.Address & ",""."","" ""))")
Dim SubStrings() As Variant: ReDim SubStrings(1 To srCount)
Dim Lens() As Long: ReDim Lens(1 To srCount)
Dim sr As Long
Dim drCount As Long
Dim dcCount As Long
Dim cString As String
For sr = 1 To srCount
cString = Data(sr, 1)
If Len(cString) > 0 Then
drCount = drCount + 1
SubStrings(sr) = Split(cString)
Lens(sr) = UBound(SubStrings(sr)) + 1
If Lens(sr) > dcCount Then dcCount = Lens(sr)
End If
Next sr
ReDim Data(1 To drCount, 1 To dcCount)
Dim dr As Long
Dim dc As Long
For sr = 1 To srCount
If Lens(sr) > 0 Then
dr = dr + 1
For dc = 1 To Lens(sr)
Data(dr, dc) = SubStrings(sr)(dc - 1)
Next dc
End If
Next sr
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim drg As Range: Set drg = dfCell.Resize(drCount, dcCount)
drg.Value = Data
drg.Resize(dws.Rows.Count - drg.Row - drCount + 1).Offset(drCount).Clear
End Sub
If the "." (dot) is the element to be stripped from strings in cells (eg no floating point numbers, nor "." is an important mark), you can use this code including deleting entire lines.
The code loops through the specified range (oRng) and when it finds ".." it will replace it with ".". Then, when no more ".." is found, indicating that the replacement job has completed, generating an error (caught), it proceeds to delete the blank rows from the blank cells in column "A".
Option Explicit
Sub fnCleanAndSplit()
Dim oRng As Excel.Range
Dim oCell As Excel.Range
Dim fDone As Boolean
Set oRng = ThisWorkbook.Sheets(1).Range("A1:A7")
Do
For Each oCell In oRng.Cells
oCell.Value = VBA.Replace(oCell.Value, "..", ".")
Next
On Error GoTo lblDone
fDone = oRng.Find("..") = ""
On Error GoTo 0
Loop Until fDone
lblDone:
oRng.TextToColumns Destination:=oRng.Cells(1), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, Other:=True, OtherChar _
:=".", TrailingMinusNumbers:=True
oRng.SpecialCells(xlCellTypeBlanks).Select
oRng.Parent.Activate 'just in case it is not activated
Selection.EntireRow.Delete
End Sub

Copy and paste multiple times and loop

I have a problem in writing a code to copy and paste multiple times.
I have 2 sheets, where in sheet 1 I have 160 Rows and 3 columns.
I need to copy each row and paste 15 times in sheet 2.
can anyone help me to sort it out.
Given that you keep your three columns as you stated and the headers in row 1, you achieve what you say by changing the ranges dynamically in a simple for loop
Sub copy_15()
Application.ScreenUpdating = False
With Worksheets("Sheet2")
Dim wS2 As Range
Set wS2 = .Range("A1").CurrentRegion
wS2.ClearContents
'Copy headers
Worksheets("Sheet1").Range("A1:C1").Copy
.Range("A1").PasteSpecial
End With
Dim lastRow1 As Long: lastRow1 = Worksheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastRow1
Worksheets("Sheet1").Range("A" & i & ":C" & i).Copy
Dim lastRow2 As Long: lastRow2 = Worksheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
Worksheets("Sheet2").Range("A" & lastRow2 + 1 & ":C" & lastRow2 + 15).PasteSpecial
Next i
Application.CutCopyMode = False
End Sub
Return Repeated Rows in Another Worksheet
Sub RepeatRows()
' Source
Const sName As String = "Sheet1"
Const sFirstRowAddress As String = "A2:C2"
' Destination
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "A2"
Dim RepeatCount As Variant
Dim msg As Long
Do
RepeatCount = InputBox("How many Times")
If IsNumeric(RepeatCount) Then
If Len(RepeatCount) = Len(Int(RepeatCount)) Then
If RepeatCount > 0 Then Exit Do
End If
End If
msg = MsgBox("Not a valid entry.", vbYesNo + vbCritical, "Try again?")
If msg = vbNo Then Exit Sub
Loop
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sData As Variant
Dim srCount As Long
Dim cCount As Long
With sws.Range(sFirstRowAddress)
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
cCount = .Columns.Count
If srCount + cCount = 2 Then ' one cell
ReDim sData(1 To 1, 1 To 1): sData(1, 1) = .Value
Else ' multiple cells
sData = .Resize(srCount).Value
End If
End With
Dim drCount As Long: drCount = srCount * RepeatCount
Dim dData As Variant: ReDim dData(1 To drCount, 1 To cCount)
Dim sr As Long
Dim n As Long
Dim c As Long
Dim dr As Long
For sr = 1 To srCount
For n = 1 To RepeatCount
dr = dr + 1
For c = 1 To cCount
dData(dr, c) = sData(sr, c)
Next c
Next n
Next sr
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
With dws.Range(dFirstCellAddress).Resize(, cCount)
.Resize(drCount).Value = dData
.Resize(dws.Rows.Count - .Row - drCount + 1).Offset(drCount).Clear
End With
MsgBox "Rows repeated.", vbInformation
End Sub

VBA code to copy and paste rows three times from one worksheet to another

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

In Excel what is the most efficient way to find and copy/paste noncontiguous data in columns?

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)

Trying to find range of values in another range and have output in another

Thought it would be as simple as, but somewhere i am wrong please help! So I am trying to find the values from rng1 in rng2 and have the output next to rng1
Thanks in advance
Sub FindValuestest()
Dim wb As Workbook, wks1, wks2 As Worksheet, rng1, rng2 As Range
Dim lRow1, lRow2 As Long
Dim v, n, r As Variant
On Error Resume Next
Set wb = ThisWorkbook
Set wks1 = wb.Worksheets("FEPR")
Set wks2 = wb.Worksheets("EQUIP")
lRow1 = wks1.Cells(wks1.Rows.Count, "B").End(xlUp).Row
lRow2 = wks2.Cells(wks2.Rows.Count, "A").End(xlUp).Row
Set rng1 = wks1.Range("B2", Cells(Rows.Count, "B").End(xlUp))
Set rng2 = wks2.Range("A1", Cells(Rows.Count, "A").End(xlUp))
lRow1 = lRow1 - 1
For v = 1 To lRow1
For n = 1 To lRow1
If n = rng2.Find(n, , xlValues, xlWhole, , , False) And rng2.Cells(n, 2) = "Commodity Tracking Bag Scanner" Then
'Debug.Print n
rng1.Cells(n, 2) = rng1.Cells(n) & " Scanner OK"
End If
Next
Next
For v = 1 To lRow1
For n = 1 To lRow1
If n = rng2.Find(n, , xlValues, xlWhole, , , False) And rng2.Cells(, 2) = "Radio" Then
rng1.Cells(n, 3) = rng1.Cells(n) & " Radio OK"
End If
Next
Next
End Sub
Match Values
Option Explicit
Sub FindValuestest()
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets("EQUIP")
Dim sLast As Long: sLast = sws.Cells(sws.Rows.Count, "A").End(xlUp).Row
Dim srg As Range: Set srg = sws.Range("A1:A" & sLast)
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets("FEPR")
Dim dLast As Long: dLast = dws.Cells(dws.Rows.Count, "B").End(xlUp).Row
Dim drg As Range: Set drg = dws.Range("B2:B" & dLast)
' Additional Variables
Dim cIndex As Variant
Dim i As Long
' Write
Application.ScreenUpdating = False
For i = 1 To dLast
cIndex = Application.Match(drg.Cells(i).Value, srg, 0)
If IsNumeric(cIndex) Then
If srg.Cells(cIndex).Offset(, 1) _
= "Commodity Tracking Bag Scanner" Then
drg.Cells(i).Offset(, 1).Value = drg.Cells(i) & " Scanner OK"
ElseIf srg.Cells(cIndex).Offset(, 1) = "Radio" Then
drg.Cells(i).Offset(, 2).Value = drg.Cells(i) & " Radio OK"
End If
End If
Next i
Application.ScreenUpdating = True
End Sub

Resources