我尝试使用datagridview
在combobox
上创建过滤器。我想要做的是过滤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
答案 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
现在你有一个存储过程和一个地方来获取和绑定数据。