Ago 29

Como filtrar las filas de un DataTable usando un RowFilter (VB.Net)

Etiquetas: VB.Net Versión para imprimir Pablo

Más de una vez me he encontrado con un formulario en el cual muestro datos con un DataGridView, pero los datos a mostrar son demasiados, entonces es bueno agregar algún filtro para minimizar la cantidad de registros mostrados.

Para hacer esto hay 2 opciones, la más lenta sería recargar los datos desde la base aplicando filtros y la más rápida, ya que funciona en memoria es filtrar los datos que ya estamos mostrando en pantalla. Para realizar esto, en este ejemplo utilizaremos un DataTable con datos de alumnos el cual filtraremos dinámicamente.

Para empezar con este ejemplo necesitaremos un Form que tenga un CheckBox para indicar si se debe aplicar el filtro o no, un ComboBox para seleccionar el campo a filtrar, un TextBox para ingresar el valor del filtro y un DataGrid para mostrar los datos.

Lo primero que haremos será llenar el ComboBox con el nombre de las columnas de nuestro DataTable:

Private Sub LlenarComboColumnas()
	If TodosAlumnos IsNot Nothing Then ' TodosAlumnos es el DataTable
		For Each c As DataColumn In TodosAlumnos.Columns
			Me.cmbCampo.Items.Add(c.ColumnName)
		Next
	End If
End Sub

Luego agregaremos un método que se encargará de manejar 3 eventos: CheckBox.CheckedChanged, ComboBox.SelectedIndexChanged y TextBox.TextChanged. En éste método se optará por aplicar el filtro o mostrar todos los registros nuevamente:

Private Sub AplicarFiltro(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkFiltro.CheckedChanged, cmbCampo.SelectedIndexChanged, txtValor.TextChanged
	cmbCampo.Enabled = chkFiltro.Checked ' Habilitar o Deshabilitar el ComboBox y TextBox
	txtValor.Enabled = chkFiltro.Checked
 
	If chkFiltro.Checked Then
		Filtrar()
	Else
		Me.cmbCampo.SelectedIndex = 0 ' Resetear el filtro
		Me.txtValor.Text = String.Empty
		AlumnosFiltrados = TodosAlumnos.Copy() ' Mostrar todos los datos nuevamente
		Me.DataGridView1.DataSource = AlumnosFiltrados.DefaultView
	End If
End Sub

Ahora nos resta filtrar, lo que haremos en este caso, ya que el ejemplo es simple, será chequear si el tipo de datos correspondiente a la columna seleccionada es String usaremos como condición LIKE y agregaremos un comodín (*) al final del valor, si en cambio es Integer usaremos = y chequearemos que el valor ingresado sea numérico.

Private Sub Filtrar()
	Try
		AlumnosFiltrados = TodosAlumnos.Copy()
 
		If chkFiltro.Checked AndAlso Me.cmbCampo.SelectedIndex >= 0 AndAlso Not String.IsNullOrEmpty(Me.txtValor.Text) Then
			Dim columna As String = Me.cmbCampo.SelectedItem.ToString()
			Dim condicion As String = "="
			Dim valor As String = txtValor.Text
			' Si no se obtienen todos los datos no se aplica el filtro
			If AlumnosFiltrados.Columns(columna).DataType Is GetType(String) Then
				condicion = "LIKE"
				valor = String.Format("'{0}*'", valor) ' Comodín al final para obtener los valores que empiezan con 'valor'
			ElseIf AlumnosFiltrados.Columns(columna).DataType Is GetType(Integer) Then
				If Not IsNumeric(valor) Then ' Chequear que sea numérico
					Throw New ArgumentException("El valor ingresado no es correcto. Debe ingresar un valor numérico.")
				End If
			End If
 
			Me.AlumnosFiltrados.DefaultView.RowFilter = String.Format("{0} {1} {2}", columna, condicion, valor)
		End If
 
		Me.DataGridView1.DataSource = Me.AlumnosFiltrados.DefaultView ' Mostramos los datos filtrados
	Catch ex As Exception
		MostrarExcepcion(ex)
	End Try
End Sub

Para probar este ejemplo puedes descargar una solución de Visual Studio 2008 (37.03 KB).

También te puede interesar:

Comentarios[6]

  1. manuelNo Gravatar

    sobre el ejemplo de como filtrar las filas de un data table quiero
    preguntarte que es el “AlumnosFiltrados” es alguna tabla o es otro data
    grid.me marca error y dice que no esta declarado

  2. PabloNo Gravatar

    Es otro DataTable, lo uso simplemente para tener siempre una copia de los datos originales. Si bajaste el ejemplo, en el Form1:

    4
    5
    6
    
    #Region " Filtros "
        Private TodosAlumnos As DataTable ' Contiene el DataTable original
        Private AlumnosFiltrados As DataTable ' DataTable sobre el que aplicaremos los filtros

  3. JoseNo Gravatar

    Hola, gracias por el ejemplo. Te hago una consulta, pensando en un gran datatable de cientos de miles de registros, no consume mas memoria la copia del datatable AlumnosFiltrados, no se podria filtrar sobre el mismo datatable y poner y quitar el filtro cuando sea necesario ?

  4. PabloNo Gravatar

    @José, si obviamente tener una copia va a consumir más recursos, y se puede hacer sobre la misma tabla, es sólo que a veces puede servir tener una copia. Para este ejemplo solamente no es muy útil, pero si vas a estar editando datos o algo, te puede ser útil.

  5. daniel aguirreNo Gravatar

    oee tio ns si se avianda dado cuenta pero exitste la funcion DATAVIEW k filtra un data table como consulta sql solo se haria en 4 lineas de codigo y mas eficiente es mm!! ns para k esta la herramienta si no saben usarla mm!!

  6. PabloNo Gravatar

    Se ha disparado la alarma anti-hoygan.

Deja un comentario