none
Lentitud al cargar datos de un datagridview a otro formulario RRS feed

  • Pregunta

  • Buenas nuevamente! Tengo en visual.net un datagridview que recibe datos de una tabla de sql server 2017 que me muestra todos mis registros, este datagrid lo uso para buscar el registro que necesito. Empleé un código que cito más abajo para que al hacer doble click en el registro, me abra un form que pasa los datos a cajas de texto.

    Frm_cargaHC2.TEX_NHC.Text = Me.Dgv_Buscarpaciente.Rows(Fila).Cells(1).Value.ToString

    El formulario externo viene a ser este "cargaHC2" que se abre al final que indico qué dato va en cada caja de texto con un Frm_cargaHC2.Show(). Bien, el código anda. Pero el tema es que demora muchísimo en cargar todo y a veces, se "tara" y no carga. Son como 44 campos los que debe pasar del datagrid a sus respectivas cajas de texto, algunos de ellos son campos de texto bastante largos.

    A su vez, esto me preocupa porque en este formulario donde se deben cargar los datos, tengo un tabcontrol con pestañas que contendrán otros datagridview que a su vez, tienen consultas efectuadas en sql (en otras tablas) que deben cargar en el load del form. Entonces, me temo que sea un gran desastre. 

    Como no tengo experiencia y estoy haciendo algo para uso personal, no tengo idea de programación, les agradecería me sugieran una mejor manera de hacerlo dado que esta, no creo que vaya a funcionar. Se me ocurrió modificar todo y que en lugar de abrir otro formulario sea todo en el mismo, será que eso me mejorará el rendimiento?

    PD: es una base de datos en sql que tiene varias tablas, una de carga de la  historia clínica con todos los datos básicos (que son estos 44 campos), otra que toma como llave foránea el ID de esa tabla de carga, donde registraré las consultas (que se podrán ver en el datagridview en una de las pestañas del tabcontrol que posee ese form que debe abrirse, de esa manera veo en el formulario de ese paciente, haciendo una búsqueda por su número de historia clínica, sus consultas y no todas) y así con otras tablas más. Esta parte ya la tengo hecha y funciona, el tema es la gran lentitud. Me temo que no lo estoy haciendo de manera correcta.

    jueves, 10 de mayo de 2018 19:46

Respuestas

  • Hola:
    Este ejemplo consta de 2 Forms como los de las imágenes

    Copia y pega el siguiente código

    Para el Form1

    Option Explicit On
    Option Strict On
    Imports System.Data.SqlClient
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Try
                Dim msCadenaSQL As String = "Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
                Dim lsQuery As String = "SELECT employeeid, lastname FROM employees ORDER BY employeeid"
                Using loConexion As New SqlConnection(msCadenaSQL)
                    Using loDataAdapter As New SqlDataAdapter(lsQuery, loConexion)
                        Dim loDataTable As New DataTable
                        loDataAdapter.Fill(loDataTable)
                        Me.dgvEmployees.DataSource = loDataTable
                    End Using
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub

        Private Sub dgvEmployees_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellClick
            If e.RowIndex = -1 Then
                Return
            End If
            Dim loFila As DataGridViewRow = Me.dgvEmployees.CurrentRow()
            Using loForm As New Form2
                loForm.Fila = loFila
                loForm.ShowDialog()
            End Using
        End Sub
    End Class

    Para el Form2

    Option Explicit On
    Option Strict On
    Imports System.Data.SqlClient
    Public Class Form2
        Public Property Fila As DataGridViewRow

        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            Try
                'Visualizar los datos de employee
                Me.txtEmployeeid.Text = Fila.Cells("employeeid").Value.ToString
                Me.txtlastname.Text = Fila.Cells("lastname").Value.ToString
                'Visualizar los datos de orders de el employee seleccionado
                Dim msCadenaSQL As String = "Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
                Dim lsQuery As String = "SELECT orderid, orderdate FROM orders WHERE employeeid=@Id"
                Using loConexion As New SqlConnection(msCadenaSQL)
                    Using loComando As New SqlCommand(lsQuery, loConexion)
                        'añadir parametro al comando
                        loComando.Parameters.Add(New SqlParameter("@Id", Fila.Cells("employeeid").Value))
                        Using loDataAdapter As New SqlDataAdapter(loComando)
                            Dim loDataTable As New DataTable
                            loDataAdapter.Fill(loDataTable)
                            Me.dgvOrders.DataSource = loDataTable
                        End Using
                    End Using
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
    End Class

    Un saludo desde Bilbo
    Carlos
    viernes, 11 de mayo de 2018 7:46

Todas las respuestas

  • Hola:
    Este ejemplo consta de 2 Forms como los de las imágenes

    Copia y pega el siguiente código

    Para el Form1

    Option Explicit On
    Option Strict On
    Imports System.Data.SqlClient
    Public Class Form1
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Try
                Dim msCadenaSQL As String = "Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
                Dim lsQuery As String = "SELECT employeeid, lastname FROM employees ORDER BY employeeid"
                Using loConexion As New SqlConnection(msCadenaSQL)
                    Using loDataAdapter As New SqlDataAdapter(lsQuery, loConexion)
                        Dim loDataTable As New DataTable
                        loDataAdapter.Fill(loDataTable)
                        Me.dgvEmployees.DataSource = loDataTable
                    End Using
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub

        Private Sub dgvEmployees_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles dgvEmployees.CellClick
            If e.RowIndex = -1 Then
                Return
            End If
            Dim loFila As DataGridViewRow = Me.dgvEmployees.CurrentRow()
            Using loForm As New Form2
                loForm.Fila = loFila
                loForm.ShowDialog()
            End Using
        End Sub
    End Class

    Para el Form2

    Option Explicit On
    Option Strict On
    Imports System.Data.SqlClient
    Public Class Form2
        Public Property Fila As DataGridViewRow

        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            Try
                'Visualizar los datos de employee
                Me.txtEmployeeid.Text = Fila.Cells("employeeid").Value.ToString
                Me.txtlastname.Text = Fila.Cells("lastname").Value.ToString
                'Visualizar los datos de orders de el employee seleccionado
                Dim msCadenaSQL As String = "Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
                Dim lsQuery As String = "SELECT orderid, orderdate FROM orders WHERE employeeid=@Id"
                Using loConexion As New SqlConnection(msCadenaSQL)
                    Using loComando As New SqlCommand(lsQuery, loConexion)
                        'añadir parametro al comando
                        loComando.Parameters.Add(New SqlParameter("@Id", Fila.Cells("employeeid").Value))
                        Using loDataAdapter As New SqlDataAdapter(loComando)
                            Dim loDataTable As New DataTable
                            loDataAdapter.Fill(loDataTable)
                            Me.dgvOrders.DataSource = loDataTable
                        End Using
                    End Using
                End Using
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End Sub
    End Class

    Un saludo desde Bilbo
    Carlos
    viernes, 11 de mayo de 2018 7:46
  • Muchas gracias Carlos! Había considerado hacer una nueva consulta para traer los datos sin "pedirlos" del datagrid pero no me cerraba bien por qué no funcionaba del todo bien. Y creo que ya me di cuenta dónde hice "la chanchada". Resulta que en ese form donde tengo el tabcontrol en el que cargo los datos al hacer dobleclick en el registro del datagridview tengo combobox no enlazados y datatimepicker. Entonces, en mi desconocimiento, como la 1era vez que lo probé anduvo y bastante "rápido", no pensé que allí pudiera estar el error. Pero ahora, dado que no me andaba del todo bien y no entendía por qué (lo hice con otro form y me funcionaba perfectamente) empecé a pensar qué diferenciaba un form de otro y ahí me di cuenta que creo que el error está aquí:

    Esa línea que puse arriba es de un textbox (eso está claro en el evento dobleclick del datagridview del formulario "principal"). Pero para los combobox y el datatimepicker puse así:

    para el datatime (hay 1 solo en el form): Frm_cargaHC2.DTP_Fechanac.Value = .Cells(6).Value.ToString

    y para los combobox (varios): Frm_cargaHC2.CMB_Sexo.SelectedItem = .Cells(8).Value.ToString

    Leí por este foro que otro usuario tenía problemas al pasar los datos del datagridview al combobox y uno de los miembros que respondía (creo que Leandro Tuttini) le decía que el problema era que intentaba recuperar los datos y pasarlos al combobox y que no era conveniente, que hay que tomar los datos de la base de datos. Yo lo que quería hacer era justamente recuperarlos, para luego poder editarlos o leerlos (o crear nuevos registros en otras tablas asociados a esa persona, todo para lo cual necesito que se abra ese form que es muy semejante a uno donde hago la carga inicial de esa persona).

    Millón de gracias por tu tiempo Carlos! y te agradecería si me opinaras sobre esto que puse, que estoy casi convencida que es el problema pero prefiero me des tu opinión de experto, dado que yo no me dedico a esto (hace poco más de 1 mes que estoy aprendiendo de ustedes) y estoy creándome una aplicación para uso personal porque en el mercado no existe ninguna que cumpla con mis necesidades y mandarla a hacer, me es imposible por ahora. Te mando un saludo desde el sur de Argentina, La Pampa (Santa Rosa, su capital).

    viernes, 11 de mayo de 2018 16:18
  • La verdad lo que me sucedió fue de lo más insólito (desde mi perspectiva claro). Paso a relatarles. 
    Probé con 1 solo textbox y columna del datagrid y vi que no abría (uno que era sólo texto). Entonces quité todo y dije a ver si al menos me abre el form! y para mi sorpresa NO LO ABRE! Probé abrir el form desde un botón a ver si abría, pues sí abre.
    Bueno empecé a hacer doble click más rápido, más lento, a ver si era una cuestión del evento... pues para mi sorpresa haciendo eso di con que SOLO abre el formulario si hago dobleclick en una columna (una columna que está por la mitad del datagridview, entonces ahí sí me carga de la fila seleccionada, todos los datos que le pido). Ahí comprendí por qué "a veces me lo abría y otras no"... claro, dependía de si yo justo hacía el doble click en esa columna. Lo que no tengo idea es por qué esa columna o dónde le di la instrucción para que lo haga sólo en esa.
    Conclusión: mi código original anda bien... sin nada de lo que pensé del combobox o del datatime. Cambio la pregunta a por qué me toma esa columna en específico?
    El código es ese que puse en mi pregunta original:
    Private Sub Dgv_Buscarpaciente_CellContentDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles Dgv_Buscarpaciente.CellContentDoubleClick

    Dim Fila As Byte = CByte(Me.Dgv_Buscarpaciente.CurrentCell.RowIndex)
    Frm_cargaHC.TEX_NHC.Text = Me.Dgv_Buscarpaciente.Rows(Fila).Cells(1).Value.ToString
    Frm_cargaHC.LAB_Fecha1.Text = Me.Dgv_Buscarpaciente.Rows(Fila).Cells(2).Value.ToString
    Frm_cargaHC.TEX_Apellido.Text = Me.Dgv_Buscarpaciente.Rows(Fila).Cells(3).Value.ToString
    Frm_cargaHC.TEX_DNI.Text = Me.Dgv_Buscarpaciente.Rows(Fila).Cells(4).Value.ToString

    (así para todos los objetos con sus columnas y termina con)

    Frm_cargaHC.Show()
    End sub

    El selectionmode del datagridview es Fullrowselect. Arranca de 1 porque el datagridview tiene una columna que añadí que es un checkbox para poder eliminar los registros y está oculta (aparece si uno tilda un checkbox). Y la columna que por alguna razón toma como la celda para ejecutar el evento del dobleclick es la de Edad que vendría a ser la columna 7 del datagrid y no tengo la más remota idea de por qué! Alguna idea de dónde metí la pata?
    viernes, 11 de mayo de 2018 19:20
  • Un poco avergonzada que acabo de darme cuenta que pifié el evento... content... cambié por doubleclick y listo! Gracias!!!
    viernes, 11 de mayo de 2018 20:11