2015-09-28 58 views
5

Ho un recordset ADO pieno nel mio modulo VBA. Ho anche una tabella in ACCESS che ha esattamente la stessa struttura del recordset.inserire l'intero recordset ADO nella tabella ACCESSO esistente WITHOUT LOOP

Ora riempio la tabella utilizzando un ciclo (che va bene) passando per ogni record del set di dati.

Quello che mi chiedo: c'è un modo per inserire un intero recordset nel tavolo degli accessi? (e ancora più importante: sarebbe molto più veloce)

+0

https://support.microsoft.com/en-us/kb/195082 mostra l'uso di un recordset disconnesso per eseguire un aggiornamento: non sono sicuro di inserire ... –

risposta

6

Ecco un esempio di base (eseguito da Excel in questo caso) che illustra l'utilizzo di un recordset disconnesso per aggiungere record.

Sub Tester() 

    Dim con As ADODB.Connection, rs As ADODB.Recordset 
    Dim i As Long 

    Set con = getConn() 

    Set rs = New ADODB.Recordset 
    rs.CursorLocation = adUseClient '<<<< important! 

    'get an empty recordset to add new records to 
    rs.Open "select * from Table1 where false", con, _ 
      adOpenDynamic, adLockBatchOptimistic 

    'disconnect the recordset and close the connection 
    Set rs.ActiveConnection = Nothing 
    con.Close 
    Set con = Nothing 

    'add some new records to our test recordset 
    For i = 1 To 100 
     rs.AddNew 
     rs("UserName") = "Newuser_" & i 
    Next i 

    'reconnect to update 
    Set con = getConn() 
    Set rs.ActiveConnection = con 

    rs.UpdateBatch '<<< transfer to DB happens here: no loop! 

    rs.Close 

    'requery to demonstrate insert was successful 
    rs.Open "select * from Table1", con, _ 
      adOpenDynamic, adLockBatchOptimistic 

    Do While Not rs.EOF 
     Debug.Print rs("ID").Value, rs("UserName").Value 
     rs.MoveNext 
    Loop 

    rs.Close 
    con.Close 
End Sub 

Function getConn() As ADODB.Connection 
    Dim rv As New ADODB.Connection 
    Dim strConn As String 

    strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" _ 
    & "Data Source = " & ThisWorkbook.Path & "\Test.accdb" 

    rv.Open strConn 
    Set getConn = rv 
End Function 
+0

grazie, io uso qualcosa di simile. La domanda era come evitare di dover usare un loop e semplicemente scaricare l'intero recordset nella tabella come si può fare tra due tabelle di accesso (SELECT * INTO SomeTable FROM SomewhereElse) Ma utile comunque! –

+0

Gli unici cicli che ho sono di caricare il recordset di test e di visualizzare il risultato dopo l'aggiornamento. Il caricamento dei dati avviene tutto nella singola riga 'UpdateBatch'. A quale ciclo ti riferisci? –

+0

Oops si è reso conto che mi mancava la parte più importante. Ma ora vedo. Era quello che speravo di trovare. Molto utile, grazie per aver chiarito –

0

No. Non esiste un equivalente inverso - potrebbe essere SetRows - al metodo GetRows.

1

Recordsets VBA esistono praticamente in memoria chiamata durante l'esecuzione finché non sono contenuti in un formato fisico reale (cioè, csv, txt, xlsx, XML, temperatura tabella di database) salvato sul disco rigido. Questo è simile ai frame di dati in panda R o Python, dataset SAS, array PHP e altre strutture dati.

Considera l'esportazione dell'ADO in tale formato utilizzando i metodi CopyFromRecordset in un foglio di calcolo Excel da salvare come csv, txt, xlsx o xml. In alternativa, è possibile utilizzare il metodo Save per salvare il recordset in un tipo di formato persistente come xml.

Poi, aggiungere file risultante a tavola MS Access con le sue funzioni automatiche di migrazione dei dati:

  • Per i fogli di calcolo: DoCmd.TransferSpreadsheet
  • Per txt, csv, o altri file delimitati: DoCmd.TransferText
  • per i file XML : Application.ImportXML
  • Per/OLEDB legata tabelle di database locali o ODBC: INSERT INTO Query di accodamento SQL

+0

ADO in Excel per l'accesso. Sembra che sia più veloce di un'istruzione INSERT in loop. È un peccato che tu non possa scrivere un'istruzione SQL INSERTS nella tabella usando un'istruzione SELECT che prende i dati da un recordset (o forse un array ..... Hmm. VALORI ... – HarveyFrench