Excel VBA Match Columns while Pasting - excel

I have small set of data in excel with 4 columns
File A:
SNO TYPE CountryA CountryB CountryD
1 T1 A1 B2 D1
2 T2 A2 B2 D2
and i have this data in another excel file
File B:
SNO TYPE CountryB CountryA CountryC
11 T10 B10 A10 C10
22 T20 B20 A20 C20
33 T30 B30 A30 C30
Now if i want to paste the data in file B over the data in file A, i want the column names to align automatically using some vba code.
So the End result should look like,
SNO TYPE CountryA CountryB CountryC CountryD
1 T1 A1 B1 -- D1
2 T2 A2 B2 -- D2
11 T10 A10 B10 C10 --
22 T20 A20 B20 C20 --
33 T30 A30 B30 C30 --

This should work for you:
Sub MatchUpColumnDataBasedOnHeaders()
Dim wbk As Workbook
Set wbk = ThisWorkbook
Set ws = wbk.Sheets(1)
Set ws2 = wbk.Sheets(2)
Dim cell As Range
Dim refcell As Range
Application.ScreenUpdating = False
ws.Select
For Each cell In ws.Range("A1:Z1")
cell.Activate
ActiveCell.EntireColumn.Copy
For Each refcell In ws2.Range("A1:Z1")
If refcell.Value = cell.Value Then refcell.PasteSpecial (xlPasteValues)
Next refcell
Next cell
Application.ScreenUpdating = True
End Sub
It's funny, I have this feeling there is a really easy non-VBA way to do this - but I couldn't find the button for it on google. This will work for columns A to Z on sheets 1 and 2. This assumes your headers are in row 1.
EDIT - IN ADDITION:
I noticed that you wanted to do this with files and you didn't say anything about sheets. This is how you would do it with different workbooks:
Sub MatchUpColumnDataBasedOnHeadersInFiles()
Dim wbk As Workbook
Set wbk = ThisWorkbook
Workbooks.Open Filename:="C:\PasteIntoWorkbook.xlsx"
Set wbk2 = Workbooks("PasteIntoWorkbook.xlsx")
Set ws = wbk.Sheets(1)
Set ws2 = wbk2.Sheets(1)
Dim cell As Range
Dim refcell As Range
wbk.Activate
Application.ScreenUpdating = False
ws.Select
For Each cell In ws.Range("A1:N1")
wbk.Activate
ws.Select
cell.Activate
ActiveCell.EntireColumn.Copy
wbk2.Activate
ws2.Select
For Each refcell In ws2.Range("A1:N1")
If refcell.Value = cell.Value Then refcell.PasteSpecial (xlPasteValues)
Next refcell
Next cell
ws2.Select
Range("A1").Select
wbk.Activate
ws.Select
Range("A1").Select
Application.ScreenUpdating = True
End Sub
So if were heart-set on working with different .xls files, then that is how yo would do that. You obviously would just need to adjust the file path to whatever your paste-into file would be.

Match column coding
Sheet2 = Your original HEADERS ( Only required headers - Put them into row 1 )
Sheet1 = your data along with the headers but headers are not in sync which could be having more headers or less but you want your data as per the headings present in the sheet2
now put your data into sheet2 ( in row 2 ) below the headers which are already present into sheet2 and run the below coding and your data will appear as per the required headers.
Sub Rahul()
Dim Orig_Range As Range
Dim New_Range As Range
Dim ToMove As Range
Dim RowOld, RowNew As Long
Dim ColOld, ColNew As Long
Dim WSD As Worksheet
Dim Cname As String
Set WSD = ActiveSheet
ColOld = WSD.Cells(1, Application.Columns.Count).End(xlToLeft).Column
ColNew = WSD.Cells(2, Application.Columns.Count).End(xlToLeft).Column
RowNew = WSD.Cells(Application.Rows.Count, 1).End(xlUp).Row
RowOld = 1
Set Orig_Range = Range(WSD.Cells(1, 1), WSD.Cells(1, ColOld))
For i = 1 To ColOld
Set New_Range = Range(WSD.Cells(2, 1), WSD.Cells(2, ColNew))
Cname = Orig_Range.Cells(RowOld, i).Value
Set ToMove = New_Range.Find(what:=Cname, LookIn:=xlValues, LookAt:=xlWhole, SearchOrder:=xlByColumns, MatchCase:=True)
If ToMove Is Nothing Then
New_Range.Cells(1, i).Resize(RowNew, 1).Select
Selection.Insert shift:=xlToRight
ElseIf Not ToMove.Column = i Then
ToMove.Resize(RowNew, 1).Select
Selection.Cut
New_Range.Cells(1, i).Select
Selection.Insert shift:=xlToRight
End If
Next i
End Sub

Related

Copy cell (A1) of sheet VN to the first open cell in column F of sheet VL, then A2 to the next open cell in F

I'm trying to write a macro to copy the contents of cell A1 of sheet wsVN to the first open cell in column F of sheet wsVL, then copy A2 to the next open cell in F, then A3 to the next and so on up to A305. Sheet VL has a header row with the first open cell being F2. That's where I'm trying to past A1. Then I have a couple rows with data then another open cell where I'd like to past A2. Then 5 rows of data before the next open cell where A3 should go. Here is as close as I have made it so far:
Sub Data_Transfer()
'
' Data_Transfer Macro
' Transfers VariableNames Data to the next available row of sheet VariableList.
Dim lastRow As Integer
Dim wsVN As Worksheet
Dim wsVL As Worksheet
Dim sourceRange As Range
Dim targetRange As Range
Set wsVN = Worksheets("VariableNames")
Set wsVL = Worksheets("VariationList")
If Len(wsVL.Range("F1").Value) > 0 Then
lastRow = wsVL.Range("F2").End(xlDown).Row
Else
lastRow = 2
End If
Set sourceRange = wsVN.Range("A1")
Set targetRange = wsVL.Range("F" & lastRow).Offset(1, 0)
sourceRange.Copy
targetRange.PasteSpecial _
Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
End Sub
Hopefully someone will offer some guidance on this. It would be appreciated very much!
Thanks
Try this, adjusting sheet names to suit.
Sub x()
Dim r As Range
With Worksheets("Sheet1") 'source sheet
For Each r In .Range("A1", .Range("A" & Rows.Count).End(xlUp))
Worksheets("Sheet2").Range("F:F").SpecialCells(xlCellTypeBlanks)(1).Value = r.Value 'destination sheet
Next r
End With
End Sub
More on SpecialCells.

Get value from SpinButton to determine the number of loops

Is there any way to get the value of a cell that is connected to a SpinButton and to determine the number of times a data will be copied.
For example everytime you press the Left or Right Button it will subtract or add a value with a minimum of 1 and maximum of 1000.
This is my code so far in copying data.
Range("D3:D10").Copy
Worksheets("Sheet2").Range("A2").PasteSpecial , Transpose:=True
The range of the cell that is associate in the SpinButton is "G7"
I want to get the value of that cell G7 to determine how many times it will copy the data from range D3 to D10.
The values is on "Sheet1". I want it to be pasted on "Sheet2".
Assuming the active sheet has the G7 and range to copy
Range("D3:D10").Copy
Worksheets("Sheet2").Range("A2:A" & 2 + [G7].Value).PasteSpecial , Transpose:=True
Application.CutCopyMode = False
Edit: paste to first available cell in sheet2
-
Sub Copy_Trspose()
Dim LstRw As Long, pRng As Range, cRng As Range, x
Dim sh As Worksheet, ws As Worksheet
Set ws = Sheets("Sheet2")
Set sh = Sheets("Sheet1")
Application.ScreenUpdating = False
With sh
Set cRng = .Range("D3:D10")
x = .Range("G7").Value
End With
With ws
LstRw = .Cells(.Rows.Count, "A").End(xlUp).Row + 1
Set pRng = .Range(.Cells(LstRw, "A"), .Cells(LstRw + x, "A"))
End With
cRng.Copy
pRng.PasteSpecial , Transpose:=True
Application.CutCopyMode = False
End Sub

Specific criteria 'Greater than 50000' OR 'Less than -50000'

This is what I have so far. There are a couple of amendments I want to make, that I don't completely understand how to do;
On line 3, I want my 'Copying criteria' to be 'Greater than 50000' or 'Less than 50000'.
How can I specify the cells on Sheet2 where the first item is copied to? For example, Sheet2! B10?
How can I then restrict the columns copied from the row on Sheet 1 which meets my criteria to (for example) columns A, B, E, F, H, I, O, & AG from Sheet1?
a = Worksheets("Sheet1").Cells(Rows.Count, 1).End(x1Up).Row
For i = 2 To a
If Worksheets("Sheet1").Cells(i, 3).Value = **>50000 OR <50000** Then
Worksheets("Sheet1").Rows(i).Copy
Worksheets("Sheet2").Activate
b = Worksheets("Sheet2").Cells(Rows.Count, 1).End(x1Up).Row
Worksheets("Sheet2").Cells(b + 1, 1).Select
ActivateSheet.Paste
Worksheets("Sheet1").Activate
End if
Next
Application.CutCopyMode = False
ThisWorkbook.Worksheets("Sheet1").Cells(1, 1).Select
End Sub
you could use Abs() function and have one check only:
and use Range property of Worksheet object to select wanted columns in given row by means of Intersect() method:
Option Explicit
Sub main()
Dim a As Long, i As Long
Dim sht2 As Worksheet
Set sht2 = Worksheets("Sheet2") ' set a worksheet object for destination sheet
With Worksheets("Sheet1") ' reference Sheet1
a = .Cells(.Rows.Count, 1).End(xlUp).Row ' get referenced sheet column A row index of last not empty cell
For i = 2 To a
If Abs(.Cells(i, 3).Value) > 50000 Then ' if cell value in current row index and column 3 is greater than 50000 or less then -500000
Intersect(.Rows(i), .Range("A:B , E:F, H:I, O:O, AG:AG")).Copy
sht2.Cells(sht2.Rows.Count, 1).End(xlUp).Offset(1).PasteSpecial
Application.CutCopyMode = False
End If
Next
End With
End Sub
You are using x1Up instead of xlUp.
Application.ScreenUpdating = False
Dim cell As Range
With Worksheets("Sheet1")
For Each cell In .Range("A2", .Cells(Rows.Count, 1).End(xlUp)).Offset(0, 2)
If cell.Value > -50000 Or cell.Value < 50000 Then
With Worksheets("Sheet2")
cell.EntireRow.Range("A1:B1,E1:F1,H1,I1,O1,AG1").Copy Destination:=.Cells(Rows.Count, 1).End(xlUp).Offset(1)
End With
End If
Next
End With

Loop through worksheets, paste data in another worksheet in columns with matching name

I want to merge tables from multiple Excel sheets with uncommon and common column names.
I can't get the loop to go to sheets in my workbook and paste in the combine worksheet.
For example I have the following tables:
Sheet1:
name surname color
Eva x
steven y black
Mark z white
Sheet2:
Surname color name code
L Green Pim 030
O yellow Xander 34
S Rihanna 567
My third sheet (the combine sheet) has all the possible column names of all sheets so it looks like:
name surname color code
The macro should read Sheet1 and Sheet2 then paste data in the combine sheet under the correct column name.
The combine sheet should looks like this, with the elements of Sheet2 under the elements of Sheet1:
name surname color code
Eva x
steven y black
Mark z white
Pim L Green 030
Xander O yellow 34
Rihanna S 567
I couldn't get the loop to read then paste data in the right column.
Sub CopyDataBlocks_test2()
'VARIABLE NAME 'DEFINITION
Dim SourceSheet As Worksheet 'The data to be copied is here
Dim CombineSheet As Worksheet 'The data will be copied here
Dim ColHeaders As Range 'Column headers on Combine sheet
Dim MyDataHeaders As Range 'Column headers on Source sheet
Dim DataBlock As Range 'A single column of data
Dim c As Range 'a single cell
Dim Rng As Range
'The data will be copied here (="Place holder" for the first data cell)
Dim i As Integer
'Dim WS_Count As Integer 'for all sheets in active workbook
'Dim j As Integer 'Worksheets count
'Change the names to match your sheetnames:
Set SourceSheet = Sheets(2)
Set CombineSheet = Sheets("Combine")
With CombineSheet
Set ColHeaders = .Range(.Cells(1, 1), .Cells(1, .Columns.Count).End (xlToLeft))
Set Rng = .Cells(.Rows.Count, 1).End(xlUp).Offset(1)
End With
With SourceSheet
Set MyDataHeaders = .Range(.Cells(1, 1), .Cells(1, .Columns.Count).End(xlToLeft))
For Each c In MyDataHeaders
If Application.WorksheetFunction.CountIf(ColHeaders, c.Value) = 0 Then
MsgBox "Can't find a matching header name for " & c.Value & _
vbNewLine & "Make sure the column names are the same and try again."
Exit Sub
End If
Next c
'A2:A & the last cell with something on it on column A
Set DataBlock = .Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp))
Set Rng = Rng.Resize(DataBlock.Rows.Count, 1)
For Each c In MyDataHeaders
i = Application.WorksheetFunction.Match(c.Value, ColHeaders, 0)
'Writes the values
Rng.Offset(, i - 1).Value = Intersect(DataBlock.EntireRow, c.EntireColumn).Value
Next c
End With
End Sub
you just wrap your With SourceSheet - End With block code into a For each sourceSheet in Worksheets - Next loop checking not to process "Combine" sheet itself
it'd be cleaner to move that into a helper Sub like follows:
Option Explicit
Sub CopyDataBlocks_test2()
'VARIABLE NAME 'DEFINITION
Dim sourceSheet As Worksheet 'The data to be copied is here
Dim ColHeaders As Range 'Column headers on Combine sheet
With Worksheets("Combine") '<--| data will be copied here
Set ColHeaders = .Range(.Cells(1, 1), .Cells(1, .Columns.Count).End(xlToLeft))
For Each sourceSheet In Worksheets '<--| loop through all worksheets
If sourceSheet.Name <> .Name Then ProcessSheet sourceSheet, ColHeaders, .Cells(.Rows.Count, 1).End(xlUp).Offset(1) '<--| process data if not "Combine" sheet
Next
End With
End Sub
Sub ProcessSheet(sht As Worksheet, ColHeaders As Range, rng As Range)
Dim MyDataHeaders As Range 'Column headers on Source sheet
Dim c As Range 'a single cell
Dim i As Integer
Dim DataBlock As Range 'A single column of data
With sht
Set MyDataHeaders = .Range(.Cells(1, 1), .Cells(1, .Columns.Count).End(xlToLeft))
For Each c In MyDataHeaders
If Application.WorksheetFunction.CountIf(ColHeaders, c.Value) = 0 Then
MsgBox "In worksheet " & .Name & " can't find a matching header name for " & c.Value & vbNewLine & "Make sure the column names are the same and try again."
Exit Sub
End If
Next c
Set DataBlock = .Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp)) 'A2:A & the last cell with something on it on column A
For Each c In MyDataHeaders
i = Application.WorksheetFunction.Match(c.Value, ColHeaders, 0)
rng.Offset(, i - 1).Resize(DataBlock.Rows.Count, 1).Value = DataBlock.Columns(c.Column).Value 'Writes the values
Next c
End With
End Sub

Copy Rows Into New Sheet If Value Matches In Same Column In Sheet 1 & Sheet 2

I need all rows returned into a new Sheet if there are matching values in Column G in two different sheets (Q1 DATA, Q2 DATA).
I placed a VLOOKUP formula =VLOOKUP('Q2 DATA'!D:D,'Q1 DATA'!D:D,2) into the 3rd sheet where I want the rows returned to, but I keep getting a #REF! error.
I'm new to Excel so I'm sure my VLOOKUP is broken, but I can't seem to figure it out. Any help would be greatly appreciated!
Assuming your data in Sheet Q1 is structured something as shown in the image below:
and Sheet Q2 is as:
Now, each row value of Column D in Sheet Q2 is to be matched with Column D of Sheet Q1. If match found, copy range E:I from Sheet Q1 to Sheet Q2.
Try this code:
Sub Demo()
Dim data1WS As Worksheet, outputWS As Worksheet
Dim lastRow As Long
Dim myRange As Range, rFound As Range
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Set dataWS = ThisWorkbook.Sheets("Sheet Q1")
Set outputWS = ThisWorkbook.Sheets("Sheet Q2")
lastRow = dataWS.Cells(Rows.Count, "D").End(xlUp).row
Set myRange = Range(dataWS.Cells(2, 4), dataWS.Cells(lastRow, 4))
For Each cel In myRange
Set rFound = outputWS.Columns(4).Find(What:=cel.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not rFound Is Nothing Then
Range(outputWS.Cells(cel.row, 5), outputWS.Cells(cel.row, 9)).Value = Range(dataWS.Cells(cel.row, 5), dataWS.Cells(cel.row, 9)).Value
End If
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
This will give output in Sheet Q2 as:

Resources