Vba 对于每个Ws循环,不切换工作表

Vba 对于每个Ws循环,不切换工作表,vba,excel,Vba,Excel,我有一个小宏,用来将数据从Book1的工作表1复制/粘贴到新的工作簿Book2。之后,我希望它循环遍历Book1中的其余工作表,并复制/粘贴到Book2中,但不包含标题 下面的宏完成了第一步,但每次都会继续复制/粘贴工作表1中的记录,而不是切换工作表以复制/粘贴新数据 Sub CopyData() ' Copy A:D from all sheets to template Dim ws As Worksheet Dim sheetIndex As Integer sheetIndex =

我有一个小宏,用来将数据从Book1的工作表1复制/粘贴到新的工作簿Book2。之后,我希望它循环遍历Book1中的其余工作表,并复制/粘贴到Book2中,但不包含标题

下面的宏完成了第一步,但每次都会继续复制/粘贴工作表1中的记录,而不是切换工作表以复制/粘贴新数据

Sub CopyData()

' Copy A:D from all sheets to template

Dim ws As Worksheet
Dim sheetIndex As Integer

sheetIndex = 1

'First Sheet pulls in headers and data

    Windows("Book1.xlsx").Activate
    Sheets(1).Select
    Range("A1:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy
    Windows("Book2.xlsm").Activate
    ActiveSheet.Paste
    Windows("Book1.xlsx").Activate

'Every other worksheet only copies over data

For Each ws In ActiveWorkbook.Worksheets
   If ws.Index <> 1 Then
    Windows("Book1.xlsx").Activate
    Range("A2:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy
    Windows("Book2.xlsm").Activate
    Range("A1").End(xlDown).Offset(1).Select
    ActiveSheet.Paste
   End If
    sheetIndex = sheetIndex + 1
Next ws
End Sub
我不是很有经验,所以如果上面的代码没有优化,我很抱歉。提前感谢您的帮助

快速且非常脏的解决方案:

For Each ws In ActiveWorkbook.Worksheets
    ws.Activate
    'rest of the code
Next ws

如果您将工作簿分配给一个变量并在工作表中循环,而不使用Activate和Select,这会更好。

您就快到了,但您需要具体说明要处理哪些工作表和工作簿。此外,您不需要选择它们进行复制/粘贴

假设要粘贴到Book2.xlsm中的工作表是Sheet1:

Sub CopyData()

' Copy A:D from all sheets to template

Dim ws As Worksheet, ws2 as worksheet
Dim sheetIndex As Integer
Dim wb1 as workbook, wb2 as workbook

Set wb1 = Workbooks("Book1.xlsx")
set wb2 = Workbooks("Book2.xlsx")

Set ws = wb1.sheets(1)
set ws2 = wb2.sheets(2)


'First Sheet pulls in headers and data

 ws.Range("A1:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy ws2.range("A1")

'Every other worksheet only copies over data

For Each ws In wb1
   If ws.Index <> 1 Then
       ws.Range("A2:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy ws2.Range("A1").End(xlDown).Offset(1,0)
   End If
Next ws

End Sub

要实现这样的目标,您必须知道如何初始化工作簿和工作表。请抽出时间研究如何在vba中初始化对象,因为这将在将来对您有所帮助

 Sub CopyData()

' Copy A:D from all sheets to template

Dim ws As Worksheet
Dim sheetIndex As Integer
Dim wbBook1 As Workbook, wbBook2 As Workbook

sheetIndex = 1

'First Sheet pulls in headers and data
Set wbBook1 = ThisWorkbook              'The Workbook where we will copy the data;     This contains the macro
Windows("Book2.xlsx").Activate          'Because we don't know the book name we will just activate it to initialize
                                    'the second workbook where we will copy our data from Book1
Set wbBook2 = ActiveWorkbook

'Every other worksheet only copies over data

'Now that we initialize our two workbooks we will now copy it in the corresponding sheets

For Each ws In wbBook1.Worksheets
    With ws
        If ws.Index = 1 Then
         .Range("A2:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy wbBook2.Sheets(1).Range("A1")

        Else:
            sheetIndex = sheetIndex + 1
            wbBook2.Worksheets.Add After:=wbBook2.Sheets(sheetIndex - 1) 'Add additional worksheet on the end to paste our other data
            .Range("A2:D" & Cells(Rows.Count, "C").End(xlUp).Row).Copy wbBook2.Sheets(sheetIndex).Range("A1")

        End If
    End With
Next ws
End Sub

使用“选择”和“不合格范围”、“工作表”等会产生错误,尤其是在处理多个工作簿和工作表时。相反-使用工作表和工作簿变量并正确限定所有范围。谢谢你,约翰,我会查一查的。真不敢相信我忘了把它加进去。现在可以工作了,谢谢!当你说不使用激活和选择时,你能详细说明吗?我不是还需要说variable.Activate才能回到正确的工作簿吗?抱歉技能差:@Matt-阅读约翰·科尔曼评论中的链接。这里有很好的解释。关于@Vitaya所说的例子,请参见下面我的答案about@Matt显然,提供这个答案仅仅是为了完整性。沿着这条路走下去,你会保留你危险的容易出现bug的隐式ActiveSheet引用,只会把问题推迟到下次它们咬你的时候……后端。不要这样做。“选择和激活”用于宏录制器代码,而不是您键入的内容。@MathieuGuindon谢谢Mathieu,我是新来的,所以以前从宏录制器获得了我的临时代码。很高兴知道我可以改进它:我同意。随着时间的推移,我需要更好地理解vba,而不是通过其他例子拼凑起来。感谢对苦艾酒的了解。快速提问-我在脚本中没有看到ws1集,但它在For-Each循环中,这应该只是“ws”吗?