none
Formulario continuo con ADO y sin tablas vinculadas. RRS feed

  • Pregunta

  • Hola:

    quiero hacer lo equivalente a un formulario continuo pero con ADO y sin tener tablas vinculadas. En parte es debido porque algunas veces tengo que obtener datos de SQL Server. Además quiero que sea desconectado, es decir, guardarlo al final, porque he de hacer unas comprobaciones complejas.

    Una opcion que he considerado es la de usar CreateControl, es decir crear los controles en tiempo de ejecución. El problema es que no se como asignarles los eventos necesarios ya que necesito hacer unas validaciones concretas en los textbox.

    La idea sería por ejemplo crear una fila de textbox, con sus eventos y demás, y después, segun el numero de filas que quiera, que esa fila se repita esas veces, y que sus eventos funcionen correctamente claro.

     

    lunes, 13 de septiembre de 2010 19:05

Respuestas

  • Alvaro, hay varias maneras de trabajar con recordset desconectado. Una vez lo hice con adostream..si consigo el ejemplo lo publico.

    Por otro lado, aqui dejo una manera de llenar un formulario contínuo desconectado. No puedes editar ni eliminar directamente.

    Dim ConnStr As New ADODB.Connection
    Function getDisconnectedRS(sql)
    Dim RS As New ADODB.Recordset
    Set RS = New ADODB.Recordset
    RS.CursorLocation = 3 'adUseClient
    RS.Open sql, ConnStr, 3, 1

    Set RS.ActiveConnection = Nothing 'disconnect here
    Set getDisconnectedRS = RS
    End Function

    Private Sub Form_Load()
    Dim myRS As New ADODB.Recordset
    Set myRS = getDisconnectedRS("SELECT * from Clientes")
    Set Me.Recordset = myRS
    myRS.Close: Set myRS = Nothing
    End Sub

    Private Sub Form_Open(Cancel As Integer)
    Set ConnStr = CurrentProject.Connection
    End Sub

    fuente:http://www.goexpert.info/tag/create-disconnected-recordset

    jueves, 16 de septiembre de 2010 13:50

Todas las respuestas

  • Hola Alvaro...no recuerdo si ya te pasé este ejemplo, pero puede servirte. Es una flexgrid que llenas y cierras conexión. Al pié de ésta, hay cuadros de texto para crear nuevo o editar. El enlace: http://www.tucondominioaldia.com.ve/archivos/ejemGrid.zip

     

    lunes, 13 de septiembre de 2010 23:07
  • Si, ya me pasaste ese ejemplo y no pude abrirle. El elemento flexgrid (ni el datagrid) no viene disponible en Access 2003, por lo menos yo con los dos equipos que he trabajado tienen la instalacion completa de Access y ninguno de los dos lo tienen.

    Creo que es un elemento de VB6 por lo que tendría que tener instalado Visual BAsic. Aqui en casa no tendría ningún problema en instalarlo, pero el equipo en el que ha de funcionar la aplicacion está restringido y no puedo ni instalar ni añadir nada. (Si pudiera usario VB.net o c# en vez de access)

    Por tanto esa opción no me sirve.

    Lo que quiero hacer es sencillo en principio, pero en cuanto hay tablas relacionadas con restricciones de indices y hay que usar ADO ya es un caos. Estoy barajando la opcion de usar una tabla temporal en la que volcar los datos, aunque no quería andar creando y borrando tablas en el archivo de aplicacion, no es lo mas elegante.

    lunes, 13 de septiembre de 2010 23:14
  • Hola Alvaro

    La única opción que tienes, trabajando con Access 2003, es crearte un proyecto ADP, que trabaja con SQL Server directamente y ADO. El problema es que a partir de Access 2007 no es recomendable su uso.

    Otra opción, es crearte tablas locales en Access, y cargarlas con los datos de las tablas de SQL Server cada vez que te haga falta. Los formularios de Access NO funcionan con ADO (los mdb), así que tendrías que usar DAO. Podrías crearte un procedimiento que te reconectara la tablas vinculadas sín tener que usar un DSN. Yo utilizo una tabla que contiene los nombres de las tablas vinculadas, y la utilizo para revincular las tablas. Mi código es éste:

    <pego>

    Public Function DSNLess()
        On Error GoTo Error_Conexion
        Dim sConnect As String
        Dim db As DAO.Database, tdf As DAO.TableDef, rs As DAO.Recordset
       
        'Cadena conexión
        sConnect = "ODBC;DRIVER=SQL Server;SERVER=MiServidor;DATABASE=MiBD;Trusted_Connection=Yes"
       
        Set db = CurrentDb
        Set rs = db.OpenRecordset("tblTablas", dbOpenForwardOnly)
        'Borro la tabla vinculada y la vuelvo a vincular. De este modo, se actualiza cualquier cambio realizado en el servidor
        Do Until rs.EOF
            db.TableDefs.Delete rs.Fields("Tabla")
            db.TableDefs.Refresh
            Set tdf = db.CreateTableDef(rs.Fields("Tabla"), dbAttachSavePWD, rs.Fields("Tabla"), sConnect)
            db.TableDefs.Append tdf
            Set tdf = Nothing
            rs.MoveNext
            DoEvents
        Loop
        'Actualizo la colección de tabledefs
        db.TableDefs.Refresh
        Set tdf = Nothing
        db.Close
        Set db = Nothing
       
    '    Debug.Print "TERMINADO"
        Exit Function
    Error_Conexion:
        If Err.Number = 3265 Then
            Resume Next
        Else
            Dim sError As String
            sError = "Se ha producido un error al reconectar contra el servidor: " & vbCrLf & _
                     "     Error: " & Err.Number & vbCrLf & _
                     "     Descipcion: " & Err.Description & _
                     "Póngase en contacto con el administrador"
            MsgBox sError, vbCritical + vbOKOnly, "Error crítico"
        End If
    End Function

    Espero te sirva.

    Salu2,


    José Mª Fueyo [MS MVP Access]
    martes, 14 de septiembre de 2010 9:39
  • Si, he pensado en eso, vincular las tablas de esa forma sería la unica manera, porque cuando me conecto con una base mdb el nombre del archivo va cambiando.

     

    Una duda sobre formularios continuos:

    He creado una tabla temporal que basicamente tiene Id y Cantidad como campos. Despues tengo una tabla articulos con Id, Nombre y Stock (hay mas pero los omito)

    Para tener en un formulario continuo algo asi:

    Id  Nombre Cantidad Stock

    lo que hago es una sentencia sql ocn Left Join (pues la tabla temporal está vacía) de la forma:

    SELECT Articulos.Id, Articulos.Nombre, Articulos.Stock, temp.Cantidad FROM Articulos LEFT JOIN temp WHERE Articulos.Id = temp.Id

    El unico problema es que cuando abro el formulario, los articulos que no estan en temp tienen en Cantidad valor "vacio" y quiero que me aparezca ahi un valor 0. Como podría hacerlo? Como puedo recorrer todos los textbox Cantidad del formulario para ponerles a 0?

    martes, 14 de septiembre de 2010 18:27
  • Hola

    Podrías probar a crear una vista, y usar la función IsNull de SQL Server para convertir esos valores a 0.

    A la hora de vincular, en la lista de tablas disponibles aparecen también las vistas.

    Salu2,


    José Mª Fueyo [MS MVP Access]
    miércoles, 15 de septiembre de 2010 9:26
  • Alvaro, hay varias maneras de trabajar con recordset desconectado. Una vez lo hice con adostream..si consigo el ejemplo lo publico.

    Por otro lado, aqui dejo una manera de llenar un formulario contínuo desconectado. No puedes editar ni eliminar directamente.

    Dim ConnStr As New ADODB.Connection
    Function getDisconnectedRS(sql)
    Dim RS As New ADODB.Recordset
    Set RS = New ADODB.Recordset
    RS.CursorLocation = 3 'adUseClient
    RS.Open sql, ConnStr, 3, 1

    Set RS.ActiveConnection = Nothing 'disconnect here
    Set getDisconnectedRS = RS
    End Function

    Private Sub Form_Load()
    Dim myRS As New ADODB.Recordset
    Set myRS = getDisconnectedRS("SELECT * from Clientes")
    Set Me.Recordset = myRS
    myRS.Close: Set myRS = Nothing
    End Sub

    Private Sub Form_Open(Cancel As Integer)
    Set ConnStr = CurrentProject.Connection
    End Sub

    fuente:http://www.goexpert.info/tag/create-disconnected-recordset

    jueves, 16 de septiembre de 2010 13:50
  • Un comentario al código que muestras arriba. Cuando declara las variables también las inicializa. Me explico:

    Usar Dim RS As New ADODB.Recordset es equivalente a hacer :

    Dim rs as ADODB.Recordset

    Set rs = new ADODB.Recordset

     

    Por tanto, ya no habria que inicializarla despues. El problema es que se está reservando memoria para una variable que puede que no se use. Desde mi punto de vista es un error de eficiencia.

    • Propuesto como respuesta guarracuco lunes, 20 de septiembre de 2010 19:51
    lunes, 20 de septiembre de 2010 15:49
  • Gracias, lo tendré en cuenta.
    lunes, 20 de septiembre de 2010 19:52