VBA - Copy Variable Number of Rows from a Workbook to Another - vba

Our office has recently updated to excel 2013 and a code which worked in the 2010 version is not working. I've searched on several threads here on SO and have yet to find a solution that works for this particular case.
The code identifies and copies a range of cells from an open workbook and logs them into a second workbook, one range of cells at a time. The reason it's set up to copy only 1 row at a time is because the number of rows to be copied varies from time to time. Since the change to 2013, the Selection.PasteSpecial functions have been triggering the debug prompt.
In practice, the worksheet is being used as a routing form. Once it's filled out, we run the code and save all the relevant information in a separate workbook. Since it's a routing form, the number of people on it varies, and we need a row for each person in order to track their 'status'.
The code:
Sub Submit()
'Transfer code
Dim i As Long, r As Range, coltoSearch As String
coltoSearch = "I"
'Change i = # to transfer rows of data. Needs to be the first row which copies over.
'This is to identify how many rows are to be copied over. If statement ends the for loop once an "empty" cell is reached
For i = 50 To Range(coltoSearch & Rows.Count).End(xlUp).Row
Set r = Range(coltoSearch & i)
If Len(r.Value) = 0 Then
Exit For
End If
'Copies the next row on the loop
Range(Cells(i, 1), Cells(i, 18)).Copy
'open the workbook where row will be copied to
Workbooks.Open FileName:= _
"Workbook2"
'definition for the first empty row in Workbook 2, or the row under the last occupied cell in the Log
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'selects the first cell in the empty row
ActiveSheet.Cells(erow, 1).Select
' Pastes the copied row from Workbook 1 into Workbook 2. First line is highlighted when debugging
Selection.PasteSpecial Paste:=xlPasteValuesAndNumberFormats
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.CutCopyMode = False
'moves to the next row
Next i
Any thoughts? I'm open to all options. Thanks for your time.

The Working alternative to select is
ActiveSheet.Cells(erow, 1).PasteSpecial Paste:=xlPasteValuesAndNumberFormats
but just for be sure that everything is going fine you have to set the range where i you want to paste everything
dim rngToFill as range
Set rngToFill = ActiveSheet.Cells(erow, 1)
maybe instead of using ActiveSheet you have to define that sheet after opening the wb with
dim wb as Workbook, ws as worksheet
set wb = Workbooks.Open FileName:="Workbook2"
set ws = wb.Sheets(nameofthesheet) 'or number of the sheet
then
set rngToFill = ws.Cells(erow, 1)
then you can paste in that range using .PasteSpecial method, but before doing that, try to be sure that there is no merged cell and that the worksheet we're you are going to paste values is not protected.
rngToFill.PasteSpecial xlPasteValuesAndNumberFormats
Your code:
dim wb as Workbook, ws as worksheet
set wb = Workbooks.Open(FileName:="Workbook2")
set ws = wb.Sheets(nameofthesheet) 'or number of the sheet
erow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
if erow = 0 then erow = 1
set rngToFill = ws.Cells(erow, 1)
rngToFill.PasteSpecial xlPasteValuesAndNumberFormats
The B plan is to use a for loop iterating throug the cell you want to copy... but it's painfull slowly!
Dim wb As Workbook, newWs As Worksheet, oldWs As Worksheet
Dim z As Integer
Set oldWs = ActiveSheet
Set wb = Workbooks.Open("Workbook2")
Set newWs = wb.Sheets(1)
erow = ws.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
If erow = 0 Then erow = 1
For z = 1 To 18
newWs.Cells(erow, z) = oldWs.Cells(i, z).Value
Next z
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.CutCopyMode = False
'moves to the next row
Next i

Related

Copy varying range from multiple sheets and paste from same row

I am working currently with one workbook and want to implement a preparatory work, copy/pasting all the relevant range from my workbook contained in separate worksheets (3 worksheets at most).
I have the below code to loop through the worksheets, unfortunately I am unable to write the paste-command so as to paste these ranges from the same row successively. I want Transpose:= True. I.E Rgn from sheet1 starting from B2, after last filled cell on the right starts Rgn from Sheet2, after last filled cell starts Rgn from Sheet3 (provided Rgn exists for Sheet3).
Currently, my code overwrites what was copied from previous sheet.
I found a potential reference here (VBA Copy Paste Values From Separate Ranges And Paste On Same Sheet, Same Row Offset Columns (Repeat For Multiple Sheets)) but I am not sure how to use Address nor how the Offset is set in the solution.
' Insert temporary tab
Set sh = wb.Sheets.Add(after:=wb.Sheets(wb.Sheets.Count))
sh.Name = "Prep"
'Loop
For Each sh In wb.Worksheets
Select Case sh.Index
Case 1
Sheets(1).Range("D16:D18").Copy
Case 2
lastrow = Sheets(2).Range("A" & Rows.Count).End(xlUp).Row
lastcol = Sheets(2).Cells(9, Columns.Count).End(xlToLeft).Column
Set Rng = Sheets(2).Range("M9", Sheets(2).Cells(lastrow, lastcol))
Rng.Copy
Case 3
'Check if Range (first col for answers) is not empty
If Worksheetunction.CountA(Range("L9:L24")) = 0 Then
Exit For
Else
lastrow = Sheets(3).Range("A" & Rows.Count).End(xlUp).Row
lastcol = Sheets(3).Cells(9, Columns.Count).End(xlToLeft).Column
Set Rng = Sheets(3).Range("L9", Sheets(3).Cells(lastrow, lastcol))
Rng.Copy
End If
End Select
wb.Sheets("Prep").UsedRange.Offset(1,1).PasteSpecial Paste:=xlPasteAll, Transpose:=True
Next
Set sh = Nothing
Set Rng = Nothing
Can you try this? UsedRange can be unpredictable. You can also have problems if you don't have anything in the first cell of Rng, in which case this code will need adjusting.
I would also prefer to use the sheeet name rather than index.
Sub x()
Dim sh As Worksheet, wb As Workbook, Rng As Range
Set sh = wb.Sheets.Add(after:=wb.Sheets(wb.Sheets.Count))
sh.Name = "Prep"
'Loop
For Each sh In wb.Worksheets
Select Case sh.Index
Case 1
Set Rng = sh.Range("D16:D18")
Case 2
lastrow = sh.Range("A" & Rows.Count).End(xlUp).Row
lastcol = sh.Cells(9, Columns.Count).End(xlToLeft).Column
Set Rng = sh.Range("M9", sh.Cells(lastrow, lastcol))
Case 3
'Check if Range (first col for answers) is not empty
If WorksheetFunction.CountA(sh.Range("L9:L24")) = 0 Then
Exit For
Else
lastrow = sh.Range("A" & Rows.Count).End(xlUp).Row
lastcol = sh.Cells(9, Columns.Count).End(xlToLeft).Column
Set Rng = sh.Range("L9", sh.Cells(lastrow, lastcol))
End If
End Select
Rng.Copy
wb.Sheets("Prep").Cells(2, Columns.Count).End(xlToLeft).Offset(, 1).PasteSpecial Paste:=xlPasteAll, Transpose:=True
Next
Set sh = Nothing
Set Rng = Nothing
End Sub

Copy and paste rows from one to another worksheet VBA

I know already a few people had that problem but their solutions did not help me. I am pretty new to VBA and I want to copy a row if the respective first cell is not empty to another file and iterate as long as the data is.
So far so good. My code runs the first time and actually works (for one line). But then the macro does not open the file again and spits out an error. If I want to manually open the target file it says: "Removed Feature: Data Validation from /xl/worksheets/sheet2.xml part" (and I think this is the reason why it does not iterate further). Do you have any idea what I can do?
Sub transferData()
Dim LastRow As Long, i As Integer, erow As Long
LastRow = ActiveSheet.Range("BC" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If IsEmpty(Cells(i, 63).Value) = False Then
Range(Cells(i, 55), Cells(i, 63)).Select
Selection.Copy
Workbooks.Open Filename:="PATH.xlsx"
Worksheets("NewProjects").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.PasteSpecial
ActiveSheet.Sort.SortFields.Clear
ActiveWorkbook.Save
ActiveWorkbook.Close SaveChanges:=False
Application.CutCopyMode = False
End If
Next i
End Sub
Data Validation for the file is corrupt (dropdown lists) - either delete Data Validation, or fix it
Once the file is fixed, the code bellow will copy the data without opening the destination file multiple times. It AutoFilters current sheet for empty values in column BK (63), and copies all visible rows, from columns BC to BK, to the end of the new file (starting at first unused cell in column A)
Option Explicit
Public Sub TransferData()
Const OLD_COL1 = "BC"
Const OLD_COL2 = "BK"
Const NEW_COL1 = "A"
Dim oldWb As Workbook, oldWs As Worksheet, oldLR As Long
Dim newWb As Workbook, newWs As Worksheet, newLR As Long
On Error Resume Next 'Expected errors: new file not found, new sheet name not found
Set oldWb = ThisWorkbook
Set oldWs = ActiveSheet 'Or: Set oldWs = oldWb.Worksheets("Sheet2")
oldLR = oldWs.Cells(oldWs.Rows.Count, OLD_COL1).End(xlUp).Row
Application.ScreenUpdating = False
Set newWb = Workbooks.Open(Filename:="PATH.xlsx")
Set newWs = newWb.Worksheets("NewProjects")
If Not newWs Is Nothing Then
newLR = newWs.Cells(oldWs.Rows.Count, NEW_COL1).End(xlUp).Row
With oldWs.Range(oldWs.Cells(2, OLD_COL2), oldWs.Cells(oldLR, OLD_COL2))
.AutoFilter Field:=1, Criteria1:="<>"
If .SpecialCells(xlCellTypeVisible).Cells.Count > 2 Then
oldWs.Range(oldWs.Cells(3, OLD_COL1), oldWs.Cells(oldLR, OLD_COL2)).Copy
newWs.Cells(newLR + 1, NEW_COL1).PasteSpecial
Application.CutCopyMode = False
newWs.Sort.SortFields.Clear
newWb.Close SaveChanges:=True
Else
newWb.Close SaveChanges:=False
End If
.AutoFilter
End With
End If
Application.ScreenUpdating = True
End Sub

VBA - copy the range in some cells and appear them into other sheet

I want a code that doing the following:
if the last 5 characters of the text value in the cell in column E is “(UK)” then the macro copies the range consisting of 4 cells in columns B,C,D,E in the same row and pastes below the last non-empty row in the worksheet “Sheet 1” in the same columns (so all ranges B-E with “(UK)” must be transferred to the sheet “Sheet1”);
I am just posting my code. Hope #Jonathan will learn it.
Sub CopyC()
Dim wb As Workbook
Dim ws As Worksheet
Dim sheet1lastrow As Long
Dim lastrow As Long
Set wb = ThisWorkbook
Set ws = wb.Worksheets("sheet1")
lastrow = ActiveSheet.Range("E" & Rows.Count).End(xlUp).Row
sheet1lastrow = ws.Range("E" & Rows.Count).End(xlUp).Row
For i = 1 To lastrow
If Right(ActiveSheet.Cells(i, 5).Value, 5) = "(UK)" Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 5)).Copy
ws.Cells(sheet1lastrow + 1, 2).PasteSpecial xlValues
Application.CutCopyMode = False
Application.CutCopyMode = True
End If
Next
End Sub

Fill down the workbook instead of overwriting the first entry over and over again

I am using the following code to copy and paste certain rows into a new workbook:
Sub ReportCreator()
Dim wbI As Workbook, wbO As Workbook
Dim wsI As Worksheet, wsO As Worksheet
Dim iCounter As Long
Dim lrow As Long
'~~> Source/Input Workbook
Set wbI = ThisWorkbook
'~~> Set the relevant sheet from where you want to copy
Set wsI = wbI.Sheets("Pharmas")
'~~> Destination/Output Workbook
Set wbO = Workbooks.Add
lastRow = ThisWorkbook.Worksheets("Pharmas").Cells(Rows.Count, "L").End(xlUp).Row
With wbO
'~~> Set the relevant sheet to where you want to paste
Set wsO = wbO.Sheets("Sheet1")
'~~>. Save the file
For iCounter = 2 To lastRow
If wsI.Cells(iCounter, 4) = "Barr" Then
wsI.Rows(iCounter).Copy
End If
wsO.Range("A").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Next iCounter
.SaveAs Filename:="C:\Users\rrrrr\Desktop\eeee.xls", FileFormat:=56
End With
End Sub
When the code goes down my list, any row with Barr in column 4 is copied and then pasted onto the new workbook.
The problem I'm encountering is that it's not pasting down the new workbook for each row it finds. Instead on the new workbook, it just overwrites the first row with newer information. When I debug, the code portion that looks for Barr and copies the row is working, but it's not pasting down the workbook, it's just overwriting the first row.
I've tried adding altering the paste code as follows:
wsI.Rows(iCounter).Copy
End If
lrow = Range("A" & .Rows.Count).End(xlUp).Row
wsO.Range("A" & lrow + 1).PasteSpecial Paste:=xlPasteValues,
However, it tells me Object doesn't support this property or method.
I am sure the paste code is incorrect but I'm not sure how to change it so it fills down the workbook instead of overwriting the first entry over and over again with each subsequent find of Barr.
Try this amended code
Sub OhYa()
Dim wbI As Workbook, wbO As Workbook
Dim wsI As Worksheet, wsO As Worksheet
Dim iCounter As Long
Dim lrow As Long, rw As Long
'~~> Source/Input Workbook
'Set wbI = ThisWorkbook
'~~> Set the relevant sheet from where you want to copy
Set wsI = Sheets("Pharmas")
'~~> Destination/Output Workbook
Set wbO = Workbooks.Add
lastRow = wsI.Cells(Rows.Count, 4).End(xlUp).Row
With wbO
'~~> Set the relevant sheet to where you want to paste
Set wsO = wbO.Sheets("Sheet1")
'~~>. Save the file
With wsI
For iCounter = 2 To lastRow
If wsI.Cells(iCounter, 4) = "Barr" Then
.Cells(iCounter, 4).EntireRow.Copy
rw = wsO.Cells(wsO.Rows.Count, "A").End(xlUp).Row + 1
wsO.Cells(rw, 1).PasteSpecial Paste:=xlPasteValues
End If
Next iCounter
'.SaveAs Filename:="C:\Users\rrrrr\Desktop\eeee.xls", FileFormat:=56
End With
End With
Application.CutCopyMode = 0
End Sub
In your solution you forgot to reference wsO:
lrow = wsO.Range("A" & wsO.Rows.Count).End(xlUp).Row
wsO.Range("A" & lrow + 1).PasteSpecial Paste:=xlPasteValues
This solution should work, but should be slow. You can run faster by keeping track of the next row in a variable and icrementing it whenever you paste a row.
If all you want are the values then do not use paste but assign the value to the cell directly.
lrow = wsO.Range("A" & wsO.Rows.Count).End(xlUp).Row
wsO.rows(lrow + 1).value =wsI.Rows(iCounter).value

Copy rows starting from certain row till the end using macro

I need to copy values of one excel and create a new one with required format. Say i need to copy columns from B11 to BG11 and rows will be till the end.( i don't know how to find the end of rows). And I have column heading in b7 to bg7. In between there are unwanted rows and i don't need it. So in the new excel i want column headings(which is from b7 to bg7) as first row and the values from b11 to bg11 till the end.
This is my first excel Macro. I don't know how to proceed. So with references from some stackoverflow question and other site, i have tried the below code. but it is not giving the required output.
Sub newFormat()
Dim LastRow As Integer, i As Integer, erow As Integer
LastRow = ActiveSheet.Range(“B” & Rows.Count).End(xlUp).Row
For i = 2 To LastRow
Sheets("MySheetName").Range("B7:BG7").Copy
Sheets("MySheetName").Range("B11:BG11").Copy
Workbooks.Open Filename:=”C:\Users\abcd\Documents\Newformat.xlsx”
Worksheets(“Sheet1”).Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 1).Select
ActiveSheet.Paste
ActiveWorkbook.Save
ActiveWorkbook.Close
Application.CutCopyMode = False
End If
Next i
End Sub
this may be simple. any help would be appreciated.
Few things...
Do not use Integer for rows. Post xl2007, the number of rows have increased and Integer can't hold that. Use Long
You do not need to select a range to paste on it. You can directly perform the action.
You do not need to use a loop. You can copy ranges in two chunks
Work with objects so Excel doesn't get confused by your objects.
Since Sheet1 is empty, you don't need to find the last row there. Simply start at 1.
To output the data to new workbook, you have to use Workbooks.Add
See this example (Untested)
Sub newFormat()
Dim wbO As Workbook
Dim wsI As Worksheet, wsO As Worksheet
Dim LastRow As Long, erow As Long
'~~> Set this to the relevant worksheet
Set wsI = ThisWorkbook.Sheets("HW SI Upload")
'~~> Find the last row in Col B
LastRow = wsI.Range("B" & wsI.Rows.Count).End(xlUp).Row
'~~> Open a new workbook
Set wbO = Workbooks.Add
'~~> Set this to the relevant worksheet
Set wsO = wbO.Sheets(1)
'~~> The first row in Col A for writing
erow = 1
'~~> Copy Header
wsI.Range("B7:BG7").Copy wsO.Range("A" & erow)
'~~> Increment output row by 1
erow = erow + 1
'~~> Copy all rows from 11 to last row
wsI.Range("B11:BG" & LastRow).Copy wsO.Range("A" & erow)
'~~> Clear Clipboard
Application.CutCopyMode = False
'
'~~> Code here to do a Save As
'
End Sub
Different but the same
Rename the sheet
Sub Button1_Click()
Dim wb As Workbook, ws As Worksheet, sh As Worksheet
Dim LstRw As Long, Rng As Range, Hrng As Range
Set sh = Sheets("MySheetName")
With sh
Set Hrng = .Range("B7:BG7")
LstRw = .Cells(.Rows.Count, "B").End(xlUp).Row
Set Rng = .Range("B11:BG" & LstRw)
End With
Application.ScreenUpdating = 0
Workbooks.Open Filename:="C:\Users\abcd\Documents\Newformat.xlsx"
Set wb = Workbooks("Newformat.xlsx")
Set ws = wb.Sheets(1)
Hrng.Copy ws.Cells(Rows.Count, "A").End(xlUp).Offset(1)
Rng.Copy ws.Cells(Rows.Count, "A").End(xlUp).Offset(1)
ws.Name = sh.Name 'renames sheet
wb.Save
wb.Close
End Sub