Home » excel » excel – VBA 1004 Error on Loop execution of Macro

excel – VBA 1004 Error on Loop execution of Macro

Posted by: admin March 9, 2020 Leave a comment

Questions:

Can anybody give me a sense of why I’d be receiving a 1004 error on the following code?

If it’s not clear, I’m trying to loop all sheets that are not my named sheet and try to select a particular range and copy and paste it to the compiled “Quant Sheet”

Dim ws As Worksheet
Dim x As Integer 
Dim y As Integer
Dim a As Integer
Dim b As Integer
Set ws = Worksheets("Quant Sheet")
x = 1
y = 3
a = 3
b = 2

Worksheets("Quant Sheet").Activate
For Each ws In ActiveWorkbook.Worksheets
If (ws.Name <> "Quant Sheet") Then

   ws.Range("A3").Select
   Selection.Copy
   Sheets("Quant Sheet").Select
   Cells(y, 1).Select
   ActiveSheet.Paste
   y = y + 1


End If

Next ws
How to&Answers:

You set WS as Worksheets("Quant Sheet") but then use that same variable ws to use in your loop. That may be causing the issue.

Try this:

Dim ws As Worksheet, mainWS As Worksheet
Dim x As Integer, y As Integer, a As Integer, b As Integer
Set mainWS = Worksheets("Quant Sheet")
x = 1
y = 3
a = 3
b = 2

For Each ws In ActiveWorkbook.Worksheets
If (ws.Name <> "Quant Sheet") Then
   ws.Range("A3").Copy Destination:=mainWS.Cells(y, 1)
   y = y + 1
End If

Next ws

Mainly, you want to avoid using .Select/.Activate to make sure you work more directly with the data.

Edit: FYI you can likely further make this more dynamic by not using something like y=y+1 and instead use offset, or a lastRow variable, but that’s personal preference as it’ll accomplish the same thing. (I’m also assuming the x, a, and b variables are used elsewhere in your macro…

Answer:

As was already stated, you can’t .Select a cell on a worksheet you haven’t called .Activate on first – that would fix the problem, but leave you with frail & slow .Select and .Activate calls everywhere. Instead, iterate the Worksheets collection with a For Each loop, so you get a Worksheet object to work with each iteration:

Sub test()
    Dim quantSheet As Worksheet, tempSheet as Worksheet
    Dim i As Integer

    Set quantSheet = ThisWorkbook.Worksheets("Quant Sheet")
    i = 3

    For Each tempSheet In ThisWorkbook.Worksheets
        If tempSheet.Name <> quantSheet.Name Then
            quantSheet.Cells(i, 1).Value = tempSheet.Range("A3").Value
            i = i + 1
        End If
    Next tempSheet
End Sub

Further to the good answers and comments already provided, you can neaten up your code a lot.

  • Indentation is key. You can avoid loads of errors just by sticking to simple indentation
  • Remove of all those unused variables (unless you’re using them later and haven’t shown us!)
  • Rather than copying and pasting, set your values directly using .Value. It’s quicker and better
  • Avoid Select and Activate as much as possible, as has already been pointed out. That includes ActiveSheet and ActiveWorkbook
  • Give your variables good, meaningful names and your code will almost read like a geeky VBA novel. That way you’ll always know what’s going on.

Post your working code on Code Review Stack Exchange for a full-blown peer review.