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

- 76,472
- 17
- 159
- 346

- 15
- 3
-
I am generating a report from one workbook with date search criteria and copying the found values to another workbook but while doing so for the first r it copies the row for the corresponding date but for the next r , it shows the error, Please help. – Prathamesh Sable Jul 25 '20 at 10:32
-
What `Adminaccess` is? A form? Does the error appear on this line `Worksheets("Sheet1").Range("D" & r & ":G" & r & ",K" & r & ":Q" & r).Copy`? – FaneDuru Jul 25 '20 at 10:40
-
`Worksheets` is `ActiveWorkbook.Worksheets`, as opposed to `ThisWorkbook.Worksheets`. Please refer to https://stackoverflow.com/q/10714251/11683, save the result of `Workbooks.Open()` into a variable and use it refer to the opened workbook unambiguously. – GSerg Jul 25 '20 at 10:43
-
Activating `ThisWorkbook.Worksheets("Production").Activate` in the loop, at next iteration `Worksheets("Sheet1")` will belong to `ThisWorkbook`. To be the one belonging to `MyWB`, like I suppose, you must use at the beginning of the code: `Dim sh1 as Worksheet` and after `MyWB` opening `Set sh1 = Worksheets("Sheet1")` `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`. – FaneDuru Jul 25 '20 at 10:51
-
Adminacess is a Userform @FaneDuru and the problem is in the upper line of the code you mentioned – Prathamesh Sable Jul 25 '20 at 11:14
-
Thankyou @FaneDuru , your code solved the problem. Now it is working fine. – Prathamesh Sable Jul 25 '20 at 11:21
-
Glad I could help! I will transform it in an answer. If I will be able to do kit on my mobile phone... – FaneDuru Jul 25 '20 at 12:03
2 Answers
Because of ThisWorkbook.Worksheets("Production").Activate
in the loop, at next iteration Worksheets("Sheet1")
will belong to ThisWorkbook
.
To be/remain the one belonging to MyWB
, like I suppose, you must use at the beginning of the code:
Dim sh1 as Worksheet
and after MyWB
opening Set sh1 = Worksheets("Sheet1")
followed by 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

- 38,298
- 4
- 19
- 27
"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.
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.
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. 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. 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.
Unqualified, Worksheets
refers to ActiveWorkbook.Worksheets
unless the code is written in the ThisWorkbook
module (see this answer for why).
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.
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.
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.
Avoid implicit ActiveWorkbook
references - the real solution is never to Activate
anything; the solution is to stop implicitly qualifying member calls (i.e. Worksheet
-> someWorkbook.Worksheets
, Range
-> someSheet.Range
) that belong to an object.

- 69,817
- 8
- 107
- 235