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

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

Related

How to bypass code if criteria don't match?

The code works when the criteria exists. I get an error when the criteria doesn't exist.
' Define constants.
Const srcName As String = "wfm_rawdata"
Const srcFirst As String = "D2" ' Location for Group
Const dstName As String = "bond_insurance"
Const dstFirst As String = "A2" ' do not change the 'A' (entire row).
'This function will transfer rows from one worksheet to another worksheet
' if the value = specified critiera
' Define workbook.
Dim wb As Workbook: Set wb = ActiveWorkbook ' Workbook containing this code.
' Define Source Range
Dim LastRow As Long
Dim srg As Range
' Define worksheet and column am working on and
' getting the range of last used cell using(LastRow)
With wb.Worksheets(srcName).Range(srcFirst)
LastRow = .Offset(.Worksheet.Rows.Count - .Row).End(xlUp).Row
Set srg = .Resize(LastRow - .Row + 1, 10)
End With
'Combine' critical cells into a range.
Dim brg As Range ' Built Range --> Range in the new sheet
Dim cel As Range ' Current Cell Range --> Range in the current sheet(rawdata)
'for every cell in group within wfm_rawdata sheet if the value = GO
For Each cel In srg.Cells
If cel.Value = "BOND INSURANCE" Then
' If the range in the new sheet have nothing then
' add specific criteria from the group in wfm_rawdata
If brg Is Nothing Then
Set brg = cel
' if there is range in there combine the new and
' old range together using -> Union function
Else
Set brg = Union(brg, cel)
End If
End If
Next cel
Application.ScreenUpdating = False
' Copy and delete critical rows of Source Range.
With wb.Worksheets(dstName).Range(dstFirst)
.Resize(.Worksheet.Rows.Count - .Row + 1, _
.Worksheet.Columns.Count).clear
Set brg = brg.EntireRow ' 'Convert' cells into rows.
brg.Copy .Offset ' Copy. 'Offset' because range is in 'With'.
brg.Delete ' Delete.
End With
How can I use a Boolean or other function to bypass the above code if the criteria doesn't exist?
For example if criteria "dog" exists then run the code and if it doesn't exist bypass the code.
I use this code to run three modules with code similar to the top code.
Sub master()
Call report1
Call report2
Call report3
End Sub
One you've assigned srg you can use Match() to check whether it contains any instances of the term you're interested in:
'...
'...
' Define worksheet and column am working on and getting the range of last used cell using(LastRow)
With wb.Worksheets(srcName).Range(srcFirst)
LastRow = .Offset(.Worksheet.Rows.Count - .Row).End(xlUp).Row
Set srg = .Resize(LastRow - .Row + 1, 10)
End With
'Exit if "BOND INSURANCE" is not found in `srg`
If IsError(Application.Match("BOND INSURANCE", srg, 0)) Then Exit 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

How to paste data into next empty cell to the right?

I want to copy data from sheet1 to sheet2, row number 9 with one condition. The data should be inserted to the next empty cell to the right.
I wrote a procedure that is a bit more general than #FahmiYogyas question.
Assume the source range is a named range of one or more cells (here NamedRange1) and the top left cell of the destination is a second named range (here NamedRange2).
Option Explicit
'
' start this as example
'
Sub test1()
copyData Range("NamedRange1"), Range("NamedRange2")
End Sub
'
'
'
Sub copyData(sourceRange As Range, destinationRange As Range)
Dim myCell As Range
Dim columnOffset As Long
Dim firstCell As Range
Dim isFirst As Boolean
'
' increase the column offset until the first destination cell is empty
'
Do While Not IsEmpty(destinationRange.Offset(0, columnOffset))
columnOffset = columnOffset + 1
Loop
isFirst = True
'
' now get the value of the source cells
' and insert it at the destination position
' offset is used to allow for arbitrary source ranges
For Each myCell In sourceRange
If isFirst Then
Set firstCell = myCell
isFirst = False
End If
destinationRange.Offset(myCell.Row - firstCell.Row, myCell.Column - firstCell.Column + columnOffset).Value = myCell.Value
Next
End Sub

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

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

Resources