Exception thrown: 'System.IndexOutOfRangeException' in VB.net - vb.net

So I keep getting the error
Exception thrown: 'System.IndexOutOfRangeException'
For my array counter. I'm still learning Visual Basic but I have programming knowledge in other languages, so I'm not sure if I'm just not translating between syntax properly here, or if it's just a logic error I'm not seeing.
The arrayNumsMultiply() array is an Integer array declared with 6 values. My counter variable was also declared as an Integer previously in the program.
The following code is meant to count through the 6 numbers, check if they have two integers in them (ex: 47, so 4 and 7), and then add them together. From there, it stores it back into the array and wipes the previous value. I have a System.Console.WriteLine in the code to see if the If statement is even being initiated and it's not, but the counter console log is. Any idea on what I may be doing wrong? (The specific line where the error is being thrown is the If arrayNumsMultiply(counter).ToString.Length = 2 Then)
For counter = 0 To 5
If arrayNumsMultiply(counter).ToString.Length = 2 Then
Dim numOne As String = arrayNumsMultiply(counter).ToString().Substring(1, 1)
Dim numTwo As String = arrayNumsMultiply(counter).ToString().Substring(2, 1)
Convert.ToInt32(numOne)
Convert.ToInt32(numTwo)
Dim totalNum As Integer
totalNum = numOne + numTwo
arrayNumsMultiply(counter) = totalNum
System.Console.WriteLine("If statement for adding in an integer working")
End If
System.Console.WriteLine("Counter working")
Next counter

If the length of you string is 2, the the first character is at position 0 and the second character is at position 1. Like most things in .net this is zero based. So the correct code for these lines is...
Dim numOne As String = arrayNumsMultiply(counter).ToString().Substring(0, 1)
Dim numTwo As String = arrayNumsMultiply(counter).ToString().Substring(1, 1)

Related

How many .ToString("N0") can I have?

I am getting a warning:
Severity Code Description Project File Line Suppression State
Warning BC42322 Runtime errors might occur when converting 'String' to 'IFormatProvider'.
I have 2 .ToString("N0") in my code in the same Sub. Can I not have 2 in the same sub? They go to different labels but, I am new to VB as well so please do not judge. Thanks!
If Integer.TryParse(input, infantry) Then
Dim hpai = Integer.Parse(frmMainGame.lblHPAI.Text, Globalization.NumberStyles.AllowThousands, Globalization.CultureInfo.InvariantCulture)
frmMainGame.lblHPAI.Text = (hpai - infantry * 2).ToString("N0")
frmMainGame.lblInfantryNumberPlayer.Text -= input.ToString("N0") '<---- One that gets the warning
Else
' handle not an int inputted case
End If
Let's look at this line:
frmMainGame.lblInfantryNumberPlayer.Text -= input.ToString("N0")
You're applying the -= operator to STRINGS. This operator has no meaning for strings. Are you trying to apply some kind of reverse-concatenation? Removing any occurrence of input from within the label text? That code just doesn't make sense at all.
If you're actually trying to do a numeric operation, you need to actually work with numbers... convert the label string to an integer, not the integer to a string.
If Integer.TryParse(input, infantry) Then
Dim hpai = Integer.Parse(frmMainGame.lblHPAI.Text, Globalization.NumberStyles.AllowThousands, Globalization.CultureInfo.InvariantCulture)
frmMainGame.lblHPAI.Text = (hpai - infantry * 2).ToString("N0")
Dim numPlayer = Integer.Parse(frmMainGame.lblInfantryNumberPlayer.Text)
frmMainGame.lblInfantryNumberPlayer.Text = (numplayer - input).ToString("N0") '<---- One that gets the warning
Else
' handle not an int inputted case
End If

Type mismatch in for loop including tests of worksheet cell values

I am receiving a type mismatch error in my VBA macro. Here is the essential part of my code:
Public Function CalculateSum(codes As Collection, ws As Worksheet) As Double
On Error GoTo ErrorHandler
If ws Is Nothing Then
MsgBox ("Worksheet is necessery")
Exit Function
End If
Dim balanceColumnIndex, codesCulumnIndex As Integer
Dim searchStartRow, searchEndRow As Integer
balanceColumnIndex = 17
codesColumnIndex = 4
searchStartRow = 7
searchEndRow = ws.Cells(ws.Rows.Count, codesColumnIndex).End(xlUp).Row
Dim result As Double
result = 0#
For counter = searchStartRow To searchEndRow
If Len(ws.Cells(counter, codesColumnIndex)) > 0 And Len(ws.Cells(counter, balanceColumnIndex)) > 0 And _
IsNumeric(ws.Cells(counter, codesColumnIndex).Value) And IsNumeric(ws.Cells(counter, balanceColumnIndex).Value) Then
If Contains(codes, CLng(ws.Cells(counter, codesColumnIndex).Value)) Then
result = result + ws.Cells(counter, balanceColumnIndex).Value
''' ^^^ This line throws a type-mismatch error
End If
End If
Next counter
CalculateSum = result
ErrorHandler:
Debug.Print ("counter: " & counter & "\ncode: " & ws.Cells(counter, codesColumnIndex).Value & "\namount: " & ws.Cells(counter, balanceColumnIndex).Value)
End Function
Now what happens is that a type-mismatch error occures on the line where current row balance is added to result even though:
searchEndRow equals 129, and somehow counter equals 130
cells under current address are empty, yet somehow they pass test for length and numeric values (I stopped to debug at this point, IsNumeric(ws.Cells(counter, codesColumnIndex).Value) returns true!
Now I am simply confused and I don't know what to do. Please help.
As commenters have noted, Cells(...).Value is a Variant. This means that operators may not apply to .Value the way you expect. For tests using Len or other string operations, expressly convert to a string. For example, instead of Len(ws.Cells(...)), try Len(CStr(ws.Cells(...).Value)). That way you will know that Len is giving you the result you expect.
Similarly, where you add to result, use result = result + CDbl(ws.Cells(...).Value) to make sure you are adding Double values together.
To answer your question regarding errors that happen differently on different computers, what I have most often experienced is that it is the specific data in question. As one of the commenters pointed out, Empty is indeed numeric since it implicitly converts to 0! As a result, IsNumeric(Empty) is True. Using CStr guards against that in your code because IsNumeric(CStr(Empty)) = IsNumeric("") = False. Using IsNumeric(CStr(...)) prevents you from trying to add 0# + "", which is a type mismatch. So perhaps the user has an empty cell that you don't have in your test data, and that's causing the problem. That's not the only possibility, just the one I have encountered most.

Run-Time Error '9': subscript out of range with WorksheetFunction

I'm trying to write a simple code to look at a data input section and add that data into an existing data table. The number of rows I want to copy changes every time so I attempted to make the array capable of adjusting size to suit.
Dim size As Integer
Dim new_resources() As String
Dim i as Integer
size = worksheetfunction.CountA("E:E") - 1
**ReDim new_resources(size)**
i=1
For i to size
new_resources(i) = cells(i+1,5)
Next i
I get the following error:
Run-time error '9': Subscript out of range.
on the line marked with **.
If you're getting that error on your ReDim line, it must mean that size is less than zero, which must mean that COUNTA("E:E") is returning zero. You may want to assert that size >= 0 before attempting to ReDim your array. For example:
size = worksheetfunction.CountA("E:E") - 1
If size < 0 Then
MsgBox "Error! No rows found in column E."
Else
ReDim new_resources(size)
End If
Arrays start with 0 not 1. So Change your new_resources(i) to new_resources(i-1).
That's not how the WorksheetFunction object works. On the worksheet, that is sufficient to pass in a cell range but not in VBA.
Dim sz As Long
Dim new_resources() As String
Dim i as Integer
sz = worksheetfunction.CountA(Range("E:E")) - 1
ReDim new_resources(sz)
i=1
For i to sz
new_resources(i) = cells(i+1, 5)
Next i
'alternates
sz = worksheetfunction.CountA(Columns(5)) - 1
sz = worksheetfunction.CountA(Cells(1, 5).EntireColumn) - 1
You need to reference one or more cells on a worksheet like you do in other VBA operations. The lack of a parent worksheet worries me; maybe you should address that as well.

VBA Macro Run time error 6: overflow- coding inside a loop

Having a problem with this Error. I am creating a GA and the loop is to assign my fitness value to an array.
some of the variables
Dim Chromolength as integer
Chromolength = varchromolength * aVariables
Dim i as integer, j as integer, counter as integer
Dim Poparr() As Integer
Dim FitValarr() As Integer
the code:
ReDim Poparr(1 To PopSize, 1 To Chromolength)
For i = 1 To PopSize
For j = 1 To Chromolength
If Rnd < 0.5 Then
Poparr(i, j) = 0
Else
Poparr(i, j) = 1
End If
Next j
Next i
For i = 1 To PopSize
j = 1
counter = Chromolength
Do While counter > 0
FitValarr(i) = FitValarr(i) + Poparr(i, counter) * 2 ^ (j - 1)
j = j + 1
counter = counter - 1
Loop
Next i
I am having problems with:
FitValarr(i) = FitValarr(i) + Poparr(i, counter) * 2 ^ (j - 1)
I apologize, I am fairly new to VBA.
An overflow condition arises when you create an integer expression that evaluates to a value larger than can be expressed in a 16-bit signed integer. Given the expression, either the contents of FitValarr(i), or the expression 2^(j-1) could be overflowing. Suggest all the the variables presently declared as Int be changed to Long. Long integers are 32-bit signed values and provide a correspondingly larger range of possible values.
I had the same run time error 6. After much investigation l discovered that mine was a simple 'divide by zero' error.
I set up an integer value to hold Zip codes, and Error 6 events plagued me - until I realized that a zip code of 85338 exceeded the capacity of an int...
While I didn't think of a zip code as a "value" it was nonetheless certainly interpreted as one. I suspect the same could happen with addresses as well as other "non-numeric" numeric values. Changing the variable to a string resolved the problem.
It just didn't occur to me that a zip code was a "numeric value." Lesson learned.

integer to string problems

I'm trying to make a slot machine program. This procedure that I'm trying to do will assign a name to 3 randomly generated numbers. For some reason I'm getting a conversion error saying that it cant convert the integer to a string. I tried cstr() as well but the problem persisted
Sub GenerateNumbers()
Dim numbers(2) As Integer
Dim names(5) As String
Dim x As Integer
names(0) = "Cherries"
names(1) = "Oranges"
names(2) = "Plums"
names(3) = "Bells"
names(4) = "Melons"
names(5) = "Bar"
For x = 0 To 2
numbers(x) = names(CInt(Int((6 * Rnd()) + 1)))
Next x
End Sub
gives me error: conversion from string "Oranges" to type 'Integer' is not valid
The problem is that you are getting a random string from the names array and trying to assign it to numbers, which is declared as an array of integers. Of course this is not gonna work.
Apart from that, there is also the issue with out of bounds index as Eric pointed out.
Edit in response to comments:
To get the text values of those randomly generated slot machine results you just need to declare the array to store results as strings, same way as names is declared.
To be able to get the results from a separate procedure, you need to change it from Sub to Function, which is a procedure that can return a value, an array of strings in this case. Then you can call this function from your Main or any other procedure and store the returned value in a variable.
I also corrected the part with random result generation.
Module SlotMachine
Sub Main()
Dim slotResults As String()
'Get the results
slotResults = GenerateResults()
'Some further processing of results here, e.g. print results to console
For Each item In slotResults
Console.WriteLine(item)
Next
'Wait for keypress before closing the console window
Console.ReadLine()
End Sub
'Generates random results
Function GenerateResults() As String()
Dim results(2) As String
Dim names(5) As String
Dim x As Integer
names(0) = "Cherries"
names(1) = "Oranges"
names(2) = "Plums"
names(3) = "Bells"
names(4) = "Melons"
names(5) = "Bar"
Randomize()
For x = 0 To 2
results(x) = names(Int(6 * Rnd()))
Next x
Return results
End Function
End Module
Int(6 * Rnd()) will get you 0-5, if you +1, then overflow