[英]Excel VBA: Opening Workbooks and Copying Cells
下面的宏从列表中打开一系列工作簿,然后从中复制一些数据。 它在第一个工作簿上正常工作,然后在第二个工作簿上崩溃。 我尝试过更改顺序,它始终是导致其崩溃的第二个工作簿。
Sub ImportData()
Dim lastRow As Long
Dim lastSumRow As Long
Dim j As Long
Dim k As Long
With ActiveSheet
lastRow = ActiveSheet.Cells(1048576, 1).End(xlUp).Row
End With
For k = 2 To lastRow
k = 2
lastUsedRow = ThisWorkbook.Sheets("Summary").Cells(1048576, 1).End(xlUp).Row
If ActiveSheet.Cells(k, 2).Value <> "Imported" Then
Workbooks.Open Filename:=ThisWorkbook.Path & "\Analysis\" & Cells(k, 1), UpdateLinks:=False
ActiveWorkbook.Sheets("Summary").Activate
For j = 3 To 100
If j Mod 3 = 0 Then
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 1).Value = ActiveWorkbook.Sheets("Summary").Cells(j, 1).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 2).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 1, 2).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 3).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 1, 3).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 4).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 1, 4).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 5).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 2, 2).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 6).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 2, 3).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 7).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 2, 4).Value
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 8).Value = ActiveWorkbook.Sheets("Summary").Cells(j + 1, 5).Value
End If
Next j
ActiveWorkbook.Close
End If
ThisWorkbook.Sheets("Setup").Cells(k, 2).Value = "Imported"
Next k
End Sub
我猜你的错误在这里:
Workbooks.Open Filename:=ThisWorkbook.Path & "\\Analysis\\" & Cells(k, 1), UpdateLinks:=False 'Ooops ^^^^^
该.Activate
和.Select
呼叫进行卷积足够,我不是真的要花费精力搞清楚什么应该是在你的代码通过循环第二次运行特定点活动工作表。 不管它是什么,它都与您开始时不同,并且对Cells
的无条件调用隐式地引用了当时是ActiveSheet
任何工作表。 这将生成错误的文件名(或完全失败),然后滚轮脱落。
最好的办法是根本不使用Active*
对象。 获取对您正在使用的对象的引用,然后使用它们。 这样,您就不会有电线交叉的可能性。 在查看时,您可以给他们命名,使您一眼就能清楚地看到正在使用的内容。
在获得不使用Activate
和Select
的代码之前,请结合其他因素。
lastSumRow
是从来没有使用过lastUsedRow
从未声明。 我假设他们应该是同一回事。 您应该将Option Explicit
放在模块的顶部,以避免此类错误(甚至更糟)。
这两行代码在一起几乎没有什么意义:
For j = 3 To 100 If j Mod 3 = 0 Then
如果您只想复制每第3行,请跳过所有除法,仅以3 Step
递增循环计数器:
For j = 3 To 99 Step 3
请注意,您可以在99处停止,因为100 Mod 3
永远不会为0
。
您的With
块此处未使用捕获的参考...
With ActiveSheet lastRow = ActiveSheet.Cells(1048576, 1).End(xlUp).Row End With
...但是您一直使用在With
块中有用的这种模式:
ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 1).Value = ... ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 2).Value = ... ThisWorkbook.Sheets("Summary").Cells((j / 3) + lastUsedRow, 3).Value = ...
硬编码Cells(1048576, 1)
在旧版本的Excel上将失败。 您应该改用Rows.Count。
如评论中所述, k = 2
创建一个无限循环。
您无需使用以下代码重复查找要复制到的工作表的最后一行:
lastUsedRow = ThisWorkbook.Sheets("Summary").Cells(1048576, 1).End(xlUp).Row
每次您执行“ j
”循环时,最后一行将增加一。 只需将1加到lastUsedRow
而不是对所有的体操进行计数。
如果您正在使用Worksheets
,请使用Worksheets
集合而不是Sheets
集合:
ThisWorkbook.Sheets("Summary") '<--I could return a Chart!
将所有这些放在一起,您将得到类似于以下代码的内容。 请注意,当您启动此宏时,我不知道ActiveSheet
应该是什么,因此我只是将其命名为存储在active
的变量。 它很可能也是它也获得参考的其他工作表之一(我不知道)-如果是这样,您应该将它们合并为一个参考:
Public Sub ImportData()
Dim lastRow As Long
Dim lastUsedRow As Long
Dim dataRow As Long
Dim fileNameRow As Long
Dim active As Worksheet
Set active = ActiveSheet
With active
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
End With
Dim setupSheet As Worksheet
Set setupSheet = ThisWorkbook.Worksheets("Setup")
With ThisWorkbook.Worksheets("Summary")
lastUsedRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For fileNameRow = 2 To lastRow
If active.Cells(fileNameRow, 2).Value <> "Imported" Then
Dim source As Workbook
Set source = Workbooks.Open(ThisWorkbook.Path & "\Analysis\" & _
active.Cells(fileNameRow, 1), False)
Dim dataSheet As Worksheet
Set dataSheet = source.Worksheets("Summary")
For dataRow = 3 To 99 Step 3
.Cells(lastUsedRow, 1).Value = dataSheet.Cells(dataRow, 1).Value
.Cells(lastUsedRow, 2).Value = dataSheet.Cells(dataRow + 1, 2).Value
.Cells(lastUsedRow, 3).Value = dataSheet.Cells(dataRow + 1, 3).Value
.Cells(lastUsedRow, 4).Value = dataSheet.Cells(dataRow + 1, 4).Value
.Cells(lastUsedRow, 5).Value = dataSheet.Cells(dataRow + 2, 2).Value
.Cells(lastUsedRow, 6).Value = dataSheet.Cells(dataRow + 2, 3).Value
.Cells(lastUsedRow, 7).Value = dataSheet.Cells(dataRow + 2, 4).Value
.Cells(lastUsedRow, 8).Value = dataSheet.Cells(dataRow + 1, 5).Value
lastUsedRow = lastUsedRow + 1
Next
source.Close
End If
setupSheet.Cells(fileNameRow, 2).Value = "Imported"
Next
End With
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.