Domanda

Ho un modulo di Access 2007 ricercabile tramite una casella combinata.Quando aggiungo un nuovo record, devo aggiornare la casella combinata per includere l'elemento appena aggiunto.

Presumo che sia necessario fare qualcosa nell'evento AfterInsert del modulo ma non riesco a capire cosa.

Come posso riassociare la casella combinata dopo averla inserita in modo che il nuovo elemento appaia nell'elenco?

È stato utile?

Soluzione

Il modo più semplice per garantire che la casella combinata sia sempre aggiornata è semplicemente ripetere la query sulla casella combinata una volta che ha ottenuto il focus.Anche se il recordset viene poi aggiornato da qualche altra parte, la tua casella combinata è sempre aggiornata.Un semplice TheCombobox.Requery nell'evento OnFocus dovrebbe essere sufficiente.

Altri suggerimenti

Ci sono due possibili risposte che sono efficienti:

  1. utilizzare l'evento AfterInsert del modulo per eseguire nuovamente la query sulla casella combinata (così come l'evento OnDeleteConfirm).Ciò sarà sufficiente se la casella combinata non visualizza i dati che l'utente può aggiornare e che devono essere aggiornati se il record sottostante viene aggiornato.

  2. se gli aggiornamenti ai dati devono riflettersi nella casella combinata, avrebbe senso aggiungere una nuova query negli eventi AfterUpdate dei controlli utilizzati per modificare i dati visualizzati nella casella combinata.

Ad esempio, se la tua casella combinata elenca i nomi delle persone nella tabella, ti consigliamo di utilizzare il metodo n. 2 e, nell'evento AfterUpdate di Me!txtFirstName e Me!txtLastName, ripetere la query sulla casella combinata.Dato che stai eseguendo la stessa operazione in quattro posti, ti consigliamo di scrivere una subroutine per eseguire la requery.Quindi, il sub sarebbe simile a questo:

  Private Sub RequerySearchCombo()
    If Me.Dirty Then Me.Dirty = False
    Me!MyCombo.Requery
  End Sub

Il motivo per cui assicurati di ripetere la query solo quando c'è effettivamente un aggiornamento ai dati visualizzati nella casella combinata è perché se stai popolando la casella combinata con l'elenco dell'intera tabella, la ripetizione della query può richiedere molto tempo se tu avere decine di migliaia di record.

Un'altra alternativa che salva tutte le nuove query sarebbe quella di avere un rowsource vuoto per la casella combinata e popolarlo solo dopo che sono stati digitati 1 o 2 caratteri e filtrare i risultati visualizzati dalla combinazione in base ai caratteri digitati.Per questo, utilizzeresti l'evento OnChange della casella combinata:

Private Sub MyCombo_Change()
  Dim strSQL As String

  If Len(Me!MyCombo.Text) = 2 Then
     strSQL = "SELECT MyID, LastName & ', ' & FirstName FROM MyTable "
     strSQL = strSQL & "WHERE LastName LIKE " & Chr(34) & Me!MyCombo.Text & Chr(34) & "*"
     Me!MyCombo.Rowsource = strSQL 
  End If
End Sub

Il codice precedente presuppone che tu stia cercando il nome di una persona in una casella combinata che visualizza "Cognome, Nome".

C'è un altro avvertimento importante:se stai cercando un modulo associato a una tabella completa (o un'istruzione SQL che restituisce tutti i record nella tabella) e utilizzi la navigazione nei segnalibri per individuare i record, questo metodo non si ridimensionerà molto bene, poiché richiede l'estrazione dell'intero indice per i campi cercati attraverso il cavo.Nel caso della mia casella combinata immaginaria sopra, utilizzeresti FindFirst per navigare fino al record con il valore MyID corrispondente, quindi è l'indice per MyID che dovrebbe essere estratto (anche se solo il numero di pagine indice necessarie per soddisfare la ricerca verrebbe effettivamente annullata).Questo non è un problema per le tabelle con poche migliaia di record, ma oltre i 15-20K circa può costituire un collo di bottiglia della rete.

In tal caso, invece di navigare tramite segnalibro, utilizzeresti la casella combinata per filtrare il risultato impostato sul singolo record.Questo è, ovviamente, estremamente efficiente, indipendentemente dal fatto che tu stia utilizzando un backend Jet o un backend server.È altamente auspicabile iniziare a incorporare questo tipo di efficienza nella tua applicazione il prima possibile.Se lo fai, diventa molto più semplice l'upsize a un server back-end, o rende abbastanza indolore se dovessi raggiungere quel punto critico con una massa di nuovi dati che rendono il vecchio metodo troppo inefficiente per essere facile da usare.

Presumo che la tua casella combinata sia un controllo su un modulo, non un controllo casella combinata in una barra di comando.Questa casella combinata ha una proprietà chiamata rowsource, che può essere una lista di valori (marito;moglie;figlio;ragazza) o un'istruzione SQL SELECT (SELECT relationshipDescription FROM Table_relationType).

Presumo anche che il recordset del modulo abbia qualcosa a che fare con il recordset della casella combinata.Quello che dovrai fare è, una volta che il recordset del tuo modulo è adeguatamente aggiornato (evento afterUpdate credo), per reinizializzare la proprietà rowsource del controllo combobox

se l'origine record è un'istruzione SQL:

myComboBoxControl.recordsource = _
    "SELECT relationDescription FROM Table_relationType"

o se si tratta di una lista di valori

myComboBoxControl.recordsource = myComboBoxControl.recordsource & ";nephew"

Ma soprattutto trovo la tua richiesta molto strana.Hai una relazione riflessiva (genitore-figlio) sul tuo tavolo?

Normalmente utilizzerei l'evento NotInList per aggiungere dati a una combo con

   Response = acDataErrAdded

Per aggiornare la combinazione.

Il riferimento per gli sviluppatori di Access 2007 contiene tutti i dettagli, incluso il codice di esempio:http://msdn.microsoft.com/en-us/library/bb214329.aspx

Eseguire nuovamente la query sulla casella combinata nel modulo dopo l'evento di aggiornamento e l'evento di eliminazione.La tua casella combinata sarà aggiornata ogni volta che l'utente apporta modifiche al recordset, sia che si tratti di un nuovo record, di una modifica o di un'eliminazione.

A meno che gli utenti non debbano avere le modifiche di tutti gli altri non appena vengono apportate, non ripetere la query sulla casella combinata ogni volta che viene attivata perché non solo l'utente dovrà attendere (cosa evidente con recordset di grandi dimensioni), ma non è necessario se il il recordset non è cambiato.Ma se è così, è necessario ripetere la query dell'intero modulo non appena qualcun altro apporta una modifica, non solo la casella combinata.Questo sarebbe uno scenario molto insolito.

Dopo l'aggiornamento:

Private Sub Form_AfterUpdate()    
    On Error GoTo Proc_Err 

    Me.cboSearch.Requery   

    Exit Sub    
Proc_Err:    
    MsgBox Err.Number & vbCrLf & vbCrLf & Err.Description
    Err.Clear        
End Sub

Dopo l'eliminazione:

Private Sub Form_Delete(Cancel As Integer)    
    On Error GoTo Proc_Err 

    Me.cboSearch.Requery   

    Exit Sub    
Proc_Err:    
    MsgBox Err.Number & vbCrLf & vbCrLf & Err.Description
    Err.Clear        
End Sub
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top