2012-05-05 21 views
5

Sto eseguendo questo codice nella sottomascheda del mio foglio dati quando il mio modulo viene caricato e non ricevo messaggi di errore o interruzioni di codice. Il mio debug.print mostra che il Recordset rs è pieno di 2131 record come dovrebbe, ma il mio modulo mostra una singola riga con #Nome? in ogni campo Sicuramente le proprietà della sorgente di controllo sui miei controlli corrispondono ai nomi dei campi che ho elencato sopra. RS è una variabile a livello di modulo e non la sto chiudendo o non la imposto fino a quando il modulo non si chiude.In memoria, Stand-Alone, disconnessione recordset ADO

Qualche idea di cosa sto sbagliando?

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, così ho appena letto this on the MSDN site:

Il recordset deve contenere uno o più campi che sono indicizzati in modo univoco, come la chiave primaria di una tabella.

(Nota: Questa informazione sembra essere errato in questo contesto.)

+2

Questo è un tavolino (4 campi). Ma immagino di non aver mai dovuto davvero svilupparmi per le imprese, quindi sono abituato a inserire grandi quantità di dati (10.000 record e talvolta di più) in viste del foglio dati. Con Gigabit Ethernet e dischi rigidi veloci nel nostro server non ho lamentele da parte dei miei utenti, anche se stiamo usando DAO con tabelle collegate ODBC. Quindi, non sto davvero scusando il mio approccio tanto quanto sto solo dicendo che "finora" funziona davvero abbastanza bene. – HK1

risposta

4

ho scoperto che l'unico modo che posso fare questo lavoro è quello di utilizzare LockType adLockPessimistic o adLockOptimisic. adLockReadOnly non funziona per ovvi motivi e per qualche ragione adLockBatchOptimistic non consente ai record di essere visualizzati nel mio modulo anche se il recordset sembra essere perfettamente funzionante.

Ho anche scoperto che non è necessario avere una chiave primaria definita per questo tipo di Recordset disconnesso da associare a un modulo. Sono sicuro che non sarai in grado di apportare modifiche o aggiornamenti al recordset tramite il modulo ma durante i miei test ho scoperto che non potevo apportare alcuna modifica a questo tipo di modulo/recordset perché stavo ricevendo l'errore 3270 (qualcosa a che fare con una proprietà mancante). Questo è davvero al di fuori della portata di questa domanda.

Ecco la quantità minima di codice necessario per creare un gruppo di lavoro in memoria di record:

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 

La sua prima apparizione a me che il legame di un modulo (visualizzazione Foglio dati nel mio caso) a questo tipo di record disconnesso sarebbe essere una soluzione buona e semplice per le mie particolari esigenze. Tuttavia, ho incontrato diversi problemi. L'ordinamento di modulo predefinito non sembra funzionare quando si associa il modulo a un recordset ADO. Inoltre, per qualche ragione non ho mai potuto ottenere questo recordset per essere modificabile/aggiornabile, che era un requisito per i miei bisogni (in pratica lo usavo come elenco di controllo multiplo). Se si ottiene il recordset da una tabella (anche se è una tabella vuota) e quindi si disconnette, è possibile aggirare questo problema. Apparentemente la tabella fornisce una sorta di struttura o proprietà che non sono riuscito a impostare nel mio codice sopra, a giudicare dal messaggio di errore 3270 che ottengo quando provo ad aggiungere/modificare un record. E non ho capito quali sono queste proprietà o come impostarle.

In conclusione, penso che ricorro ad utilizzare una tabella "temp" di Access, poiché sarà meno complicata e non avrà i problemi che ho appena elencato sopra.

+0

Nei giorni passati, ho avuto un desiderio simile di creare un semplice set di dati in memoria. Ho avuto simili frustrazioni e ho rinunciato pure. –

7

E 'possibile impostare una chiave primaria di un record che è soltanto un oggetto in memoria?

Sì, utilizzare adFldKeyColumn come Attrib per Append Method. Maggiori informazioni su FieldAttributeEnum.

Se si dispone già di un campo univoco adatto (o una combinazione di campi) disponibile dall'istruzione SQL, utilizzare quello. In caso contrario, creare un campo intero lungo e utilizzarlo come falso campo della chiave primaria ... incrementare il valore per ogni riga inserita.

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

vedere anche se questo articolo dal Journal Database di Danny Lesandrini è utile: Create In-Memory ADO Recordsets

+0

ok, quindi ho aggiunto un campo chiave primaria come suggerito sopra e l'ho compilato, ma continuo a vedere # nome? in tutti i miei campi. Sono sconcertato. – HK1

4

Nota: Sono stato in grado di ottenere tutto per funzionare correttamente con l'inserimento di nuovi record utilizzando l'esempio sopra indicato al Create In-Memory ADO Recordsets quindi modificando il seguente al codice forme ... 'Nota: Il trucco era quello di utilizzare rstADO.MoveFirst & rstADO.MoveLast dopo 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