troubleshooting Question

Index out of range. Must be non-negative and less than the size of the collection

Avatar of imstac73
imstac73 asked on
ASP.NETVisual Basic.NET
7 Comments1 Solution1213 ViewsLast Modified:
My users are receiving the attached error when trying to access our system.  When a user accesses the site the code checks to see which AD group they are in and populates a dropdown list values based on their permissions on page load.  

I did not write this code and so I don't know how to fix the issue.  I would really appreciate anyone's help.  Below is the code that is related to the error.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not Page.IsPostBack) Then


            Dim usergroups As List(Of String) 'getting the current user's groups
            usergroups = GetGroups()
            If (usergroups.Contains("Forecasting_Branch_HQ")) Then 'adds all office branches if the user has the Forecasting_Branch_HQ user role
                'If (True) Then
                ddl_Branch.Items.Add(New ListItem("All Branches", "-1"))
                SqlDataOffice.SelectCommand = "SELECT Branch_OfficeID, Branch_Office, Active, Forecasting_Group FROM Branch_Offices WHERE (Active = 1) ORDER BY Branch_Office"
            Else
                'combining the user's groups into a single comma delimited string        
                Dim builder As New StringBuilder
                Dim isFirst As Boolean = True
                For Each t As String In usergroups
                    If Not isFirst Then
                        builder.Append(",")
                    End If
                    builder.Append(t)
                    isFirst = False
                Next

                Dim joinedUserGroups As String = builder.ToString()

                'formatting the string of groups to be SQL statement friendly
                joinedUserGroups = "'" + joinedUserGroups.Replace(",", "','") + "'"

                'generating the select statement for the datasource that populates the dropdown with the appropriate branch offices.
                SqlDataOffice.SelectCommand = "SELECT Branch_OfficeID, Branch_Office, Active, Forecasting_Group FROM Branch_Offices WHERE (Active = 1) AND Forecasting_Group IN (" + joinedUserGroups + ") ORDER BY Branch_Office"
            End If
            ddl_Branch.DataBind()
        End If
        'Since you can't programatically access sqldatasource data in any other way I'm calling the select method here and casting the response to a dataview to access it...
        'Setting the select parameters elsewhere in the SQLDataForecast.Selecting event
        Dim ForecastDataView As DataView = CType(SqlDataForecast.Select(DataSourceSelectArguments.Empty), DataView)
        For Each row As DataRow In ForecastDataView.Table.Rows
            For rv As Integer = 6 To row.ItemArray.Count() - 2
                If (row.ItemArray(rv) IsNot DBNull.Value) Then
                    revenueTotal(rv - 6) += row.ItemArray(rv)
                End If
            Next
            SqlDataForecastBreakdownTotals.SelectCommand = "SELECT [ForecastBreakdownID], [Forecast_KeyID], [BreakdownType], [Margin], [Mth1Amt], [Mth2Amt], [Mth3Amt], [Mth4Amt], [Mth5Amt], [Mth6Amt], [Mth7Amt], [Mth8Amt], [Mth9Amt], [Mth10Amt], [Mth11Amt], [Mth12Amt], [MthsTotal], [RemainderYrAmt], [NextYrAmt], [NextYr2Amt] FROM [vw_Forecasts_Breakdown_Union] WHERE ([Forecast_KeyID] = " + row.Item(1).ToString() + ")"
            Dim BreakdownDataView As DataView = CType(SqlDataForecastBreakdownTotals.Select(DataSourceSelectArguments.Empty), DataView)
            For Each breakdownrow As DataRow In BreakdownDataView.Table.Rows
                Select Case breakdownrow.Item("BreakdownType") 'since it's laid out in rows rather then columns have to get which breakdown type the row is and sum it up based off that
                    Case "Labor"
                        For l As Integer = 4 To breakdownrow.ItemArray.Count() - 2
                            If (breakdownrow.ItemArray(l) IsNot DBNull.Value) Then
                                laborTotal(l - 4) += Math.Round(breakdownrow.ItemArray(l))
                            End If
                        Next
                    Case "Subs/Pos"
                        For s As Integer = 4 To breakdownrow.ItemArray.Count() - 2
                            If (breakdownrow.ItemArray(s) IsNot DBNull.Value) Then
                                subsPOTotal(s - 4) += Math.Round(breakdownrow.ItemArray(s))
                            End If
                        Next
                    Case "Materials"
                        For m As Integer = 4 To breakdownrow.ItemArray.Count() - 2
                            If (breakdownrow.ItemArray(m) IsNot DBNull.Value) Then
                                materialsTotal(m - 4) += Math.Round(breakdownrow.ItemArray(m))
                            End If
                        Next
                    Case "Retainage"
                        For r As Integer = 4 To breakdownrow.ItemArray.Count() - 2
                            If (breakdownrow.ItemArray(r) IsNot DBNull.Value) Then
                                retainageTotal(r - 4) += Math.Round(breakdownrow.ItemArray(r))
                            End If
                        Next
                End Select
            Next
        Next
        For i As Integer = 0 To revenueTotal.Length - 2
            If i = 12 Then
                Continue For
            End If
            revenueTotal(revenueTotal.Length - 1) += revenueTotal(i)
        Next
        For i As Integer = 0 To laborTotal.Length - 2
            If i = 12 Then
                Continue For
            End If
            laborTotal(laborTotal.Length - 1) += laborTotal(i)
        Next
        For i As Integer = 0 To subsPOTotal.Length - 2
            If i = 12 Then
                Continue For
            End If
            subsPOTotal(subsPOTotal.Length - 1) += subsPOTotal(i)
        Next
        For i As Integer = 0 To materialsTotal.Length - 2
            If i = 12 Then
                Continue For
            End If
            materialsTotal(materialsTotal.Length - 1) += materialsTotal(i)
        Next
        For i As Integer = 0 To retainageTotal.Length - 2
            If i = 12 Then
                Continue For
            End If
            retainageTotal(retainageTotal.Length - 1) += retainageTotal(i)
        Next
        RevenueTotalsRepeater.DataSource = revenueTotal
        RevenueTotalsRepeater.DataBind()
        LaborTotalRepeater.DataSource = laborTotal
        LaborTotalRepeater.DataBind()
        SubsPOsTotalRepeater.DataSource = subsPOTotal
        SubsPOsTotalRepeater.DataBind()
        MaterialsTotalRepeater.DataSource = materialsTotal
        MaterialsTotalRepeater.DataBind()
        RetainageTotalRepeater.DataSource = retainageTotal
        RetainageTotalRepeater.DataBind()
        Dim SQLDates As SqlDataSource = SqlDataForecastDates 'getting the datasource to load dates
        Dim dv As DataView

        dv = CType(SQLDates.Select(DataSourceSelectArguments.Empty), DataView) 'filling a dataview to get at data
        'getting the dates and years to rename the columns
        Dim StartDate As Date = CType(dv.Table.Rows(0)(0), Date)
        Dim RemYr As String = CType(dv.Table.Rows(0)(1), String)
        Dim NxtYr As String = CType(dv.Table.Rows(0)(2), String)
        Dim NxtYr2 As String = CType(dv.Table.Rows(0)(3), String)
        'setting titles for the totals table        
        Mnt1_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt2_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt3_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt4_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt5_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt6_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt7_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt8_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt9_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt10_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt11_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        StartDate = DateAdd(DateInterval.Month, 1, StartDate)
        Mnt12_AmtTotalTitle.Text = StartDate.ToString("MMM yyyy")
        RemainderTotalTitle.Text = "Remainder " + RemYr
        NextYr1TotalTitle.Text = NxtYr
        NextYr2TotalTitle.Text = NxtYr2


    End Sub
Private Function GetGroups() As List(Of String)
        Dim user As String = Page.User.Identity.Name
        user = user.Split("\")(1) 'had to remove the FGI_MAIN domain name that came with the username...
        Dim Groups As New List(Of String)

        Dim rootDSE As New DirectoryEntry("LDAP://RootDSE") 'gets the ldap server handle
        Dim DFN As String = rootDSE.Properties("defaultNamingContext").Value.ToString()
        Dim entry As New DirectoryEntry("LDAP://" + DFN) 'gets the handle on the ldap domain name
        Dim mySearcher As New DirectorySearcher(entry)

        ' Limiting the search results to only the current user. It has a wildcard symbol after the username
        ' because the userprincipalname comes back as username@domain (@dynamicsystemsusa.com) and all we're really concerned with is the username
        mySearcher.Filter = "(&(objectCategory=Person)(objectClass=user)(userPrincipalName=" + user + "*))"
        'mySearcher.Filter = "(&(objectCategory=Person)(objectClass=user)(cn=Stac*))"

        Dim searchResults As SearchResultCollection = mySearcher.FindAll()

        If searchResults.Count > 0 Then 'We've got a user!
            For Each result As SearchResult In searchResults 'getting all the groups this member is a part of
                For i As Integer = 0 To (result.Properties.Item("MemberOf").Count - 1)
                    'removing extraneous information, just need the group name...
                    Dim groupstr As String = result.Properties("MemberOf").Item(i)
                    groupstr = groupstr.Split(",")(0)
                    groupstr = groupstr.Substring(3)

                    Groups.Add(groupstr)
                Next
            Next
        End If
        Return Groups
    End Function
   Protected Sub SqlDataForecast_Selecting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs) Handles SqlDataForecast.Selecting
        If e.Command.Parameters.Item(0).Value Is Nothing Or e.Command.Parameters.Item(1).Value Is Nothing Then 'don't want this event messing with the default datasource settings
            e.Command.Parameters.Item(0).Value = ddl_Branch.Items.Item(ddl_Branch.SelectedIndex).Text
            e.Command.Parameters.Item(1).Value = ddlProjectType.SelectedValue
        End If
    End Sub
7-3-2013-2-55-55-PM.jpg
Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 7 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 7 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros