Usuario
Error con Recorset

Pregunta
-
Hola
Estoy trabajando con vb6 estoy recuperando datos desde la db al momento de pasarle los datos a mis controles de formulario me da un mensaje de error. La operación no esta permitida si el objeto esta cerrado, pero no le veo problema al codigo, ¿Que puede estar mal?
Private Sub btnBuscar_Click() Dim rs As New ADODB.Recordset, objCliente As New ClienteRepositorio txtId.Text = CStr(id) If Not txtId.Text Then Set rs = objCliente.Buscar(CInt(txtId.Text)) If rs.EOF And rs.BOF Then rs.MoveFirst Else txtId.Text = rs.Fields("ClienteId") txtRazonSocial.Text = rs.Fields("RazonSocial") txtDireccion.Text = rs.Fields("Direccion") End If End If End Sub
Saludos!
Todas las respuestas
-
Revisa el método ClienteRepositorio.Buscar, no vaya a ser que haga un Close del recordset antes de devolverlo. El Close hay que hacerlo cuando ya no necesites usar más el recordset, por lo que en este caso tendrías que hacer el close al final de btnBuscar_Click, no vale con que se cierre dentro de objCliente.Buscar.
Y sí, esto efectivamente es malo para la estructura del programa, porque lo ideal sería que el objeto se cierre dentro del mismo método que lo abre. Para poder trabajar así, tendrías que devolver desde el método buscar los propios valores buscados (idealmente encapsulándolos en un Data Transfer Object) y no el recordset. Esto a su vez también contribuiría a mejorar la estructura del programa, ya que los objetos de acceso a datos (el recordset) quedarían circunscritos a la capa de datos, y no se propagarían a la capa de interfaz de usuario.
-
Hola Alberto
Voy a investigar como puedo usar DTO en vb6
Te muestro el método Buscar.
Public Function Buscar(id As Integer) As ADODB.Recordset Dim rs As New ADODB.Recordset Dim strSQL As String On Error Resume Next Conectar strSQL = "SELECT ClienteId, RazonSocial, Direccion FROM Clientes WHERE ClienteId = " & id & "" rs.Open , cn, adOpenStatic, adLockOptimistic Set Buscar = rs End Function
Saludos! -
Pues no, en Buscar no hay un Close, luego el problema no es el que yo suponía (aunque da lugar a otro problema: no se está haciendo en ningún sitio el Close... pero eso es otro tema). Si fuera VB.NET te diría que la variable "rs" se mantiene viva mientras exista una referencia a ella, pero hace tanto tiempo que no manejo VB6 que ya no me acuerdo de cómo funcionaba en esta versión la destrucción de objetos. ¿Puede ser que al ser rs una variable local a la función se destruya al abandonar la misma (o por lo menos se cierre, con lo que la referencia devuelta como resultado ya no sería operativa)?
-
-
Hola Alberto, que yo recuerde, todos los objetos de VB6 son ActiveX y por lo tanto sujetos a las reglas de IUnknown. Si la función devuelve el recordset, entonces no se destruye aun si nació de una variable local.
Un detalle que veo: Bueno, primero aclaro que igual que Alberto, yo tengo años también de que no toco VB clásico, pero si mal no recuerdo, el hecho de que EOF y BOF fueran True implicaba que la consulta no devolvió registros, y por lo tanto MoveFirst no logrará nada. Me parece que esa parte del código debería ser:
rs.MoveFirst If Not (rs.EOF) Then 'Sí hay un registro. Llenar las casillas de texto. End If
Jose R. MCP
My GIT Repositories | Mis Repositorios GIT -
Hola José
Muchas gracias por la observación ya lo implemente, funciona perfecto dare una leida a los conceptos que mencionas.
Saludos!
Nadie valida al rs.MoveFirst solo entra a la considición cuando el rs.EOF es igual a false.- Editado JulianSanchez domingo, 17 de junio de 2018 19:19