handling Index was outside the bounds of the array.

Answered handling Index was outside the bounds of the array.

  • Friday, August 03, 2012 12:43 PM
     
      Has Code
    I am trying to search for a string in my array and if successfull set that string to nothing
    currently I am using the code below but it has been letting me down because when it cannot locate the string in the array it returns the error "Index was outside the bounds of the array.". Can someone help me on how I can avoid this error. I've put a lot of " If Not IsNothing" in my code but they are not helping.How can I avoid it.
      For intfirst = 0 To myArray.Length - 1
    
                If intfirst < myArray.Length Then 'Added Line
    
    
                    If Not IsNothing(myArray(intfirst)) = True Then
                        If Not IsNothing(myArray(intfirst).IndexOf(myDeletedRawMaterialCode)) = True Then
                            intIndex = myArray(intfirst).IndexOf(myDeletedRawMaterialCode)
                            If intIndex >= 0 Then
                                Exit For
                            End If
                        End If
                    End If
                Else
                    MsgBox("Error  " & intfirst & "  ")
                End If
    
            Next
            myArray(intfirst) = ""


    If you think it you can achieve it

All Replies

  • Friday, August 03, 2012 12:48 PM
     
     

    Hello,

    You have a loop in which you go from 0 to the maximum index of the array.

    When you exit the loop, the index value is the maximum index value, plus one.

    Therefore you cannot write "MyArray(intfirst)"

  • Friday, August 03, 2012 1:00 PM
     
     Answered Has Code
    Try this

    Private Sub DoIt() If ReplaceIt(MyArray, myDeletedRawMaterialCode) > -1 Then 'The character has been replaced Else 'The character hasn't been found End If End Sub

    Private Function ReplaceIt(MyArray As String(), Code As String) As Integer For intfirst = 0 To MyArray.Length - 1 Dim intIndex As Integer = MyArray(intfirst).IndexOf(Code) If intIndex >= -1 Then 'Do the replacement here Return intIndex End If Next Return -1 End Function


    • Marked As Answer by tendaimare Saturday, August 04, 2012 11:49 AM
    •  
  • Friday, August 03, 2012 1:12 PM
     
     Answered Has Code

    intFirst is incremented with each iteration. The loop is left as soon as the value is greater than the upper limit for the loop. If your array has 51 items (index 0..50), the loop exits as soon as the value 51 is reached. As there is no item with index 51 in the array, the exception is thrown.

    So you must handle the case of an item not being found. For example, put the code in a function, and replace "exit for" by "Return intFirst", and after the "Next" execute "return -1" for showing the item has not been found. The caller can evalutate the function return value and, if it -1, skip accessing the array.

    As you're not correctly using these functions, here's a suggestion how to do it:

       Shared Function Find(ByVal myArray As String(), ByVal Search As String) As Integer
    
          For i = 0 To myArray.Length - 1
             If myArray(i) IsNot Nothing Then 'can be deleted if the items in the array are never Nothing
                Dim pos = myArray(i).IndexOf(Search)
    
                If pos >= 0 Then
                   Return i
                End If
             End If
          Next
    
          Return -1
    
       End Function

    Call:

          Dim index = Find(myArray, myDeletedRawMaterialCode)
    
          If index > -1 Then
             myArray(index) = String.Empty
          End If
    

    However, there are powerful built-in functions. You do not have to write the loop on your own (unless it's for excersising):

    Dim index = Array.FindIndex(myArray, Function(item) item.IndexOf(myDeletedRawMaterialCode) >= -1)
    This line does the same.


    Armin

    • Marked As Answer by tendaimare Saturday, August 04, 2012 11:49 AM
    •  
  • Friday, August 03, 2012 2:24 PM
     
     

    Thanks for the replies. I adopted Armin Zingler's way with the function and the call but I suspect that sometimes it is failing to remove the string.because later I see the string in the array. How can the function return -1 when the string is right there in the array? Because everytime the function returns -1 something wrong happens.  


    If you think it you can achieve it

  • Friday, August 03, 2012 2:57 PM
     
     

    The search is case sensitive. Mabe that's the reason. Searching for "A" doesn't find "a".

    Can you give an example of a contained string and of a value to be searched? (copy&paste both values)

    BTW, is there a reason why you just store "" in the array? I you use a List(Of), you can simply remove the item.


    Armin


  • Friday, August 03, 2012 3:05 PM
     
      Has Code

    This is the code that I have so I assign a particular datagrid cell value to a string variable and use that variable when searching in the array.

            myDeletedRawMaterialCode = ProductsRawMaterialGrid.GridViewElement.CurrentRow.Cells("RawMaterialCode").Value
            Me.ProductsRawMaterialGrid.Rows.RemoveAt(ProductsRawMaterialGrid.GridViewElement.CurrentRow.Index)
    
            'Try
            'Dim index = Array.FindIndex(myArray, Function(item) item.IndexOf(myDeletedRawMaterialCode) >= -1)
            'intfirst = myArray.ToList().FindIndex(Function(arrItem As String) arrItem.Equals(myDeletedRawMaterialCode))
            'myArray(intfirst) = String.Empty
    
            'Catch ex As Exception
    
            'End Try
    
    
            Dim index = Find(myArray, myDeletedRawMaterialCode)
    
            If index > -1 Then
                myArray(index) = String.Empty
            ElseIf index = -1 Then
    
                Try
                    intfirst = myArray.ToList().FindIndex(Function(arrItem As String) arrItem.Equals(myDeletedRawMaterialCode))
                    myArray(intfirst) = ""
                Catch ex As Exception
                End Try
    
                MsgBox(index.ToString)
            End If


    If you think it you can achieve it

  • Friday, August 03, 2012 3:10 PM
     
     

    Can you give an example of a contained string and of a value to be searched? (copy&paste both values)

    Delete the empty exception handler. It hides if the application crashes, so you can't fix it.

    EDIT: Why do you call two Find functions now?


    Armin


  • Saturday, August 04, 2012 7:32 AM
     
      Has Code

    I've realised that the code is working fine but actually sometimes when I presume that a certain text value has been put into the array, its not been the case at all the value is not in that array so I need to look at the code that I am using to input the text values into the array. I've removed the exception handler and the other find function.

            myDeletedRawMaterialCode = ProductsRawMaterialGrid.GridViewElement.CurrentRow.Cells("RawMaterialCode").Value
    
            Dim index = Find(myArray, myDeletedRawMaterialCode)
    
            If index > -1 Then
                myArray(index) = String.Empty
                Me.ProductsRawMaterialGrid.Rows.RemoveAt(ProductsRawMaterialGrid.GridViewElement.CurrentRow.Index)
            End If
    
            If index = -1 Then
                MsgBox("Failed to remove the particular raw material " & index.ToString & " Please try again ", MsgBoxStyle.Exclamation, "Error")
            End If
    

    The code I am using to put the text values into the array is as follows, I know I need to take a good look at it again because once in a while it allows a row to be added to my datatable when the primary key of that row has not been added to my array and thats when the error comes in because now when I want to remove the row and remove its primary key from the array the key is not there and the function returns -1 :

     myArrayLimit = myTable.Rows.Count
            Dim myAddedRawMaterialCode As String = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialCode").Value
    
            myArray(myArrayLimit) = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialCode").Value
    
            Dim index = Find(myArray, myAddedRawMaterialCode)
    
            If index > -1 Then
    
                Dim myDr As DataRow = myTable.NewRow
                myDr.Item("ProductCode") = txtProductCode.Text
                myDr.Item("RawMaterialCode") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialCode").Value 'RawMaterialCode
                myDr.Item("RawMaterialDescription") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialDescription").Value
                myDr.Item("RawMaterialUnit") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("UnitOfMeasure").Value
                myDr.Item("UnitCostPerTon") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawUnitCostPrice").Value
                myDr.Item("RawMaterialCategory") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialCategory").Value
                myDr.Item("RawMaterialFinishedGoodsGroup") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RawMaterialFinishedGoodsGroup").Value
                myDr.Item("RMWasteFactor") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RMWasteFactor").Value
                myDr.Item("RMMoistureFactor") = RawMaterialsGridview.GridViewElement.CurrentRow.Cells("RMMoistureFactor").Value
                '***
                myDr.Item("Include") = False
                myDr.Item("PercentageInMix") = "0.00"
                myDr.Item("CostValueInMIx") = "0.00"
    
                myTable.Rows.Add(myDr)
    
                If RadRadioServiceItem.IsChecked = True Then
                    If myTable.Rows.Count = 1 Then
                        btnAddRM.Enabled = False
                        RadPanel5.Enabled = False
                    End If
                End If
    
                If RadRadioRawMaterials.IsChecked = True Then
                    If myTable.Rows.Count = 1 Then
                        btnAddRM.Enabled = False
                        RadPanel5.Enabled = False
    
                    End If
                End If
    
                If RawMaterialsGridview.GridViewElement.CurrentRow.IsSelected = False Then
                    Exit Sub
                Else
                    Me.RawMaterialsGridview.Rows.RemoveAt(RawMaterialsGridview.GridViewElement.CurrentRow.Index)
                End If
    
                ProductsRawMaterialGrid.Refresh()
    
                For i As Integer = 0 To ProductsRawMaterialGrid.Rows.Count - 1 Step 1
                    ProductsRawMaterialGrid.Rows.Item(i).Height = 30
                Next
    
                PinkPanel.BackColor = Color.HotPink
                PanelRawMaterialsZoom.Visible = False
                RawMaterialsGridview.Visible = False
    
                BtnSave.Enabled = True
                BtnClear.Enabled = True
                btnFinancials.Enabled = True
                BtnExit.Enabled = True
                BtnCalendar.Enabled = True
                BtnCalculator.Enabled = True
                btnRemoveRawMaterial.Enabled = True
            End If
    
    
            If index = -1 Then
                MsgBox("Cannot proceed with Adding Raw Material, Please try again", MsgBoxStyle.Exclamation, "Error")
                Exit Sub
            End If

     

    If you think it you can achieve it

  • Saturday, August 04, 2012 9:01 AM
     
     Answered

    Hello Tendemaire,

    Is there any reason you use an array instead of a clone of your datatable.

    The last will probably make your code much easier to do.

    Clones the structure of the DataTable, including all DataTable schemas and constraints but without the content.

     http://msdn.microsoft.com/en-us/library/system.data.datatable.clone.aspx


    Success
    Cor

    • Marked As Answer by tendaimare Saturday, August 04, 2012 11:49 AM
    •  
  • Saturday, August 04, 2012 10:17 AM
     
     
    Thanks Cor Ligthert good suggestion, i'll keep it in mind andtry it out soon, but now I have to submit the work soon so I kind of have to work with the code thats there, currently the above code is giving good results except for once in a while when it messes up. But I am strongly considering your suggestion, because I think you get the picture of what I hope to achieve.

    If you think it you can achieve it