![](/img/trans.png)
[英]Why am I getting a Subscript Out of Range Error 9 when referencing another Workbook/Worksheet in VBA?
[英]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
由于ThisWorkbook.Worksheets("Production").Activate
在循环中,在下一次迭代Worksheets("Sheet1")
将属于ThisWorkbook
。
要成为/保持属于MyWB
的那个,就像我想的那样,您必须在代码的开头使用:
Dim sh1 as Worksheet
在MyWB
打开Set sh1 = Worksheets("Sheet1")
其次是LastRow = sh1.Range("A" & Rows.count).End(xlUp).Row
。
然后,将有问题的行更改为
sh1.Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy
“下标超出范围”(运行时错误 9)是一个常见错误,这意味着您正在尝试使用该数组/集合中不存在的下标从数组或集合中检索项目。
Dim things(0 To 9) As Long
things(10) = 42 '<~ "subscript out of range"
当您尝试按名称从Sheets
集合中检索Worksheet
时,Excel object model 会引发该错误,但指定的工作表在提供的Sheets
集合中不存在。
ActiveWorkbook.Worksheets("boom") '<~ if sheet is not in ActiveWorkbook sheets, error 9 is raised.
诀窍是始终明确哪些对象属于什么。 例如:
Workbooks.Open FileName:=MyPath & MyWB LastRow = Worksheets("Sheet1").Range("A" & Rows.count).End(xlUp).Row
在这里,我们明确说明了此Range
调用应使用的Worksheet
(但Rows
隐含地使用ActiveSheet
限定),但Worksheets
集合隐含地引用ActiveWorkbook
的任何内容。 这行得通,因为那时我们刚刚打开了一个工作簿,因此该工作簿必须处于活动状态!
Workbooks.Open
是一个function ,它返回对打开的Workbook
object 的引用。 考虑捕获该引用并消除对函数副作用的隐含依赖:
Dim book As Workbook
Set book = Application.Workbooks.Open(MyPath & MyWB)
所以在这里:
'*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
如果意图是迭代ThisWorkbook
中的行,那不是这里发生的事情,因为If Worksheets("Sheet1")...
没有明确说明它正在处理的工作簿,所以如果ActiveWorkbook
不是ThisWorkbook
并且没有工作表在那里命名为“Sheet1”,会引发错误 9。
不合格, Worksheets
指的是ActiveWorkbook.Worksheets
,除非代码是在ThisWorkbook
模块中编写的(请参阅此答案了解原因)。
因此,最简单的解决方案是对事物进行限定:
'*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
现在代码说明了它的作用,并按照它所说的去做 - 没有隐含地依赖副作用和全局 state。
如果在编译时ThisWorkbook
中存在“Sheet1”( ThisWorkbook
始终是包含您的 VBA 项目的工作簿),那么您可以使用工作表的CodeName
定义一个编译时标识符,您可以按原样使用该标识符来引用该特定在代码中的任何地方工作表- 例如,如果您在 VBE 的项目资源管理器中找到“Sheet1”,然后探索其属性 (F4),您可以将其(Name)
属性从Sheet1
更改为有意义的东西。
与“生产”表相同,可能只是ProductionSheet
,然后不再需要从任何Sheets
集合中取消引用它,它就在那里等待使用。
避免隐式ActiveWorkbook
引用——真正的解决方案是永远不要Activate
任何东西; 解决方案是停止对属于 object 的隐式限定成员调用(即Worksheet
-> someWorkbook.Worksheets
、 Range
-> someSheet.Range
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.