none
Error con Recorset RRS feed

  • 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!

    sábado, 16 de junio de 2018 15:05

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.

    sábado, 16 de junio de 2018 19:41
  • 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!

    sábado, 16 de junio de 2018 19:49
  • 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)?
    sábado, 16 de junio de 2018 20:40
  • Ya lo solucione

    No le estaba pasando la consulta al recorset

    rs.Open strSQL, cn, adOpenStatic, adLockOptimistic

    Saludos!

    sábado, 16 de junio de 2018 23:23
  • 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

    domingo, 17 de junio de 2018 7:48
  • 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.
    domingo, 17 de junio de 2018 19:15