Search code examples
visual-studio-2015ado.netsql-server-2016-express

Visual Basic 2015: Populating a ListView from SQL Connection


I started learning Visual Basic at the request of my employer, and I've reached a point in my learning project that is frustrating me.

I'm attempting to populate a ListView using data from a specific table in my SQL database, but I keep getting the same error no matter how I try to fix it:

Argument Out of Range Exception - Invalid Argument=Value of '1' is not valid for 'index'.

Here's the code that's generating the exception:

Private Sub MasterListSeries_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     lvMasterListSeries.Columns.Add("Unique ID", 75, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Working Title", 100, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Book Count", 75, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Genre", 75, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Published Title", 100, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Date Started", 85, HorizontalAlignment.Center)
     lvMasterListSeries.Columns.Add("Date Completed", 85, HorizontalAlignment.Center)

     Using myConnection As New SqlConnection(dbConnection)
         myConnection.Open()
         Dim Count As Integer
         Dim i As Integer = 0
         Using CountRows As New SqlCommand("SELECT Count(uniqueID) FROM tblSeries", myConnection)
             Count = Convert.ToDecimal(CountRows.ExecuteScalar)
         End Using
         Using querySeries As New SqlCommand("SELECT uniqueID, workingtitle, forecastedbookcount, genre, publishedtitle, datestarted, datecompleted FROM tblSeries", myConnection)
             Dim qsResult As SqlDataReader = querySeries.ExecuteReader()
             While qsResult.Read
                 i = Convert.ToDecimal(qsResult("uniqueID"))
                 lvMasterListSeries.Items.Add(New ListViewItem(Convert.ToString(qsResult("uniqueID"))))
                 lvMasterListSeries.Items(i).SubItems(1).Text = Convert.ToString(qsResult("workingtitle"))
                 lvMasterListSeries.Items(i).SubItems(2).Text = Convert.ToString(qsResult("forecastedbookcount"))
                 lvMasterListSeries.Items(i).SubItems(3).Text = Convert.ToString(qsResult("genre"))
                 lvMasterListSeries.Items(i).SubItems(4).Text = Convert.ToString(qsResult("publishedtitle"))
                 lvMasterListSeries.Items(i).SubItems(5).Text = Convert.ToString(qsResult("datestarted"))
                 lvMasterListSeries.Items(i).SubItems(6).Text = Convert.ToString(qsResult("datecompleted"))
             End While
         End Using
     End Using
 End Sub

The exception occurs on the third line of the While qsResult.Read sequence.

I've read two threads on Stack Overflow, two threads on Dream_In_Code, and another on Code Guru...all to no avail.

I found a question on MSDN's community forums, but it appears to be using Datasets, whereas I'm trying to learn ADO.NET with active connections...and I'm afraid I wasn't able to convert it into something usable for me.

Here's a screen capture of the debug window of Visual Studio:

Visual_Studio_Debug_Screen

The ListView (upon population) should look something like the results of the SQL query shown here:

SQL_Query_Screen

I appreciate any assistance, and I thank you for taking the time to read this.


Solution

  • You're calling Items(i) instead of Items.Item(i). Items just returns the collection of items in the ListView. you need to call Items.Item(i).SubItems...

    Private Sub MasterListSeries_Load(sender As Object, e As EventArgs) Handles MyBase.Load
         lvMasterListSeries.Columns.Add("Unique ID", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Working Title", 100, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Book Count", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Genre", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Published Title", 100, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Date Started", 85, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Date Completed", 85, HorizontalAlignment.Center)
    
         Using myConnection As New SqlConnection(dbConnection)
             myConnection.Open()
             Dim Count As Integer
             Dim i As Integer = 0
             Using CountRows As New SqlCommand("SELECT Count(uniqueID) FROM tblSeries", myConnection)
                 Count = Convert.ToDecimal(CountRows.ExecuteScalar)
             End Using
             Using querySeries As New SqlCommand("SELECT uniqueID, workingtitle, forecastedbookcount, genre, publishedtitle, datestarted, datecompleted FROM tblSeries", myConnection)
                 Dim qsResult As SqlDataReader = querySeries.ExecuteReader()
                 While qsResult.Read
                     i = Convert.ToDecimal(qsResult("uniqueID"))
                     lvMasterListSeries.Items.Add(New ListViewItem(Convert.ToString(qsResult("uniqueID"))))
                     lvMasterListSeries.Items.Item(i).SubItems(1).Text = Convert.ToString(qsResult("workingtitle"))
                     lvMasterListSeries.Items.Item(i).SubItems(2).Text = Convert.ToString(qsResult("forecastedbookcount"))
                     lvMasterListSeries.Items.Item(i).SubItems(3).Text = Convert.ToString(qsResult("genre"))
                     lvMasterListSeries.Items.Item(i).SubItems(4).Text = Convert.ToString(qsResult("publishedtitle"))
                     lvMasterListSeries.Items.Item(i).SubItems(5).Text = Convert.ToString(qsResult("datestarted"))
                     lvMasterListSeries.Items.Item(i).SubItems(6).Text = Convert.ToString(qsResult("datecompleted"))
                 End While
             End Using
         End Using
    
     End Sub
    

    I would suggest doing it like below though, where you pass an array of values to your ListViewItem. Less prone to errors.

    Private Sub MasterListSeries_Load(sender As Object, e As EventArgs) Handles MyBase.Load
         lvMasterListSeries.Columns.Add("Unique ID", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Working Title", 100, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Book Count", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Genre", 75, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Published Title", 100, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Date Started", 85, HorizontalAlignment.Center)
         lvMasterListSeries.Columns.Add("Date Completed", 85, HorizontalAlignment.Center)
    
         Using myConnection As New SqlConnection(dbConnection)
             myConnection.Open()
             Dim Count As Integer
             Dim i As Integer = 0
             Using CountRows As New SqlCommand("SELECT Count(uniqueID) FROM tblSeries", myConnection)
                 Count = Convert.ToDecimal(CountRows.ExecuteScalar)
             End Using
             Using querySeries As New SqlCommand("SELECT uniqueID, workingtitle, forecastedbookcount, genre, publishedtitle, datestarted, datecompleted FROM tblSeries", myConnection)
                 Dim qsResult As SqlDataReader = querySeries.ExecuteReader()
                 While qsResult.Read
                     lvMasterListSeries.Items.Add(
                        New ListViewItem({
                            Convert.ToString(qsResult("uniqueID")),
                            Convert.ToString(qsResult("workingtitle")),
                            Convert.ToString(qsResult("forecastedbookcount")),
                            Convert.ToString(qsResult("genre")),
                            Convert.ToString(qsResult("publishedtitle")),
                            Convert.ToString(qsResult("datestarted")),
                            Convert.ToString(qsResult("datecompleted")      
                        })
                     )
                 End While
             End Using
         End Using
    
     End Sub