none
Cargar DataGridView sin tener que recargar toda la base de datos [Solucionado] RRS feed

  • Pregunta

  • Hola a todos, tengo un problema que estado tratando de resolver pero no puedo y buscando tampoco he dado con la solución.

    Estoy trabajando con .NET y Access como base de datos.

    Tengo dos formularios: 

    El primero tiene el DataGridView donde se muestran los clientes de la tabla clientes y al hacer doble clic en una fila me muestra otro formulario en Showdialog para ver la fila de una forma mas ordenada en el formulario y la posibilidad de agregar, modificar, borrar y clonar los datos de una fila. Lo hago de esta forma por temas de diseño ya que la tabla tiene 20 campos de registro y poner todo en un mismo formulario seria incomodo para el usuario (es la forma como lo veo) ademas de que resoluciones como la de 800x600 no se podría ver bien por lo que necesito agregar los datos de esta forma.

    Tengo un DataSet y un DataTable para tener los datos de la base de Access y lo muestro en un DataGridView y hasta aquí todo bien pero el problema es el siguiente:

    Cuando guardo un registro lo hago con INSERT y lo hace bien pero atrás del formulario esta el DataGridView y cuando salgo de la ventana esta fila no aparece entonces solo creo una función que vuelva a recargar el DataSet y lo ponga en el DataGridView y funciona PEEEEEEROOOOOO cuando tengo unos 100,000 o 400,000 registros a la hora de guardar, modificar o clonar un dato tarda una eternidad y esto al usuario no le parecerá gracioso.

    Por lo que, ¿cómo puedo actualizar un DataGridView sin recargar todo el DataSet? 

    Veo que BindingSource soluciona el problema pero lo implemente en mi proyecto pero no me funcionó ya que el DataGridView y el formulario de llenado no se encuentran en el mismo lugar (Por lo menos no me funcionó a mí así).

    También intenté agregar una fila "fantasma" es decir con DataGridView..Rows.Add() pero me da problemas ya que cuando selecciono esa fila y modifico me dice visual studio que afecto 0 de 1 fila esperada.

    Cualquier otra aclaración que necesitan avísenme para poder solucionar este problema que llevo meses.


    • Editado Wipo viernes, 15 de febrero de 2019 22:59
    miércoles, 13 de febrero de 2019 2:58

Respuestas

  • Hola:
    >¿Cómo podría hacer la conexión llenando un dataset con dos tablas?<
     Try
                Dim dsBase As New DataSet
                Dim adaptador1 As New OleDb.OleDbDataAdapter("SELECT * FROM Clientes", cnn)
                adaptador1.Fill(dsBase,"Clientes")
                Dim adaptador2 As New OleDb.OleDbDataAdapter("SELECT * FROM Grupos", cnn)
                adaptador2.Fill(dsBase,"Grupos")
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try

    Un saludo desde Bilbo
    Carlos

    • Propuesto como respuesta Pedro AlfaroModerator jueves, 14 de febrero de 2019 15:40
    • Marcado como respuesta Wipo viernes, 15 de febrero de 2019 2:10
    jueves, 14 de febrero de 2019 10:43

Todas las respuestas

  • Hola:

    Dices: "Cuando guardo un registro lo hago con INSERT...". Si tienes un datatable configurado correctamente (con un dataadapter de lectura y escritura), ¿porque haces un INSERT 'externo', ajeno al datatable?

    Simplemente modifica/añade el registro en el datatable, luego haces un Update y un AcceptChanges, y a volar ;-) Solo tienes que pasar el datatable entre los formularios, y todo sería automático.

    Un saludo


    miércoles, 13 de febrero de 2019 8:16
  • Hola:
    ¿Has probado a poner en Form un DataGridView y un TabControl co 4 o mas pestañas (donde irian los 20 controles para tus 20 campo)?
    Te muestro una imagen de un caso "mas" exagerado que el tuyo.
    En concreto el TabControl tiene 8 pestañas y en esas 8 pestañas hay 65 controles.

    Un Saludo desde Bilbo
    Carlos


    miércoles, 13 de febrero de 2019 9:38
  • Hola:

    Dices: "Cuando guardo un registro lo hago con INSERT...". Si tienes un datatable configurado correctamente (con un dataadapter de lectura y escritura), ¿porque haces un INSERT 'externo', ajeno al datatable?

    Simplemente modifica/añade el registro en el datatable, luego haces un Update y un AcceptChanges, y a volar ;-) Solo tienes que pasar el datatable entre los formularios, y todo sería automático.

    Un saludo


    Bueno acabo de eliminar el código y empezar desde cero ya que estoy un poco confundido y me gustaría que me orientaras a crear una conexión para que se haga todo de forma automática.

    En la base de datos tengo 2 tablas una llamada Grupos y otra Llama Clientes

    Tengo en un modulo la conexión:

        Public Sub ConectarDataSet()
            Dim cnn As New OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & My.Settings.DireccionBase & "\" & My.Settings.NombreBase)
            cnn.Open()
    
            Try
                Dim adaptador As New OleDb.OleDbDataAdapter("SELECT * FROM Clientes, Grupos", cnn)
                Dim dsBase As New DataSet
                adaptador.Fill(dsBase)
    
                dsBase.Tables(0).TableName = "Clientes"
                dsBase.Tables(1).TableName = "Grupos"
    
                Dim TabGrupos As New User_Clientes
                Dim TabClientes As New User_Clientes
    
                TabGrupos.Data_tabla.DataSource = dsBase.Tables("Grupos")
                TabClientes.Data_tabla.DataSource = dsBase.Tables("Clientes")
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
    
        End Sub

    Donde hago la conexión, la dirección la guardo en una variable ya que la base de datos puede ser cambiante.

    Trato de hacer la conexion pero no me deja. He visto que si uso sql puedo hacer:

    SELECT * FROM Clientes; SELECT * FROM Grupos

    Pero estoy trabajando con access así que si hago eso me da un error: "Caracters found after end of SQL Statement"

    ¿Cómo podría hacer la conexión llenando un dataset con dos tablas?

    Busque como hacer una conexión pero siempre dan el ejemplo con una tabla pero yo tengo 2.

    Se que esto pueda considerarse como fuera del tema pero creo que desde aquí tengo el problema.



    Lento pero seguro.

    jueves, 14 de febrero de 2019 1:51
  • Hola:
    >¿Cómo podría hacer la conexión llenando un dataset con dos tablas?<
     Try
                Dim dsBase As New DataSet
                Dim adaptador1 As New OleDb.OleDbDataAdapter("SELECT * FROM Clientes", cnn)
                adaptador1.Fill(dsBase,"Clientes")
                Dim adaptador2 As New OleDb.OleDbDataAdapter("SELECT * FROM Grupos", cnn)
                adaptador2.Fill(dsBase,"Grupos")
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try

    Un saludo desde Bilbo
    Carlos

    • Propuesto como respuesta Pedro AlfaroModerator jueves, 14 de febrero de 2019 15:40
    • Marcado como respuesta Wipo viernes, 15 de febrero de 2019 2:10
    jueves, 14 de febrero de 2019 10:43
  • Gracias me funcionó la conexión.

    Lento pero seguro.

    viernes, 15 de febrero de 2019 2:10
  • Apenas estoy aprendiendo ADO.NET (creo que así se llama) ya que antes usaba visual basic 6.0 y tenia ADODB y empecé a migrar a Visual studio pero hay muchos tutoriales distintos que al final estuve combinando bindingsource y de ahí tenia muchos errores.

    Ya hice lo que propones y me puse a buscar y lo que tengo funciona pero me gustaria saber si lo hago de forma correcta, de ser así ya daría por concluido la pregunta:

    Tengo variables para manejar la tabla grupos y la tabla clientes pero por ahora solo importa la tabla clientes ya que la tabla grupos seguiría el mismo proceso

    Module Declararciones Public dsBase As New DataSet Public conexionbd As String = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & My.Settings.DireccionBase & "\" & My.Settings.NombreBase Public cnn As New OleDb.OleDbConnection Public adaptadorClientes As New OleDb.OleDbDataAdapter Public adaptadorGrupos As New OleDb.OleDbDataAdapter Public tablaClientes As DataTable Public tablaGrupos As DataTable Public rowCliente As DataRow Public constructorClientes As OleDb.OleDbCommandBuilder Public Sub ConectarDataSet() Try cnn = New OleDb.OleDbConnection(conexionbd) cnn.Open() dsBase = New DataSet() adaptadorClientes = New OleDb.OleDbDataAdapter("SELECT * FROM Clientes", cnn) adaptadorGrupos = New OleDb.OleDbDataAdapter("SELECT * FROM Grupos", cnn) adaptadorClientes.Fill(dsBase, "Clientes") adaptadorGrupos.Fill(dsBase, "Grupos") tablaClientes = dsBase.Tables("Clientes") tablaGrupos = dsBase.Tables("Grupos") rowCliente = tablaClientes.NewRow() constructorClientes = New OleDb.OleDbCommandBuilder(adaptadorClientes) Catch ex As Exception MsgBox(ex.Message) End Try End Sub

    End module

      

    Tengo en un modulo donde guardo la conexión y demás variables.

    y en furmulario de clientes en el boton guardar tengo:

    rowCliente("Grupo") = Combo_grupos.Text
                    rowCliente("Nombre_del_grupo") = Combo_NombreGrupo.Text
                    rowCliente("Fecha") = Date_Fecha.Text
                    rowCliente("Nombre") = Text_NombreP.Text
                    rowCliente("Direccion") = Text_DireccionP.Text
                    rowCliente("Colonia") = Text_ColoniaP.Text
                    rowCliente("Telefono") = Text_TelefonoP.Text
                    rowCliente("Garantia1") = Text_Garantia1P.Text
                    rowCliente("Garantia2") = Text_Garantia2P.Text
                    rowCliente("Prestamo") = Text_Prestamo.Text
                    rowCliente("Abono") = Abono
                    rowCliente("Nombre_Aval") = Text_NombreA.Text
                    rowCliente("Direccion_Aval") = Text_DireccionA.Text
                    rowCliente("Colonia_Aval") = Text_ColoniaA.Text
                    rowCliente("Telefono_Aval") = Text_TelefonoA.Text
                    rowCliente("Garantia1_Aval") = Text_Garantia1A.Text
                    rowCliente("Garantia2_Aval") = Text_Garantia2A.Text
    
                    tablaClientes.Rows.Add(rowCliente)
    
                adaptadorClientes.Update(tablaClientes)
                tablaClientes.AcceptChanges()

    Y funciona correctamente por si alguien tiene el mismo problema.

    Mas que nada aunque ya esta solucionado el problema, ¿lo estoy haciendo de la forma mas óptima?

     

    Lento pero seguro.


    • Editado Wipo viernes, 15 de febrero de 2019 3:33
    viernes, 15 de febrero de 2019 3:32
  • Hola:
    Hay 2 modelos, el desconectado que es que tu estas usando.
    El modelo conectado (el que uso yo) que seria algo como esto.
            Try
                Dim msCadenaACCESS As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & Application.StartupPath & "\TU_BASE_DE_DATOS.accdb"
                Dim lsQuery As String = "INSERT INTO clientes (grupo, nombre_grupo, fecha,  demas campos) VALUES (@Grupo, @Nombre_grupo, @Fecha, demas parametros)"
                Using loConexion As New OleDbConnection(msCadenaACCESS)
                    ' crear comando
                    Using loComando As New OleDbCommand(lsQuery, loConexion)
                        'añadir parametros al comando
                        loComando.Parameters.Add(New OleDbParameter("@Grupo", Combo_grupos.text))
                        loComando.Parameters.Add(New OleDbParameter("@Nombre_grupo", Combo_Nombregrupos.text))
                        loComando.Parameters.Add(New OleDbParameter("@Fecha", Date_fecha.text))
                       
                        Demas parametros
                       
                        loConexion.Open()   ' abrir conexión
                        loComando.ExecuteNonQuery()
                    End Using
                End Using
            Catch Exp As Exception
                Me.Cursor = Cursors.Default
                MessageBox.Show(Exp.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Information)
            End Try

    >¿lo estoy haciendo de la forma mas óptima?<
    Las 2 formas son validas, pero a mi me parece mejor el modelo que uso yo, pero para eso estan los "colores"

    Un saludo desde Bilbo
    Carlos


    viernes, 15 de febrero de 2019 7:52
  • Creo que por ahora usare la forma desconectado ya que tengo una base de datos local y no hay más que un usuario y por lo que leí, esta mejor esta opción pero ya en un futuro si tuviera que hacer una aplicación que se conecten varias personas a la vez me serviría más esta opción.

    Gracias por mostrar la otra forma de conexión.


    Lento pero seguro.

    viernes, 15 de febrero de 2019 22:59