2013-04-26 29 views
7

Lavoro su un Access DB e devo utilizzare una connessione origine dati a un server SQL.Come popolare un ListBox con un ADODB.Recordset (Errore 91) Per completare il completamento automatico in Access

Per fare che io uso l'oggetto ADODB con:

-ADODB.Connection

-ADODB.Recordset

Codice Up-to-date, a seguito di un'osservazione di Ian Kenney

Dim cnn As ADODB.Connection 
    Set cnn = New ADODB.Connection 
    Dim rs As ADODB.Recordset 

    cnn.ConnectionString = "driver={SQL Server};provider=SQLOLEDB;server=10.****;uid=****readonly;pwd=****readonly;database=****" 
    cnn.Open 

    Set rs = cnn.Execute("SELECT [MATRI], [NOMPRE] FROM SCHEME_DB.TABLE WHERE NOMPRE LIKE '*" & Me.Textbox_recherche.Text & "*'") 



    Me.Liste_choix.RowSourceType = "Table/List" 
    Me.Liste_choix.Recordset = rs 

    rs.Close 
    cnn.Close 

(Questo codice (una parte del codice) è un modo per eseguire un completamento automatico in Access con un TextBox e un ListBox)

E ho un errore 91 quando si esegue questo codice: "Errore 91: variabile dell'oggetto o Con variabile di blocco non impostata ".

Non capisco come risolvere questo problema.

Grazie in anticipo.

risposta

5

Ci hai detto che il codice genera Errore 91, "Variabile oggetto o Con variabile di blocco non impostata". Sfortunatamente, non hai indicato quale riga fa scattare l'errore. Questo ci costringe a indovinare dove si trova il problema.

Un problema è qui:

Me.Liste_choix.Recordset = rs 

che tenta una cessione di un oggetto all'altro. Il segno = è sufficiente per le assegnazioni con tipi di dati semplici ... ovvero MyVariable = 2. Tuttavia, è necessario includere la parola chiave Set con assegnazioni di oggetto.

Set Me.Liste_choix.Recordset = rs 

Sebbene si debba apportare tale modifica, non sono certo che sia stata la causa dell'errore 91; Avrei immaginato che l'accesso si sarebbe lamentato "Uso non valido della proprietà" invece.

L'istruzione SELECT è un altro problema, ma di nuovo non sono sicuro che contribuisca all'errore segnalato. La clausola WHERE utilizza un confronto Like con un modello che ha * come carattere jolly. Quella query potrebbe restituire ciò che ti aspetti quando lo esegui da DAO. Ma stai usando ADO che considera * come un semplice carattere di asterisco senza alcun significato speciale. Quindi la query probabilmente non restituisce alcuna riga quando viene eseguita da ADO. Sostituire * con %.

Come consiglio generale, se il modulo di codice non include già Option Explicit nella sezione Dichiarazioni, aggiungerlo. Quindi esegui Debug-> Compila dal menu principale dell'Editor VB. Risolve qualsiasi problema del compilatore. Assicurati di aver fatto queste cose prima di qualsiasi ulteriore risoluzione dei problemi.

+0

Grazie, ti do la taglia, ma penso che un problema importante sia il modo in cui dichiarare l'oggetto ADODB.Connection. Dobbiamo dichiarare questo oggetto con .Properties (non so esattamente perché ...) come nella mia risposta ... –

4

aver chiuso il set di record e la connessione prima di usarlo

rs chiuso qui

rs.Close 

e la connessione viene chiusa qui

cnn.Close 

Me.Liste_choix.RowSourceType = "Table/List" 

rs usate qui

Me.Liste_choix.Recordset = rs 

Aggiorna Dal docs:

Usando il metodo Close per chiudere un oggetto Connection chiude anche eventuali oggetti Recordset attivi associati alla connessione. Un oggetto Command associato all'oggetto Connection che si sta chiudendo sarà persistente , ma non sarà più associato a un oggetto Connection; ovvero la sua proprietà ActiveConnection sarà impostata su Nothing. Inoltre, , la raccolta Parametri dell'oggetto Comando verrà cancellata da qualsiasi parametro definito dal provider .

L'utilizzo del metodo Close per chiudere un oggetto Recordset, Record o Stream rilascia i dati associati e qualsiasi accesso esclusivo che è possibile avere ai dati tramite questo particolare oggetto. È possibile chiamare in seguito il metodo Open per riaprire l'oggetto con gli stessi attributi . Mentre un oggetto Recordset viene chiuso, la chiamata di qualsiasi metodo che richiede un cursore dinamico genera un errore.

SQL INIEZIONE C'è anche un rischio sql injection costruendo SQL direttamente dall'input dell'utente.
Questa domanda (MS Access prepared statements) mostra come usare una query parametrizzata - potrebbe valere la pena dare un'occhiata.

+0

Questa non è la causa dell'errore, facendo scorrere l'rs.Close e cnn.Close sotto Me.Liste_choix.Recordset = rs, ho già avuto la errore. –

+0

hai provato a muovere la rs.close/cnn.close dopo aver usato il recordset? –

+0

Sì ... Me.Liste_choix.RowSourceType = "Tabella/List" Me.Liste_choix.Recordset = rs rs.Close cnn.Close –

7

ho risolto il mio problema (Error 91), c'era tre problemi: la creazione del ADODB.Connection, il * nel Select (Grazie a HansUp) e il set per la listbox.recordset (grazie a HansUp nuovo)

ho risolto l'errore:

 Private Sub Textbox_recherche_Change() 

       Dim cnn As ADODB.Connection 
       Set cnn = New ADODB.Connection 
       Dim rs As ADODB.Recordset 

'A important point to solve the Error 91 is to declare your ADODB.Connection with .Properties like that : (I don't use Windows NT authentification but the SQL Server authentification) 


       With cnn 
        .Provider = "Microsoft.Access.OLEDB.10.0" 
        .Properties("Data Provider").Value = "SQLOLEDB" 
        .Properties("Data Source").Value = "10.******" 
        .Properties("User ID").Value = "*****readonly" 
        .Properties("Password").Value = "*****readonly" 
        .Open 
       End With 

    'The second point is to replace the * in the search for the autocompletion by the % 

       Set rs = cnn.Execute("SELECT [NOMPRE] FROM ****.***** WHERE NOMPRE LIKE '%" & Me.Textbox_recherche.Text & "%'") 

    'You have to declare the RowSourceType of your listbox to "Table/Query" 

      Me.Liste_choix.RowSourceType = "Table/Query" 

    'And Finally to SET your recordset like that: 

      Set Me.Liste_choix.Recordset = rs 

       rs.Close 
       cnn.Close 

       Set cnn = Nothing 
       Set rs = Nothing    

      End Sub