使用多个组合框过滤数据网格视图中的数据

时间:2016-01-24 10:25:23

标签: sql-server vb.net datagridview combobox filtering

我尝试使用datagridviewcombobox上创建过滤器。我想要做的是过滤datagridview中的过滤数据。我已经尝试了一些我认为可以解决问题的方法,但它不起作用。我有五个comboboxes用于过滤。例如,第一个combobox是年份,那么我仍然希望将搜索过滤到年级,然后过滤到部分,依此类推。因此,用户将能够从数据库中对其搜索进行排序或过滤。到目前为止,我有我的存储过程代码,并尝试了两个combobox

存储过程dbo.uspYearGradeFilter

ALTER PROCEDURE [dbo].[uspYearGradeFilter]
    @Year Nvarchar(20),
    @Grade Nvarchar(20)
AS
BEGIN
    SET NOCOUNT ON;

        SELECT si.StudentID,SI.Surname,SI.FirstName,SI.MiddleName,si.Gender,si.BirthDay,SI.TelNum,
        Birthday,getdate() AS [Today],
            Datediff(yy,BirthDay,getdate()) -
            CASE
                WHEN DATEADD(YY, DATEDIFF(YY,BirthDay,getdate()),BirthDay)
                >GETDATE() THEN 1
                ELSE 0

            END AS [age]
        FROM StudentInformation SI
        JOIN StudentHistory SH
        ON SI.StudentID = SH.StudentID

        WHERE sh.SchoolYear Like '%'+ @Year+'%' AND sh.levels Like '%'+ @Grade+'%' 
END

存储过程dbo.uspYearFilter

ALTER PROCEDURE [dbo].[uspYearFilter]
    @Year Nvarchar(20)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;


        SELECT si.StudentID,SI.Surname,SI.FirstName,SI.MiddleName,si.Gender,si.BirthDay,SI.TelNum,
        Birthday,getdate() AS [Today],
            Datediff(yy,BirthDay,getdate()) -
            CASE
                WHEN DATEADD(YY, DATEDIFF(YY,BirthDay,getdate()),BirthDay)
                >GETDATE() THEN 1
                ELSE 0

            END AS [age]
        FROM StudentInformation SI
        JOIN StudentHistory SH
        ON SI.StudentID = SH.StudentID
        WHERE sh.SchoolYear Like '%'+ @Year+'%' 

END

vb.net代码cboYear

Private Sub cboYear_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboYear.SelectedIndexChanged
        If cboYear.SelectedIndex >= 0 Then
            Using cmd As New SqlClient.SqlCommand("dbo.uspYearFilter", cn)
                cmd.Parameters.AddWithValue("@Year ", cboYear.Text)
                cmd.CommandType = CommandType.StoredProcedure
                da.SelectCommand = cmd
                dt.Clear()
                da.Fill(dt)
                dgv1.RowTemplate.Height = 30
                dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
                dgv1.AutoGenerateColumns = False
                dgv1.Columns(0).Name = "Student ID"
                dgv1.Columns(0).DataPropertyName = "StudentID"
                dgv1.Columns(1).Name = "Last Name"
                dgv1.Columns(1).DataPropertyName = "SurName"
                dgv1.Columns(2).Name = "First Name"
                dgv1.Columns(2).DataPropertyName = "FirstName"
                dgv1.Columns(3).Name = "Middle Name"
                dgv1.Columns(3).DataPropertyName = "MiddleName"
                dgv1.Columns(4).Name = "Gender"
                dgv1.Columns(4).DataPropertyName = "Gender"
                dgv1.Columns(5).Name = "Birthday"
                dgv1.Columns(5).DataPropertyName = "Birthday"
                dgv1.Columns(6).Name = "Age"
                dgv1.Columns(6).DataPropertyName = "Age"
                dgv1.Columns(7).Name = "ContactNumber"
                dgv1.Columns(7).DataPropertyName = "TelNum"
                dgv1.DataSource = dt
            End Using

        ElseIf cboYear.SelectedIndex > 0 And cboGrade.SelectedIndex > 0 Then
            Using cmd As New SqlClient.SqlCommand("dbo.uspYearGradeFilter", cn)
                cmd.Parameters.AddWithValue("@Year ", cboYear.Text)
                cmd.Parameters.AddWithValue("@Grade ", cboGrade.Text)
                cmd.CommandType = CommandType.StoredProcedure
                da.SelectCommand = cmd
                dt.Clear()
                da.Fill(dt)
                dgv1.RowTemplate.Height = 30
                dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
                dgv1.AutoGenerateColumns = False
                dgv1.Columns(0).Name = "Student ID"
                dgv1.Columns(0).DataPropertyName = "StudentID"
                dgv1.Columns(1).Name = "Last Name"
                dgv1.Columns(1).DataPropertyName = "SurName"
                dgv1.Columns(2).Name = "First Name"
                dgv1.Columns(2).DataPropertyName = "FirstName"
                dgv1.Columns(3).Name = "Middle Name"
                dgv1.Columns(3).DataPropertyName = "MiddleName"
                dgv1.Columns(4).Name = "Gender"
                dgv1.Columns(4).DataPropertyName = "Gender"
                dgv1.Columns(5).Name = "Birthday"
                dgv1.Columns(5).DataPropertyName = "Birthday"
                dgv1.Columns(6).Name = "Age"
                dgv1.Columns(6).DataPropertyName = "Age"
                dgv1.Columns(7).Name = "ContactNumber"
                dgv1.Columns(7).DataPropertyName = "TelNum"
                dgv1.DataSource = dt

            End Using

        End If

CboGrade

Private Sub cboGrade_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboGrade.SelectedIndexChanged
        If cboYear.SelectedIndex > 0 And cboGrade.SelectedIndex > 0 Then
            Using cmd As New SqlClient.SqlCommand("dbo.uspYearGradeFilter", cn)
     cmd.Parameters.AddWithValue("@Year ", cboYear.Text)
            cmd.Parameters.AddWithValue("@Grade ", cboGrade.Text)
                cmd.CommandType = CommandType.StoredProcedure
                da.SelectCommand = cmd
                dt.Clear()
                da.Fill(dt)
                dgv1.RowTemplate.Height = 30
                dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
                dgv1.AutoGenerateColumns = False
                dgv1.Columns(0).Name = "Student ID"
                dgv1.Columns(0).DataPropertyName = "StudentID"
                dgv1.Columns(1).Name = "Last Name"
                dgv1.Columns(1).DataPropertyName = "SurName"
                dgv1.Columns(2).Name = "First Name"
                dgv1.Columns(2).DataPropertyName = "FirstName"
                dgv1.Columns(3).Name = "Middle Name"
                dgv1.Columns(3).DataPropertyName = "MiddleName"
                dgv1.Columns(4).Name = "Gender"
                dgv1.Columns(4).DataPropertyName = "Gender"
                dgv1.Columns(5).Name = "Birthday"
                dgv1.Columns(5).DataPropertyName = "Birthday"
                dgv1.Columns(6).Name = "Age"
                dgv1.Columns(6).DataPropertyName = "Age"
                dgv1.Columns(7).Name = "ContactNumber"
                dgv1.Columns(7).DataPropertyName = "TelNum"
                dgv1.DataSource = dt
            End Using
        ElseIf cboYear.SelectedIndex >= 0 Then
            Using cmd As New SqlClient.SqlCommand("dbo.uspYearFilter", cn)
                cmd.Parameters.AddWithValue("@Year ", cboYear.Text)
                cmd.CommandType = CommandType.StoredProcedure
                da.SelectCommand = cmd
                dt.Clear()
                da.Fill(dt)
                dgv1.RowTemplate.Height = 30
                dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
                dgv1.AutoGenerateColumns = False
                dgv1.Columns(0).Name = "Student ID"
                dgv1.Columns(0).DataPropertyName = "StudentID"
                dgv1.Columns(1).Name = "Last Name"
                dgv1.Columns(1).DataPropertyName = "SurName"
                dgv1.Columns(2).Name = "First Name"
                dgv1.Columns(2).DataPropertyName = "FirstName"
                dgv1.Columns(3).Name = "Middle Name"
                dgv1.Columns(3).DataPropertyName = "MiddleName"
                dgv1.Columns(4).Name = "Gender"
                dgv1.Columns(4).DataPropertyName = "Gender"
                dgv1.Columns(5).Name = "Birthday"
                dgv1.Columns(5).DataPropertyName = "Birthday"
                dgv1.Columns(6).Name = "Age"
                dgv1.Columns(6).DataPropertyName = "Age"
                dgv1.Columns(7).Name = "ContactNumber"
                dgv1.Columns(7).DataPropertyName = "TelNum"
                dgv1.DataSource = dt
            End Using
    End If

1 个答案:

答案 0 :(得分:1)

如果您只是将代码复制并粘贴到项目中,此代码将无法运行,但它应该非常接近。在这里,我重构了存储过程以接受可能来自组合框的所有参数。您可以按照相同的模式添加任意数量的其他参数。 每个参数默认为NULL,以便您可以从代码中调用它,而无需将SqlParameter实际添加到命令中。如果用户未从一个或多个组合中选择值,您将执行此操作。 COALESCE函数将使用参数值,如果它不为null,否则它将只匹配数据库值,从而有效地关闭该列的过滤器。

ALTER PROCEDURE [dbo].[uspStudentFilter]
    @Year Nvarchar(20) = NULL,
    @Grade Nvarchar(20) = NULL,
    @Other1 Nvarchar(20) = NULL,
    @Other2 Nvarchar(20) = NULL
AS
BEGIN
    SET NOCOUNT ON;
        SELECT si.StudentID,SI.Surname,SI.FirstName,SI.MiddleName,si.Gender,si.BirthDay,SI.TelNum,
        Birthday,getdate() AS [Today],
            Datediff(yy,BirthDay,getdate()) -
            CASE
                WHEN DATEADD(YY, DATEDIFF(YY,BirthDay,getdate()),BirthDay)
                >GETDATE() THEN 1
                ELSE 0
            END AS [age]
        FROM StudentInformation SI
        INNER JOIN StudentHistory SH
            ON SI.StudentID = SH.StudentID
        WHERE sh.SchoolYear LIKE COALESCE('%'+ @Year+'%', sh.SchoolYear)
            AND sh.Levels LIKE COALESCE('%' + @Grade + '%', sh.Levels)
            AND sh.Other1 LIKE COALESCE('%' + @Other1 + '%', sh.Other1)
            -- etc.. for each filter
END

现在,您只需要构建一次网格(除非我遗漏了某些内容,并且每个过滤器选项需要不同的列)。在某个初始化位置执行此操作,我在Form_Load中显示,但您可能希望将其放在自己的Sub中。

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    dgv1.RowTemplate.Height = 30
    dgv1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders
    dgv1.AutoGenerateColumns = False
    dgv1.Columns(0).Name = "Student ID"
    dgv1.Columns(0).DataPropertyName = "StudentID"
    dgv1.Columns(1).Name = "Last Name"
    dgv1.Columns(1).DataPropertyName = "SurName"
    dgv1.Columns(2).Name = "First Name"
    dgv1.Columns(2).DataPropertyName = "FirstName"
    dgv1.Columns(3).Name = "Middle Name"
    dgv1.Columns(3).DataPropertyName = "MiddleName"
    'etc...
    'etc.....
End Sub

最后,使用一个Sub来获取数据并绑定网格。只需从每个组合框选择更改事件中调用此Sub。仅当组合具有选定内容时,它才会向命令添加SqlParameter。请记住,存储过程可以处理未传递参数,因为它具有默认值。

Private Sub BindGrid()
    Using cmd As New SqlCommand("dbo.uspStudentInfo", cn)

        cmd.CommandType = CommandType.StoredProcedure

        'Add a parameter for all comboboxes but only if a value is selected:

        If cboYear.SelectedIndex >= 0 Then
            Dim paramYear As New SqlParameter("@Year", SqlDbType.NVarChar, 20)
            paramYear.Value = cboYear.Text
            cmd.Parameters.Add(paramYear)
        End If

        If cboGrade.SelectedIndex >= 0 Then
            Dim paramGrade As New SqlParameter("@Grade", SqlDbType.NVarChar, 20)
            paramGrade.Value = cboGrade.Text
            cmd.Parameters.Add(paramGrade)
        End If

        'Etc, etc...

        da.SelectCommand = cmd
        dt.Clear()
        da.Fill(dt)
        dgv1.DataSource = dt

    End Using
End Sub

现在你有一个存储过程和一个地方来获取和绑定数据。