I am currently using the following code to copy paste data from File- "Source" to File-"Destination". It is selecting the rows till data ends in Column-1.
However, currently all the columns from A to AE are selected, but instead I want selective columns like A,F,K,AA to be selected.
I understand that the code in "wb.ActiveSheet.Range("A2:AE" & N).Copy" needs to be changed but not sure of the syntax.
Can anyone help me with this? Appreciate the help in advance.
Dim wb As Workbook
Set wb = ActiveWorkbook
Dim N As Long
Dim LastRow As Long
N = Cells(2, 1).End(xlDown).Row
wb.ActiveSheet.Range("A2:AE" & N).Copy
Set y = Workbooks.Open("C:\Desktop\Destination.xlsx")
y.Activate
y.Sheets("Data").Select
y.Sheets("Data").Activate
For Each Cell In y.Sheets("Data").Columns(1).Cells
If Len(Cell) = 0 Then Cell.Select: Exit For
Next Cell
Selection.PasteSpecial Paste:=xlPasteValues
Application.DisplayAlerts = False
ActiveWorkbook.Close True
Application.DisplayAlerts = True
Application.CutCopyMode = False
You can use the Application.Union to combine ranges from different columns (from row 2 until N).
Also, instead of looping through your y.Sheets("Data").Columns(1).Cells to find the empty Cell, you can just use LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1.
I added 2 With wb.Sheets("Sheet1") to fully qualify all variables and Range nested underneath.
Code
Option Explicit
Sub CopyColumns()
Dim wb As Workbook
Dim Y As Workbook
Dim N As Long
Dim LastRow As Long
Dim CopyRng As range
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Set wb = ActiveWorkbook
' you need to specify the sheet, otherwise it will take the Active Sheet
With wb.Sheets("Sheet1") ' <-- modify to your sheet's name
N = .Cells(.Rows.Count, "A").End(xlUp).Row ' <-- get last row from Column "A", skips blank cells in te middle
' set the range to Columns A, F, K, AA
Set CopyRng = Application.Union(.Range("A2:A" & N), .Range("F2:F" & N), .Range("K2:K" & N), .Range("AA2:AA" & N))
End With
Set Y = Workbooks.Open("C:\Desktop\Destination.xlsx")
With Y.Sheets("Data")
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row + 1 '<-- get first empty row at Column A to paste at
CopyRng.Copy
.Range("A" & LastRow).PasteSpecial xlPasteValues
End With
Y.Close True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.CutCopyMode = False
End Sub
Related
I'm working in Excel 2016, and I have a macro where I'm trying to remove ALL duplicated rows from the main worksheet and move them to the Duplicates worksheet starting at A3 and what is happening is that in the Duplicates worksheet is that it is cutting only 1 of the rows and NOT both rows from the Main worksheet. Any help/direction as to what I'm doing wrong would be appreciated. Thanks.
Here is my macro code:
Sub CutDuplicates()
Dim Rng As Range, i As Long
Application.ScreenUpdating = False
Set Rng = Range("A3:A" & Range("A" & Rows.Count).End(xlUp).Row)
For i = Rng.Rows.Count To 1 Step -1
If Application.WorksheetFunction.CountIf(Rng, Cells(i, "A")) > 1 Then
lr = Sheets("Duplicates").Cells(Rows.Count, "A").End(xlUp).Row + 1
Rows(i).EntireRow.Cut Destination:=Sheets("Duplicates").Range("A" & lr)
Rows(i).EntireRow.Delete
End If
Next i
Application.ScreenUpdating = True
End Sub
Note there's a subtle bug in your posted code: Rng starts in Row#3, but in your loop i is relative to Rng, not the whole sheet, so (eg) when i=1 that's Row#3 on the sheet, not Row#1.
Instead of cutting as you go, you can collect the rows to be cut and then move them:
Sub CutDuplicates()
Dim Rng As Range, i As Long, col As New Collection, ws As Worksheet
Dim c As Range
Application.ScreenUpdating = False
Set ws = ActiveSheet 'always qualify all ranges with a worksheet object...
Set Rng = ws.Range("A3:A" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)
'collect all duplicate rows
For i = 1 To Rng.Rows.Count
If Application.WorksheetFunction.CountIf(Rng, Rng.Rows(i).Value) > 1 Then
col.Add i 'store row# in collection
End If
Next i
'now cut the duplicates to the other sheet
Set c = Sheets("Duplicates").Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
For i = col.Count To 1 Step -1 'step backwards through the rows
Rng.Rows(col(i)).EntireRow.Cut Destination:=c
Set c = c.Offset(1, 0) 'next paste destination
Rng.Rows(col(i)).EntireRow.Delete
Next i
Application.ScreenUpdating = True
End Sub
I want to say thank you for the help I've been getting lately. So I am testing the VBA and I noticed that when I copy and paste data to the worksheet, it would overwrite the hidden rows. Is there a way to copy and paste the data without overwriting the hidden rows?
Public Sub CNPInStock()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim lr1 As Long, lr2 As Long
Set ws1 = ThisWorkbook.Sheets(Sheets.Count) 'Last Worksheet
Set ws2 = ThisWorkbook.Sheets(Sheets.Count - 1) 'Second to Last Worksheet
lr1 = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Offset(1).Row
lr2 = ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row
ws2.Range("A1:C" & lr2).Autofilter Field:=3, Criteria1:=">0", Operator:=xlFilterValues
ws2.Range("A2:C" & lr2).SpecialCells(xlCellTypeVisible).Copy
ws1.Range("A" & lr1).PasteSpecial xlPasteValues
End Sub
It is the same behavior as with normal copy and paste operation done without VBA.
While you can simultaneously copy data from the multiple rows by Selecting visible cells and then Copying, you cannot Paste into multiple regions with one single operation (if some rows are filtered out, this is basically what you are trying to do).
You need to loop with For ... Next through each row to paste the data.
Maybe the following solution will help you:
Sub CNPInStock()
'source-sheet
Dim sws As Worksheet
'target-sheet
Dim tws As Worksheet
Dim i As Long
Dim j As Long
Dim iEnd As Long
Set sws = Sheets("Source")
Set tws = Sheets("Target")
'only for faster calculation
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
'get end of source-sheet
iEnd = sws.Range("A" & sws.Rows.Count).End(xlUp).Row
'init row for target-sheet
j = 1
'loop the source-sheet
For i = 1 To iEnd
'your filter in column 3 with value > 0
If sws.Cells(i, 3).Value > 0 Then
'check if row in target-sheet is hidden
Do Until tws.Rows(j).Hidden = False
j = j + 1
Loop
'copy source to target
sws.Range(Cells(i, 1), Cells(i, 3)).Copy Destination:=tws.Cells(j, 1)
j = j + 1
End If
Next i
'back to automatic (slower) calculation
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub
I am trying to filter a range of data (by using "Yes" from column L) on 1 worksheet ("2. Select Study-Specific Forms") and copy the data to the last row of another worksheet ("3. Worksheet"). I am using the code below. So far the code filters the data on the first worksheet but the data does not copy to the second worksheet.
Thanks in advance for any assistance.
Sub FilterAndCopy2()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Dim LastRow As Long, LastRow2 As Long
Dim TARGetSheet As Worksheet, TKSheet As Worksheet
Set TARGetSheet = Sheets("2. Select Study-Specific Forms") 'Set sheet where filtered data is
Set TKSheet = Sheets("3. Worksheet") ' Set Sheet name to copy data to
LastRow = TARGetSheet.Range("L" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
LastRow2 = TKSheet.Range("A" & Rows.Count).End(xlUp).Row + 1 ' Determine the next empty row in order to paste the data
With TARGetSheet
.AutoFilterMode = False
With .Range("G7", "L" & LastRow)
.AutoFilter
.AutoFilter Field:=6, Criteria1:="Yes"
End With
End With
TARGetSheet.Range("G7", "L" & LastRow).Copy
TKSheet.Range("A" & LastRow2).PasteSpecial (xlPasteAll)
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
End Sub
I'm trying to copy a table from sheet 1, defined by the area D21:O21, until the end – (minus) the last 4 lines.
I have a problem pasting results. In sheet 2 I have a table that feeds pivot charts. After I delete previous filled rows (with values) and paste new ones (new values) the table extends further than it is supposed to. It adds blank cells downstream as if the copied sheet 1 had more rows with values.
For example: Imagine that my table (in sheet 1) has 600 rows with values. If I paste to the table (in sheet 2) it extends further than 600 rows (approx. 10000). Instead of adding multiple empty lines I want 600 except last 4 lines = from top to 596 rows.
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
ws1.Range("D21:O21" & Last_Row1).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
Try this:
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long, table As Range
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Set table = ws1.Range("D21:O28") // I arbitrarily set this to 8 rows
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
table.Resize(table.Rows.Count - 4, table.Columns.Count).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
Sub Prime()
Dim Last_Row1 As Long, Last_Row2 As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Sheets("Enter DATA here")
Set ws2 = Sheets("DATA")
Application.ScreenUpdating = False
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).Row ' Determine the lastrow of the data to copy
Last_Row2 = ws2.Range("A" & Rows.Count).End(xlUp).Row ' Determine the next empty row in order to paste the data
ws1.Range("D21:O" & Last_Row1-4).Copy ws2.Range("A" & Last_Row2)
Application.ScreenUpdating = True
End Sub
You can use Offset function to exclude the last 4 rows.
Last_Row1 = ws1.Range("C" & Rows.Count).End(xlUp).offset(-4,0).Row
When you copy the range, you should delete row indicator "21" behind column "O", otherwise, the code would not select till the last row. Like following:
ws1.Range("D21:O" & Last_Row1).Copy ws2.Range("A" & Last_Row2)
I have the following which works ok but instead of copying the entire row from the "Combined" worksheet to the "Summary" worksheet I only want to copy columns A to T. This is a first attempt so any help would be gratefully received!
`Private Sub CommandButton1_Click()
'Define Variables
Dim DestSh As Worksheet
Dim s As Worksheet
Dim c As Integer
Dim i
Dim LastRow
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Delete the Combined sheet if it exists
Application.DisplayAlerts = False
On Error Resume Next
ActiveWorkbook.Worksheets("Combined").Delete
On Error GoTo 0
Application.DisplayAlerts = True
'Add a new Combined worksheet
Set DestSh = ActiveWorkbook.Worksheets.Add
DestSh.Name = "Combined"
'Select Summary worksheet and copy headings and column widths to Combined worksheet
Sheets("Summary").Activate
Range("A24").EntireRow.Select
Selection.Copy Destination:=Sheets("Combined").Range("A1")
For c = 1 To Sheets("Summary").Columns.Count
Sheets("Combined").Columns(c).ColumnWidth = Sheets("Summary").Columns(c).ColumnWidth
Next
'Loop through all worksheets sheets that begin with ra
'and copy to the combined worksheet
For Each s In ActiveWorkbook.Sheets
If LCase(Left(s.Name, 2)) = "ra" Then
Application.Goto Sheets(s.Name).[A1]
Selection.Range("A23:Q50").Select
Selection.Copy Destination:=Sheets("Combined"). _
Cells(Rows.Count, 1).End(xlUp)(2)
End If
Next
'Copy all rows that contain Yes in column A to Summary worksheet
LastRow = Sheets("Combined").Range("A" & Rows.Count).End(xlUp).Row
Sheets("Summary").Range("A25:V500").ClearContents
For i = 1 To LastRow
If Sheets("Combined").Cells(i, "A").Value = "Yes" Then
Sheets("Combined").Cells(i, "A").EntireRow.Copy Destination:=Sheets("Summary").Range("A" & Rows.Count).End(xlUp).Offset(1)
End If
Next i
'Force return to Summary worksheet
Worksheets("Summary").Activate
End Sub
You can use the .Resize() method to change the range that is copied. Replace your line where you copy and paste it to the new destination with this one and it should work:
Sheets("Combined").Cells(i, "A").Resize(1, 20).Copy Destination:=Sheets("Summary").Range("A" & Rows.Count).End(xlUp).Offset(1)