ListViewItem - " throws an InvalidArgument=Value of '4' is not valid for 'index'. Parameter name: index" error

I have a ListViewItem control that I've added to my Form using VS 2005/VB.NET on XP Pro.

I added a ListViewItemComparer Class (Class and Form code in Snippet window below) so that I can click on any "Header" column and have it sort data in Ascending/Descending order.

What I've noticed is that if I click on the LVI Control or even the Headers in the LVI before/or after I run a Query on a DB to fill the LVI, it gives me the following error, " throws an InvalidArgument=Value of '4' is not valid for 'index'. Parameter name: index". If I don't click on the LVI or it's headers before I run the query, of course, no error is produced.

If anyone knows a solution to avoid this that would be great. The only way I can get around it right now is to close and re-open the application, which is unacceptable to the folks that will use it.

Thank you for your time,
Wally
-- CLASS CODE --
Option Explicit On
Option Strict On
 
Imports System
Imports System.Windows.Forms.SortOrder
Imports System.Collections
 
Public Class ListViewItemComparer
    Implements IComparer
 
    ' ListViewItemComparer private members
    Private _column As Integer
    Private _cDataType As String
    Private _SortOrder As SortOrder = SortOrder.Ascending
 
    ' Property to get/set the column index for comparison
    Public Property Column() As Integer
        Get
            Return _column
        End Get
        Set(ByVal value As Integer)
            _column = value
        End Set
    End Property
 
    'Property to get/set the datatype of the column concerned
    Public Property ColumnDataType() As String
        Get
            Return _cDataType
        End Get
        Set(ByVal value As String)
            _cDataType = value
        End Set
    End Property
 
    ' Property to get/set the SortOrder for comparison
    Public Property SortOrder() As SortOrder
        Get
            Return _SortOrder
        End Get
        Set(ByVal value As SortOrder)
            _SortOrder = value
        End Set
    End Property
 
    ' ListViewItemComparer Constructor
    Public Sub New()
 
    End Sub
 
    ' Comparison Logic
    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
        ' Convert the arguments to the ListViewItem Objects
        Dim itemX As ListViewItem = CType(x, ListViewItem)
        Dim itemY As ListViewItem = CType(y, ListViewItem)
        Dim CompareResult As Integer = 0
 
        ' handle logic for possible null values
        If itemX Is Nothing And itemY Is Nothing Then
            Return 0
        Else
            If itemX Is Nothing Then
                CompareResult = -1
            Else
                If itemY Is Nothing Then
                    CompareResult = 1
                End If
            End If
        End If
 
        Select Case _cDataType
            Case "Numeric"
                ' Convert column text to numbers before
                ' comparing decimal itemXVal, itemYVal;
                Dim itemXVal As Decimal = [Decimal].Parse(itemX.SubItems(Column).Text)
                Dim itemYVal As Decimal = [Decimal].Parse(itemY.SubItems(Column).Text)
                CompareResult = [Decimal].Compare(itemXVal, itemYVal)
 
            Case "DateTime"
                ' Convert column text to DateTime before
                ' comparing DateTime itemXDateTime, itemYDateTime;
                Dim itemXDateTime As Date = DateTime.Parse(itemX.SubItems(Column).Text)
                Dim itemYDateTime As Date = DateTime.Parse(itemY.SubItems(Column).Text)
                CompareResult = DateTime.Compare(itemXDateTime, itemYDateTime)
 
            Case Else
                ' String comparison
                Dim itemXText As String = itemX.SubItems(Column).Text
                Dim itemYText As String = itemY.SubItems(Column).Text
                CompareResult = String.Compare(itemXText, itemYText)
        End Select
        ' Negate the CompareResult if sorting in descending order
        If SortOrder = SortOrder.Ascending Then
            Return CompareResult
        Else
            Return -CompareResult
        End If
    End Function ' Compare
End Class ' ListViewItemComparer
 
---------------------- FORM CODE -------------------------------
 
Private Sub lstQueryResults_ColumnClick(ByVal sender As Object, ByVal e As ColumnClickEventArgs) Handles lstQueryResults.ColumnClick
        ' An instance of ListViewItemCopmarer for comparison
        Dim TheColumnSorter As ListViewItemComparer
 
        ' Set ListViewItemSorter property to the new ListViewItemComparer Instance
        TheColumnSorter = CType(lstQueryResults.ListViewItemSorter, ListViewItemComparer)
 
        If TheColumnSorter Is Nothing Then
            ' Create a new ListViewItemComparer
            TheColumnSorter = New ListViewItemComparer()
            ' TheColumnSorter = lstQueryResults.ListViewItemSorter
            lstQueryResults.ListViewItemSorter = TheColumnSorter
        End If
 
        'set the properties of the ListViewItemComparer
        'set the column to the column that is clicked
        TheColumnSorter.Column = e.Column
 
        ' Dictate the column's datatype
        ' Column's Index starts with 0
        If e.Column = 0 Or e.Column = 1 Then
            TheColumnSorter.ColumnDataType = "String"
        Else
            If e.Column = 2 Then
                TheColumnSorter.ColumnDataType = "Numeric"
            Else
                If e.Column = 3 Then
                    TheColumnSorter.ColumnDataType = "DateTime"
                End If
            End If ' Toggle the sorting order
        End If
        If TheColumnSorter.SortOrder = Ascending Then
            TheColumnSorter.SortOrder = Descending
        Else
            TheColumnSorter.SortOrder = Ascending
        End If
        ' Call the ListView's (lstQueryResults control) Sort Method, perform sorting
        lstQueryResults.Sort()
    End Sub
 
-- FORM CODE --
Private Sub lstQueryResults_ColumnClick(ByVal sender As Object, ByVal e As ColumnClickEventArgs) Handles lstQueryResults.ColumnClick
        ' An instance of ListViewItemCopmarer for comparison
        Dim TheColumnSorter As ListViewItemComparer
 
        ' Set ListViewItemSorter property to the new ListViewItemComparer Instance
        TheColumnSorter = CType(lstQueryResults.ListViewItemSorter, ListViewItemComparer)
 
        If TheColumnSorter Is Nothing Then
            ' Create a new ListViewItemComparer
            TheColumnSorter = New ListViewItemComparer()
            ' TheColumnSorter = lstQueryResults.ListViewItemSorter
            lstQueryResults.ListViewItemSorter = TheColumnSorter
        End If
 
        'set the properties of the ListViewItemComparer
        'set the column to the column that is clicked
        TheColumnSorter.Column = e.Column
 
        ' Dictate the column's datatype
        ' Column's Index starts with 0
        If e.Column = 0 Or e.Column = 1 Then
            TheColumnSorter.ColumnDataType = "String"
        Else
            If e.Column = 2 Then
                TheColumnSorter.ColumnDataType = "Numeric"
            Else
                If e.Column = 3 Then
                    TheColumnSorter.ColumnDataType = "DateTime"
                End If
            End If ' Toggle the sorting order
        End If
        If TheColumnSorter.SortOrder = Ascending Then
            TheColumnSorter.SortOrder = Descending
        Else
            TheColumnSorter.SortOrder = Ascending
        End If
        ' Call the ListView's (lstQueryResults control) Sort Method, perform sorting
        lstQueryResults.Sort()
    End Sub

Open in new window

wally_davisAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

planoczCommented:
The sorter does not care if the date is a number or datetime, etc.
all you need is this code....
'IN FORM
    Private sortColumn As Integer = -1
   Private Sub Listview1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles Listview1.ColumnClick
        ' Determine whether the column is the same as the last column clicked.
        If e.Column <> sortColumn Then
            ' Set the sort column to the new column.
            sortColumn = e.Column
            ' Set the sort order to ascending by default.
            Listview1.Sorting = SortOrder.Ascending
        Else
            ' Determine what the last sort order was and change it.
            If Listview1.Sorting = SortOrder.Ascending Then
                Listview1.Sorting = SortOrder.Descending
            Else
                Listview1.Sorting = SortOrder.Ascending
            End If
        End If
        ' Call the sort method to manually sort.
        Listview1.Sort()
        ' Set the ListViewItemSorter property to a new ListViewItemComparer object.
        Listview1.ListViewItemSorter = New ListViewItemComparer(e.Column, Listview1.Sorting)
    End Sub
 
'IN CLASS
' Implements the manual sorting of items by columns.
Class ListViewItemComparer
    Implements IComparer
    Private col As Integer
    Private order As SortOrder
 
    Public Sub New()
        col = 0
        order = SortOrder.Ascending
    End Sub
    Public Sub New(ByVal column As Integer, ByVal order As SortOrder)
        col = column
        Me.order = order
    End Sub
    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
                        Implements System.Collections.IComparer.Compare
        Dim returnVal As Integer = -1
        returnVal = [String].Compare(CType(x, ListViewItem).SubItems(col).Text, _
                        CType(y, ListViewItem).SubItems(col).Text)
        ' Determine whether the sort order is descending.
        If order = SortOrder.Descending Then
            ' Invert the value returned by String.Compare.
            returnVal *= -1
        End If
        Return returnVal
    End Function
End Class

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
wally_davisAuthor Commented:
I tried your code. Definitely much cleaner, however, I still get the same failure. If I click on one of the Headers in the LVI before I run the Query or go to perform a Sort (using this Class and Form Routine) after a query and go to run another query, it gives me the following error:

Error --> ArgumentOutOfRangeException was unhandled - InvalidArgument=Value of '8' is not valid for 'index'. Parameter name: index <--
And fails on this line of code: m_ParentWindows.Invoke(m_NotifyMainWindow, msg). SEE BELOW CODE SNIPPET
While sqlReader.Read()
                currec += 1
                Dim msg As THREAD_MESSAGE
                msg.msgid = 101
                Dim message As New LIST_CTRL_DATA
                message.WksName = sqlReader("Workstation_Name").ToString
                message.InstallStatus = sqlReader("Install_Status").ToString
                message.InstallDate = sqlReader("Install_Date").ToString
                message.AppName = sqlReader("Name").ToString
                message.Version = sqlReader("Version").ToString
                message.Build = sqlReader("Build").ToString
                message.PackageName = sqlReader("Package_Name").ToString
                message.City = sqlReader("City").ToString
                message.State = sqlReader("State").ToString
                message.Percent = (currec * 100) / maxrecs
                msg.msgdata = message
                m_ParentWindow.Invoke(m_NotifyMainWindow, msg) <-- THROWS THE ERROR RIGHT HERE.
            End While

Open in new window

0
planoczCommented:
I don't see how you are using this with Listview. Not enough info. to see what you are trying to do.
I think I would have to see the rest of the code to follow what you are trying to do between the sql and Listview.
I use the listview with sql and with the sorter all the time and I have never gotten that error.
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

wally_davisAuthor Commented:
Here's my MAIN FORM CODE and SITTHREAD.VB Class code. I didn't attach the ListViewItemComparer Class since you already provided that.
If you need anything else, please let me know.

Thank you,
Wallace


MAIN FORM CODE - FORM1.VB
 
Imports Microsoft.Office.Interop
Imports System.IO
Imports System.Threading
Imports System.Data.SqlClient
Imports System.Windows.Forms.SortOrder
 
 
Public Class frmSITMain
 
    'Create an instance of the SITThread Class
    Private sitThread As SITThread
    Private packageStats As Hashtable
    Private profiles As Hashtable
    'The thread doing the work sends a message back
    'IE: Sending a message is same concept as calling this method with arguments
    Public Sub UpdateFormThreadCallback(ByVal msg As THREAD_MESSAGE)
        'Process our messages here...
 
        If msg.msgid = 101 Then 'MSG 101 is progress ctrl and list control update
            'Update List Control..
 
 
            Dim lvi As ListViewItem = lstQueryResults.Items.Add(lstQueryResults.Items.Count + 1)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).WksName)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).AppName)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).Version)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).Build)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).PackageName)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).InstallStatus)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).InstallDate)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).City)
            lvi.SubItems.Add(CType(msg.msgdata, LIST_CTRL_DATA).State)
            lvi.ListView.GridLines = True
            lvi.ListView.FullRowSelect = True
            lvi.ListView.AllowColumnReorder = True
            ' lvi.ListView.Sorting = None
            queryProgress.Value = CType(msg.msgdata, LIST_CTRL_DATA).Percent
 
 
        ElseIf msg.msgid = 254 Then 'MSG 254
            lstQueryResults.Items.Clear()
        ElseIf msg.msgid = 255 Then 'MSG 255 Thread Exited
            btnQuery.Text = "Query"
        End If
 
    End Sub
 
    Public Class package_status
        Public name As String
        Public version As String
        Public build As String
        Public Installed As Boolean
        Public Uninstalled As Boolean
        Public Installing As Boolean
        Public Uninstalling As Boolean
        Public Sub New()
 
        End Sub
    End Class
 
    Private sortColumn As Integer = -1
    Private Sub lstQueryResults_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lstQueryResults.ColumnClick
        ' Determine whether the column is the same as the last column clicked.
        If e.Column <> sortColumn Then
            ' Set the sort column to the new column.
            sortColumn = e.Column
            ' Set the sort order to ascending by default.
            lstQueryResults.Sorting = SortOrder.Ascending
        Else
            ' Determine what the last sort order was and change it.
            If lstQueryResults.Sorting = SortOrder.Ascending Then
                lstQueryResults.Sorting = SortOrder.Descending
            Else
                lstQueryResults.Sorting = SortOrder.Ascending
            End If
        End If
        ' Call the sort method to manually sort.
        lstQueryResults.Sort()
        ' Set the ListViewItemSorter property to a new ListViewItemComparer object.
        lstQueryResults.ListViewItemSorter = New ListViewItemComparer(e.Column, lstQueryResults.Sorting)
    End Sub
 
    'Private Sub lstQueryResults_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles lstQueryResults.MouseDown
    '    If e.Button = Windows.Forms.MouseButtons.Right Then
    '        ContextMenuStrip1.Show(lstQueryResults, New Point(e.X, e.Y))
    '    End If
 
    'If lstQueryResults.SelectedIndices(1) Then
    '    lstQueryResults.Columns.Count.ToString()
    'End If
 
    'Dim colStart As Integer = 0
    'Dim colEnd As Integer = 0
    'Dim X As Integer
 
    'For X = 0 To (lstQueryResults.Columns.Count - 1)
    '    colEnd = colEnd + lstQueryResults.Columns(X).Width
    '    If colStart <= e.X And e.Y <= colEnd Then
    '        Label1.Text = "Column clicked: " & X + 1
    '        Exit For
    '    End If
    '    colStart += lstQueryResults.Columns(X).Width
    'Next
    'End Sub
 
    'This function will check the form data and start the thread if all is ok
    Private Sub btnQuery_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnQuery.Click
        If sitThread.m_thread Is Nothing Then
 
            btnExport.Enabled = False
 
            If rbSingleDev.Checked = True And txtDevFile.Text = "" Then
                MsgBox("Unable to process request. Please enter a Workstation name.", _
                MsgBoxStyle.OkOnly, "Workstation Name required")
                Exit Sub
            End If
 
            If rbMultiDev.Checked = True And txtDevFile.Text = "" Then
                MsgBox("Unable to process request. Please select a text file that contains list of workstation names to query against.", _
                MsgBoxStyle.OkOnly, "Source Text file required")
                Exit Sub
            End If
 
            If rbIntermediate.Checked = True Then
                If Not ValidateAdvancedOptions() Then
                    Exit Sub
                Else
                    Dim sql As String = ""
 
                    If cmbPackages.SelectedIndex <> 0 Then
                        sql = String.Format("{0} s.name{1}'{2}'", sql, cmbCompSfw.SelectedItem.ToString, cmbPackages.SelectedItem.ToString)
                        If cmbAndOr1.SelectedIndex <> 0 Then sql = String.Format("{0} {1}", sql, cmbAndOr1.SelectedItem.ToString)
                    End If
 
                    If cmbVersions.SelectedIndex <> 0 Then
                        sql = String.Format("{0} s.version{1}'{2}'", sql, cmbCompVer.SelectedItem.ToString, cmbVersions.SelectedItem.ToString)
                        If cmbAndOr2.SelectedIndex <> 0 Then sql = String.Format("{0} {1}", sql, cmbAndOr2.SelectedItem.ToString)
                    End If
 
                    If cmbBuilds.SelectedIndex <> 0 Then
                        sql = String.Format("{0} s.build{1}'{2}'", sql, cmbCompBuild.SelectedItem.ToString, cmbBuilds.SelectedItem.ToString)
                        If cmbAndOr3.SelectedIndex <> 0 Then sql = String.Format("{0} {1}", sql, cmbAndOr3.SelectedItem.ToString)
                    End If
 
                    If cmbStatuses.SelectedIndex <> 0 Then
                        sql = String.Format("{0} s.Install_status{1}'{2}'", sql, cmbCompStat.SelectedItem.ToString, cmbStatuses.SelectedItem.ToString)
                    End If
 
 
 
                    sitThread.SetQueryLevel(QueryLevel.advanced, sql)
                End If
            Else
                sitThread.SetQueryLevel(QueryLevel.basic, "")
            End If
 
            Dim qt As QueryType
            Dim data As Object = Nothing
 
            If rbSingleDev.Checked = True Then
                qt = QueryType.one
                data = txtDevFile.Text
            End If
 
            If rbMultiDev.Checked = True Then
                If clbSites.CheckedItems.Count < 1 Then
                    MessageBox.Show("You must check at least one City checkbox from the Locations list", "Site Selection", MessageBoxButtons.OK)
                    Exit Sub
                Else
                End If
                qt = QueryType.many
                data = txtDevFile.Text
            End If
 
            If rbAllDevs.Checked = True Then
                If clbSites.CheckedItems.Count < 1 Then
                    MessageBox.Show("You must check at least one City checkbox from the Locations list", "Site Selection", MessageBoxButtons.OK)
                    Exit Sub
                Else
                End If
            End If
 
            sitThread.SetSitesCollection(clbSites.CheckedItems)
 
            Dim states As UInteger
            If cbStatInstalling.Checked Then states = states Or 1
            If cbStatInstalled.Checked Then states = states Or 2
            If cbStatUninstalling.Checked Then states = states Or 4
            If cbStatUninstalled.Checked Then states = states Or 8
 
            sitThread.SetStates(states)
 
            'Here we'll pass no data in since  all the values out of the DB will be parsed...
            If rbAllDevs.Checked = True Then qt = QueryType.all
 
            sitThread.SetThreadData(qt, data)
            sitThread.m_thread = New Thread(AddressOf sitThread.ThreadFunc)
            sitThread.m_thread.Start()
            btnQuery.Text = "Stop"
            Timer1.Start()
        Else
            MsgBox("Please wait for the processing to finish")
        End If
 
        'Exit Sub
 
    End Sub
 
    Public Sub New()
        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        sitThread = New SITThread(Me)
        queryProgress.Maximum = 100
        queryProgress.Minimum = 0
 
        'Set Colheadings
        lstQueryResults.Columns.Add("Row Number")
        lstQueryResults.Columns.Add("Workstation Name")
        lstQueryResults.Columns.Add("Application Name")
        lstQueryResults.Columns.Add("Version")
        lstQueryResults.Columns.Add("Build")
        lstQueryResults.Columns.Add("Package Name")
        lstQueryResults.Columns.Add("Install Status")
        lstQueryResults.Columns.Add("Install Date")
        lstQueryResults.Columns.Add("City")
        lstQueryResults.Columns.Add("State")
        lstQueryResults.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize)
 
        InitPackageNames()
 
        'Select First...
        cmbStatuses.SelectedIndex = 0
        cmbCompSfw.SelectedIndex = 0
        cmbCompStat.SelectedIndex = 0
        cmbCompVer.SelectedIndex = 0
        cmbCompBuild.SelectedIndex = 0
        cmbAndOr1.SelectedIndex = 0
        cmbAndOr2.SelectedIndex = 0
        cmbAndOr3.SelectedIndex = 0
 
        Timer1.Interval = 1000
 
    End Sub
 
    Private Sub InitPackageNames()
        cmbPackages.Items.Add("Select a Package")
        cmbVersions.Items.Add("Select a Version")
        cmbBuilds.Items.Add("Select a Build")
 
 
        Try
            Dim sqlStr As New SqlConnectionStringBuilder()
            sqlStr.DataSource = db_config.server
            sqlStr.InitialCatalog = db_config.catalog
            sqlStr.ConnectTimeout = 300
            sqlStr.IntegratedSecurity = True
 
            Dim sqlCon As New SqlConnection(sqlStr.ConnectionString)
            If sqlCon.State = ConnectionState.Open Then
                sqlCon.Close()
            Else
                sqlCon.Open()
            End If
 
            Dim sqlCommand As New SqlCommand
            sqlCommand.Connection = sqlCon
            sqlCommand.CommandText = "SELECT DISTINCT s.NAME FROM software s ORDER by s.name"
            sqlCommand.CommandTimeout = 300
            Dim sqlReader As SqlDataReader
            sqlReader = sqlCommand.ExecuteReader()
            While sqlReader.Read()
                cmbPackages.Items.Add(sqlReader("name").ToString)
            End While
            If cmbPackages.Items.Count > 0 Then cmbPackages.SelectedIndex = 0
            sqlReader.Close()
 
            sqlCommand.CommandText = "SELECT DISTINCT s.build FROM software s ORDER by s.build"
            sqlCommand.CommandTimeout = 300
            sqlReader = sqlCommand.ExecuteReader()
            While sqlReader.Read()
                cmbBuilds.Items.Add(sqlReader("build").ToString)
            End While
            If cmbBuilds.Items.Count > 0 Then cmbBuilds.SelectedIndex = 0
            sqlReader.Close()
 
            sqlCommand.CommandText = "SELECT DISTINCT s.Version FROM software s ORDER by s.version"
            sqlCommand.CommandTimeout = 300
            sqlReader = sqlCommand.ExecuteReader()
            While sqlReader.Read()
                cmbVersions.Items.Add(sqlReader("version").ToString)
            End While
            If cmbVersions.Items.Count > 0 Then cmbVersions.SelectedIndex = 0
            sqlReader.Close()
 
            sqlCon.Close()
 
        Catch e As SqlException
            MsgBox(e.Message, MsgBoxStyle.Critical, "MSSQL Exception")
        End Try
    End Sub
 
    Private Sub rbSingleDev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbSingleDev.Click
        rbMultiDev.Checked = False
        rbAllDevs.Checked = False
        btnBrowse.Enabled = False
        lblWksFile.Text = "Workstation Name"
        txtDevFile.ReadOnly = False
        txtDevFile.Text = ""
        txtDevFile.Enabled = True
        If rbBasic.Checked = True Then
            Call rbBasic_CheckedChanged(sender, e)
        Else
            Call rbIntermediate_CheckedChanged(sender, e)
        End If
 
        ' selectAllSitesCheckBox.Enabled = False
        Call clearSiteCheckboxes()
 
    End Sub
 
    Private Sub rbMultiDev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbMultiDev.Click
        rbSingleDev.Checked = False
        rbAllDevs.Checked = False
        btnBrowse.Enabled = True
        lblWksFile.Text = "Workstation Text File"
        txtDevFile.ReadOnly = True
        txtDevFile.Text = ""
        txtDevFile.Enabled = True
        If rbBasic.Checked = True Then
            Call rbBasic_CheckedChanged(sender, e)
        Else
            Call rbIntermediate_CheckedChanged(sender, e)
        End If
 
        Call clearSiteCheckboxes()
    End Sub
    Private Sub rbAllDevs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbAllDevs.Click, txtDevFile.HideSelectionChanged
        rbSingleDev.Checked = False
        rbMultiDev.Checked = False
        btnBrowse.Enabled = False
        lblWksFile.Text = "All Devices"
    End Sub
 
    Private Sub rbBasic_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbBasic.Click
        grpAdvanced.Enabled = False
        lblSoftName.Enabled = False
        lblBuild.Enabled = False
        lblStatus.Enabled = False
        lblVersion.Enabled = False
        cmbCompSfw.Enabled = False
        cmbCompStat.Enabled = False
        cmbCompVer.Enabled = False
        cmbCompBuild.Enabled = False
        grpStatuses.Enabled = True
        If rbAllDevs.Checked = True Then
            Call rbIntermediate_CheckedChanged(sender, e)
            'rbIntermediate.Checked = True
        End If
    End Sub
    Private Sub rbBasic_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbBasic.Click
        Dim Co = "Choose Operator"
        Dim Op = "Optional"
 
        cmbCompSfw.Text = Co
        cmbCompSfw.Enabled = False
        cmbPackages.Text = "Select a Package"
        cmbPackages.Enabled = False
        cmbAndOr1.Text = "Optional"
        cmbAndOr1.Enabled = False
 
        cmbCompVer.Text = Co
        cmbCompVer.Enabled = False
        cmbVersions.Text = "Select a Version"
        cmbVersions.Enabled = False
        cmbAndOr2.Text = Op
        cmbAndOr2.Enabled = False
 
        cmbCompBuild.Text = Co
        cmbCompBuild.Enabled = False
        cmbBuilds.Text = "Select a Build"
        cmbBuilds.Enabled = False
        cmbAndOr3.Text = Op
        cmbAndOr3.Enabled = False
 
        cmbCompStat.Text = Co
        cmbCompStat.Enabled = False
        cmbStatuses.Text = "Select a Status"
        cmbStatuses.Enabled = False
 
        rbSingleDev.Checked = True
        Me.rbMultiDev.Enabled = False
        Me.rbAllDevs.Enabled = False
 
        cbStatInstalling.Checked = False
        cbStatInstalled.Checked = False
        cbStatUninstalling.Checked = False
        cbStatUninstalled.Checked = False
 
        Call clearSiteCheckboxes()
 
    End Sub
    Private Sub rbIntermediate_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbIntermediate.Click
        grpAdvanced.Enabled = True
        lblSoftName.Enabled = True
        lblBuild.Enabled = True
        lblStatus.Enabled = True
        lblVersion.Enabled = True
        cmbCompSfw.Enabled = True
        cmbCompStat.Enabled = True
        cmbCompVer.Enabled = True
        cmbCompBuild.Enabled = True
        grpStatuses.Enabled = False
        cbStatInstalling.Checked = False
        cbStatInstalled.Checked = False
        cbStatUninstalling.Checked = False
        cbStatUninstalled.Checked = False
        Me.rbMultiDev.Enabled = True
        Me.rbAllDevs.Enabled = True
    End Sub
 
    Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
        Dim dlg As New OpenFileDialog
        dlg.Title = "Find workstation list file"
        dlg.InitialDirectory = "C:\"
        dlg.Filter = "Text Documents (*.txt)|*.txt"
        dlg.FilterIndex = 1
        dlg.Multiselect = False
        dlg.CheckFileExists = True
        dlg.CheckPathExists = False
        If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            txtDevFile.Text = dlg.FileName
        End If
 
    End Sub
 
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        If sitThread.m_thread.Join(1) = True Then
            Timer1.Stop()
            btnQuery.Text = "Query"
            sitThread.m_thread = Nothing
            If lstQueryResults.Items.Count > 0 Then
                btnExport.Enabled = True
            End If
        End If
 
    End Sub
 
    Private Sub frmSITMain_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        'Just in case someone decides to exit the app mid query...
        If Not sitThread.m_thread Is Nothing Then
            If sitThread.m_thread.IsAlive Then sitThread.m_thread.Abort()
        End If
    End Sub
 
    Private Sub cmbCompSfw_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCompSfw.SelectionChangeCommitted
        If cmbCompSfw.SelectedIndex <> 0 Then
            cmbPackages.Enabled = True
        Else
            cmbPackages.Enabled = False
            cmbAndOr1.Enabled = False
            cmbPackages.SelectedIndex = 0
            cmbAndOr1.SelectedIndex = 0
        End If
 
    End Sub
 
    Private Sub cmbPackages_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbPackages.SelectionChangeCommitted
        If cmbPackages.SelectedIndex <> 0 Then
            cmbAndOr1.Enabled = True
        Else
            cmbAndOr1.Enabled = False
            cmbAndOr1.SelectedIndex = 0
        End If
    End Sub
 
    Private Sub cmbCompVer_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCompVer.SelectionChangeCommitted
        If cmbCompVer.SelectedIndex <> 0 Then
            cmbVersions.Enabled = True
        Else
            cmbVersions.Enabled = False
            cmbAndOr2.Enabled = False
            cmbVersions.SelectedIndex = 0
            cmbAndOr2.SelectedIndex = 0
        End If
    End Sub
 
    Private Sub cmbVersions_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbVersions.SelectionChangeCommitted
        If cmbVersions.SelectedIndex <> 0 Then
            cmbAndOr2.Enabled = True
        Else
            cmbAndOr2.Enabled = False
            cmbAndOr2.SelectedIndex = 0
        End If
    End Sub
 
    Private Sub cmbCompBuild_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCompBuild.SelectionChangeCommitted
        If cmbCompBuild.SelectedIndex <> 0 Then
            cmbBuilds.Enabled = True
        Else
            cmbBuilds.Enabled = False
            cmbAndOr3.Enabled = False
            cmbBuilds.SelectedIndex = 0
            cmbAndOr3.SelectedIndex = 0
        End If
    End Sub
 
    Private Sub cmbBuilds_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbBuilds.SelectionChangeCommitted
        If cmbBuilds.SelectedIndex <> 0 Then
            cmbAndOr3.Enabled = True
        Else
            cmbAndOr3.Enabled = False
            cmbAndOr3.SelectedIndex = 0
        End If
    End Sub
 
    Private Sub cmbCompStat_SelectionChangeCommitted(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbCompStat.SelectionChangeCommitted
        If cmbCompStat.SelectedIndex <> 0 Then
            cmbStatuses.Enabled = True
        Else
            cmbStatuses.Enabled = False
            cmbStatuses.SelectedIndex = 0
        End If
    End Sub
 
    Private Function ValidateAdvancedOptions() As Boolean
        'Gen base sqltext...
 
 
        Dim compcnt As UInteger = 0
        Dim andorlog As UInteger = 0
        Dim critcnt As UInteger = 0
 
        If cmbCompSfw.SelectedIndex <> 0 Then compcnt += 1
        If cmbCompVer.SelectedIndex <> 0 Then compcnt += 1
        If cmbCompBuild.SelectedIndex <> 0 Then compcnt += 1
        If cmbCompStat.SelectedIndex <> 0 Then compcnt += 1
 
        If cmbPackages.SelectedIndex <> 0 Then critcnt += 1
        If cmbVersions.SelectedIndex <> 0 Then critcnt += 1
        If cmbBuilds.SelectedIndex <> 0 Then critcnt += 1
        If cmbStatuses.SelectedIndex <> 0 Then critcnt += 1
 
        If cmbAndOr1.SelectedIndex <> 0 Then andorlog += 1
        If cmbAndOr2.SelectedIndex <> 0 Then andorlog += 1
        If cmbAndOr3.SelectedIndex <> 0 Then andorlog += 1
 
        'Check for major offenders....
        If compcnt = 0 Then
            MsgBox("In advanced mode you must select at least one operator:" & vbCrLf & "= or <>", MsgBoxStyle.Exclamation, "Invalid search options")
        ElseIf critcnt <> compcnt Then
            MsgBox("Please check values associated for all = or <> operators", MsgBoxStyle.Exclamation, "Invalid search options")
        Else
 
            Return True
 
        End If
 
        Return False
    End Function
 
    Private Sub btnExport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExport.Click
        Dim dlg As New SaveFileDialog
        dlg.Title = "Export Results"
        If Not My.Computer.FileSystem.CurrentDirectory = "C:\Temp" Then
            My.Computer.FileSystem.CreateDirectory("C:\Temp")
        End If
        dlg.InitialDirectory = "C:\Temp"
        ' dlg.Filter = "CSV (*.csv)|*.csv"
        dlg.Filter = "XLS (*.xls)|*.xls"
        dlg.FilterIndex = 1
        dlg.CheckFileExists = False
        dlg.CheckPathExists = True
        If dlg.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Dim lvName As New ListView
            Call ExportToExcel(lstQueryResults)
        End If
    End Sub
 
    Public Sub ExportToExcel(ByVal lvName As ListView)
        Dim objExcelApplication As New Excel.Application
        Dim objExcelSheet As New Excel.Worksheet
        Dim objExcelBook As Excel.Workbook
 
        Try
 
            If objExcelApplication Is Nothing Then
                MsgBox("It was not possible to open Microsoft Excel", MsgBoxStyle.Critical, "Exporting to Excel")
                Exit Sub
            End If
 
            Dim oldCI As System.Globalization.CultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture
            System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("en-US")
 
            objExcelBook = objExcelApplication.Workbooks.Add
            objExcelSheet = objExcelBook.Worksheets(1)
 
            Dim lvRows As Int16
            Dim lvColumns As Byte
 
            For lvColumns = 1 To lvName.Columns.Count
                objExcelSheet.Cells(1, lvColumns) = lvName.Columns(lvColumns - 1).Text
                objExcelSheet.Cells(1, lvColumns).Font.Bold = True
            Next
 
            For lvRows = 1 To lvName.Items.Count
                For lvColumns = 1 To lvName.Columns.Count
 
                    If lvColumns = 1 Then
                        objExcelSheet.Cells(lvRows + 1, lvColumns) = lvName.Items(lvRows - 1).Text.ToString
                    Else
                        objExcelSheet.Cells(lvRows + 1, lvColumns) = lvName.Items(lvRows - 1).SubItems(lvColumns - 1).Text.ToString
                    End If
 
                Next
            Next
 
            objExcelSheet.Cells.WrapText = False
            objExcelApplication.Visible = True
            System.Threading.Thread.CurrentThread.CurrentCulture = oldCI
 
 
        Catch COMEx As System.Runtime.InteropServices.COMException
            MsgBox("Microsoft Excel not ready", MsgBoxStyle.Critical, "Exporting to Excel")
 
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Exporting to Excel")
 
        Finally
            objExcelSheet = Nothing
            objExcelApplication = Nothing
            GC.Collect()
        End Try
 
    End Sub
 
    Private Sub btnSetDefaults_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetDefaults.Click
 
        lstQueryResults.Items.Clear()
        queryProgress.Value = 0
        rbBasic.Checked = True
        txtDevFile.Text = ""
        rbSingleDev.Checked = True
        clbSites.SetSelected(0, False)
 
        ' Unchecks the CLB Checkboxes and 
        ' selectAllSitesCheckbox
        Call clearSiteCheckboxes()
        If selectAllSitesCheckBox.Checked = True Then
            selectAllSitesCheckBox.Checked = False
        End If
 
        'Reset "Advanced Searched Options" to default
        Dim Co = "Choose Operator"
        Dim Op = "Optional"
 
        cmbCompSfw.Text = Co
        cmbCompSfw.Enabled = False
        cmbPackages.Text = "Select a Package"
        cmbPackages.Enabled = False
        cmbAndOr1.Text = "Optional"
        cmbAndOr1.Enabled = False
 
        cmbCompVer.Text = Co
        cmbCompVer.Enabled = False
        cmbVersions.Text = "Select a Version"
        cmbVersions.Enabled = False
        cmbAndOr2.Text = Op
        cmbAndOr2.Enabled = False
 
        cmbCompBuild.Text = Co
        cmbCompBuild.Enabled = False
        cmbBuilds.Text = "Select a Build"
        cmbBuilds.Enabled = False
        cmbAndOr3.Text = Op
        cmbAndOr3.Enabled = False
 
        cmbCompStat.Text = Co
        cmbCompStat.Enabled = False
        cmbStatuses.Text = "Select a Status"
        cmbStatuses.Enabled = False
 
        Call rbBasic_CheckedChanged(sender, e)
 
    End Sub
 
    Private Sub rbSingleDev_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbSingleDev.CheckedChanged
        txtDevFile.Visible = True
        txtDevFile.Enabled = True
        lblWksFile.Visible = True
        btnBrowse.Enabled = False
        lblWksFile.Text = "Workstation Name"
        txtDevFile.ReadOnly = False
        txtDevFile.Text = ""
        clbSites.Enabled = False
        alldevicesLabel.Visible = False
        selectAllSitesCheckBox.Enabled = False
    End Sub
 
    Private Sub rbMultiDev_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbMultiDev.CheckedChanged
        txtDevFile.Visible = True
        txtDevFile.Enabled = True
        lblWksFile.Visible = True
        txtDevFile.Text = ""
        lblWksFile.Text = "Workstation Text File"
        txtDevFile.ReadOnly = True
        btnBrowse.Enabled = True
        clbSites.Enabled = True
        alldevicesLabel.Visible = False
        selectAllSitesCheckBox.Enabled = True
    End Sub
 
    Private Sub rbAllDevs_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rbAllDevs.CheckedChanged
        If rbAllDevs.Checked = True Then txtDevFile.Hide()
        If rbAllDevs.Checked = True Then lblWksFile.Hide()
        btnBrowse.Enabled = False
        lblWksFile.Text = "All Devices"
        clbSites.Enabled = True
        alldevicesLabel.Visible = True
        selectAllSitesCheckBox.Enabled = True
        If rbAllDevs.Checked = True Then
            Call rbIntermediate_CheckedChanged(sender, e)
            'rbIntermediate.Checked = True
        End If
    End Sub
 
    Private Sub clearSiteCheckboxes()
        ' Unchecks the CLB Checkboxes
        Dim myEnumerator As IEnumerator
        myEnumerator = clbSites.CheckedIndices.GetEnumerator
        Dim y As Integer
        While myEnumerator.MoveNext() <> False
            y = CInt(myEnumerator.Current)
            clbSites.SetItemChecked(y, False)
        End While
    End Sub
 
    Private Sub selectAllSitesCheckBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles selectAllSitesCheckBox.CheckedChanged
        ' Select all Site checkboxes
        If selectAllSitesCheckBox.Checked = True Then
            For i As Integer = 0 To clbSites.Items.Count - 1
                clbSites.SetItemChecked(i, True)
            Next
        Else
            Call clearSiteCheckboxes()
        End If
    End Sub
    Private Sub exitButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles exitButton.Click
        Me.Close()
    End Sub
 
    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub
 
    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        AboutBox.Show()
    End Sub
 
    Private Sub UpdateHistoryToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpdateHistoryToolStripMenuItem.Click
        HistoryForm.Show()
    End Sub
End Class
 
 
 
THREADING CLASS Code - SITTHREAD.VB
Imports System.Threading
Imports System.IO
Imports System.Data.SqlClient
 
 
Public Structure THREAD_MESSAGE
    Public msgid As UInteger
    Public msgdata As Object
End Structure
 
'Structure is one to one with each row of the lstQueryResults control
Public Class LIST_CTRL_DATA
    Public WksName As String
    Public InstallStatus As String
    Public InstallDate As String
    Public PackageName As String
    Public AppName As String
    Public Version As String
    Public Build As String
    Public City As String
    Public State As String
    Public Percent As UInteger
 
    Public Sub New()
        WksName = ""
        InstallStatus = ""
        InstallDate = ""
        PackageName = ""
        AppName = ""
        Version = ""
        Build = ""
        City = ""
        State = ""
    End Sub
End Class
 
Public Enum QueryType As Integer
    one = 1
    many = 2
    all = 3
End Enum
 
Public Enum QueryLevel As Integer
    basic = 1
    advanced = 2
End Enum
 
 
Public Class SITThread
    Public m_thread As Thread
    Private m_ParentWindow As Form
 
    'So we can know what to do in the thread with the data
    Private m_advancesql As String
    Private m_level As QueryLevel
    Private m_type As QueryType
    Private m_fileorwks As String
    Private m_sites As Collection
    Private m_states As Collection
 
    'Known same as C++ callback, or function pointer ( note it is a type not a function )
    Private Delegate Sub NotifyMainWindow(ByVal msg As THREAD_MESSAGE)
    'We need an object of this deletegate
    Private m_NotifyMainWindow As NotifyMainWindow
 
    Public Sub SetQueryLevel(ByVal level As QueryLevel, ByVal sql As String)
        m_level = level
        m_advancesql = sql
    End Sub
    Public Sub SetSitesCollection(ByVal sites As CheckedListBox.CheckedItemCollection)
        'Build a list of sites... Thread data must be extracted from form data to prevent a train wreck
        m_sites.Clear()
        For Each str As String In sites
            m_sites.Add(str)
        Next
    End Sub
 
    Public Sub SetStates(ByVal states As UInteger)
        'States are masked as integers...
        '1 Installing
        '2 Installed
        '4 Uninstalling
        '8 Uninstalled
        m_states.Clear()
        If states And 1 Then m_states.Add(0)
        If states And 2 Then m_states.Add(1)
        If states And 4 Then m_states.Add(2)
        If states And 8 Then m_states.Add(3)
    End Sub
 
 
    Public Sub SetThreadData(ByVal type As QueryType, ByVal data As Object)
        m_type = type
        Select Case m_type
            Case QueryType.one
                m_fileorwks = CType(data, String)
            Case QueryType.many
                m_fileorwks = CType(data, String)
            Case QueryType.all
                m_fileorwks = "All"
        End Select
    End Sub
 
    'This is equal to a C++ Constuctor ( it initializes all class members )
    Public Sub New(ByRef frmParent As frmSITMain)
        m_ParentWindow = frmParent
        m_NotifyMainWindow = AddressOf frmParent.UpdateFormThreadCallback
        m_thread = Nothing
        m_sites = New Collection()
        m_states = New Collection()
    End Sub
 
    Private Function GetStatesSQLString() As String
        Dim states As String = ""
        For i As Integer = 1 To m_states.Count()
            If i = 1 Then
                states += "s.install_status='" + m_states(i).ToString + "'"
            Else
                states += " OR s.install_status='" + m_states(i).ToString + "'"
            End If
        Next
        Return states
    End Function
 
    Private Function GetSitesSQLString()
        Dim sites As String = ""
        If m_sites.Count > 0 Then
            For i As Integer = 1 To m_sites.Count()
                If i = 1 Then
                    sites += "n.city='" + m_sites(i) + "'"
                Else
                    sites += " OR n.city='" + m_sites(i) + "'"
                End If
            Next
        End If
        Return sites
    End Function
 
    Private Function GetWorkstationSQLString() As String
        Dim workstations As String = ""
        Dim lines As New Collection
        Dim objReader As New StreamReader(m_fileorwks)
 
        'Read all lines into a collection... makes it easy to OR as sql text...
        While Not objReader.EndOfStream
            Dim device As String = objReader.ReadLine().Trim
            If device <> "" Then
                lines.Add(device)
            End If
        End While
        objReader.Close()
 
        'Create the sql OR'ed workstation list...
        If lines.Count > 0 Then
            For i As Integer = 1 To lines.Count()
                If i = 1 Then
                    workstations += "n.Workstation_Name='" + lines(i) + "'"
                Else
                    workstations += " OR n.Workstation_Name='" + lines(i) + "'"
                End If
            Next
        End If
        'Return the or'ed values...
 
        Return workstations
 
    End Function
    Public Sub ThreadFunc()
        Dim clrmsg As THREAD_MESSAGE
        clrmsg.msgdata = Nothing
        clrmsg.msgid = 254
        m_ParentWindow.Invoke(m_NotifyMainWindow, clrmsg)
 
        'Setup base fields.... we will build the where clause later... 
        Dim query As String = String.Format("SELECT n.Workstation_Name , s.install_status , s.install_date , s.name , s.version , s.build , s.Package_Name , n.city , n.state FROM software s , network n where")
        Dim cntquery As String = String.Format("SELECT count(*) FROM software s , network n where")
 
        'Build the OR clause of sites
        Dim sites As String = GetSitesSQLString()
        'Build the OR clause of install states
        Dim states As String = GetStatesSQLString()
 
        'Build the OR's and AND's for Workstation specs...
        Select Case m_type
            Case QueryType.one
                cntquery = String.Format("{0} ( s.mac=n.mac AND n.Workstation_Name='{1}' )", cntquery, m_fileorwks)
                query = String.Format("{0} ( s.mac=n.mac AND n.Workstation_Name='{1}' )", query, m_fileorwks)
            Case QueryType.many
                Dim workstations As String = GetWorkstationSQLString()
                cntquery = String.Format("{0} ( s.mac=n.mac )", cntquery)
                query = String.Format("{0} ( s.mac=n.mac )", query)
                If workstations <> "" Then
                    cntquery = String.Format("{0} AND ({1})", cntquery, workstations)
                    query = String.Format("{0} AND ({1})", query, workstations)
                End If
            Case QueryType.all
                cntquery = String.Format("{0} ( s.mac=n.mac )", cntquery)
                query = String.Format("{0} ( s.mac=n.mac )", query)
        End Select
 
        'Append to base... if needed
        If sites <> "" Then
            cntquery = String.Format("{0} AND ({1})", cntquery, sites)
            query = String.Format("{0} AND ({1})", query, sites)
        End If
 
        'Only used for basic...
        If m_level = QueryLevel.basic Then
 
            'Append to base... if needed
            If states <> "" Then
                cntquery = String.Format("{0} AND ({1})", cntquery, states)
                query = String.Format("{0} AND ({1})", query, states)
            End If
        Else
            cntquery = String.Format("{0} AND ({1})", cntquery, m_advancesql)
            query = String.Format("{0} AND ({1})", query, m_advancesql)
        End If
 
 
        query = String.Format("{0} ORDER BY n.Workstation_Name ASC", query, states)
 
        Trace.WriteLine(cntquery)
        Trace.WriteLine(query)
        'Time to make it run....
 
        Try
            Dim sqlStr As New SqlConnectionStringBuilder()
            sqlStr.DataSource = db_config.server
            sqlStr.InitialCatalog = db_config.catalog
            sqlStr.IntegratedSecurity = True
 
            Dim sqlCon As New SqlConnection(sqlStr.ConnectionString)
            sqlCon.Open()
 
            Dim sqlCommand As New SqlCommand
            sqlCommand.Connection = sqlCon
            sqlCommand.CommandText = cntquery
 
            Dim sqlReader As SqlDataReader
            sqlReader = sqlCommand.ExecuteReader()
 
            Dim maxrecs As Integer
            Dim currec As Integer = 0
 
            If sqlReader.HasRows Then
                sqlReader.Read()
                maxrecs = sqlReader(0)
                sqlReader.Close()
            End If
 
 
 
            'Non Counted....
            sqlCommand.CommandText = query
            sqlReader = sqlCommand.ExecuteReader()
 
 
            While sqlReader.Read()
                currec += 1
                Dim msg As THREAD_MESSAGE
                msg.msgid = 101
                Dim message As New LIST_CTRL_DATA
                message.WksName = sqlReader("Workstation_Name").ToString
                message.InstallStatus = sqlReader("Install_Status").ToString
                message.InstallDate = sqlReader("Install_Date").ToString
                message.AppName = sqlReader("Name").ToString
                message.Version = sqlReader("Version").ToString
                message.Build = sqlReader("Build").ToString
                message.PackageName = sqlReader("Package_Name").ToString
                message.City = sqlReader("City").ToString
                message.State = sqlReader("State").ToString
                message.Percent = (currec * 100) / maxrecs
                msg.msgdata = message
                m_ParentWindow.Invoke(m_NotifyMainWindow, msg)
            End While
 
            sqlReader.Close()
            sqlCon.Close()
 
        Catch e As SqlException
            MsgBox(e.Message, MsgBoxStyle.Critical, "MSSQL Exception")
        End Try
 
        MsgBox("Query is now complete!", MsgBoxStyle.OkOnly, "software collection query")
 
    End Sub
 
End Class

Open in new window

0
planoczCommented:
Are you using 2003 or 2005?
0
wally_davisAuthor Commented:
VS 2005
0
planoczCommented:
I think alot of the problem is in using threading and NotifyMainWindow.
Need to go back to standard style format in the main form. in 2005 you can use (load) to Initialize Data and not worry about placing in sub new or (designer form). Also you have public classes inside classes which is sometimes hard to troubleshoot.
0
wally_davisAuthor Commented:
That's what I thought. Well, I'm going to remove the LVI only because my manager want's to Right-Click, Copy and Paste within the LVI and I know that would require a lot of extra work. So, I'm going to have to remove the LVI, add the DGV and re-write some code to make it work with the DGV.

I appreciate the direction and the initial Class information I need for proper sorting. I'll go ahead and award you the points for both that and your extended efforts to help me re-thing the design of my application.

Thanks again planocz!
Wallace
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.