Error 1004 on range.paste - vba

I'm currently getting mad on a macro.
I spent hours on the internet searching for a solution, but I came to the point where I have to ask for help :(
I get a
run-time error '1004' application-defined or object-defined error
on this line: Range(rngZelle1.Offset(1, 2)).Paste
Option Explicit
Sub import()
Dim bk As Workbook
Dim sh, asheet As Worksheet
Dim rngZelle, rngZelle1 As Range
Dim strSuchwort, sDate, sPath, sName As String
Application.ScreenUpdating = False
Set sh = ActiveSheet
strSuchwort = "test"
sPath = "C:\Users\stefan.******\Downloads\" 'you dont need to know my real name :P
sName = Dir(sPath & "*.xl*")
Do While sName <> ""
Set bk = Workbooks.Open(sPath & sName)
For Each asheet In ActiveWorkbook.Worksheets
asheet.Activate
For Each rngZelle In Range("A:A")
If UCase(rngZelle) Like UCase(strSuchwort) Then
sDate = Right(rngZelle, 10)
Range(rngZelle.Offset(2, 1), rngZelle.Offset(25, 1)).copy
For Each rngZelle1 In sh.Range("A:A")
If rngZelle1 = sDate Then
Range(rngZelle1.Offset(1, 2)).Paste '<---- thats the line i get the error
End If
Next rngZelle1
End If
Next rngZelle
Next asheet
Everything goes well up to the mentioned line. I tried to replace it for test purposes by "msgbox sdate" what went well.
What I really dont get, in the previous loop the copy goes well. It seems to be all about the paste line.
I hope one of you guys can help a totally noob out :) Every help is really appreciate as I'm getting really nuts on this.

Paste is a Workbook method which can't be used on a Range object.
The corresponding Range method is PasteSpecial which takes 4 optional parameters. The Paste parameter takes an xlPasteType which is xlPasteAll by default. For clarity I usually include xlPasteType even if using the default.
If you change:
Range(rngZelle1.Offset(1, 2)).Paste
to:
Range(rngZelle1.Offset(1, 2)).PasteSpecial xlPasteAll
your code should work.

Following the comments above by #Scott Craner and #user3598756 , there a few "corrections" need to be made:
Dim sh, asheet As Worksheet means asheet As Worksheet and sh As Variant.
The same goes to Dim rngZelle , rngZelle1 As Range, only the second one is Range while , rngZelle As Variant.
To conclude the first section of declaration, it should be:
Dim bk As Workbook
Dim sh As Worksheet, asheet As Worksheet
Dim rngZelle As Range, rngZelle1 As Range
Dim strSuchwort As String, sDate As String, sPath As String, sName As String
Regarding the For Each asheet In ThisWorkbook.Worksheets loop:
There is no need to asheet.Activate , you can use With asheet instead.
Regarding your error, if you Copy >> Paste in 2 code lines, you need to replace the syntax of the Paste line to `PasteSpecial xlPasteAll.
For Each asheet Loop Code
For Each asheet In ThisWorkbook.Worksheets
With asheet
For Each rngZelle In .Range("A:A")
If UCase(rngZelle.Value) Like UCase(strSuchwort) Then
sDate = Right(rngZelle.Value, 10)
Range(rngZelle.Offset(2, 1), rngZelle.Offset(25, 1)).Copy
For Each rngZelle1 In sh.Range("A:A")
If rngZelle1.Value = sDate Then
rngZelle1.Offset(1, 2).PasteSpecial xlPasteAll
End If
Next rngZelle1
End If
Next rngZelle
End With
Next asheet

sorry for my late reply. Unfortunately I haven't had much time the last couple of weeks.
First of all, .PasteSpecial did the job :) thanks a lot!
Dim sh, asheet As Worksheet means asheet As Worksheet and sh As
Variant
Thank you very much for the tip, I learned something new :)
Unfortunately the with asheet and end with results in a macro what doesn't copy and paste the figures, so I stick to the loop.
I managed to build a final and working macro, but it takes 90 Minutes to run (final version shall import 5 times of current data) and it blocks the clipboard while running.
So if anyone ha any idea how to speed it up and bypass the clipboard (copy destination etc doesn't work for any reason) it would be really appreciate.
Option Explicit
Sub import()
Dim bk As Workbook
Dim sh As Worksheet, asheet As Worksheet
Dim sSkill As Range, pval As Range, lstZelle As Range, target As Range, stype As Range, lstZelle1 As Range
Dim strSuchwort As String, sDate As String, sPath As String, sName As String, strSuchwort1 As String, strSuchwort2 As String
Dim row As Integer, col As Integer
Application.ScreenUpdating = False
Set sh = ActiveSheet
sPath = "C:\Users\*******\test\"
sName = Dir(sPath & "*.xl*")
Do While sName <> ""
Set bk = Workbooks.Open(sPath & sName)
sh.Range("A1").AutoFilter field:=1, Criteria1:="<>"
For Each lstZelle In sh.Range("B:B")
If lstZelle <> "" Then
strSuchwort = lstZelle & "*"
strSuchwort2 = lstZelle.Offset(0, -1)
For Each lstZelle1 In sh.Range("C:C")
If lstZelle1 <> "" Then
strSuchwort1 = lstZelle1
For Each asheet In ActiveWorkbook.Worksheets
asheet.Activate
If asheet.Name = strSuchwort2 Then
For Each sSkill In Range("A:A")
If UCase(sSkill) Like UCase(strSuchwort) Then
sDate = Right(sSkill, 10)
For Each stype In Range(sSkill.Offset(1, 0), sSkill.Offset(1, 100))
If UCase(stype) Like UCase(strSuchwort1) Then
Range(stype.Offset(1, 0), stype.End(xlDown)).copy
For Each pval In sh.Range("1:1")
If pval = sDate Then
col = pval.Column
row = lstZelle.row
sh.Cells(row, col).PasteSpecial xlPasteValues
End If
Next pval
End If
Next stype
End If
Next sSkill
End If
Next asheet
End If
Next lstZelle1
End If
Next lstZelle
bk.Close SaveChanges:=False
sName = Dir()
Loop
Application.ScreenUpdating = True
sh.AutoFilterMode = False
End Sub

Related

VBA Writing IFERROR to Multiple Cells with For...Next Loop

I am trying to apply "=IFERROR" to a spreadsheet containing over 1000 rows of data. I already came up with a way to make the entries hard-coded. But is there a way to fill the cells with something like "=IFERROR(IFERROR(A1,B1),"")" rather than the value? Below is the hard-coded version:
Sub HardCodeIFERROR()
Dim a As Integer, xRecordCount1 As Integer
Set w(1) = Sheets("ABC")
xRecordCount1 = w(1).Cells(Rows.Count, 1).End(xlUp).Row
For a = 1 To xRecordCount1
w(1).Cells(a, 3).Value = Application.WorksheetFunction.IfError(Application.WorksheetFunction.IfError(Range("A" & a), Range("B" & a)), "")
Next a
Exit Sub
End Sub
Thank you in advance for your help!
You can instead just use .Formula:
w(1).Cells(a, 3).Formula = "=IFERROR(IFERROR(A" & a & ",B" & a & "),"""")"
Note you can skip the loop and just use a range:
Sub HardCodeIFERROR()
Dim ws1 As Worksheet
Dim a As Integer, xRecordCount1 As Integer
Set ws1 = Sheets("Sheet1")
xRecordCount1 = ws1.Cells(ws1.Rows.Count, 1).End(xlUp).Row
With ws1
.Range(.Cells(1, 3), .Cells(xRecordCount1, 3)).FormulaR1C1 = "=IFERROR(IFERROR(RC[-2],RC[-1]),"""")"
End With
End Sub
Note: Make sure to use the sheet with the Rows.Count whenever you use it, just like you do with Cells() and Range(). Also, I changed the sheet name because I wasn't sure if you intended to do a Sheet Array or not, so I used a more clear (IMO) variable name.
Just use the Formula property:
Sub HardCodeIFERROR()
Dim a As Integer, xRecordCount1 As Integer
'Need to declare the size of the array if you are going to assign worksheets to "w(1)"
Dim w(1 To 1) As Worksheet
Set w(1) = Sheets("ABC")
'Ensure you fully qualify "Rows.Count" by specifying which worksheet you are referring to
xRecordCount1 = w(1).Cells(w(1).Rows.Count, 1).End(xlUp).Row
'Apply formula to all cells
w(1).Range("C1:C" & xRecordCount1).Formula = "=IFERROR(IFERROR(S1,V1),"""")"
End Sub

VBA Returns Error after Range.Find finds nothing

I have two worksheets in Excel, New Sheet and Old Sheet. I am trying to search in Column A of Old Sheet if the column contains each of the entries of Column A of New Sheet. I am using the following VBA code to search, but it returns an error on the second search (the non column header search). I have no idea what I'm doing wrong - any help is appreciated. Here is my code:
Sub Sample()
Dim lastRow As Integer
Dim i As Integer
Dim rng As Range
Dim searchrng As Range
Dim searchval As String
lastRow = Sheets("New One").Range("A65000").End(xlUp).Row
Sheets("Old One").Activate
Set searchrng = Sheets("Old One").Range("A1:A10000")
For i = 1 To lastRow
Sheets("New One").Activate
searchval = Sheets("New One").Cells(i, 1).Value
Set rng = searchrng.Find(searchval)
If Not rng Is Nothing Then
MsgBox "Found " & searchval & " in " & rng.Address
Else
Sheets("New One").Activate
Sheets("New One").Cells(i, 1).EntireRow.Interior.Color = vbRed
End If
Next i
End Sub
The error is always Run-time error '1004' - Method 'Find' of object 'Range' failed.
Avoid using .Select
Sub Sample()
Dim lastRow As Integer
Dim i As Integer
Dim rng As Range
Dim searchrng As Range
Dim searchval As String
Dim oldWS As Worksheet, newWS As Worksheet
Set oldWS = Worksheets("Old One")
Set newWS = Worksheets("New One")
lastRow = newWS.Range("A65000").End(xlUp).Row
Set searchrng = oldWS.Range("A1:A10000")
For i = 1 To lastRow
searchval = newWS.Cells(i, 1).Value
Set rng = searchrng.Find(searchval)
If Not rng Is Nothing Then
MsgBox "Found " & searchval & " in " & rng.Address
Else
newWS.Cells(i, 1).EntireRow.Interior.Color = vbRed
End If
Next i
End Sub
Does that work for you? I tested it in mine and it worked. Make sure the ranges you give are correct.
But, I agree with #ScottHoltzman - you can do this with Conditional Formatting, avoiding the use of VBA.
Thanks to everyone for the help.
I was able to get it to work by conditional formatting, thanks to Scott Holtzman for the idea. In the end, I used COUNTIF however, instead of IsError.
=COUNTIF('Old One'!$A:$A, 'New One'!$A1)=1
applied to Column A in 'New One' Worksheet.

Looping through all worksheets VBA

I am trying to loop through all the worksheets in the activeworkbook to perform a repetitive task.
I currently have the code below:
Sub sort_sectors()
Dim i As Integer
Dim rng As Range
Dim SortRng As Range
Dim rng1 As Integer
Dim ws As Worksheet
Dim wb As Workbook
Dim LastCol As Long
Dim LastRow As Long
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
'This is marking several of the sheets of which I do not want to run the sub
If ws.Range("a9").Value = "x" Then
NextIteration:
End If
'Reference point is rng1 to select the desired range
With Range("a1:t100")
rng1 = .Find(what:="sector", LookIn:=xlValues).Row
End With
'return the row number for the sector header
LastCol = ws.Cells(20, ws.Columns.Count).End(xlToLeft).Column
LastRow = ws.Range("a15").End(xlDown).Row
'I am going to add the code below to finish out the task that I want to complete
Next
End Sub
I am sure the problem is that I'm misunderstanding something about how the for each loop actually works. Hopefully someone's answer will allow to better understand.
I really appreciate any help on this.
I made some edits to the code, and now I actually do have an error :) I tried making the changes you suggested for the "with ws.range etc..." piece of the code, and I get the object error 91.
Below is my new and "improved" code.
Sub sort_sectors()
Dim i As Integer
Dim rng As Range
Dim SortRng As Range
Dim intAnchorRow As Integer
Dim intMktCapAnchor As Integer
Dim intSectorAnchor As Integer
Dim ws As Worksheet
Dim wb As Workbook
Dim LastCol As Long
Dim LastRow As Long
Set wb = ActiveWorkbook
For Each ws In ActiveWorkbook.Worksheets
'Filter out the sheets that we don't want to run
If ws.Range("a9").Value <> "x" Or ws.Name = "__FDSCACHE__" Or ws.Name = "INDEX" Then
'Get the anchor points for getting sort range and the sort keys
''''''THIS IS THE PART THAT IS NOW GIVING ME THE ERROR'''''''
With ws.Range("a1:t100")
intAnchorRow = .Find(what:="sector", LookIn:=xlValues).Row
intSectorAnchor = .Find(what:="sector", LookIn:=xlValues).Column
intMktCapAnchor = .Find(what:="Market Cap", LookIn:=xlValues).Column
End With
'Find the last row and column of the data range
LastCol = ws.Cells(20, ws.Columns.Count).End(xlToLeft).Column
LastRow = ws.Range("a15").End(xlDown).Row
Set SortRng = Range(Cells(intAnchorRow + 1, 1), Cells(LastRow, LastCol))
Range(SortRng).Sort key1:=Range(Cells(intAnchorRow + 1, intSectorAnchor), Cells(LastRow, intSectorAnchor)), _
order1:=xlAscending, key2:=Range(Cells(intAnchorRow + 1, intMktCapAnchor), Cells(LastRow, intMktCapAnchor)), _
order2:=xlDescending, Header:=xlNo
End If
Next
End Sub
Thanks again. This has been very helpful for me.
If I've understood your issue correctly, you don't want to use a worksheet with an x in cell A9.
If that's the case I would change the condition of the if statement to check if the cell does not contain the x. If this is true, it enters the rest of the code. If not, it goes to the next iteration.
Also, your NextIteration: doesn't do anything in the If statement.
Sub sort_sectors()
Dim i As Integer
Dim rng As Range
Dim SortRng As Range
Dim rng1 As Integer
Dim ws As Worksheet
Dim wb As Workbook
Dim LastCol As Long
Dim LastRow As Long
Set wb = ActiveWorkbook
For Each ws In wb.Worksheets
'This is marking several of the sheets of which I do not want to run the sub
If ws.Range("a9").Value <> "x" Then
'Reference point is rng1 to select the desired range
With Range("a1:t100")
rng1 = .Find(what:="sector", LookIn:=xlValues).Row
End With
'return the row number for the sector header
LastCol = ws.Cells(20, ws.Columns.Count).End(xlToLeft).Column
LastRow = ws.Range("a15").End(xlDown).Row
'I am going to add the code below to finish out the task that I want to complete
End If
Next
End Sub
The : operator is used to return the code to that line after a goto call.
For example
sub gotoEx()
for i = 1 to 10
if i = 5 then
goto jumpToHere
end if
next i
jumpToHere: '<~~ the code will come here when i = 5
'do some more code
end sub
And of course you can use this structure in your code if you wish, and have the jumpToHere: line just before the next
e.g.
for each ws in wb.Worksheets
if ws.Range("a9").Value = "x" then
goto jumpToHere
end if
'the rest of your code goes here
jumpToHere:
next

Subscript Out of Range Error in Code

I have a macro that moves data from a master sheet to their respective sheets in a workbook by group and then creates a separate workbook of each of those sheets... But I have been getting an error and don't remember having changed anything on it. Can someone let me know what is wrong and how to fix it?
Subscript out of range error in line starting with Activeworkbook.SaveAs...
Sub transfer_data()
Application.ScreenUpdating = False
Dim filter_criteria As String
Dim bridge_rows As Integer
Dim rng As Range
Dim rng2 As Range
Dim dest_num_rows As Integer
bridge_rows = Worksheets("Bridge").Range("A1").CurrentRegion.Rows.Count
Set rng = Worksheets("Master").Range("A6").CurrentRegion
For n = 3 To bridge_rows + 1
filter_criteria = Application.WorksheetFunction.Index(Worksheets("Bridge").Range("A1:B" & bridge_rows), Application.WorksheetFunction.Match(Worksheets(n).Name, Worksheets("Bridge").Range("B1:B" & bridge_rows), 0), 1)
dest_num_rows = Worksheets(n).Range("A1").CurrentRegion.Rows.Count
rng.AutoFilter Field:=7, Criteria1:=filter_criteria
Set rng2 = rng.Offset(1, 0).Resize(rng.Rows.Count - 1, 6)
rng2.Copy Destination:=Worksheets(n).Range("A" & dest_num_rows + 1)
Workbooks.Add
ActiveWorkbook.SaveAs Filename:="H:\BX-HR\BX-INDUSTRIAL RELATIONS\HR REPRESENTATIVES\PRIVATE\HRSSC\US&CA Benefits\Data Files\" & Workbooks("Retroactive Premiums - Semi-monthly v2.xlsm").Worksheets(n).Name, FileFormat:=xlCSV, CreateBackup:=False
ThisWorkbook.Sheets(n).Range("A1").CurrentRegion.Copy Destination:=ActiveWorkbook.Worksheets(1).Range("A1")
ActiveWorkbook.Close savechanges:=True
Next n
rng.AutoFilter
Worksheets("Master").Range("A7:A" & rng.Rows.Count + 5).Clear
Worksheets("Master").Range("D7:D" & rng.Rows.Count + 5).Clear
Application.ScreenUpdating = True
End Sub
Your error must be related to this part of the line that's giving you the error:
Workbooks("Retroactive Premiums - Semi-monthly v2.xlsm").Worksheets(n)
There are two reasons for this to give an error:
Workbooks("Retroactive Premiums - Semi-monthly v2.xlsm"): a workbook with the specified name is not currently open.
Worksheets(n): the specified workbook with that name is open but it doesn't have a sheet with the n index.
This is one main reason why one should declare variables/objects and work with them :) Things like Activeworkbook/Select etc should be avoided.
You should be use the code like this
Sub Sample()
Dim wbThis As Workbook, wbNew As Workbook
Dim sPath As String
sPath = "H:\BX-HR\BX-INDUSTRIAL RELATIONS\HR REPRESENTATIVES\PRIVATE\HRSSC\US&CA Benefits\Data Files\"
Set wbThis = ThisWorkbook '<~~ "Retroactive Premiums - Semi-monthly v2.xlsm" ???
'
'~~> Rest of the code
'
Set wbNew = Workbooks.Add
wbNew.SaveAs Filename:=sPath & wbThis.Worksheets(n).Name, FileFormat:=xlCSV, CreateBackup:=False
'
'~~> Rest of the code
'
End Sub

Copy and Paste Loop based on Cell value

Created a macro below thanks to help from another that works.
Basically, it takes the value of the cell in column A and, if a sheet doesn't exist with that cells name, creates it. Then it pastes all rows of data that have the corresponding cell value to that sheet. Ie. if a cell contains the following:
column a column b
dc00025 data value
If dc00025 doesn't exist, it'll make the sheet. And paste all rows with dc00025 in A.
This works perfectly. However, I noticed when you run this macro after a sheet has already been created, for some reason it adds thousands of columns dramatically slowing down excel.
To fix this, would it be possible to modify the script to only copy columns b:o rather tahnt he entire row? Pasting them starting at A3 would be preferable but I'm not sure how to fix that.
Thanks in advance.
Sub CopyCodes()
Application.ScreenUpdating = False
Dim rCell As Range
Dim lastrow As Long
lastrow = Sheets("Data").UsedRange.Rows.Count
For Each rCell In Worksheets("Data").Range("A2:A" & lastrow).SpecialCells(xlCellTypeConstants)
If Not SheetExists(rCell.Value) Then
With Worksheets.Add(, Worksheets(Worksheets.Count))
.Name = rCell.Value
End With
End If
Worksheets("Data").Rows(1).EntireRow.Copy Worksheets(rCell.Value).Rows(1)
Worksheets(rCell.Value).Range("A" & Rows.Count).End(xlUp)(2).EntireRow.Value = _
rCell.EntireRow.Value
Next rCell
Application.ScreenUpdating = True
End Sub
Function SheetExists(wsName As String)
On Error Resume Next
SheetExists = Worksheets(wsName).Name = wsName
End Function
Suggested fix:
Sub CopyCodes()
Application.ScreenUpdating = False
Dim rCell As Range
Dim lastrow As Long
Dim shtData as worksheet, shtDest as worksheet
Dim sheetName as string
set shtData=worksheets("Data")
lastrow = shtData.cells(rows.count,1).end(xlup).row
For Each rCell In shtData.Range("A2:A" & lastrow).SpecialCells(xlCellTypeConstants)
sheetName = rCell.Value
If Not SheetExists(sheetName) Then
set shtDest = Worksheets.Add(, Worksheets(Worksheets.Count))
shtDest.Name = sheetName
shtData.Rows(1).EntireRow.Copy shtDest.Rows(1)
Else
set shtDest = Worksheets(sheetName)
End If
shtDest.Range("A" & Rows.Count).End(xlUp).offset(1,0).EntireRow.Value = _
rCell.EntireRow.Value
Next rCell
Application.ScreenUpdating = True
End Sub