vba import cells from other workbooks error - vba

I am trying to copy some range of cells from other workbooks, but I get the error:
'runtime '1004' error
Error defined by application or object
if I try to use the "range(cells(i,j), cells(k,h))" sintax instead of the range("A1:Z1"). I.e., In the following code the line "PASTE 1" produces an error, while the line "PASTE 2" runs smoothly (obviously I don't want to use the second one because I need to run a loop over different ranges).
Sub Importa()
Dim directory As String
Dim fileName As String
Dim wbfrom As Workbook
Dim wbto As Workbook
Application.ScreenUpdating = False
Application.DisplayAlerts = False
directory = "mydirectory"
fileName = Dir(directory & "*.xl??") 'find the first *.xl?? file; ' wildcards: multiple character (*) single character (?)
Set wbto = ThisWorkbook
Set wbfrom = Workbooks.Open(directory & fileName, False, True)
' copy some cells
wbfrom.Sheets(1).Range(Cells(9, 6), Cells(15, 6)).Copy
'PASTE 1
wbto.Sheets(1).Range(Cells(9, 1), Cells(15, 1)).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
'PASTE 2
'wbto.Sheets(1).Range("A1:A8").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wbfrom.Close SaveChanges:=False
'Turn on screen updating and displaying alerts again
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

the problem is that you need to qualify the Cells to a particular sheet/workbook. Otherwise, it is implictly belonging to the ActiveSheet, and since the wbFrom is Active at run-time, the range cannot exist (because cells on one worksheet cannot define a range on another worksheet)
Two ways to handle this, one is qualifying Cells like so:
With wbto.Sheets(1)
.Range(.Cells(9, 1), .Cells(15, 1)).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
End With
The other is to coerce the address from the cells:
wbto.Sheets(1).Range(Cells(9, 1).Address, Cells(15, 1).Address).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
My preference is for the first option, as it tends to be more dynamic and easy to read and modify later, if you need to do so.

Related

Copy and pasting between excel workbooks

I have a Macro that copies and pastes from one excel document to another. For some reason, I had an error when using pastespecial immediately after copying and pasting from the other source doc. So as a workaround I just pasted normally, and then copied it again and then used pastespecial. My problem is that when running this Macro for some reason it adds a space to the end of the numbers turning them into text. Meaning that my graphs don't recognize them.
Workbooks.Open (fileLocation & "/" & fileName & fileType)
Worksheets(sourceWorksheet).Select
rowInUse = 46 'Add data row and name of sheet being imported into
mySheet = "sheet2"
pasteLocation = "D5"
lastColumn = ActiveSheet.Cells(rowInUse, Columns.Count).End(xlToLeft).Column
Range(Cells(rowInUse, firstColumn), Cells(rowInUse, lastColumn)).Copy
ActiveWorkbook.Close SaveChanges:=False
Worksheets(mySheet).Select
Range(tempPasteLocation).Select
ActiveSheet.Paste
Sheets(mySheet).Select
Range(tempPasteLocation, Cells(tempRow, tempColumn + lastColumn)).Select
Selection.Copy
Range(pasteLocation).Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
Range(tempPasteLocation, Cells(tempRow, tempColumn + lastColumn)).Select
Selection.ClearContents
Does anyone have any idea why this is happening or how to fix it?
Thank you
Perform a direct value transfer instead of Copy, PasteSpecial, Values.
Replace,
Sheets(mySheet).Select
Range(tempPasteLocation, Cells(tempRow, tempColumn + lastColumn)).Select
Selection.Copy
Range(pasteLocation).Select
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=True
With this,
with workSheets(mySheet)
with .Range(tempPasteLocation, .Cells(tempRow, tempColumn + lastColumn))
.Range(pasteLocation).resize(.rows.count, .columns.count) = .value2
end with
end with

Copy data from one workbook to another while performing a check

Completely new to VBA. But here is the code I have. The first code box is to perform a check that Cell X in Workbook1 equals Cell Y in Workbook2, if successful it will continue to my second code box where it will pull the data from the designated cells and then paste it in the row where the active cell is currently located. The second code box needs an overhaul to designate the paste function into the active row, starting at the active cell.
I get errors trying to get the row where the active cell is currently located.
Here's the flow..
Command Button Click
Select File with data to be copied from (this workbook has static cells so data is being pulled from the same cell regardless of which spreadsheet is being used)
Perform a check that workbook1 process number (static cell) matches process number in workbook 2 in the current row where active cell is located (same column, changing rows)
4a. Success- Proceed to copy and paste data into active row beginning at the active cell
4b. Fail- Error message and don't copy or paste.
Code:
Sub Foo()
Dim vFile As Variant
Dim wbCopyTo As Workbook
Dim wsCopyTo As Worksheet
Dim wbCopyFrom As Workbook
Dim wsCopyFrom As Worksheet
Set wbCopyTo = ActiveWorkbook
Set wsCopyTo = ActiveSheet
'-------------------------------------------------------------
'Open file with data to be copied
vFile = Application.GetOpenFilename("Excel Files (*.xl*)," & _
"*.xl*", 1, "Select Excel File", "Open", False)
'If Cancel then Exit
If TypeName(vFile) = "Boolean" Then
Exit Sub
Else
Set wbCopyFrom = Workbooks.Open(vFile)
Set wsCopyFrom = wbCopyFrom.Worksheets(1)
End If
'Process number check to see if values match and the data is being put in the correct row
Dim projectNumber As Long
Dim column As Integer
Dim row As Integer
Dim rng As Range
'Set column and row to whatever row/column contains the Project Number in wsCopyFrom (could also use Range if its a particular cell)
projectNumber = wsCopyFrom.Range("G5).Value
Set rng = wsCopyTo.Cells.EntireRow.Select 'Get selected row in Active Worksheet
For Each c In rng.Cells ' Check each cell in row/range
If c.Value = projectNumber ' Project number was found
MsgBox("Project number found!")
' Insert copy and pasting code here.... See below code box
End If
Next c
' Project number was not found in selected range if you get to this point
MsgBox("Project Number Does Not Match")
'Close file that was opened
wbCopyFrom.Close SaveChanges:=False
Code:
'Copy and Pasting
wsCopyFrom.Range("F21").Copy
wsCopyTo.Range("Active Row, beginning at Active Cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("G21").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("L21").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("M21").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("R21").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("S21").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("G31").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("M31").Copy
wsCopyTo.Range(""Active Row and Offset one column to the right from previous cell).PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("S31").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("F41").Copy
wsCopyTo.Range(""Active Row and Offset one column to the right from previous cell).PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wsCopyFrom.Range("G41").Copy
wsCopyTo.Range("Active Row and Offset one column to the right from previous cell").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=False
If what you want is to copy from 1 file and paste it on another file without pasting it over already existing content then you should opt for a VBscript instead of excel.
Example below:
strPathSrc = "C:\......" ' Source files folder
strMaskSrc = "*.csv" ' Source files filter mask can be any format
iSheetSrc = 3 ' Source sheet index or name sheet you want to copy
strPathDst = "C:\....xlsx" ' Destination file
iSheetDst = 1 ' Destination sheet index or name
Set objExcel = CreateObject("Excel.Application")
Set fso = CreateObject("Scripting.FileSystemObject")
objExcel.Visible = false
Set objWorkBookDst = objExcel.Workbooks.Open(strPathDst)
Set objSheetDst = objWorkBookDst.Sheets(iSheetDst)
Set objShellApp = CreateObject("Shell.Application")
Set objFolder = objShellApp.NameSpace(strPathSrc)
Set objItems = objFolder.Items()
objItems.Filter 64 + 128, strMaskSrc
objExcel.DisplayAlerts = False
For Each objItem In objItems
Set objWorkBookSrc = objExcel.Workbooks.Open(objItem.Path)
Set objSheetSrc = objWorkBookSrc.Sheets(iSheetSrc)
GetUsedRange(objSheetSrc).Copy
Set objUsedRangeDst = GetUsedRange(objSheetDst)
iRowsCount = objUsedRangeDst.Rows.Count
objWorkBookDst.Activate
objSheetDst.Cells(iRowsCount + 1, 1).Select
objSheetDst.Paste
objWorkBookDst.Application.CutCopyMode = False
objWorkBookSrc.Close
Next
objExcel.ActiveWorkbook.Save
fso.DeleteFile "C:......", True 'delete original file if required
Function GetUsedRange(objSheet)
With objSheet
Set GetUsedRange = .Range(.Cells(1, 1), .Cells(.UsedRange.Row + .UsedRange.Rows.Count - 1, .UsedRange.Column + .UsedRange.Columns.Count - 1))
End With
End Function
Paste this into a notepad and save it as .vbs then run it and should have you sorted. you can even automate this with windows scheduler if necessary.
Hope it helps

Paste Special error 1004 PasteSpecial method of Range class failed

I have looked thoroughly at the current answers for this problem and none of them have fixed mine.
The operation is simply copying a selection of a sheet and copying to a new book called budget.
Again I have tried multiple different ways of doing the same thing and none of them seem to change this error. The select method works,it only breaks when I try to paste.
Code:
Range("B3").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Dim wk As Workbook
Set wk = Workbooks.Add
wk.SaveAs FileName:=ThisWorkbook.path & "\" & "Budget.xlsx"
wk.Activate
wk.Unprotect
wk.Worksheets("Sheet1").Range("B3").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Thanks,
If you try exactly the steps in the code manually, you will find it also fails. The issue is that inbetween copying the cells and trying to paste them, you are creating a new workbook and saving it. This cancels copy/paste mode (i.e. the "marching ants" around the copied range disappear), so there is nothing to paste.
The solution is to not use Selection at all. In general any time you find yourself writing .Select in VBA you're doing it wrong (see this question for detail). Here is how I would re-write your code:
Dim wk As Workbook
Set wk = Workbooks.Add
wk.SaveAs Filename:=ThisWorkbook.Path & "\" & "Budget.xlsx"
ThisWorkbook.Range("B3").CurrentRegion.Copy
wk.Worksheets("Sheet1").Range("B3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Try the code below (explanation inside the code as comments):
Dim wk As Workbook
Set wk = Workbooks.Add
wk.SaveAs Filename:=ThisWorkbook.Path & "\" & "Budget.xlsx"
wk.Activate
wk.Unprotect
' have the Copy>>Paste section together
Dim LastCol As Long
Dim LastRow As Long
' you never mentioned which sheet to copy from, I used the first index
With ThisWorkbook.Sheets(1)
LastCol = .Range("B3").End(xlToRight).Column
LastRow = .Range("B3").End(xlDown).Row
.Range("B3", .Cells(LastRow, LastCol)).Copy ' <-- Copy without Select
End With
' Paste without Select
wk.Worksheets("Sheet1").Range("B3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False

Need to copy & paste from several different sheets into one sheet vertically

I'm attempting to write a macro that will copy a range of cells from a sheet, paste them into a sheet ("Bulksheet") that will contain all pasted data, then move on to the next tab after the first sheet. This needs to be done for 40+ tabs. Luckily, the data is in the same place in each tab, including the Bulksheet tab.
I can easily get this to apply to one tab, but returning to the first active tab and then moving on to the next is giving me no end of trouble.
Ex. code (shortened to the crucial bit). At the bottom where Next is would be where I need to move to the next sheet and do the same function, returning to "Bulksheet" and pasting in the next empty cell in column C.:
Sub
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ws.Activate
Range("C100:F103").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Bulksheet").Select
Range("D1").End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next
End Sub
Try looping through the sheets using an index value instead.
Sub
Dim i as integer
For i = 1 to worksheets.count
sheets(i).Activate
if activesheet.name <> "Bulksheet" then
Range("C100:F103").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Bulksheet").Select
Range("D1").End(xlDown).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
end if
Next
End Sub
Try this:
Sub CopyToBulksheet()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
If ws.Name <> "Bulksheet" Then
ws.Activate
Range("C1:F10").Copy
Sheets("Bulksheet").Select
Range("D" & Cells.Rows.Count).End(xlUp).Offset(1, 0).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End If
Next
End Sub

Calling on a Range in VBA

What am I doing wrong with my code below? I am trying to name a range of data that is highlighted in excel and be able to call it in the VBA code and paste it, transpose it, etc. somewhere else but it keeps giving me an error.
Sub routine()
Dim rng As Range
Set rng = ActiveCell.CurrentRegion
Cells(10, "D").Select
rng.PasteSpecial
End Sub
I also notice that when type "ActiveCell." and hit space i get a drop down of options. however the case isn't true when i type "Cells(1,1)." and space. Why is that? Thank you guys for your help!
Edit: after reading the comments:
Here is a simpler way to copy a range of cells, then pasting special (values) to somewhere else. I obtained this code my recording a macro entirely.
Sub Macro1()
Range("A1:C3").Select
Selection.Copy
Cells(10,"D").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Application.CutCopyMode = False
End Sub
If you meant to copy the D10 range to whatever activecell is, then Change
Cells(10, "D").Select
to
Cells(10, "D").copy
You also need to specify what do you want to SPECIALLY PASTE (values? format?)
So your full code should be like
Sub routine()
Dim rng As Range
Set rng = ActiveCell.CurrentRegion
Cells(10, "D").Copy
rng.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False 'This will only paste values
Application.CutCopyMode = False
End Sub