0

New to VBA, is issue seems to be the following line,

Set NoMonths = Worksheets("Sheet4").Range("C13")

Unsure why as in cell c13 on sheet4 there contains a number value for example 5.

Can someone help please.

Full code:

Sub DefferedRev()

    Set NoMonths = Worksheets("Sheet4").Range("C13")
    Dim i As Integer
    Dim q As Integer


    If Worksheets("Sheet13").Range("B40") = Worksheets("Sheet13").Range("C82") Then
        For i = 5 To 7
            Cells(48, i).Value = 0
        Next i
    Else
        For i = 5 To 7
            q = (i Mod NoMonths) - 5
            Dim VectorToSum() As String
            ReDim VectorToSum(1 To q)
            For w = 1 To q
                VectorToSum(w) = (Worksheets("Sheet13").Cells(38, i).Value * Worksheets("Sheet13").Cells(7, i).Value) / (NoMonths * NoMonths - w)
            Next w
            ValueIn = Application.WorksheetFunction.Sum(VectorToSum)

            Cells(48, i).Value = ValueIn
        Next i
    End If

End Sub
Teamothy
  • 2,000
  • 3
  • 16
  • 26
thesis boi
  • 17
  • 1
  • 3
    Suggest you don't have a worksheet named "Sheet4" in the active workbook. (You should get in the habit of declaring all variables.) – SJR Oct 30 '19 at 11:35
  • Remove "Set" from line Set NoMonths = Worksheets("Sheet4").Range("C13") as you don't seem to be using NoMonths as Range Object. – Bilal Oct 30 '19 at 11:38
  • My 1st thought is you don't have a sheet named "Sheet4", but now that I have looked at your code more closely. It appears you are using NoMonths as a variant, as suggested earlier, you don't set a variant. – Davesexcel Oct 30 '19 at 12:37
  • 2
    @Davesexcel, If `"Sheet4"` would be present in the current project, VBA would create a `Variant/Object/Range` type variable for `NoMonths`. The code would have worked (at least past that specific line generating the error) – JvdV Oct 30 '19 at 12:41

1 Answers1

2

Subscript out of range

means that the Worksheets() property cannot find a worksheet named Sheet4.

  1. Make sure the sheet name has no additional spaces before, after or between Sheet4. In case of any doubt rename it to ensure correct naming of the sheet.

  2. In case of working with multiple workbooks (or in general following a good practice) specify in which workbook your worksheet is by using:

    Set NoMonths = ThisWorkbook.Worksheets("Sheet4").Range("C13") 'ThisWorkbook is the workbook this code is in
    

Additionally I recommend to use Option Explicit and declare all your variables proplery before you use them. For Example:

Dim NoMonths As Range
Set NoMonths = ThisWorkbook.Worksheets("Sheet4").Range("C13") 

Further if you use Cells(48, i).Value = 0 you don't define in which workbook this cell is. So Excel makes a guess and it might fail. Always specify a workbook/worksheet for all Range, Cells, Rows, Columns objects.

Thisworkbook.Worksheets("Sheet13").Cells(48, i).Value = 0

Better approach is to set the worksheets to a variable to make your code short and clean and re-use that variable.

Dim ws As Worksheet
Set ws = Thisworkbook.Worksheets("Sheet13")

ws.Cells(48, i).Value = 0

Finally I highly recommend to use meaningful variable names and worksheet names. Sheet13 and Sheet4 are pretty bad choices for names. Choosing a good name should be the very fist thing you do. Because if you do that last you will have to change it everywhere in your code.


So in the end your code should be something like this:

Option Explicit

Public Sub DefferedRev()
    Dim NoMonths As Range
    Set NoMonths = ThisWorkbook.Worksheets("Sheet4").Range("C13")

    Dim ws As Worksheet
    Set ws = ThisWorkbook.Worksheets("Sheet13")


    If ws.Range("B40").Value = ws.Range("C82").Value Then
        'For i = 5 To 7
        '    ws.Cells(48, i).Value = 0
        'Next i

        'this loop can be written at once (faster!)
        'replace it with the following line
        ws.Range(ws.Cells(48, 5), ws.Cells(48, 7)).Value = 0
    Else
        Dim i As Long
        For i = 5 To 7
            Dim q As Long
            q = (i Mod NoMonths) - 5

            Dim VectorToSum() As String
            ReDim VectorToSum(1 To q)

            Dim w As Long
            For w = 1 To q
                VectorToSum(w) = (ws.Cells(38, i).Value * ws.Cells(7, i).Value) / (NoMonths * NoMonths - w)
            Next w

            ws.Cells(48, i).Value = Application.WorksheetFunction.Sum(VectorToSum)
        Next i
    End If
End Sub
Pᴇʜ
  • 56,719
  • 10
  • 49
  • 73
  • As it is not being used as a range object, would it be better for NoMonths be an Integer? e.g. `Dim NoMonths as Integer` and `NoMonths = ThisWorkbook.Worksheets("Sheet4").Range("C13").Value`? – Gravitate Oct 30 '19 at 16:39
  • @Gravitate Yes, you can do that. But I recommend `Long` as there is no benefit in using `Integer` over `Long`. – Pᴇʜ Oct 30 '19 at 16:40
  • Hmm... I've never really thought about that. Integer is just my go to numeric type (unless I specifically need larger values). Thanks! Presumably, integer does use less memory? Just not enough to make any noticeable difference? – Gravitate Oct 30 '19 at 16:47
  • @Gravitate Actually using less memory *would* be a reason to prefer `Integer` (even if it would only be a tiny benefit is would be a benefit). But in VBA it does not use less memory it uses the exactly same amount of memory as a `Long` does but at the same time it still cannot take as large numbers as `Long`. So there is only disadvantages. I recommend to read [this](https://stackoverflow.com/questions/26409117/why-use-integer-instead-of-long/26409520#26409520) if you are interested why. • Note this is valid for VBA and does not apply to other coding languages. – Pᴇʜ Oct 31 '19 at 07:25
  • Thanks for the link. I will take a look. – Gravitate Oct 31 '19 at 08:57
  • Thank you, this has been very helpful. I have ran into another issue though when redefining the VectorToSum to be `ReDim VectorToSum(0 To q - 1)` (an empty vector of lengh q) I am getting the same error, why may this be. @Pᴇʜ – thesis boi Nov 01 '19 at 14:42
  • @CharlesEwing make sure `q - 1` is `> 0` if it is `0` or negative the array cannot be defined. Check which value `q` has in case of error. – Pᴇʜ Nov 01 '19 at 17:22