Excel VBA Subscript out of range error - vba

I modified a script to cut a big chunck of data into small pieces to keep subscript in the range.
I suppose to import data into spreadsheet, but it says
Run-time error '9':
Subscript out of range
Code
Private Sub btnRefresh_Click()
Dim W As Worksheet: Set W = ActiveSheet
Dim Last As Integer: Last = W.Range("b2000").End(xlUp).Row
Dim Last1 As Integer
Dim Symbols As String
Dim i, n, x, y As Integer
Last1 = Last - CInt(Last / 10) * 9
x = 5
For n = Last1 To Last Step CInt(Last / 10)
For i = x To n
Symbols = Symbols & W.Range("b" & i).Value & "+"
Next i
x = i
'Stop
Symbols = Left(Symbols, Len(Symbols) - 1)
Debug.Print Symbols
'Stop
Dim URL As String: URL = "http://finance.yahoo.com/d/quotes.csv?s=" & Symbols & "&f=snxl1c7g0h0" & Cells(2, 11) & "j0k0va2j1e7rs7dy"
Dim Http As New WinHttpRequest
Http.Open "GET", URL, False
Http.Send
Dim Resp As String: Resp = Http.ResponseText
Dim Lines As Variant: Lines = Split(Resp, vbNewLine)
Dim sLine As String
y = 5
For i = y To n
sLine = Lines(i)
Debug.Print sLine
'Stop
If InStr(sLine, ",") > 0 Then
Values = Split(sLine, ",")
W.Cells(i, 3).Value = Split(Split(sLine, Chr(34) & "," & Chr(34))(1), Chr(34))(0)
W.Cells(i, 4).Value = Split(Split(sLine, Chr(34) & "," & Chr(34))(2), Chr(34))(0)
W.Cells(i, 5).Value = Values(UBound(Values) - 14)
W.Cells(i, 6).Value = Values(UBound(Values) - 13)
W.Cells(i, 7).Value = Values(UBound(Values) - 12)
W.Cells(i, 8).Value = Values(UBound(Values) - 11)
W.Cells(i, 9).Value = Values(UBound(Values) - 10)
W.Cells(i, 10).Value = Values(UBound(Values) - 9)
W.Cells(i, 11).Value = Values(UBound(Values) - 8)
W.Cells(i, 12).Value = Values(UBound(Values) - 7)
W.Cells(i, 13).Value = Values(UBound(Values) - 6)
W.Cells(i, 14).Value = Values(UBound(Values) - 5)
W.Cells(i, 15).Value = Values(UBound(Values) - 4)
W.Cells(i, 16).Value = Values(UBound(Values) - 3)
W.Cells(i, 17).Value = Values(UBound(Values) - 2)
W.Cells(i, 18).Value = Values(UBound(Values) - 1)
W.Cells(i, 19).Value = Values(UBound(Values))
End If
Next i
Symbols = ""
Next n
W.Cells.Columns.AutoFit
End Sub

First off, make sure you have
Option Explicit
at the top of your code so you can make sure you don't mess any of your variables up.
Subscript out of range means that the program declares (DIM) an array to be of a certain length, but tries to reference an element with a subscript greater than the actual length. Often, but not always, this happens because a loop goes one index too far. Another common cause is using an index that has never been assigned a valid value.

Related

If Not or StrCmp Error? Received Runtime error 1004

What Im trying to do: Copy last 3 write ups from other sheets (j). The other sheets have a header, but if there are no write ups itll grab the header then error the other 2. I need it to fill the cells on the active sheet to say "No Writeups" if it trys pulling the header as a write up and stop so it doesnt error.
What I tried to do: In Cells(1,1) the header reads "Date". As K searches through column 1, I attempted to do a strComp? for the "Date" text? bc integers and strings dont compare well?
I'm getting a runtime error 1004?
Dim FirstLine As String
Dim NewestEntry As Integer
FirstLine = 6
Dim GrabbedDate As String
For j = 0 To 20 '(20) Tail Tabs/Number of Tabs
NewestEntry = Worksheets(Tail(j)).Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count
For k = NewestEntry To NewestEntry - 2 Step -1
GrabbedDate = Worksheets(Tail(j)).Cells(k, 1).Text
If StrComp(GrabbedDate, "Date") = 0 Then
k = 0
If Not k = 1 Then
Worksheets(Tail(j)).Cells(k, 1).Copy Worksheets("StepBrief").Cells(FirstLine, 4) 'Date
Worksheets(Tail(j)).Cells(k, 4).Copy Worksheets("StepBrief").Cells(FirstLine, 5) 'Code
Worksheets(Tail(j)).Cells(k, 5).Copy Worksheets("StepBrief").Cells(FirstLine, 6) 'Pilot
Worksheets(Tail(j)).Cells(k, 8).Copy Worksheets("StepBrief").Cells(FirstLine, 7) 'Start Up
Worksheets(Tail(j)).Cells(k, 11).Copy Worksheets("StepBrief").Cells(FirstLine, 8) 'Airboorne
Worksheets(Tail(j)).Cells(k, 14).Copy Worksheets("StepBrief").Cells(FirstLine, 9) 'Shutdown
FirstLine = FirstLine + 1
Else
If k = 1 Then
Worksheets("StepBrief").Cells(FirstLine, 4).Value = "" 'Date
Worksheets("StepBrief").Cells(FirstLine, 5).Value = "" 'Code
Worksheets("StepBrief").Cells(FirstLine, 6).Value = "" 'Pilot
Worksheets("StepBrief").Cells(FirstLine, 7).Value = "No Write Up" 'Start Up
Worksheets("StepBrief").Cells(FirstLine, 8).Value = "No Write Up" 'Airboorne
Worksheets("StepBrief").Cells(FirstLine, 9).Value = "No Write Up" 'Shutdown
FirstLine = FirstLine + 1
End If
End If
End If
Next k
Next j

button different from Module?

Private Sub CommandButton1_Click()
Dim nbp As Long
Dim i As Long
Dim p As Long
Dim FV As Variant
Dim CS As Variant
Dim K As Variant
Dim iFV As Integer
Dim iCS As Double
If Range("B9") = "Semi-Annual" Then
p = DateDiff("yyyy", Cells(4, 3), Cells(5, 3))
nbp = p * 2
For i = 5 To nbp + 4
Cells(5, 10).Value = Cells(4, 3).Value
Cells(i + 1, 10).Value = DateAdd("m", 6, Cells(i, 10).Value)
Next i
For i = 6 To nbp + 5
Cells(i, 14).Value = Cells(7, 2).Value * (Cells(8, 2).Value / 2)
Next i
FV = Sheet2.Range("J5:J10").Value
CS = Sheet3.Range("F1:G8000").Value
For iFV = 1 To UBound(FV)
For iCS = 1 To UBound(CS, 2)
If FV(iFV, 1) = CS(iCS, 1) Then
K(iFV, 1) = CS(iCS, 2)
End If
Next
Next
Sheet2.Range("K5:K10").Value = K
End If
End If
If Range("B9") = "Annual" Then
nbp = DateDiff("yyyy", Cells(4, 3), Cells(5, 3))
For i = 5 To nbp + 4
Cells(5, 10).Value = Cells(4, 3).Value
Cells(i + 1, 10).Value = DateAdd("m", 12, Cells(i, 10).Value)
Next i
End if
If Range("B9") = "Quarterly" Then
p = DateDiff("yyyy", Cells(4, 3), Cells(5, 3))
nbp = p * 4
For i = 5 To nbp + 4
Cells(5, 10).Value = Cells(4, 3).Value
Cells(i + 1, 10).Value = DateAdd("m", 3, Cells(i, 10).Value)
Next i
End If
If Range("B9") = "Monthly" Then ' to choose from a list .
p = DateDiff("yyyy", Cells(4, 3), Cells(5, 3))
nbp = p * 12
For i = 5 To nbp + 4
Cells(5, 10).Value = Cells(4, 3).Value
Cells(i + 1, 10).Value = DateAdd("m", 3, Cells(i, 10).Value)
Next i
End If
End Sub
I have added all the code in the button to help. i am not sure if that will help, anyway here is it. if the user chooses semi annual then couple of things take place. Same goes for the rest "ifs" but i need to fix this issue first then move on to the rest. the code to too long, it is simple and not complicated.
Now that more of the code is posted, I think I understand what the problem is.
Wherever you reference Cells() VBA assumes it applies to ActiveSheet. And I think you should fully qualify the calls to be Sheet2.Cells() for example or whatever you need.
When you call the code behind a button, the button resides on a sheet and it references the cells on that sheet. But when you moved the code to a module it no longer referenced the sheet with the button, but whatever other sheet was active at the time.
So whenever you see Cells() or Range() without a worksheet specification in front of it, change it so that it you target a specific worksheet.
PS. Avoid using Integer and prefer Long instead. Also, prefer relative referencing such as Sheet2.Range("G2").Cells(i,j) instead of absolute referencing Sheet2.Cells(1+i, 6+j) or string math such as Sheet2.Range("G" & 1+i & ":G" & 5+i).

vba vlookup returns values stored as text

What is wrong with this code? When run it returns good values but their formatting is bad - values are stored as text
For i = 2 To nrow
For j = 2 To ncol
With Worksheets(j - 1)
Set rang= .Range("A:F")
End With
Dim wart As Variant
wart = Application.VLookup(Cells(i, 1), rang, 6, False)
Cells(i, j) = wart
If IsError(Cells(i, j)) Then Cells(i, j) = 0
Cells(i, j) = Format(Cells(i, j), "Percent")
When data type of wart is changed to Double - "type mismatch" error appears
Formatting was done wrong!
Format(Cells(i, j), "Percent") doesn't seem right
Replace Cells(i, j) = Format(Cells(i, j), "Percent") with Cells(i, j).NumberFormat= "0.00%"
Also make sure you set the value if the cell by Cells(i, j).Value = wart.

excel vba search multiple criteria

when I run this VBA macro I get the same result despite putting in different nurse id thanks, this code came from a video that I watch and has been modified to work with multiple criteria
Sub finddata()
Dim nursenumber As String
Dim finalrow As Integer
Dim i As Integer
Dim course As Integer
Dim nurserow As Integer
nursenumber = InputBox("please enter nurse number")
nurserow = InputBox("please enter nurse row")
finalrow = Sheets("S1").Range("A10000").End(xlUp).Row
course = ADORIE
'fire update
For i = 2 To finalrow
Worksheets("S1").Activate
If Cells(i, 1) = nursenumber & Cells(i, 7) = "FIRE" Then
Cells(i, 9).Copy
Worksheets("database").Activate
Cells(nurserow, 2).PasteSpecial
End If
'cpr
If Cells(i, 1) = nursenumber & Cells(i, 7) = "CPRNURL4" Or _
Cells(i, 7) = "BUCPRBYS" Or Cells(i, 7) = "BUCPREMS" Or _
Cells(i, 7) = "CPRACLSR" Or Cells(i, 7) = "CPRADULT" Or _
Cells(i, 7) = "CPRALIED" Or Cells(i, 7) = "CPRBASIC" Or _
Cells(i, 7) = "CPRBYST" Or Cells(i, 7) = "CPRCO567" Or _
Cells(i, 7) = "CPRMANHA" Or Cells(i, 7) = "CPRMCORP" Or _
Cells(i, 7) = "CPRNURL4" Then
Cells(i, 9).Copy
Worksheets("database").Activate
Cells(nurserow, 3).PasteSpecial
Next i
End Sub
Following my comments above, also, your code is screaming for a Select Case instead of your multiple Or.
Code
Sub finddata()
Dim nursenumber As String
Dim finalrow As Integer
Dim i As Integer
Dim course As Integer
Dim nurserow As Integer
nursenumber = InputBox("please enter nurse number")
nurserow = InputBox("please enter nurse row")
finalrow = Sheets("S1").Range("A10000").End(xlUp).Row
course = ADORIE
With Worksheets("S1")
For i = 2 To finalrow
If .Cells(i, 1) = nursenumber Then
Select Case .Cells(i, 7).Value
Case "FIRE"
.Cells(i, 9).Copy Destination:=Worksheets("database").Cells(nurserow, 2)
Case "CPRNURL4", "BUCPRBYS", "CPRACLSR", "CPRADULT", "CPRALIED", "CPRBASIC", "CPRBYST", "CPRCO567", "CPRMANHA", "CPRMCORP", "CPRNURL4"
.Cells(i, 9).Copy Destination:=Worksheets("database").Cells(nurserow, 3)
End Select
End If
Next i
End With
End Sub

Can't retrieve a value from my dictionary using its key using vba

I am completely stumped on this problem here. I created a macro that will read values from the current spreadsheet, place those values into a dictionary using row numbers as keys, create a new spreadsheet, grab the values from those dictionaries, and add them to the new spreadsheet. There are three dictionaries that are filled. I have no problem getting the values from two of the dictionaries and I even have no problems getting the first couple of values from the problematic dictionaries. But when I try to retrieve the last two values in the last For Next loop, the values are read as "" instead of an actual value. The image below is a message that I built from looping the problematic dictionary.
I had the debug loop that produced this message within the last For Next loop. As you can see each key has a value, but when I use dataN.Exist(key) for just the last two values I get "" as the value. I don't understand. The exact same code works to pull the first couple of values but not the last couple. I have even moved those values to different rows but still got the same "". Here is the entire code here below:
Sub Transfer2NewWorkbook()
Dim currentsheet As String
Dim newsheet As String
Dim analysisDate As String
Dim initial As String
Dim aInitial() As String
Dim analystInit As String
Dim aBatch() As String
Dim batch As String
Dim batchNo As String
Dim key As Variant
Dim ikey As Variant
Dim SrowN As String
Dim rowN As Integer
Dim rowD As String
Dim wb As Object
Dim dataRangeN As Range, dataRangeB As Range, dataRangeI As Range
Dim dataN As Object
Set dataN = CreateObject("Scripting.Dictionary")
Dim dataB As Object
Set dataB = CreateObject("Scripting.Dictionary")
Dim dataI As Object
Set dataI = CreateObject("Scripting.Dictionary")
Dim teststring As String
' Grab and Create filenames
currentsheet = ActiveWorkbook.Name
newsheet = currentsheet & "-" & "uploadable"
' Grab data from original spreadsheet
analysisDate = ActiveWorkbook.Sheets(1).Cells(1, 9).Value
initial = ActiveWorkbook.Sheets(1).Cells(1, 2).Value
aInitial = Split(initial, "/")
analystInit = aInitial(1)
batch = ActiveWorkbook.Sheets(1).Cells(1, 4).Value
aBatch = Split(batch, ":")
batchNo = aBatch(1)
Set dataRangeN = Range("A:A")
Set dataRangeB = Range("B:B")
Set dataRangeI = Range("I:I")
For i = 4 To dataRangeB.Rows.Count
If Not IsEmpty(dataRangeB(i, 1)) Then
If StrComp(ActiveWorkbook.Sheets(1).Cells(i, 2).Value, "End") = 0 Then
Exit For
ElseIf StrComp(ActiveWorkbook.Sheets(1).Cells(i, 2).Value, "Blank") = 0 Then
If StrComp(ActiveWorkbook.Sheets(1).Cells(i, 1).Value, "Unseeded") = 0 Or StrComp(ActiveWorkbook.Sheets(1).Cells(i, 1).Value, "Seeded") = 0 Then
If Not IsEmpty(dataRangeI(i, 1)) Then
dataN.Add i, ActiveWorkbook.Sheets(1).Cells(i, 1).Value
dataB.Add i, ActiveWorkbook.Sheets(1).Cells(i, 2).Value
dataI.Add i, ActiveWorkbook.Sheets(1).Cells(i, 9).Value
End If
End If
ElseIf StrComp(ActiveWorkbook.Sheets(1).Cells(i, 2).Value, "Check") = 0 Then
If StrComp(ActiveWorkbook.Sheets(1).Cells(i, 1).Value, "Std") = 0 Then
If Not IsEmpty(dataRangeI(i, 1)) Then
dataN.Add i, ActiveWorkbook.Sheets(1).Cells(i, 1).Value
dataB.Add i, ActiveWorkbook.Sheets(1).Cells(i, 2).Value
dataI.Add i, ActiveWorkbook.Sheets(1).Cells(i, 9).Value
End If
End If
ElseIf StrComp(ActiveWorkbook.Sheets(1).Cells(i, 2).Value, "DUP") = 0 Then
rowD = dataB.Keys()(dataB.Count - 1)
If StrComp(ActiveWorkbook.Sheets(1).Cells(i - 1, 1).Value, "CBOD") = 0 Then
dataN.Add rowD, "DUP-CBOD"
ElseIf StrComp(ActiveWorkbook.Sheets(1).Cells(i - 1, 1).Value, "BOD") = 0 Then
dataN.Add rowD, "DUP-BOD"
End If
Else
dataB.Add i, ActiveWorkbook.Sheets(1).Cells(i, 2).Value
dataI.Add i, ActiveWorkbook.Sheets(1).Cells(i, 9).Value
End If
Else
If StrComp(ActiveWorkbook.Sheets(1).Cells(i, 1).Value, "DUP") = 0 Then
rowD = dataB.Keys()(dataB.Count - 1)
If StrComp(ActiveWorkbook.Sheets(1).Cells(i - 1, 1).Value, "CBOD") = 0 Then
dataN.Add rowD, "DUP-CBOD"
ElseIf StrComp(ActiveWorkbook.Sheets(1).Cells(i - 1, 1).Value, "BOD") = 0 Then
dataN.Add rowD, "DUP-BOD"
End If
End If
End If
Next i
' Open new spreadsheet
Set wb = Workbooks.Add("C:\Users\dalythe\documents\uploadtemp.xlsx")
ActiveWorkbook.Sheets(1).Cells(2, 2).Value = analysisDate
ActiveWorkbook.Sheets(1).Cells(2, 4).Value = analystInit
ActiveWorkbook.Sheets(1).Cells(3, 5).Value = batchNo
rowN = 4
For Each key In dataB.Keys
If dataI.Exists(key) Then
SrowN = CStr(rowN)
If dataN.Exists(key) Then
ActiveWorkbook.Sheets(1).Cells(SrowN, 1).Value = dataN(key)
End If
ActiveWorkbook.Sheets(1).Cells(SrowN, 2).Value = dataB(key)
ActiveWorkbook.Sheets(1).Cells(SrowN, 3).Value = dataI(key)
rowN = CInt(SrowN)
rowN = rowN + 1
End If
Next
ActiveWorkbook.SaveAs (newsheet & ".xlsx")
End Sub