0

I'm trying to set up a code which essentially looks at an array of worksheets, and perform the exact same check for each of those. Unfortunately I seem to be getting the following message anytime I try to access the With... function (through which I would like the array to operate):

Run-time error '9': Subscription out of range

Although the variable

WshtNames(w)

does end up taking the name required, it cannot seem to store it so that it can be applied to the respective worksheet? Any help greatly appreciated. Code below:

    Option Explicit

Public Cell, WshtNames As Variant, Check_Tab, Bench_OAS_Level, Bench_OAS_Change, Bench_Spread_Dur, Bench_Duration, Bench_Convexity, ws As Worksheets, FirstHeaderColumn, LRow, LastRow As Long

Sub Definitions()

Set Bench_OAS_Level = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Bench OAS Level")
Set Bench_OAS_Change = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Bench OAS Change")
Set Bench_Spread_Dur = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Bench Spread Dur")
Set Bench_Duration = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Bench Duration")
Set Bench_Convexity = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Bench Convexity")
Set Check_Tab = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Check")

End Sub

Sub Check_OOT()

Call Definitions

Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlManual

Dim CalcRange, FirstHeaderRow, LastColumn As Range
Dim w As Long

WshtNames = Array("Bench_OAS_Level", "Bench_OAS_Change", "Bench_Spread_Dur", "Bench_Duration", "Bench_Convexity")

For w = LBound(WshtNames) To UBound(WshtNames)

  With Worksheets(WshtNames(w))

    Set LastColumn = .UsedRange.Find("Total", , xlValues, xlWhole)
    Set FirstHeaderRow = .UsedRange.Find("Level 1", , xlValues, xlWhole)
    FirstHeaderColumn = FirstHeaderRow.Column + 2
    LastRow = .Cells(Rows.Count, LastColumn.Column).End(xlUp).Row

    Set CalcRange = .Range(.Cells(FirstHeaderRow.Row + 2, FirstHeaderRow.Column + 3), .Cells(LastRow, LastColumn.Column))

       For Each Cell In CalcRange
          If Not IsError(Cell) Then
           If Cell > 500 Or Cell < -100 Then
           Cell.Font.Bold = True
           Cell.Interior.ColorIndex = 36
           Cell.EntireRow.Copy
              Call Copy_into_Check_Tab
           End If
        End If
       Next Cell

  End With

Next w

End Sub
Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
GCoxxx
  • 65
  • 7
  • could you upload a screenshot of just the worksheet tab names on your screen? – Marcucciboy2 Jun 13 '18 at 15:59
  • The exact names are in the Sub_Definitions, referenced as each worksheet. – GCoxxx Jun 13 '18 at 16:06
  • I see them written out but based on the problems with the current answers it seems like they're trying to access a worksheet that is spelled wrong/ doesnt exist/etc and a picture *might* clear things up – Marcucciboy2 Jun 13 '18 at 16:33

3 Answers3

2

It seems like the names of the worksheets are:

  • Bench OAS Level
  • Bench OAS Change
  • Bench Spread Dur
  • Bench Duration
  • Bench Convexity

But that you're storing them in the array as:

  • Bench_OAS_Level
  • Bench_OAS_Change
  • Bench_Spread_Dur
  • Bench_Duration
  • Bench_Convexity

(with underscores).

Does this fix the problem?

Also, it might be helpful to add a dictionary object to the public scope:

public worksheetDictionary as object

And change the definitions code to:

Sub Definitions()
    set worksheetDictionary = CreateObject("Scripting.Dictionary")

    With Workbooks("TEST Overview Tool Barclays May 2018")
        Call worksheetDictionary.Add("Bench_OAS_Level", .Worksheets("Bench OAS Level"))
        Call worksheetDictionary.Add("Bench_OAS_Change",.Worksheets("Bench OAS Change"))
        Call worksheetDictionary.Add("Bench_Spread_Dur", .Worksheets("Bench Spread Dur"))
        Call worksheetDictionary.Add("Bench_Duration", .Worksheets("Bench Duration"))
        Call worksheetDictionary.Add("Bench_Convexity", .Worksheets("Bench Convexity"))

        Set Check_Tab = Workbooks("TEST Overview Tool Barclays May 2018").Worksheets("Check")
    End With
End Sub

Then, you'd change the for loop in your main block to start like this:

For each k in worksheetDictionary.Keys
    With worksheetDictionary(k)

Hope that helps!

Chip R.
  • 350
  • 2
  • 6
  • Don't use `Call`, it is now deprecated. – AJD Jun 13 '18 at 20:19
  • Can you point me towards some MSDN documentation for that? I always thought it was a stylistic thing, and I prefer to use Call in my code. If it's deprecated, I should probably stop though. The only thing I found was [this](https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/call-statement), which mentions that they're optional but no more. @AJD – Chip R. Jun 13 '18 at 21:20
  • @ChipR. that is awesome! Thanks so much mate. Great insight on the dictionary too – GCoxxx Jun 14 '18 at 09:52
  • @ChipR. MSDN documentation aint what it used to be! The newer pages don't have the discussion they used to have about it being for backwards compatibility and is now deprecated. I also remember a discussion somewhere (linked from some answer here on SO) about how Call and () can affect how parameters are passed in some circumstances. – AJD Jun 14 '18 at 19:35
  • @ChipR.: https://stackoverflow.com/questions/2573597/should-i-use-call-keyword-in-vb-vba – AJD Jun 14 '18 at 19:40
  • @AJD. Thanks for the response. Interesting about the deprecation; I'll definitely keep my eye out for that. And, yes, re: Call and () parameters is exactly why I use call all the time for my subroutine calls. The short version is: I like having input parameters inside () always, and NOT using the "Call" keyword means you have to put parameters outside parens, after a space from the subroutine name, and delimited by commas, which I think is clunky. Using Call with all subroutines allows me to always put input parameters inside parens. – Chip R. Jun 14 '18 at 20:54
1

Try changing...

Dim CalcRange, FirstHeaderRow, LastColumn As Range
Dim w As Long

WshtNames = Array("Bench_OAS_Level", "Bench_OAS_Change", "Bench_Spread_Dur", "Bench_Duration", "Bench_Convexity")

 For w = LBound(WshtNames) To UBound(WshtNames)

     With Worksheets(WshtNames(w))

To...

Dim CalcRange, FirstHeaderRow, LastColumn As Range
Dim w As variant

WshtNames = Array("Bench_OAS_Level", "Bench_OAS_Change", "Bench_Spread_Dur", "Bench_Duration", "Bench_Convexity")

 Foreach w in wshtNames

     With Worksheets(w)
1

When using UBound and LBound you must use the second parameter to tell the compiler which dimension of the array that youre wanting to loop through.

 example:  For w = LBound(WshtNames,1) To UBound(WshtNames,1)

or

 example: For w = LBound(WshtNames,2) To UBound(WshtNames,2)

Youre getting out of range b.c the compiler doesnt knwo what/where youre trying to tell it to go.

I ran this for fun and works as expected

enter image description here

Here is the proper way to address setting workbook values

WshtNames = Array("Bench_OAS_Level", "Bench_OAS_Change", "Bench_Spread_Dur", "Bench_Duration", "Bench_Convexity")

set wb = Workbooks(“workbookname.filextension”)

For w = LBound(WshtNames) To UBound(WshtNames)

  With wb.Worksheets(WshtNames(w))
Doug Coats
  • 6,255
  • 9
  • 27
  • 49
  • thanks very much, that was very helpful. Unfortunately the subscription still seems out of range, even when I input the dimensions (1 or 2 as you highlighted for example). Any idea why that may be the case? – GCoxxx Jun 13 '18 at 15:16
  • If it is on the line "With Worksheets(WshtNames(w))" it might be due to the fact youre not referencing which workbook contains said sheet. What I would do i set which workbook youre in and then reference wb.Sheets(WshtNames(w)). Make sense? – Doug Coats Jun 13 '18 at 15:24
  • Or loop through sheets. Same end different approach – Doug Coats Jun 13 '18 at 15:24
  • Yes it is exactly where you're pointing out that it breaks. I have now declared wb and set it = ThisWorkbook.Sheets(WshtNames(w)) but unfortunately it still throws that annoying out of range! I've declared wb as worksheet, workbook etc but still same issue. Driving me nuts! – GCoxxx Jun 13 '18 at 15:46
  • @ChefTony does that fix your issue and things run accordingly? – Doug Coats Jun 13 '18 at 15:47
  • referenced as pointed out but issue still there...thank you so much for your help though! – GCoxxx Jun 13 '18 at 16:07