Search first sheet coumn name in another sheet coumn and insert that column data - excel

I have 2 workbook i.e workbook A and Workbook B
A workbook having column in order A,B,C,D and B workbook having Column D,C,B,A.
I have to insert A workbook data into B workbook in proper column that is the columns inserted into proper column A in A ,B in B, C in C, D in D
I tried below code
Sub DEMO()
For i = 1 To 4
For j = 2 To 4
For k = 2 To 4
If Sheets(1).Cells(i, j).Value = Sheets(2).Cells(i, j).Value Then
Sheets(2).Cells(k, j).Value = Sheets(1).Cells(j, i).Value
End If
Next k
'MsgBox Sheets(1).Cells(2, 1).Value
'MsgBox Sheets(2).Cells(2, 1).Value
Next j
Next i
End Sub
Please help on this

To match the column names of …
Worksheet A
with the column names in …
Worksheet B
Use a loop and the WorksheetFunction.Match method
Option Explicit
Sub MatchColumns()
Dim wsA As Worksheet 'define worksheet A
Set wsA = ThisWorkbook.Worksheets("A")
Dim ColsRangeA As Range 'get column names in A
Set ColsRangeA = wsA.Range("A1", wsA.Cells(1, wsA.Columns.Count).End(xlToLeft))
Dim wsB As Worksheet 'define worksheet B
Set wsB = ThisWorkbook.Worksheets("B")
Dim ColsRangeB As Range 'get column names in B
Set ColsRangeB = wsB.Range("A1", wsB.Cells(1, wsB.Columns.Count).End(xlToLeft))
Dim MatchedColNo As Long
Dim Col As Range
For Each Col In ColsRangeA 'loop throug column names in A
MatchedColNo = 0 'initialize
On Error Resume Next 'test if column name can be found in worksheet B column names
MatchedColNo = Application.WorksheetFunction.Match(Col.Value, ColsRangeB, False)
On Error GoTo 0
If MatchedColNo <> 0 Then 'if name was found
wsB.Cells(2, MatchedColNo).Value = "Matches wsA col " & Col.Column
Else 'if name didn't match
MsgBox "no maching column found for " & Col.Value
End If
Next Col
End Sub

Copy Below Headers
The Code
'*******************************************************************************
'Purpose: Copies the values below headers from one worksheet
' to another containing the same headers.
'*******************************************************************************
Sub CopyBelowHeaders()
' !!! Header List !!! Change this to any comma separated string containing
' the values of the headers e.g. "ID, Product,Count, Price,Stock ".
Const cHeaders As String = "A,B,C,D"
Const cSource As String = "Sheet1" ' Source Worksheet Name
Const cTarget As String = "Sheet2" ' Target Worksheet Name
Const cFirstR As Long = 2 ' First Row Number
Dim rngS As Range ' Current Source Header Cell Range,
' Current Source Column Last Used Cell Range,
' Current Source Column Range
Dim rngT As Range ' Current Target Header Cell Range,
' Current Target Column Range
Dim vntH As Variant ' Header Array
Dim vntS As Variant ' Source Header Column Array
Dim vntT As Variant ' Target Header Column Array
Dim i As Long ' Header Arrays Element Counter
vntH = Split(cHeaders, ",") ' Write Header List to Header Array.
ReDim vntS(UBound(vntH)) As Long ' Resize Source Header Column Array.
ReDim vntT(UBound(vntH)) As Long ' Resize Target Header Column Array.
' Column Numbers to Column Arrays
' In Source Worksheet
With ThisWorkbook.Worksheets(cSource)
' Loop through elements of Header Array.
For i = 0 To UBound(vntH)
' In Source Row Range (Header Row, 1st Row)
With .Rows(1)
' Find current element (string) of Header Array
' in Source Row Range.
Set rngS = .Find(Trim(vntH(i)), .Cells(.Cells.Count), _
xlValues, xlWhole, xlByRows, xlNext)
' When current element was found, write column number to
' Source Header Columns Array.
If Not rngS Is Nothing Then vntS(i) = rngS.Column
End With
Next
End With
' In Target Worksheet
With ThisWorkbook.Worksheets(cTarget)
' Loop through elements of Header Array.
For i = 0 To UBound(vntH)
' In Target Row Range (Header Row, 1st Row)
With .Rows(1)
' Find current element (string) of Header Array
' in Target Row Range.
Set rngT = .Find(Trim(vntH(i)), .Cells(.Cells.Count), _
xlValues, xlWhole, xlByRows, xlNext)
' When current element was found, write column number to
' Source Header Columns Array.
If Not rngS Is Nothing Then vntT(i) = rngT.Column
End With
Next
End With
' Source Worksheet to Target Worksheet
' In Source Worksheet
With ThisWorkbook.Worksheets(cSource)
' Loop through elements of Source Array.
For i = 0 To UBound(vntS)
' When current element of Source Header Column Array and current
' element of Target Header Column Array are different than "".
If vntS(i) > 0 And vntT(i) > 0 Then
' Find Last Used Cell Range in current Source Column Range.
Set rngS = .Columns(vntS(i)).Find("*", , xlFormulas, _
xlWhole, xlByColumns, xlPrevious)
' When current Source Column is not empty.
If Not rngS Is Nothing Then
' When current Source Column contains data in at least
' one more row than the Source Header row.
If rngS.Row > 1 Then
' Calculate Source Column Range.
Set rngS = .Range(.Cells(cFirstR, vntS(i)), rngS)
' In First Cell of Target Column Range
With ThisWorkbook.Worksheets(cTarget) _
.Cells(cFirstR, vntT(i))
' Clear contents in Target Column Range from
' First Cell to bottom cell.
.Resize(Rows.Count - cFirstR + 1).ClearContents
' Resize Current Target Column Range to the size
' of Current Source Column Range.
Set rngT = .Resize(rngS.Rows.Count)
End With
' Copy values from Current Source Column Range to
' Current Target Column Range.
rngT = rngS.Value
End If
End If
End If
Next
End With
End Sub

Related

Match data in row and copy

I am stuck. I have corresponding data on two sheets. I want to go down the rows in sheet1, use the value in column M, find the matching value in sheet3 column M, then copy the data into sheet1. Sheet1 is 4000 lines. My copy logic is working, unfortunately, my loop does not end and it copies row1 until excel freezes. Any assistance is greatly appreciated - obviously I am still a VBA novice.
Dim searchTerm As String
Dim r As Long
For i = 1 To 4000
searchTerm = Worksheets("Sheet1").Range("M" & i).Text
If Worksheets("Sheet1").Range("M" & i).Value = searchTerm Then
'Select row in Sheet1 to copy
Worksheets("Sheet3").Select
Range("A" & i & startcolumn & ":AU" & i & lastcolumn).Select
Selection.Copy
'Paste row into Sheet2 in next row
Sheets("Sheet1").Select
Columns("AX").Select
ActiveSheet.Paste
'Move counter to next row
'Go back to Sheet1 to continue searching
Sheets("Sheet1").Select
End If
Next i
A VBA Lookup
The following will loop through each cell in range "M1:M4000" of worksheet "Sheet1" and try to find each cell's value in column "M" of "Sheet3". If found, the values from columns "A" to column "AU" in the found row of worksheet "Sheet3" will be copied to worksheet "Sheet1", to the same sized row range starting with column "AX".
The Code
Option Explicit
Sub SimpleLookup()
' Define workbook.
Dim wb As Workbook
Set wb = ThisWorkbook ' The workbook containing this code.
' Destination
' Define Destination Worksheet.
Dim dst As Worksheet
Set dst = wb.Worksheets("Sheet1")
Dim lValue As Variant ' Lookup Value
Dim i As Long ' Destination Rows Counter
' Source
' Define Source Worksheet.
Dim src As Worksheet
Set src = wb.Worksheets("Sheet3")
' Define Copy Range.
Dim cRng As Range
Set cRng = src.Range("A1:AU4000")
' Define Lookup Column Range.
Dim lRng As Range
Set lRng = cRng.Columns(13)
Dim rRng As Range ' Current Copy Row Range
Dim lIndex As Variant ' Lookup Index
' Loop
' Loop through rows (cells) of Criteria Column Range.
For i = 1 To 4000
' Write the value of the current cell to a variable, Lookup Value.
lValue = dst.Cells(i, "M").Value
' Define Lookup Index, the index (row) where the Lookup value
' was found in Lookup Column Range.
lIndex = Application.Match(lValue, lRng, 0)
' Evaluate Lookup Index: it will be an error value if not found.
If Not IsError(lIndex) Then
' Define Current Copy Row Range.
Set rRng = cRng.Rows(lIndex)
' Either...:
' Values only.
' Copy Current Copy Row Range to Destination Worksheet.
dst.Cells(i, "AX").Resize(, rRng.Columns.Count).Value = rRng.Value
' ...Or:
' Values, formulas, formats.
'rRng.Copy Destionation:=dst.Cells(i, "AX")
End If
Next i
End Sub

Excel VBA search id and import data from other sheet

I'm working on a project with lots of data in two different sheets which is want to combine.
For example:
My Sheet1 should contain 4 columns. Columns 1 and 2 are already filled with ID's and a status.
In Sheet2 I have 3 columns. The first contains the ID's again, the second a serial-number and the third a Yes/No.
The two sheets have around 5500 rows in it. The first a little more then the second.
I would like to run a loop which picks the first ID in Sheet1, checks if it exists in Sheet2, and if it does, it should copy the two missing columns (serial-number and Yes/No) into into Sheet1.
Then the to the next Id in Sheet1 and do the same again.
I tried it with the code below, but I'm not getting it to work.
Hope you can help me out!
Dim i As Long
Dim Found As Range
For i = 1 To Rows.Count
Worksheets("Sheet1").Activate
If Cells(i, 1).Value <> "" Then
Set Found = Worksheets("Sheet2").Range("A2", Range("A")).Find(i, 1)
If Not Found Is Nothing Then
Worksheets("Sheet1").Range(i, 3).Value = Cells(Found.Row, 2).Value
Worksheets("Sheet1").Range(i, 4).Value = Cells(Found.Row, 3).Value
End If
End If
Next i
You could try with two nested for each loops.
Sub copySerial()
Dim range1 As Range, range2 As Range
Set range1 = Worksheets("Sheet1").Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row)
Set range2 = Worksheets("Sheet2").Range("A2:A" & Cells(Rows.Count, 1).End(xlUp).Row)
For Each c1 In range1
For Each c2 In range2
If c1.Value = c2.Value Then
c1.Offset(0, 2).Value = c2.Offset(0, 1).Value
c1.Offset(0, 3).Value = c2.Offset(0, 2).Value
End If
Next c2
Next c1
End Sub
Arrays Before Ranges
Adjust the values in the constants section to fit your needs. Do it
carefully (slowly) because there are many.
First I created the second code which appeared to be super slow.
After implementing arrays, it got 30 times faster at 5000 records. I guess the extra work pays off.
Option Explicit
Sub UpdateSheetArray() ' Calculates for about 3s at 5000 records - Acceptable!
Const strSrc As String = "Sheet2" ' Source Worksheet Name
Const frSrc As Long = 2 ' Source First Row Number
Const colSrc As Long = 1 ' Source Compare Column Number
Const colSrc1 As Long = 2 ' Source Data Column 1
Const colSrc2 As Long = 3 ' Source Data Column 2
Const strTgt As String = "Sheet1" ' Target Worksheet Name
Const frTgt As Long = 1 ' Target First Row Number
Const colTgt As Long = 1 ' Target Compare Column Number
Const colTgt1 As Long = 3 ' Target Data Column 1
Const colTgt2 As Long = 4 ' Target Data Column 2
Dim wsSrc As Worksheet ' Source Worksheet
Dim wsTgt As Worksheet ' Target Worksheet
Dim vntSrc As Variant ' Source Compare Array
Dim vntSrc1 As Variant ' Source Data Array 1
Dim vntSrc2 As Variant ' Source Data Array 2
Dim vntTgt As Variant ' Target Compare Array
Dim vntTgt1 As Variant ' Target Data Array 1
Dim vntTgt2 As Variant ' Target Data Array 2
Dim rngSrc As Range ' Source Compare Range,
' Source Data Range 1,
' Source Data Range 2
Dim rngTgt As Range ' Target Compare Range,
' Target Data Range 1,
' Target Data Range 2
Dim lrSrc As Long ' Source Last Non-Empty Row Number
Dim lrTgt As Long ' Target Last Non-Empty Row Number
Dim varCur As Variant ' Current Target Cell Value
Dim i As Long ' Source Row Counter
Dim j As Long ' Target Row Counter
' Define Source and Target Worksheets.
Set wsSrc = Worksheets(strSrc)
Set wsTgt = Worksheets(strTgt)
' Calculate Last Non-Empty Row in Source Worksheet.
lrSrc = wsSrc.Columns(colSrc).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious).Row
' Calculate Last Non-Empty Row in Target Worksheet.
lrTgt = wsTgt.Columns(colTgt).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious).Row
' Define Source Compare Range and write its values to Source Compare Array.
Set rngSrc = wsSrc.Cells(frSrc, colSrc).Resize(lrSrc - frSrc + 1)
vntSrc = rngSrc
' Define Source Data Range 1 and write its values to Source Data Array 1.
Set rngSrc = rngSrc.Offset(, colSrc1 - colSrc): vntSrc1 = rngSrc
' Define Source Data Range 2 and write its values to Source Data Array 2.
Set rngSrc = rngSrc.Offset(, colSrc2 - colSrc1): vntSrc2 = rngSrc
' Define Target Compare Range and write its values to Target Compare Array.
Set rngTgt = wsTgt.Cells(frTgt, colTgt).Resize(lrTgt - frTgt + 1)
vntTgt = rngTgt
' Define Target Data Arrays (same size as Target Compare Array).
ReDim vntTgt1(1 To UBound(vntTgt), 1 To 1)
ReDim vntTgt2(1 To UBound(vntTgt), 1 To 1)
' Note: These last two arrays are going to be written to,
' while the previous four are going to be read from.
' All arrays are 2-dimensional 1-based 1-column arrays.
' Loop through elements of Target Compare Array.
For i = 1 To UBound(vntTgt)
' Write value of current element in Target Array
' to Current Target Cell Value.
varCur = vntTgt(i, 1)
' Check if Current Target Cell Value is not "".
If varCur <> "" Then
' Loop through elements of Source Compare Array.
For j = 1 To UBound(vntSrc)
' Check if value of current element in Source Array is equal
' to Current Target Cell Value.
If vntSrc(j, 1) = varCur Then
' Write current elements in Source Data Arrays
' to Target Data Arrays.
vntTgt1(i, 1) = vntSrc1(j, 1): vntTgt2(i, 1) = vntSrc2(j, 1)
' No need to loop anymore after found.
Exit For
End If
Next
End If
Next
' Define Target Data Range 1.
Set rngTgt = rngTgt.Offset(, colTgt1 - colTgt)
' Write values of Target Data Array 1 to Target Data Range 1.
rngTgt = vntTgt1
' Define Target Data Range 2.
Set rngTgt = rngTgt.Offset(, colTgt2 - colTgt1)
' Write values of Target Data Array 2 to Target Data Range 2.
rngTgt = vntTgt2
End Sub
Sub UpdateSheetRange() ' Calculates for about 90s at 5000 records - too slow!
Const strSrc As String = "Sheet2" ' Source Worksheet Name
Const frSrc As Long = 2 ' Source First Row Number
Const colSrc As Long = 1 ' Source Compare Column Number
Const colSrc1 As Long = 2 ' Source Data Column 1
Const colSrc2 As Long = 3 ' Source Data Column 2
Const strTgt As String = "Sheet1" ' Target Worksheet Name
Const frTgt As Long = 1 ' Target First Row Number
Const colTgt As Long = 1 ' Target Compare Column Number
Const colTgt1 As Long = 3 ' Target Data Column 1
Const colTgt2 As Long = 4 ' Target Data Column 2
Dim wsSrc As Worksheet ' Source Worksheet
Dim wsTgt As Worksheet ' Target Worksheet
Dim lrSrc As Long ' Source Last Non-Empty Row Number
Dim lrTgt As Long ' Target Last Non-Empty Row Number
Dim varCur As Variant ' Current Target Cell Value
Dim i As Long ' Source Row Counter
Dim j As Long ' Target Row Counter
' Define Worksheet.
Set wsSrc = Worksheets(strSrc)
Set wsTgt = Worksheets(strTgt)
' Calculate Last Non-Empty Row in Source Worksheet.
lrSrc = wsSrc.Columns(colSrc).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious).Row
' Calculate Last Non-Empty Row in Target Worksheet.
lrTgt = wsTgt.Columns(colTgt).Find(What:="*", LookIn:=xlFormulas, _
SearchDirection:=xlPrevious).Row
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
On Error GoTo ProgramError
For i = frTgt To lrTgt
varCur = wsTgt.Cells(i, colTgt).Value
If varCur <> "" Then
For j = frSrc To lrSrc
If wsSrc.Cells(j, colSrc).Value = varCur Then
wsTgt.Cells(i, colTgt1) = wsSrc.Cells(j, colSrc1).Value
wsTgt.Cells(i, colTgt2) = wsSrc.Cells(j, colSrc2).Value
Exit For
End If
Next
End If
Next
SafeExit:
With Application
.EnableEvents = True
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
Exit Sub
ProgramError:
MsgBox "An unexpected error occurred."
On Error GoTo 0
GoTo SafeExit
End Sub

Fuction has an array inside, gives back error 1004

I have a formula that works fine when hardcoded but gives me error 1004 when I put it in code. I think it's because I am using an array inside the formula. I tried .FormulaArray but it still returns an error.
ws_a.Range("D2:D" & LastRowCriar).Formula = "=IFERROR(IFERROR(IFERROR(INDEX(IBAN!D:D,MATCH(B2&I2,IBAN!F:F&IBAN!E:E,0)),INDEX(IBAN!D:D,MATCH(B2&I2-1,IBAN!F:F&IBAN!E:E,0))),INDEX(IBAN!D:D,MATCH(B2&I2-2,IBAN!F:F&IBAN!E:E,0))),INDEX(IBAN!D:D,MATCH(B2&I2-3,IBAN!F:F&IBAN!E:E,0)))"
Once again, the formula works when hardcoded, I just need some help on how to use it in VBA. Probably, I have to declare those arrays but I am not sure (if I have to or how to do it).
Hardcoded:
=IFERROR(IFERROR(IFERROR(INDEX(IBAN!D:D;MATCH(B2&I2;IBAN!F:F&IBAN!E:E;0));INDEX(IBAN!D:D;MATCH(B2&I2-1;IBAN!F:F&IBAN!E:E;0)));INDEX(IBAN!D:D;MATCH(B2&I2-2;IBAN!F:F&IBAN!E:E;0)));INDEX(IBAN!D:D;MATCH(B2&I2-3;IBAN!F:F&IBAN!E:E;0)))
Thank you!
Replace Slow Formula With VBA
With this setup, the code will write the resulting values to the 4th ("D") column (cSh1C3) in Sheet1 named "Sheet1". The sheet name wasn't mentioned, so change it appropriately, Also change the other constants to fit your needs. Maybe change cSh1C3 to an empty column first, to see if the code does the expected. There will be no formulas just the values since your formula is slowing down the worksheet considerably. If this code is doing the expected, then the formula isn't. In some cases the results differ, but I think the code is correct. When this happens, check the accuracy manually.
Option Explicit
Sub ReplaceSlowFormulaWithVBA()
' Sheet1
Const cSh1 As String = "Sheet1" ' Sheet1 Name
Const cSh1FR As Long = 2 ' Sheet1 First Row Number
Const cSh1C1 As Variant = 2 ' "B" ' Sheet1 First Column Number/Letter
Const cSh1C2 As Variant = 9 ' "I" ' Sheet1 Second Column Number/Letter
Const cSh1C3 As Variant = 4 ' "D" ' Target Column Number/Letter
' (Sheet1 Third Column Number/Letter)
Const cReduce As Long = 3 ' Reduce Number
' Sheet2
Const cSh2 As String = "IBAN" ' Sheet2 Name
Const cSh2FR As Long = 2 ' Sheet2 First Row Number
Const cSh2C1 As Variant = 6 ' "F" ' Sheet2 First Column Number/Letter
Const cSh2C2 As Variant = 5 ' "E" ' Sheet2 Second Column Number/Letter
Const cSh2C3 As Variant = 4 ' "D" ' Source Column Number/Letter
' Sheet2 Third Column Number/Letter
Dim ws1 As Worksheet ' First Worksheet
Dim ws2 As Worksheet ' Second Worksheet
Dim rng As Range ' Various Ranges
Dim vnt1 As Variant ' Sheet1 Array
Dim vnt1C1 As Variant ' Sheet1 First Column Array
Dim vnt1C2 As Variant ' Sheet1 Second Column Array
Dim vntT As Variant ' Target Array (Sheet1 Third Column Array)
Dim vnt2 As Variant ' Sheet2 Array
Dim vnt2C1 As Variant ' Sheet2 First Column Array
Dim vnt2C2 As Variant ' Sheet2 Second Column Array
Dim vntS As Variant ' Source Array (Sheet2 Third Column Array)
Dim LR As Long ' Last Row Compare Number
Dim sh1LR As Long ' Sheet1 (Current) Last Row Number
Dim sh2LR As Long ' Sheet2 (Current) Last Row Number
Dim UB1 As Long ' Sheet1 Arrays Upper Bound
Dim UB2 As Long ' Sheet2 Arrays Upper Bound
Dim i As Long ' Various Counters
Dim j As Long ' Second Array Elements Counter
Dim k As Long ' Reduce Counter
Dim lng1 As Long ' Current Sheet1 Array Value
Dim lng2 As Long ' Current Sheet2 Array Value
' IN RANGES
' Define Worksheets.
Set ws1 = ThisWorkbook.Worksheets(cSh1)
Set ws2 = ThisWorkbook.Worksheets(cSh2)
' Calculate Sheet1 Last Row Number.
Set rng = ws1.Columns(cSh1C1): GoSub LastRow: sh1LR = LR
Set rng = ws1.Columns(cSh1C2): GoSub LastRow
If LR > sh1LR Then sh1LR = LR
' Calculate Sheet2 Last Row Number.
Set rng = ws2.Columns(cSh2C1): GoSub LastRow: sh2LR = LR
Set rng = ws2.Columns(cSh2C2): GoSub LastRow
If LR > sh2LR Then sh2LR = LR
Set rng = ws2.Columns(cSh2C3): GoSub LastRow
If LR > sh2LR Then sh2LR = LR
' Write Column Ranges to Arrays.
vnt1C1 = ws1.Cells(cSh1FR, cSh1C1).Resize(sh1LR - cSh1FR + 1)
vnt1C2 = ws1.Cells(cSh1FR, cSh1C2).Resize(sh1LR - cSh1FR + 1)
vnt2C1 = ws2.Cells(cSh2FR, cSh2C1).Resize(sh2LR - cSh2FR + 1)
vnt2C2 = ws2.Cells(cSh2FR, cSh2C2).Resize(sh2LR - cSh2FR + 1)
vntS = ws2.Cells(cSh2FR, cSh2C3).Resize(sh2LR - cSh2FR + 1)
' Define Target Range.
Set rng = ws1.Cells(cSh1FR, cSh1C3).Resize(sh1LR - cSh1FR + 1)
' Release worksheet object variables.
Set ws2 = Nothing
Set ws1 = Nothing
' IN ARRAYS
' Define and populate Sheet1 Array from the two Sheet1 Column Arrays.
UB1 = UBound(vnt1C1)
ReDim vnt1(1 To UB1) ' 1D 1-based (1-row)
For i = 1 To UB1: vnt1(i) = vnt1C1(i, 1) & vnt1C2(i, 1): Debug.Print vnt1(i): Next i
' Erase the two Sheet1 Column Arrays.
Erase vnt1C1: Erase vnt1C2
' Define and populate Sheet2 Array from the two Sheet2 Column Arrays.
UB2 = UBound(vnt2C1)
ReDim vnt2(1 To UB2) ' 1D 1-based (1-row)
For i = 1 To UB2: vnt2(i) = vnt2C1(i, 1) & vnt2C2(i, 1): Next i
' Erase the two Sheet2 Column Arrays.
Erase vnt2C1: Erase vnt2C2
' Resize Target Array to rows defined by the number of elements
' in Sheet1 Array.
ReDim vntT(1 To UB1, 1 To 1) ' 2D 1-based 1-column
' Loop through elements of Sheet1 Array.
For i = 1 To UB1
If IsNumeric(vnt1(i)) Then
' Loop through Reduce Values.
For k = 0 To cReduce
' Calculate Current Sheet1 Array Value.
lng1 = vnt1(i) - k
' Loop through elements of Sheet2 Array.
For j = 1 To UB2
If IsNumeric(vnt2(j)) Then
' Calculate Current Sheet2 Array Value.
lng2 = vnt2(j)
' Compare current Sheet1 and Sheet2 Array Values.
If lng1 = lng2 Then
' Write value of current element (row) in Source
' Array to current element (row) in Target Array.
vntT(i, 1) = vntS(j, 1)
' Ensure exiting "For k"-loop immediately after
' exiting "For j"-loop.
k = cReduce
' Exit "For j"-loop.
Exit For
End If
End If
Next j
Next k
End If
Next i
' IN RANGES
' Write Target Array to Target Range.
rng = vntT
Exit Sub
LastRow:
LR = 0
Set rng = rng.Find("*", , xlFormulas, , , xlPrevious)
If Not rng Is Nothing Then LR = rng.Row
Return
End Sub

Once an active cell value is found, how to select 5 rows above and 20 rows below

I have been helped with other problems, but this is a new one, when a cell has the data value 4, I need to select 5 rows above that, and 20 rows below that and cut / copy that data to another sheet. I have everything else sorted, just this cut above and below the data point.
Copy Rows
Sub RowsCopy()
Const cSource As Variant = "Sheet1" ' Source Worksheet Name/Index
Const cTarget As Variant = "Sheet2" ' Target Worksheet Name/Index
Const cRange As String = "A7" ' Source Cell Range Address
Const cCrit As Long = 4 ' Criteria
Const cRowsA As Long = 5 ' Source Rows Above
Const cRowsB As Long = 20 ' Source Rows Below
Dim ws As Worksheet ' Target Worksheet
Dim FER As Long ' Target First Empty Row
' In Source Cell Range
With ThisWorkbook.Worksheets(cSource).Range(cRange)
' Create a reference to Target Worksheet.
Set ws = .Parent.Parent.Worksheets(cTarget)
' Calculate Target First Empty Row using column 1 (A).
FER = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' Check if value in Source Cell Range meets (is equal to) Criteria.
If .Value = cCrit Then
' Calculate Target Range Above.
' Calculate Source Range Above.
' Copy values of Source Range Above to Target Range Above.
ws.Rows(FER).Resize(cRowsA).Value _
= .Worksheet.Rows(.Row - cRowsA).Resize(cRowsA).Value
' Calculate new Target First Empty Row by adding Source Rows Above.
FER = FER + cRowsA
' Calculate Target Range Below.
' Calculate Source Range Below.
' Copy values of Source Range Below to Target Range Below.
ws.Rows(FER).Resize(cRowsB).Value _
= .Worksheet.Rows(.Row + 1).Resize(cRowsB).Value
End If
End With
End Sub
Sheet1
Sheet2
Copy and Delete Rows
Sub RowsCopyDelete()
Const cSource As Variant = "Sheet1" ' Source Worksheet Name/Index
Const cTarget As Variant = "Sheet2" ' Target Worksheet Name/Index
Const cRange As String = "A7" ' Source Cell Range Address
Const cCrit As Long = 4 ' Criteria
Const cRowsA As Long = 5 ' Source Rows Above
Const cRowsB As Long = 20 ' Source Rows Below
Dim ws As Worksheet ' Target Worksheet
Dim rng As Range ' Delete Range
Dim FER As Long ' Target First Empty Row
' In Source Cell Range
With ThisWorkbook.Worksheets(cSource).Range(cRange)
' Create a reference to Target Worksheet.
Set ws = .Parent.Parent.Worksheets(cTarget)
' Calculate Target First Empty Row using column 1 (A).
FER = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
' Check if value in Source Cell Range meets (is equal to) Criteria.
If .Value = cCrit Then
' Calculate Target Range Above.
' Calculate Source Range Above.
' Create a reference to Target Range Above (Delete Range).
Set rng = .Worksheet.Rows(.Row - cRowsA).Resize(cRowsA)
' Copy values of Source Range Above to Target Range.
ws.Rows(FER).Resize(cRowsA).Value = rng.Value
' Calculate new Target First Empty Row by adding Source Rows Above.
FER = FER + cRowsA
' Calculate Target Range Below.
' Calculate Source Range Below.
' Add Target Range Below to Delete Range.
Set rng = Union(rng, .Worksheet.Rows(.Row + 1).Resize(cRowsB))
' Copy values of Source Range Below to Target Range Below.
ws.Rows(FER).Resize(cRowsB).Value _
= .Worksheet.Rows(.Row + 1).Resize(cRowsB).Value
' Delete Source Rows
rng.Rows.Delete ' .Hidden = True, .ClearContents, .Clear
End If
End With
End Sub
Small demo:
Option Explicit
Const NEGOFFSET = 5
Const POSOFFSET = 20
Sub test()
Dim r As Range
Set r = Range("a6") 'Assuming A6 is the target cell
r.Select 'Just to show the selected range this far
Set r = r.Offset(-NEGOFFSET, 0).Resize(NEGOFFSET + 1, 1)
r.Select 'Just to show the selected range this far
Set r = r.Resize(POSOFFSET + NEGOFFSET + r.Row, 1)
r.Select 'Just to show the selected range
'*
'* Here r holds the wanted range. Handle it
'*
End Sub

Looping a single column to find a match in another worksheet

I have two worksheets (Master & Sample).
I want to update the data in Master sheet if I have a value match, unique value in column A of Master sheet with a value in column A in Sample sheet else insert a new row at the end in Master sheet.
What is the logic for this?
I have added sample data for my master and sample in the images.
Example data for Master sheet:
Example data for Sample sheet and comments:
Update Master Worksheet
Adjust the five constants (Const) to fit your needs.
The Code
Sub UpdateMaster()
Const cMaster As String = "Master" ' Master Worksheet Name
Const cSample As String = "Sample" ' Sample Worksheet Name
Const cCols As String = "A:D" ' Data Columns Range Address (or "1:4")
Const cLRC As Variant = "A" ' Last-Row Column Letter/Number (or 1)
Const cFR As Long = 2 ' First Row Number
Dim rng As Range ' Last Used Cell in Last-Row Column of both
' Worksheets, Sample/Master/Unique Range
Dim vntM As Variant ' Master Array
Dim vntS As Variant ' Sample Array
Dim vntR As Variant ' Row Array
Dim vntU As Variant ' Unique Array
Dim MNoR As Long ' Master Number of Rows
Dim SNoR As Long ' Sample Number of Rows
Dim Cols As Long ' Number of Columns in Data Columns Range
Dim i As Long ' Sample/Unique Array Row Counter
Dim j As Long ' Sample/Master/Unique Array Column Counter
Dim k As Long ' Master Array Row Counter
Dim m As Long ' Row Array Row Count(er)
' Speed up.
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
' Handle errors.
On Error GoTo ErrorHandler
' In (Last-Row Column of) Sample Worksheet
With ThisWorkbook.Worksheets(cSample).Columns(cLRC)
' Create a reference to Last Used Cell.
Set rng = .Find("*", , xlFormulas, , xlByColumns, xlPrevious)
' Check if no data in column.
If rng Is Nothing Then
MsgBox "No data in column '" & Split(.Cells(1).Address, "$")(1) _
& "'.", vbCritical, "Column Empty"
GoTo ProcedureExit
End If
' Calculate Sample Number of Rows.
SNoR = rng.Row - cFR + 1
' Create a reference to Sample Range.
Set rng = .Parent.Columns(cCols).Rows(cFR).Resize(SNoR)
' Copy Sample Range to Sample Array.
vntS = rng
End With
' In (Last-Row Column of) Master Worksheet
With ThisWorkbook.Worksheets(cMaster).Columns(cLRC)
' Create a reference to Last Used Cell.
Set rng = .Find("*", , xlFormulas, , xlByColumns, xlPrevious)
' Check if no data in column.
If rng Is Nothing Then
MsgBox "No data in column '" & Split(.Cells(1).Address, "$")(1) _
& "'.", vbCritical, "Column Empty"
GoTo ProcedureExit
End If
' Calculate Master Number of Rows.
MNoR = rng.Row - cFR + 1
' In Data Columns Range
With .Parent.Columns(cCols)
' Calculate Number of Columns in Data Columns Range.
Cols = .Columns.Count
' Create a reference to Master Range.
Set rng = .Rows(cFR).Resize(MNoR)
' Copy Master Range to Master Array.
vntM = rng
End With
End With
' Resize Row Array to Sample Number of Rows (as big as it could get).
ReDim vntR(1 To SNoR)
' Loop through rows of Sample Array.
For i = 1 To SNoR
' Loop through rows of Master Array.
For k = 1 To MNoR
' Check if value of element at current row in 1st column of Source
' Array is equal to the value of element at current row in 1st
' column of Master Array.
If vntS(i, 1) = vntM(k, 1) Then ' Match FOUND.
' Loop through the rest of the columns (to update the values).
For j = 2 To Cols
' Write value of element at current row in current column
' of Source Array to element at current row in current
' column of Master Array.
vntM(k, j) = vntS(i, j)
Next
' Stop looping through rows of Master Array (unique values).
Exit For
End If
Next
' Check if no match was found using the 'For Next Trick' i.e. when the
' for next loop finishes uninterupted, the value of the 'counter' is
' by 1 greater than the 'end' (VBA Help: "For counter = start To end").
If k = MNoR + 1 Then
' Count the number of rows in Row Array.
m = m + 1
' Write the current row number of Sample Array to Row Array.
vntR(m) = i
End If
Next
' Check if new values found.
If m > 0 Then
' Resize Row Array to number of new values found.
ReDim Preserve vntR(1 To m)
' Resize Unique Array to number of rows of Row Array and to Cols
' number of columns.
ReDim vntU(1 To m, 1 To Cols)
' Loop through rows of Row/Unique Array
For i = 1 To m
' Loop through columns of Sample/Unique Array.
For j = 1 To Cols
' Write the rows (containded in Row Array) of Sample Array to
' Unique Array.
vntU(i, j) = vntS(vntR(i), j)
Next
Next
End If
' Erase Row & Sample Arrays. All needed data is in Master & Unique Arrays.
Erase vntR
Erase vntS
' Copy Master Array to Master Range.
rng = vntM
' Erase Master Array.
Erase vntM
' Check if new values found.
If m > 0 Then
' Create a reference to Unique Range.
Set rng = rng.Cells(rng.Rows.Count, 1).Offset(1).Resize(m, Cols)
' Copy Unique Array to Unique Range.
rng = vntU
End If
MsgBox "The operation finished successfully.", vbInformation, "Success"
ProcedureExit:
' Speed down.
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
Exit Sub
ErrorHandler:
MsgBox "An unexpected error occurred. Error '" & Err.Number & "': " _
& Err.Description, vbCritical, "Error"
GoTo ProcedureExit
End Sub

Resources