2017-05-12 28 views
7

Ai đó có thể cho tôi biết lý do tại sao tôi nhận được lỗi 1004 trên mã sau không?VBA 1004 Lỗi khi thực hiện vòng lặp của Macro

Nếu đó là không rõ ràng, tôi đang cố gắng để lặp tất cả các tờ mà không phải là tên của tôi tờ và cố gắng chọn một phạm vi cụ thể và sao chép và dán nó vào biên soạn "Tấm Quant"

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 
+6

Bạn không thể chọn ô cho đến khi bạn kích hoạt trang tính chính. Sử dụng 'ws.activate' trước' AB $ 2: AE "& lastRowSF' Một khi nó làm việc hãy xem [Cách tránh sử dụng Chọn trong macro Excel VBA] (http://stackoverflow.com/questions/10714251/how- to-avoid-using-select-in-excel-vba-macros) – Jeeped

Trả lời

6

Bạn đặt WS làm Worksheets("Quant Sheet") nhưng sau đó sử dụng cùng một biến ws để sử dụng trong vòng lặp của bạn. Điều đó có thể gây ra vấn đề.

Hãy thử điều này:

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 

Chủ yếu, bạn muốn avoid using .Select/.Activate để chắc chắn rằng bạn làm việc trực tiếp hơn với dữ liệu.

Chỉnh sửa: FYI bạn có thể tiếp tục làm điều này năng động hơn bằng cách không sử dụng một cái gì đó như y=y+1 và thay vào đó sử dụng offset hoặc biến số lastRow, nhưng đó là sở thích cá nhân vì nó sẽ thực hiện điều tương tự. (Tôi cũng giả định các x, a, và b biến được sử dụng ở những nơi khác trong macro của bạn ...

+1

'ws.Range (" A3 ") Sao chép đích: = mainWS.Cells (y, 1)' .Paste là một phương thức trang tính, không phải là phạm vi phương pháp. – Jeeped

+0

@Jeeped - D'oh, cảm ơn vì đã sửa lỗi đó, tôi cũng nhận thấy nó. – BruceWayne

+0

Vâng, tôi không thể upvote bạn trong hình thức ban đầu và tôi đã hứa với con chó của tôi một cheeseburger vì vậy tôi phải đi. – Jeeped

3

As was already stated, bạn có thể không .Select một tế bào trên một bảng tính bạn đã không được gọi .Activate trên đầu tiên - đó sẽ sửa chữa vấn đề, nhưng để lại cho bạn yếu đuối & chậm .Select.Activate cuộc gọi ở khắp mọi nơi Thay vào đó, lặp bộ sưu tập Worksheets với một vòng lặp For Each, vì vậy bạn sẽ có được một đối tượng Worksheet để làm việc với mỗi lần lặp.

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 

Ngoài các câu trả lời hay và nhận xét đã được cung cấp, bạn có thể làm gọn mã của mình rất nhiều.

  • Thụt lề là khóa. Bạn có thể tránh được vô số lỗi chỉ bằng cách dán vào các vết lõm đơn giản
  • Xóa tất cả các biến không sử dụng đó (trừ khi bạn sử dụng chúng sau này và không hiển thị cho chúng tôi!)
  • Thay vì sao chép và dán sử dụng .Value. Nó nhanh hơn và tốt hơn
  • Tránh SelectActivate càng nhiều càng tốt, như đã được chỉ ra. Điều đó bao gồm ActiveSheetActiveWorkbook
  • Cung cấp cho các biến của bạn những tên tốt, có ý nghĩa và mã của bạn gần như sẽ được đọc như một cuốn tiểu thuyết VBA geeky. Bằng cách đó bạn sẽ luôn luôn biết những gì đang xảy ra.

Đăng mã làm việc của bạn trên Code Review Stack Exchange để xem xét toàn diện ngang hàng.

+0

Tôi nhận ra mình có rất nhiều việc phải làm! – Bez

Các vấn đề liên quan