[英]Why am I getting a “Script out of range” error while running the vba code for “For Loop” to copy data?
Sub GenerateProductionReport() '*Let’s define the variables* Dim GCell As Range Dim Txt$, MyPath$, MyWB$, MySheet$ Dim myValue As Integer Dim Number As Integer Dim cmdprodhrsreport As Long Dim LastRow As Long Dim r As Long Dim LastRowRpt As Long '*Search what* MyPath = "\\Mypath\xxx\xxx\xxx\" '*The name of the workbook to be searched* MyWB = "Daily Data Tracker.xlsx" Workbooks.Open FileName:=MyPath & MyWB LastRow = Worksheets("Sheet1").Range("A" & Rows.count).End(xlUp).Row '*Use the current sheet to store the found data* For r = 2 To LastRow 'In ThisWorkbook.Worksheets If Worksheets("Sheet1").Range("D" & r).Value = Adminaccess.txtstartdate.Value Then'problem here for next r Worksheets("Sheet1").Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy Application.ScreenUpdating = False ThisWorkbook.Worksheets("Production").Activate '*Range("A2:K99999").ClearContents* MySheet = ActiveSheet.Name '*Range("A2:K99999").ClearContents* LastRowRpt = Worksheets("Production").Range("A" & Rows.count).End(xlUp).Row Worksheets("Production").Range("A" & LastRowRpt + 1).Select ActiveSheet.Paste End If Next r 'ThisWorkbook.Worksheets("Sheet1").SetFocus '*Close data workbook; don’t save it; turn screen updating back on* ActiveWorkbook.Close savechanges:=False Application.ScreenUpdating = True Exit Sub End Sub
Because of ThisWorkbook.Worksheets("Production").Activate
in the loop, at next iteration Worksheets("Sheet1")
will belong to ThisWorkbook
.由于
ThisWorkbook.Worksheets("Production").Activate
在循环中,在下一次迭代Worksheets("Sheet1")
将属于ThisWorkbook
。
To be/remain the one belonging to MyWB
, like I suppose, you must use at the beginning of the code:要成为/保持属于
MyWB
的那个,就像我想的那样,您必须在代码的开头使用:
Dim sh1 as Worksheet
and after MyWB
opening Set sh1 = Worksheets("Sheet1")
在
MyWB
打开Set sh1 = Worksheets("Sheet1")
followed by LastRow = sh1.Range("A" & Rows.count).End(xlUp).Row
.其次是
LastRow = sh1.Range("A" & Rows.count).End(xlUp).Row
。
Then, change the problematic line in然后,将有问题的行更改为
sh1.Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy
"Subcript out of range" (run-time error 9) is a common error that means you're trying to retrieve an item from an array or collection, using a subscript that doesn't exist in that array/collection. “下标超出范围”(运行时错误 9)是一个常见错误,这意味着您正在尝试使用该数组/集合中不存在的下标从数组或集合中检索项目。
Dim things(0 To 9) As Long
things(10) = 42 '<~ "subscript out of range"
The Excel object model raises that error when you try to retrieve a Worksheet
from a Sheets
collection by name, but the specified sheet doesn't exist in the supplied Sheets
collection.当您尝试按名称从
Sheets
集合中检索Worksheet
时,Excel object model 会引发该错误,但指定的工作表在提供的Sheets
集合中不存在。
ActiveWorkbook.Worksheets("boom") '<~ if sheet is not in ActiveWorkbook sheets, error 9 is raised.
The trick is to always be explicit about what objects belong to what.诀窍是始终明确哪些对象属于什么。 For example:
例如:
Workbooks.Open FileName:=MyPath & MyWB LastRow = Worksheets("Sheet1").Range("A" & Rows.count).End(xlUp).Row
Here we're explicit about what Worksheet
this Range
call should work with (but Rows
is implicitly qualified with the ActiveSheet
), but the Worksheets
collection is implicitly referring to whatever the ActiveWorkbook
is.在这里,我们明确说明了此
Range
调用应使用的Worksheet
(但Rows
隐含地使用ActiveSheet
限定),但Worksheets
集合隐含地引用ActiveWorkbook
的任何内容。 That works, because by then we've just opened a workbook so that workbook must be active!这行得通,因为那时我们刚刚打开了一个工作簿,因此该工作簿必须处于活动状态!
Workbooks.Open
is a function that returns a reference to the opened Workbook
object. Workbooks.Open
是一个function ,它返回对打开的Workbook
object 的引用。 Consider capturing that reference and removing the implicit reliance on the function's side-effects:考虑捕获该引用并消除对函数副作用的隐含依赖:
Dim book As Workbook
Set book = Application.Workbooks.Open(MyPath & MyWB)
So here:所以在这里:
'*Use the current sheet to store the found data* For r = 2 To LastRow 'In ThisWorkbook.Worksheets If Worksheets("Sheet1").Range("D" & r).Value = Adminaccess.txtstartdate.Value Then'problem here for next r Worksheets("Sheet1").Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy
If the intent is to iterate rows in ThisWorkbook
, that's not what's happening here, because If Worksheets("Sheet1")...
isn't explicit about what workbook it's working against, so if the ActiveWorkbook
isn't ThisWorkbook
and there's no worksheet named "Sheet1" in there, that throws error 9.如果意图是迭代
ThisWorkbook
中的行,那不是这里发生的事情,因为If Worksheets("Sheet1")...
没有明确说明它正在处理的工作簿,所以如果ActiveWorkbook
不是ThisWorkbook
并且没有工作表在那里命名为“Sheet1”,会引发错误 9。
Unqualified, Worksheets
refers to ActiveWorkbook.Worksheets
unless the code is written in the ThisWorkbook
module (see this answer for why).不合格,
Worksheets
指的是ActiveWorkbook.Worksheets
,除非代码是在ThisWorkbook
模块中编写的(请参阅此答案了解原因)。
So the simplest solution is to just qualify things:因此,最简单的解决方案是对事物进行限定:
'*Use the current sheet to store the found data*
For r = 2 To LastRow 'In ThisWorkbook.Worksheets
If ThisWorkbook.Worksheets("Sheet1").Range("D" & r).Value = Adminaccess.txtstartdate.Value Then'problem here for next r
ThisWorkbook.Worksheets("Sheet1").Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy
Now the code says what it does, and does what it says - without implicitly relying on side-effects and global state.现在代码说明了它的作用,并按照它所说的去做 - 没有隐含地依赖副作用和全局 state。
If "Sheet1" exists in ThisWorkbook
at compile-time ( ThisWorkbook
is always the workbook that contains your VBA project), then you can use the sheet's CodeName
to define a compile-time identifier that you can use as-is to refer to that specific sheet anywhere in the code - for example if you found the "Sheet1" in the VBE's Project Explorer and then explored its properties (F4), you could change its (Name)
property from Sheet1
to something meaningful.如果在编译时
ThisWorkbook
中存在“Sheet1”( ThisWorkbook
始终是包含您的 VBA 项目的工作簿),那么您可以使用工作表的CodeName
定义一个编译时标识符,您可以按原样使用该标识符来引用该特定在代码中的任何地方工作表- 例如,如果您在 VBE 的项目资源管理器中找到“Sheet1”,然后探索其属性 (F4),您可以将其(Name)
属性从Sheet1
更改为有意义的东西。
Same with the "Production" sheet, could be just ProductionSheet
, and then there's no need to dereference it from any Sheets
collection anymore, it's just there waiting to be used.与“生产”表相同,可能只是
ProductionSheet
,然后不再需要从任何Sheets
集合中取消引用它,它就在那里等待使用。
Avoid implicit ActiveWorkbook
references - the real solution is never to Activate
anything;避免隐式
ActiveWorkbook
引用——真正的解决方案是永远不要Activate
任何东西; the solution is to stop implicitly qualifying member calls (ie Worksheet
-> someWorkbook.Worksheets
, Range
-> someSheet.Range
) that belong to an object.解决方案是停止对属于 object 的隐式限定成员调用(即
Worksheet
-> someWorkbook.Worksheets
、 Range
-> someSheet.Range
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.