Cargar datos al formulario al perder el foco

Me gustaría saber como hago para llenar los texbox de un formulario desde una base de datos access, tengo declarada la conexión a la BD en un modulo de declaraciones globales
'Conexiones Base de Datos
Global Base As New ADODB. Connection
Global rsUsuarios As New ADODB. Recordset
Global rsClientes As New ADODB. Recordset
Global rsCiudad As New ADODB. Recordset
Global rsCiudadConsulta As New ADODB. Recordset
Global rsFamilias As New ADODB. Recordset
Global rsSubfamilia As New ADODB. Recordset
Global rsProveedores As New ADODB. Recordset etc...
Y en otro modulo declaro la ruta de la bd
Sub main()
   With Base
   .CursorLocation = adUseClient
   .Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\NWIND.MDB;Persist Security Info=False"
   'frmLogin.Show
   frmPrincipal.Show
   End With
Lo que necesito hacer es que llenar un formulario de proveedores desde access para eso tengo el siguiente código
Private Sub Form_Load()
Proveedores
End sub
Private Sub txtrut_LostFocus()
Dim sql As String
If rsProveedores.EOF = True And rsProveedores.BOF = True Then
MsgBox "No Existe el registro"
Else
sql = "select * from proveedores where rut ='" & Trim(txtrut.Text) & "'"""
    lblidproveedor.Caption = rsProveedores!IdProveedor
    txtrut.Text = rsProveedores!rut
    txtDigito.Text = rsProveedores!Dv
    TxtNombre.Text = rsProveedores!Nombre
    txtGiro.Text = rsProveedores!Giro
    txtDireccion.Text = rsProveedores!Direccion
    txtTelefono = rsProveedores!Telefono
    txtEmail.Text = rsProveedores!Mail
End If
End Sub
Pero al ejecutarlo solo me entrega el primer registro de la tabla proveedores, independiente del valor que coloque en la texbox, ¿qué es lo que esta malo?, soy principiante en VB, sean generosos

1 Respuesta

Respuesta
1
veo el sql, pero no veo en donde instancias el recordset rsProveedores
set rsProveedores= New ADODB.Recordset
ni donde lo abres
rsProveedores.open sql
segun yo deberia ser:
set rsProveedores= New ADODB.Recordset
sql = "select * from proveedores where rut ='" & Trim(txtrut.Text) & "'"""
rsProveedores.open sql
    lblidproveedor.Caption = rsProveedores!IdProveedor
    txtrut.Text = rsProveedores!rut
    txtDigito.Text = rsProveedores!Dv
    TxtNombre.Text = rsProveedores!Nombre
    txtGiro.Text = rsProveedores!Giro
    txtDireccion.Text = rsProveedores!Direccion
    txtTelefono = rsProveedores!Telefono
    txtEmail.Text = rsProveedores!Mail
rsProveedores.close
set rsProveedores=nothing
Estimado, antes que nada agradezco tu respuesta, como te explicaba soy novato en visual basic, por lo que pensaba que si declaraba todas mis conexiones en módulos este ya me daba acceso a la base de datos, me falto explicar que uno de estos módulos tengo este código
'Tabla Proveedores
Sub Proveedores()
    With rsProveedores
    If .State = 1 Then .Close
    .Open "Select * from Proveedores", Base, adOpenStatic, adLockOptimistic
    End With
End Sub
' entiendo que aqui abre el recordset
por eso al cargar el formulario tengo este codigo
Private Sub Form_Load() 
Proveedores 
End sub
Copie y probé el código que me facilitaste y me el siguiente error:'3709' no se puede utilizar la conexión para realizar esta operación, esta cerrada o no es valida en este contexto.
Así que me imagino (corrígeme si estoy equivocado) que es por esta linea rsProveedores.open sql, al tener creo yo mi conexión ya abierta, elimine esta linea y ahora me da este error:'3265' no se encontró el elemento en la colección que corresponde con el nombre o el ordinal pedido.
Probé también eliminando el modulo en donde hago el recordset a la tabla proveedores para probar con tu código y nada
agradezco desde ya tu respuesta.
Saludos
Daniel
ahh se me olvido decirte que el recordst rsproveedores esta en el modulo en la ultima linea
'Conexiones Base de Datos 
Global Base As New ADODB.Connection 
Global rsUsuarios As New ADODB.Recordset 
Global rsClientes As New ADODB.Recordset 
Global rsCiudad As New ADODB.Recordset 
Global rsCiudadConsulta As New ADODB.Recordset 
Global rsFamilias As New ADODB.Recordset 
Global rsSubfamilia As New ADODB.Recordset 
Global rsProveedores As New ADODB.Recordset ' instancias el recordset rsProveedores
Me gustaria hacer otra pregunta ¿si declaro todo esto en los modulos de manera global, tengo que volver a declarar estas instancias de nuevo en los formularios?
Saludos
Daniel
ok ya me queda claro, ya se donde abres el recordset, lo abres antes de iniciar el form
pero no importa,  el recordset lo puedes declarar sin problema en un modulo, pero cuando decidas utilizarlo debes instanciarlo
set rsProveedores= New ADODB.Recordset
luego operas con el, con open y demas instruccines
una vez utilizado debes cerrarlo y finalmente eliminar la instancia o de lo contrario, iras dejando n instancias de este recordset en la memoria y eso puede dar problemas
mira la secuencia que yo utilizo para oprar con recordset ado es la sgte
Public rsProveedores As New ADODB.Recordset  ' declarado en un modulo
set rsProveedores=New ADODB.Recordset  ' instancia del recordset
rsProveedores.open sql   ' abre el recordset de acuerdo a instruccion sql
rsProveedores.recordcount   ' conteo de registros del recordset
rsProveedores.movefirst  ' inicia el puntero en el primer registro del recordset
txtrut.Text =(rsProveedores("rut")) ' asignar el dato al control
rsProveedores.close   ' cierra el recordset
set rsProveedores=nothing   ' elimina la instancia
eso suponiendo que el recordset te devuelva un unico registro , pues entiendo buscas un rut
si te devolviera mas de un registro , para pasarlos todos debes realizar un bucle que recorra todos los registros del recordset
algo asi:
rsProveedores.movefirst
do until rsProveedores.eof=true
     txtrut.Text =(rsProveedores("rut"))   ' pasa ca da rut al control
rsProveedores.MoveNext
doevents
Loop
creo que me queda claro la logica de lo que me planteas, cada vez que lo quiera utilizar lo debo instanciar de esta manera Set rsProveedores= New ADODB.Recordset, en este caso en el evento lostfocus, y bastaria con las declaraciones que tengo en los modulos (Global Base As New ADODB.Connection, Global rsProveedores As New ADODB.Recordset,
Sub Proveedores()
    With rsProveedores
    If .State = 1 Then .Close
    .Open "Select * from Proveedores", Base, adOpenStatic, adLockOptimistic
    End With
End Sub)
y que ademas debo  cerrarlo y finalmente eliminar la instancia (rsProveedores.Close
Set rsProveedores = Nothing)
Creo entender también que la instrucción rsProveedores. ¿open sql ya no la puedo usar porque mi conexión ya esta abierta en Sub Proveedores()?
de esta manera mi codigo lo deje asi
Private Sub txtrut_LostFocus()
Dim sql As String
Set rsProveedores = New ADODB.Recordset
If Trim(txtrut.Text) = "" Then Exit Sub
If Trim(txtrut.Text) <> "" Then txtrut.Locked = True
If Trim(txtrut.Text) <> "" Then txtrut.BackColor = &H8000000F
If Trim(txtrut.Text) <> "" Then txtDigito.BackColor = &H8000000F
sql = "select * from proveedores where rut ='" & Trim(txtrut.Text) & "'"""
    'lblidproveedor.Caption = (rsProveedores("idproveedor"))
    txtrut.Text = (rsProveedores("rut"))
    txtDigito.Text = (rsProveedores("dv"))
    TxtNombre.Text = (rsProveedores("nombre"))
    txtGiro.Text = (rsProveedores("giro"))
    txtDireccion.Text = (rsProveedores("direccion"))
    txtTelefono = (rsProveedores("telefono"))
    txtEmail.Text = (rsProveedores("mail"))
rsProveedores.Close
Set rsProveedores = Nothing
End Sub
disculpa que sea patudo pero no logro hacer que esto funcione, esta bien estructurado el codigo??
Si esta correcto, pero antes que nada ... tienes agregada la referencia Microsoft Activex Data Objects 2.8 Library ( o superior)
menu Proyecto/referencias
Tenia Activex Data Objects 2.1 Library, la cabo de cambiar por la 2.8 pero todo sigue igual.
Saludos y gracias por tener la amabilidad de contestar
Replique tu aplicación y no tengo problemas para recuperar los datos del recordset, quedo así:
En modulo1
Option Explicit
'Conexiones Base de Datos
Global Base As New ADODB. Connection
Global rsUsuarios As New ADODB. Recordset
Global rsClientes As New ADODB. Recordset
Global rsCiudad As New ADODB. Recordset
Global rsCiudadConsulta As New ADODB. Recordset
Global rsFamilias As New ADODB. Recordset
Global rsSubfamilia As New ADODB. Recordset
Global rsProveedores As New ADODB. Recordset ' instancias el recordset rsProveedores
Sub main()
Set Base = New ADODB.Connection  ' crea la conexion odb
Base.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\NWIND.mdb" & ";Persist Security Info=True;Jet OLEDB:Database Password=HOLA" ' cadena para apertura d base con password
Base.Open
frmPrincipal.Show
End Sub
Ha cambe la cadena de conexión, en esta puedes ponerle password a la base en este caso seria HOLA, aunque si la base no tiene password actualmente, se conecta igual
luego en el form pones el sub que realiza la busquead del dato
Private Sub txtrut_LostFocus()
Dim sql As String
Set rsProveedores = New ADODB.Recordset
If Trim(txtrut.Text) = "" Then Exit Sub
If Trim(txtrut.Text) <> "" Then txtrut.Locked = True
If Trim(txtrut.Text) <> "" Then txtrut.BackColor = &H8000000F
If Trim(txtrut.Text) <> "" Then txtDigito.BackColor = &H8000000F
sql = "select * from proveedores where rut ='" & Trim(txtrut.Text) & "'"
rsProveedores.Open sql, Base, adOpenStatic, adLockOptimistic
    lblidproveedor.Caption = (rsProveedores("idproveedor"))
    txtrut.Text = (rsProveedores("rut"))
    txtDigito.Text = (rsProveedores("dv"))
    TxtNombre.Text = (rsProveedores("nombre"))
    txtGiro.Text = (rsProveedores("giro"))
    txtDireccion.Text = (rsProveedores("direccion"))
    txtTelefono = (rsProveedores("telefono"))
    txtEmail.Text = (rsProveedores("mail"))
rsProveedores.Close
Set rsProveedores = Nothing
End Sub
Yo no pondría una búsqueda de base de datos en un evento como el LostFocus, te sugiero lo hagas en el Keyup del textrut
así cada vez que presiones enter en el text, realizas la búsqueda
Private Sub txtrut_KeyUp(KeyCode As Integer, Shift As Integer)
If KeyCode = 13 Then
Dim sql As String
Set rsProveedores = New ADODB.Recordset
If Trim(txtrut.Text) = "" Then Exit Sub
If Trim(txtrut.Text) <> "" Then txtrut.Locked = True
If Trim(txtrut.Text) <> "" Then txtrut.BackColor = &H8000000F
If Trim(txtrut.Text) <> "" Then txtDigito.BackColor = &H8000000F
sql = "select * from proveedores where rut ='" & Trim(txtrut.Text) & "'"
rsProveedores.Open sql, Base, adOpenStatic, adLockOptimistic
    lblidproveedor.Caption = (rsProveedores("idproveedor"))
    txtrut.Text = (rsProveedores("rut"))
    txtDigito.Text = (rsProveedores("dv"))
    TxtNombre.Text = (rsProveedores("nombre"))
    txtGiro.Text = (rsProveedores("giro"))
    txtDireccion.Text = (rsProveedores("direccion"))
    txtTelefono = (rsProveedores("telefono"))
    txtEmail.Text = (rsProveedores("mail"))
rsProveedores.Close
Set rsProveedores = Nothing
End If
End Sub
no olvides cerrar la conexion de base de datos al terminar de utilizarla
base.close
set base=nothing
espero te sirva.
Estimado he copiado el código que me enviaste textualmente y no he logrado hacer que este me funcione, ahora me da un error '-2147217913(80040e07)' en tiempo de ejecución: No coinciden los tipos de datos de expresión de criterios. Y al darle depurar me marca esta línea rsProveedores.Open sql, Base, adOpenStatic, adLockOptimistic.
No se si esta permitido adjuntar un link con parte de mi código pero estoy desesperado, y mucho menos quiero abusar de tu buena voluntad,
http://200.111.56.242/vs.rar 
Saludos
Ya lo que pasa es que tienes mal diseñada la tabla proveedores, el campo rut lo tienes como numero y debe ser texto..., es por eso el error.
Otra cosa
en el Sub txtrut_LostFocus()
No pongas
RsProveedores. Close
Set rsProveedores = Nothing
Base.Close
Set Base = Nothing
O no podrás realizar otra consulta desde el form a menos que lo cierres y abras todo otra vez
cierra el rsProveedores una vez que cierres el form
y cierra la conexión Base. Close una vez que finalices la aplicación.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas