Título: Llenar mas de un TextBox desde Base de Datos
Publicado por: SilverLycan68 en 1 Junio 2018, 00:12 am
Buenas tardes. Necesito llenar 20 TextBox desde una tabla en MySQL en mas de una form. Entonces hize una funcion, pero no se si sea la mejor forma de hacerlo. Sub EscribirTextBox(ByVal fForm As Form, ByVal consulta As String) Dim objeto As Object Try command = New MySqlCommand(consulta, con) reader = command.ExecuteReader If reader.Read Then For Each objeto In fForm.Controls If TypeOf objeto Is TextBox Then CType(objeto, TextBox).Text = reader(CType(objeto, TextBox).Name.Substring(3)) End If End If Next Else MsgBox("Los datos no existen") End If reader.Close() Catch ex As Exception MsgBox("Error al escribir." + vbLf + ex.ToString) End Try End Sub
Por lo que he revisado no es recomendable usar Objet.
Título: Re: Llenar mas de un TextBox desde Base de Datos
Publicado por: Eleкtro en 1 Junio 2018, 02:10 am
Yo le haría algunos cambios significativos. Prueba así: <DebuggerStepThrough> Friend Shared Sub PopulateTextBoxValues(ByVal controlCollection As Control.ControlCollection, ByVal query As String, ByVal connection As MySqlConnection) Dim owner As Control = controlCollection.Owner Try Using command As New MySqlCommand(query, connection), reader As MySqlDataReader = command.ExecuteReader() ' Do While (reader.Read()) ' ... ' Loop If (reader.Read()) Then For Each tb As TextBox In controlCollection.OfType(Of TextBox) Dim value As String = reader.GetString(tb.Name.Substring(3)) tb.Text = value Next tb Else MessageBox.Show(owner, "Los datos no existen.", owner.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If End Using Catch ex As Exception Dim errorString As String = String.Format("Error al escribir. {0}", ex.Message) MessageBox.Show(owner, errorString, owner.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub
O de forma asincrónica si lo prefieres: <DebuggerStepThrough> Friend Shared Async Sub PopulateTextBoxValuesAsync(ByVal controlCollection As Control.ControlCollection, ByVal query As String, ByVal connection As MySqlConnection) Dim owner As Control = controlCollection.Owner owner.Invoke(Sub(ctrl As Control) ctrl.Enabled = False) Try Using command As New MySqlCommand(query, connection), reader As DbDataReader = Await command.ExecuteReaderAsync() ' reader As MySqlDataReader = DirectCast(Await command.ExecuteReaderAsync(), MySqlDataReader) ' Do While Await (reader.ReadAsync()) ' ... ' Loop If Await (reader.ReadAsync()) Then Dim lock As New Object() SyncLock lock ' Safe thread synchronization. For Each tb As TextBox In controlCollection.OfType(Of TextBox) Dim value As String = CStr(reader(tb.Name.Substring(3))) ' If MySqlDataReader cast: ' Dim value As String = Await reader.GetFieldValueAsync(Of String)(Integer, Nothing) tb.BeginInvoke(Sub(x As TextBox) x.Text = value) Next tb End SyncLock Else MessageBox.Show(owner, "Los datos no existen.", owner.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation) End If End Using Catch ex As Exception Dim errorString As String = String.Format("Error al escribir. {0}", ex.Message) MessageBox.Show(owner, errorString, owner.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) Finally owner.Invoke(Sub(ctrl As Control) ctrl.Enabled = True) End Try End Sub
Por si no resulta evidente: a ambos métodos le pasarías la referencia del contenedor de controles, Form.Controls, en lugar de una referencia del Form. PD: no he probado los códigos, los escribí al vuelo. En realidad no uso MySQL para nada, así que son códigos escritos/basados en pura intuición, en teoría deberían funcionar correctamente suponiendo que quieras que hagan lo mismo que el código original que compartiste (por si acaso dejé escrito y comentado un búcle Do-While que puedes adaptar). Saludos
Título: Re: Llenar mas de un TextBox desde Base de Datos
Publicado por: Serapis en 1 Junio 2018, 05:27 am
Bueno, olvidas lo más importante y es que dices que quieres escribir en más de un formulario (que se ve que contienen controles textbox del mismo nombre?)... No voy a entrar demasiado en señalar en que no es la forma más óptima... creo que si varios textbox aparecen por igual en varios formularios, podrías crear un contenedor (control de usuario), que puedas poner a cada uno de los formularios. Esto haría innecesario recorrer la colección de controles de cada formulario, ese contenedor ya tendría esos controles... ...bueno, a lo que veníamos... Cada formulario que lo precise, declara una coleccion, de nombre idéntico (por ejemplo txtBoxes as collection) en cada formulario... Luego (desde donde se vaya a usar), creas una colección y metes en ella cada formulario que interese (esos que contiene copia de dichos textbox y que deben ser actualizados). La llamada a la función (seguramente desde un botón) sería mñás o menos así... dim colFrm = nueva coleccion with colFrm 'si form1.txtBoxes.count>0) then ' esto no debe ser necesario si en efecto como dices todos tienen textbox del mismo nombre... .Add(form1) 'end if .Add(form7) .Add(frmCuentas) .Add(form12) .Add(me) ' siendo el caso que este botón esté en este formulario... end with
call ActualizarEstosForms(colFrm, query, conex, ...) ' activar-mostrar el form que prefieras, por ejemplo colFrm.Item(0).show ' .BringToFront .Activate, .Visible=True . enable=true etc... según sea el caso estén cargados o no, visibles o no, etc...
Esto es rentable, porque la búsqueda de dichos controles solo debería hacerse una vez cuando se carga el proyecto (y si no hay cambios dinámicos de controles textbox, claro), y no cada vez que se requiera cargar datos desde la BD. private sub Main LlenarColTextboxFromformx(form1) LlenarColTextboxFromformx(form7) LlenarColTextboxFromformx(frmCuentas) LlenarColTextboxFromformx(form12) LlenarColTextboxFromformx(frmPrincipal) end sub declara en diseño en cada formulario una coleccion txtBoxes... funcion LlenarColTextboxFromformx( byref f as form) as short por cada ctrl in f.ControlCollection si ctrl.getType.name = "TextBox" luego ' otra forma de preguntar... f.txtBoxes.add(ctrl) end if siguiente
devolver f.txtBoxes.Count fin funcion
Luego creas una función que reciba como parámetro esa colección de formularios... que se recorre y de los cuales se van tomando sus textbox... funcion ActualizarEstosForms( colF as coleccion, ....) dim f as form dim tb as textbox dim txt as string
try consulta a la BD
por cada f en colF por cada tb en subf.txtBoxes try txt = Getstring(....) tb.Text = txt catch messagebox.show "Nombre del textbox no hallado, corrige el nombre" ' el error más probable, para el caso... end try siguiente siguiente catch ex as exception mesagebox.show (ex.message) ' algún problema con la base de datos... finally end try fin funcion
|