2012-05-05 57 views
5

Estoy ejecutando este código en el subformulario de mi hoja de datos cuando se carga mi formulario y no recibo ningún mensaje de error o salto de código. Mi debug.print muestra que Recordset rs está lleno de 2131 registros como debería ser, pero mi formulario muestra una sola fila con #Name? en todos los campos Las propiedades de la fuente de control en mis controles sin duda coinciden con los nombres de campo que he enumerado anteriormente. RS es una variable de nivel de formulario y no la estoy cerrando ni configurándola en nada hasta que se cierre el formulario.En memoria, independiente, Recordset ADO desconectado

¿Alguna idea de qué estoy haciendo mal?

Set rs = New ADODB.Recordset 
rs.Fields.Append "TimesUsed", adInteger 
rs.Fields.Append "strWorkType", adVarWChar, 150 
rs.Fields.Append "DateLastUsed", adDate 
rs.Fields.Append "SelectedYN", adBoolean 
Set rs.ActiveConnection = Nothing 
rs.CursorLocation = adUseClient 
rs.LockType = adLockBatchOptimistic 
rs.Open 

Dim sSQL As String 
sSQL = "MyComplicated SQL Statement Ommitted from this SO Question" 

Dim r As DAO.Recordset 
Set r = CurrentDb.OpenRecordset(sSQL, dbOpenDynaset, dbSeeChanges) 
If Not (r.EOF And r.BOF) Then 
    r.MoveFirst 
    Dim fld 
    Do Until r.EOF = True 
     rs.AddNew 
     For Each fld In r.Fields 
      rs(fld.Name) = r(fld.Name).value 
     Next 
     rs.Update 
     r.MoveNext 
    Loop 
End If 
r.Close 
Set r = Nothing 
Debug.Print rs.RecordCount '2131 records 
Set Me.Recordset = rs 

OK, por lo que acabo de leer this on the MSDN site:

El conjunto de registros debe contener uno o más campos que están indexados de forma única, como la clave primaria de una tabla.

(Nota: Esta información parece ser errónea en este contexto.)

+2

Este es un pequeño mesa (4 campos). Pero supongo que nunca tuve que desarrollarme realmente para la empresa, así que estoy acostumbrado a extraer grandes cantidades de datos (10.000 registros y, a veces más) en las vistas de la hoja de datos. Con Gigabit Ethernet y discos duros rápidos en nuestro servidor, no recibo quejas de mis usuarios a pesar de que estamos usando DAO con ODBC Linked Tables. Entonces, realmente no disculpo mi enfoque tanto como solo estoy diciendo que "hasta ahora" realmente funciona bastante bien. – HK1

Respuesta

4

descubrí que la única manera de que pueda hacer este trabajo es utilizar LockType adLockPessimistic o adLockOptimisic. adLockReadOnly no funciona por razones obvias y, por alguna razón, adLockBatchOptimistic no permite que los registros se muestren en mi formulario a pesar de que el conjunto de registros parece ser completamente funcional.

También descubrí que no es necesario tener una clave principal definida para este tipo de Recordset desconectado para vincularse a un formulario. Estoy seguro de que no podrá realizar modificaciones ni actualizaciones en el conjunto de registros a través del formulario, pero en mis pruebas descubrí que no podía realizar modificaciones en este tipo de formulario/conjunto de registros porque recibía el error 3270. (algo que ver con una propiedad perdida). Eso está realmente fuera del alcance de esta pregunta.

Aquí es la mínima cantidad de código necesario para crear un trabajo en memoria de registros:

Dim rs As ADODB.Recordset 'Form Level variable 

Private Sub Form_Load() 
    Set rs = New ADODB.Recordset 
    rs.Fields.Append "ID", adInteger 
    'Set rs.ActiveConnection = Nothing 'Not Required 
    'rs.CursorType = adOpenKeyset 'Not Required 
    'rs.CursorLocation = adUseClient 'Not Required 
    rs.LockType = adLockPessimistic 'May also use adLockOptimistic 
    rs.Open 

    Dim i as Integer 

    For i = 1 To 10 
     rs.AddNew 
     rs("ID").Value = i 
     rs.Update 
    Next i 

    Set Me.Recordset = rs 
End Sub 

Apareció por primera vez para mí que la unión de una forma (vista Hoja de datos en mi caso) para este tipo de registros desconectado haría ser una buena y simple solución para mis necesidades particulares. Sin embargo, me encontré con varios problemas. La ordenación de formularios predeterminada no parece funcionar cuando tiene su formulario vinculado a un conjunto de registros ADO. Además, por alguna razón, nunca pude conseguir que este conjunto de registros sea editable/actualizable, que era un requisito para mis necesidades (básicamente lo estaba usando como una lista de verificación múltiple). Si obtiene el conjunto de registros de una tabla (incluso si es una tabla vacía) y luego se desconecta puede evitar este problema. Aparentemente, la tabla proporciona algún tipo de estructura o propiedades que no pude establecer en mi código anterior, a juzgar por el mensaje de error 3270 que recibo cuando intento agregar/editar un registro. Y no he descubierto cuáles son esas propiedades ni cómo configurarlas.

En conclusión, creo que recurriré al uso de una tabla de "temperatura" de acceso en cambio, ya que será menos complicado y no tendrá los problemas que acabo de enumerar arriba.

+0

En días pasados, tuve el deseo similar de crear un conjunto de datos simple en memoria. Tuve frustraciones similares y también me rendí. –

7

es posible fijar una clave principal en un conjunto de registros que sólo es un objeto en memoria?

Sí, utilice adFldKeyColumn como el Attrib a la Append Method. Lea sobre FieldAttributeEnum para más detalles.

Si ya tiene un campo único adecuado (o una combinación de campos) disponible en su declaración de SQL, utilícelo. De lo contrario, cree un campo entero largo y úselo como campo de clave primaria falsa ... incremente el valor para cada fila que inserte.

rs.Fields.Append "pkey", adInteger, , adFldKeyColumn 

ver también si este artículo de Diario de base de datos de Danny Lesandrini es útil: Create In-Memory ADO Recordsets

+0

ok, ¿he agregado un campo de clave principal como se sugirió anteriormente, y lo he poblado pero sigo viendo #Name? en todos mis campos Estoy desconcertado. – HK1

4

Nota: yo era capaz de conseguir que todo funcione correctamente, junto con la inserción de nuevos registros usando el ejemplo anterior en Create In-Memory ADO Recordsets A continuación, cambiar el siguiente al código formas ... 'Nota: El truco consistía en utilizar rstADO.MoveFirst & rstADO.MoveLast después de la rstADO.Update

Option Compare Database 
Dim rstADO As ADODB.Recordset 
Dim lngRecordID As Long 

Private Sub Form_BeforeInsert(Cancel As Integer) 

    lngRecordID = lngRecordID + 1 
    rstADO.AddNew 
    rstADO("EmployeeID").value = lngRecordID 
    rstADO.Update 
    rstADO.MoveFirst 
    rstADO.MoveLast 

End Sub 

Private Sub Form_Load() 

    Dim fld As ADODB.Field 

    Set rstADO = New ADODB.Recordset 
    With rstADO 
     .Fields.Append "EmployeeID", adInteger, , adFldKeyColumn 
     .Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull 
     .Fields.Append "LastName", adVarChar, 20, adFldMayBeNull 
     .Fields.Append "Email", adVarChar, 64, adFldMayBeNull 
     .Fields.Append "Include", adInteger, , adFldMayBeNull 
     .Fields.Append "Selected", adBoolean, , adFldMayBeNull 

     .CursorType = adOpenKeyset 
     .CursorLocation = adUseClient 
     .LockType = adLockPessimistic 
     .Open 
    End With 
    Set Me.Recordset = rstADO 

End Sub 

Private Sub Form_Unload(Cancel As Integer) 

    Set rstADO = Nothing 

End Sub 
Cuestiones relacionadas