none
Como hacer un filtro de busqueda (textbox) Formulario Maestro - Detalle RRS feed

  • Pregunta

  • Tengo ya el form el cual tiene la relacion una tabla Maestro y Otra Detalle va bien, el tema es si tuviera muchos datos y quisiera buscar uno por su numero como hacer ese filtro para que me busque en el maestro y automatico muestre el detalle.

    He echo lo usual que se hace pero en este caso no funciona

    Saludos


    • Editado Javier Roque miércoles, 10 de enero de 2018 14:04
    martes, 9 de enero de 2018 14:08

Todas las respuestas

  • puedes programar la logica para la conexion y busqueda en la db en un metodo y llamar este desde el evento on keypress or change del control textbox., te deberia funcionar.
    miércoles, 10 de enero de 2018 20:53
  • bueno lo clasico que se hace para buscar lo se hacer pero como soin relacionadas maestro detalle no lo hace lo hice en el change pero no nada por eso pense k kizas en este caso seria diferente.
    viernes, 12 de enero de 2018 3:21
  • Buenas Javier,

    Podrias por favor indicarnos el codigo que estas usando? que es lo que hace y que esperas que haga? con eso, facilitas una solucion concreta

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    viernes, 12 de enero de 2018 9:22
  • Ok, disculpa la demora tengo esto:

     Private Sub txtOV_TextChanged(sender As Object, e As EventArgs) Handles txtOV.TextChanged
            Using cnx As New SqlConnection(ConfigurationManager.ConnectionStrings("cnxString").ToString())
                Try
                    Me.oDataTable.Clear()
                    If txtOV.Text <> "" Then
                        Me.oDataAdapter = New SqlDataAdapter("Select * from Ventas where Numero like '%' + '" & txtOV.Text & "' + '%'", cnx)
                    Else
                        Me.oDataAdapter = New SqlDataAdapter("Select * from Ventas order by Id", cnx)
                    End If
                    Me.oDataAdapter.Fill(Me.oDataTable)
                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try
            End Using
        End Sub

    Pero al momento de escribir solo 0 y ni termino de completar la frase sale esto.

    En ese caso solo tengo 1 registro de prueba pero si tuviera 10 o 100 entonces necesitaria buscar la especifica y apenas lo ubique me muestre el detalle de manera automatica.

    Saludos

    domingo, 14 de enero de 2018 14:43
  • Eso es lo clásico?, pues la verdad no sé que tan clásico sea eso, pero fíjate que es una pésima idea, si haces un like, y muchos inician con 2 y tienes 1 millon de registros que empiezan con el 2, crees que sea una buena idea hacer ese like?. Además, según tu código, por ninguna parte veo que llames a los detalles, entonces de donde saldrán los detalles?.

    Creo que tienes que afinar tus búsquedas, sino eso será desastroso, y no creas que te estoy alarmando en vano.

    Saludos,

    domingo, 14 de enero de 2018 17:27
  • Bueno no llamo a los detalles xk del maestro debe hacerse osea hay un relacion maestro-detalle en otro codigo que por ello se muestra como se ve. MUchos inician con el 2? perdon pero 002 es cuando es una factura y 001 cuando es una boleta muchos seran factura como boletas pero no todos seran el mismo numero- pero el resto no lo sera entonces es numero en el caso de la tabla de arriba es por donde quiero buscar  elfiltro es de arriba y automaticamente se haga lo demas la relacion ya la hice ya supongo sabes com ose hace eso solo quiero el filtro que no me sale.

    Respecto a todos 2? 

    El encabezado podra tener muchas series relacionados a factura 002- xxxx pero el resto no sera igual

    puede haber 002-00001,00002,00003,0004 xxxx suceisvamente como 001-000001,00002,0003,xxx para boletas los cuales no van hacer iguales, solo en los detalles se podra ver asi pero eso puedo no ponerlo visible.( en el detalle) es x ello que los numeros no son iguales.

    Yo lo he realizado antes pero hace mucho tiempo pero no me acuerdo.

    Saludos


    domingo, 14 de enero de 2018 20:55
  • Un ejemplo mas claro es esto:

    Los datos de productos son fictisios
    domingo, 14 de enero de 2018 21:12
  • Buenas,

    En primer lugar, decirte que utilizar un textbox directamente en la consulta es una pesima idea, ya que se puede inyectar codigo SQL, lo correcto seria hacerlo usando parametros, para evitar sorpresas.

    En segundo lugar, también te diría que para aligerar la carga, utilices un mínimo de longitud para filtrar, por ejemplo, que el texto sea 0 o más caracteres, a fin de hacer un primer gran filtro antes de empezar a consultar a la DB, si el textbox  esta vacio, haces el orden por Id, si no esta vacio y tiene menos de 3 (n) caracteres, no haces nada, y si tiene mas de 3 (n) caracteres, aplicas el filtro.

    Por ultimo,habria que ver el tipo de dato de tu columna en la DB, aunque supongo que sera Text o VarChar.

    Por ultimo,y lo que creo que es la causa del fallo, tu consulta es

    "Select * from Ventas where Numero like '%' + '" & txtOV.Text & "' + '%'",


    Te sobran comillas simples, tienes piensa en como quedaria al final, por ejemplo like '%''002-00000001''%' , cuando deberia ser like '%002-0000001%', prueba cambiando el select por esto

    "Select * from Ventas where Numero like '%" + txtOV.Text + "%'"

    Nos comentas el resultado

    Atte

    P.D= No se si el & antes y despues de la variable es necesario, mi campo es c# y ahi seguro que no lo es, si ves que es necesario, añadelo, pero sin añadir las comillas


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:


    miércoles, 17 de enero de 2018 14:37
  • Realice el cambio y  sale el mismo problema 

    Referencia a objeto no establecida como instancia de un objeto.

    Saludos.

    miércoles, 17 de enero de 2018 21:07
  • Vale

    Supongo que el problema lo tienes en la parte de mostrar detalles, seguramente intentas acceder al datagrid "maestro" por un indice en el codigo, y al estar vacio, te dice el error.

    En primer lugar, si nos pones el codigo donde te da la excepcion que nos pones, podemos mirarlo.

    En segundo lugar, para facilitarnos el codigo, si pones un breakpoint, en el codigo donde te da el error, puedes ver el estado de las variables, puede ser de gran ayuda para el tema.

    Ya te digo, tiene toda la pinta de que el datagridview "maestro" este vacio, y tu estes intentado obtener una row inexistente, probablemente baste con evaluar si la coleccionMaestro.Count  > 0 para continuar con el datetgrid de detalles

    Comentanos si tienes dudas

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    jueves, 18 de enero de 2018 10:36
  • Vacio? mm pero estoy mostrando la imagen que no lo esta.

    La relacion de maestro-detalle funciona bien solo es cuando quiero añadirle un filtro de busqueda por el numero de documento. Te voy a poner otro caso de imagen donde hay valores

    Que es similar a la imagen anterior no tiene numero vacio quizas una que otra columna si y quizas sea eso bueno como seria porque no busca el numero sin buscar  y clickeo sobre la cabecera muestra detalle tal y como esta no es que no muestre nada simplemete yo digito el numero y sale el error no es que no muestra o tengo problema en el detalle

    viernes, 19 de enero de 2018 0:42
  • Buenas Javier,

    Te digo lo mismo que antes, lo mejor para poder darte una ayuda mas concreta con la solucion, seria que nos pongas el código. Realmente pienso que la parte de la busqueda esta bien, y que te genere esa excepcion se debe a otro problema, que tenemos que intentar localizar, por eso te decia a ver si puedes poner el codigo donde se genera la excepcion, y decirnos en que linea se genera.

    Por otro lado, tambien seria util que nos de informacion de depuracion, si pones un breakpoint en la linea que genera la excepcion, que datos hay?

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    viernes, 19 de enero de 2018 9:06
  • viernes, 19 de enero de 2018 14:38
  • Hola Javier

    me parece q el error está en las comillas, intento con este código:

    ("Select * from Compras where Numero like '%" & txtOC.Text & "%'", ...)

    Saludos


    Brayan De la Cruz
    Lima - Perú

    viernes, 19 de enero de 2018 14:56
  • El problema es que no encuentra el nombre de la columna "Numero" entonces a que se debe eso y como solucionarlo

    La relación de mostrar las tablas esta así no se si por alli el filtro tenga algo porque no ubica las columnas he probado poniendo otra columna tampoco lo hace sera por ser un Maestro - Detalle?

    Private Sub CargaDatos()
            Using cnx As New SqlConnection(ConfigurationManager.ConnectionStrings("cnxString").ToString())
                Dcab = New SqlDataAdapter("Select * from Compras order by Id", cnx)
                Ddet = New SqlDataAdapter("Select * from DetalleCompra order by Id", cnx)
                Ds = New DataSet
                cnx.Open()
                Dcab.Fill(Ds, "Compras")
                Ddet.Fill(Ds, "DetalleCompra")
    
                Ds.Relations.Add("Compras_DetalleCompra", Ds.Tables("Compras").Columns("Numero"), Ds.Tables("DetalleCompra").Columns("Numero"))
    
                
                Me.dgvMaestro.DataSource = Ds
                Me.dgvMaestro.DataMember = "Compras"
                
                Me.dgvDetalle.DataSource = Ds
                Me.dgvDetalle.DataMember = "Compras.Compras_DetalleCompra"
                lblMaestro.Text = "Compras: " & Me.Ds.Tables("Compras").Rows.Count
                lblDetalle.Text = "DetalleCompras: " & Me.dgvDetalle.Rows.Count
    
                
            End Using
        End Sub

    Saludos






    viernes, 19 de enero de 2018 19:32
  • Buenas,

    No entiendo porque nos muestras ese dataset, hace referencia a las tablas Compras y DetalleCompras, pero el problema que teniamos era en la tabla Ventas no?

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    lunes, 22 de enero de 2018 21:45
  • eso es lo de menos la cosa es q es el mismo error en todos los casos no encuentra la columna a filtrar y muestro eso para que vean como esta echo.

    Igual no sale si no sale ventas no sale compras y otro mas

    Saludos

    martes, 23 de enero de 2018 1:46
  • Buenas Javier,

    Podrías ponernos la estructura de la tabla "Ventas" por favor? Quizas ahi podamos ver algo que se escape en el codigo

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:


    martes, 23 de enero de 2018 8:03
  • Saludos

    martes, 23 de enero de 2018 12:30
  • Buenas,

    La verdad es que es muy raro, si el problema fuese de SqlTableAdapter, debería lanzar SqlException y no NullReferenceException, esta ultima dice que algo es null, no que una conexión con base de datos a fallado, si pones un breakpoint en la primera linea del método:

     Me.oDataTable.Clear()

    y vas ejecutando linea a linea, los valores de las variables son correctos?

    Por otro lado, si cuando salta la excepción y estas en el catch, evalúas la propiedad "StackTrace", te dirá donde se ha producido la excepcion, podrías ponernos el StackTrace?

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:


    martes, 23 de enero de 2018 14:02
  • Hola Jorge volviendo a eso que pides solo sale eso que te indique antes:

    Sea formulario venta o compra es el mismo caso. si te pongo compras xk en ventas ya borre el filtro ya no tengo codigo y estoy mirando desde este lado hasta ver que salga para poder hacerle al resto.

    Pero como te dije antes No encuentra la columna Numero o NUmOC le cambie de nombre porque no la ubicaba pero ni asi, he filtrado por otro modo y nada yo creo que es x el tipo de relacion como que queda bloqueada la tabla de arriba por estar relacionada con la de abajo.

    Saludos


    jueves, 25 de enero de 2018 12:30
  • Buenas Javier,

    Nada que ver, el problema no viene de Numero o de NUmOC, si te fijas, el problema viene de que

    Me.oDataTable == Nothing

    Eso es lo que provoca la excepcion al llamar a .Clear() (Por eso una NullReferenceException)

    Prueba a cambiar

    Me.oDataTable.Clear()
    'Por
    If Me.oDataTable IsNot Nothing Then 
        Me.oDataTable.Clear() 
    Else 
        Me.oDataTable = New DataTable() 
    'He puesto DataTable porque creo que es el tipo, 
    'si en vez de eso es DataSet u otro, 
    'cambia el New por el que corresponda

    Con ese cambio, estas evaluando si el Datatable esta inicializado, si es asi, los limpiamos, pero en caso de no estarlo (Nothing) lo inicializamos.

    Prueba y nos comentas el resultado

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:


    lunes, 29 de enero de 2018 16:05
  • Bueno no sale el mismo problema dice nose a inicializado connectionstring aunque ya le puse el cnx.open(). Pero ya lo reviso, habia dejado de lado este proyecto por ese problema.

    lunes, 29 de enero de 2018 16:15
  • Quedo a la espera de tus noticias entonces

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    lunes, 29 de enero de 2018 16:24
  • Bueno ya lo estuve arreglando pero ya no sale errores pero tampoco filtra :S

    Saludos

    martes, 30 de enero de 2018 3:21
  • Buenas Javier,

    Podrias poner el codigo que te ha quedado para echarle un ojo a ver porque no filtra?

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    miércoles, 31 de enero de 2018 9:37
  • Bueno puede hacer eso y afinar con un top 1000 con lo que solo devuelve los 1000 priemros.

    No obstante tieens razon y siempre es mejor usar la comparación de igualdad para registros númericos.

    Otra opción es mejorar el filtro con un desplegable que le permita seleccionar la operación de filtro porejemplo conteniendo startwith, contains, equal, major than , minor tan , between y segun la operción filtrar asi queda al libre albedrio del usuario la operación de filtrado. también puede incluso poner un desplegable para indicar el top o numero maximo de registros a devolver como top 100, top 500 , top 1000, all , first, last etc...

    El filtro debe ser siempre sobre la tabla maestraa y al pulsar sobre un registro de la maestra deberia cargar los registros de la tabla detalle en el segundo grid. ESE ES EL FUNCIONAMIENTO CLASICO MAESTRO DETALLE. y para hacerlo efeciente siempre debe cargar el detalle bajo petición del click del grid del maestro.

    miércoles, 31 de enero de 2018 9:43
  • Using cnx As New SqlConnection(ConfigurationManager.ConnectionStrings("cnxString").ToString())
                Try
                    If Me.oDataTable IsNot Nothing And txtOC.Text <> "" Then
                        Me.oDataTable.Clear()
                        Me.oDataAdapter = New SqlDataAdapter("Select * from Compras where NumOC like '%" & txtOC.Text.Trim & "%'", cnx)
                    Else
                        
                        Me.oDataAdapter = New SqlDataAdapter("Select * from Compras order by Id", cnx)
                    End If
    
                    Me.oDataAdapter.Fill(Me.oDataTable)
                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try
            End Using


    jueves, 1 de febrero de 2018 16:32
  • Buenas,

    Siento el retraso... Comprobar elvalor de oDataTable no deberia ser la condicion del filtro, solo deberia estar para limpiarla o no, prueba asi:

    Using cnx As New SqlConnection(ConfigurationManager.ConnectionStrings("cnxString").ToString())
        Try
            'Evaluamos si es Nothing para limpiarla o no
            If Me.oDataTable IsNot Nothing Then
                Me.oDataTable.Clear()
            End If
            
            'Aplicamos o no el filtro
            If txtOC.Text <> "" Then
               Me.oDataAdapter = New SqlDataAdapter("Select * from Compras where NumOC like '%" & txtOC.Text.Trim & "%'", cnx)
            Else                    
               Me.oDataAdapter = New SqlDataAdapter("Select * from Compras order by Id", cnx)
            End If
    
            Me.oDataAdapter.Fill(Me.oDataTable)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Using

    Con lo que tenias antes, si el datatable era Nothing, nunca iba a aplicar el filtro

    Nos comentas el resultado

    Atte



    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    miércoles, 7 de febrero de 2018 12:52
  • Esto es lo que obtuve:

    miércoles, 7 de febrero de 2018 14:21
  • Vale,

    Veo que el datatable no lo usas antes, ya que es null, puedes hacerlo asi

    Using cnx As New SqlConnection(ConfigurationManager.ConnectionStrings("cnxString").ToString())
        Try
            'Evaluamos si es Nothing para limpiarla o no
            If Me.oDataTable IsNot Nothing Then
                Me.oDataTable.Clear()
            Else
                Me.oDataTable = New DataTable() 
            End If
            
            'Aplicamos o no el filtro
            If txtOC.Text <> "" Then
               Me.oDataAdapter = New SqlDataAdapter("Select * from Compras where NumOC like '%" & txtOC.Text.Trim & "%'", cnx)
            Else                    
               Me.oDataAdapter = New SqlDataAdapter("Select * from Compras order by Id", cnx)
            End If
    
            Me.oDataAdapter.Fill(Me.oDataTable)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Using

    Con eso, si el datatable tenia valor, lo vas a limpiar, si era NothingN lo vas a iniciar.

    Nos comentas comocte va. 

    Atte


    No olvides votar mi comentario si te ha ayudado y marcarlo como respuesta si ha sido la solución, con eso ayudas a mejorar mi reputación en la comunidad y a identificar la respuesta a la gente que tenga el mismo problema.

    Para obtener una respuesta lo más rápida y concisa posible, te recomiendo:

    miércoles, 7 de febrero de 2018 18:47
  • Bueno no sale ningun error pero tampoco filtra es decir muestra las 3 filas del maestro mas no uno del filtrado solo no hace nada. Bueno creo que no se puede filtrar un maestro-detalle Quizas la consulta debe ser distinta a la forma del codigo quizas de la relacion

    'relacion de tablas
                Ds.Relations.Add("Compras_DetalleCompra", Ds.Tables("Compras").Columns("NumOC"), Ds.Tables("DetalleCompra").Columns("NumOC"))

    algo por alli

    Saludos

    miércoles, 7 de febrero de 2018 19:51