Ho scartabellato tra i vari database che nel corso degli anni ho realizzato.
Ne ho trovato uno dove ho una funzione di ricerca praticamente identica a quella che serve a te.
Un database su cui archiviavo le serie tv che vedevo e volevo vedere, con il numero di episodi, le stagioni,lo stato di avanzamento della visione, lo stato della serie e molto altro.
Ora ne uso uno diverso, ma è tutto automatizzato tramite json che si collegano ai database di film e wikipedia, che mi riempiono in automatico tutti i dati necessari prelevati dai loro archivi e non fa al caso nostro.
Premetto che il codice è scritto velocemente e a coda di gatto, ma rende l'idea dell'approccio logico e strutturale.
E premetto anche che questo è uno dei tantissimi modi con cui si può realizzare.
Tutto si avvale di due semplici form
un form serietv, che uso per inserire, modificare, cancellare e ricercare le serie tv
ed un form ricerche, al quale passo i dati da ricercare al form serietv che saranno filtrati tramite la funzione filter e non tramite query.
Uso filter perchè serietv essendo un form multifunzione ha una fonte dati propria e quindi al caricamento ha già tutti i dati necessari e quindi non c'è bisogno che vada ad utilizzare una query. Basta semplicemente filtrare i dati già caricati dalla fonte dati.
Quello che ci interessa è il form di ricerca ed il codice che fa funzionare il tutto.
L'immagine è questa.
Ogni controllo che vedi, non è associato, quindi tutte le azioni vengono controllate tramite vba.
Ogni controllo, con il dato selezionato va ad aprire il form serietv, al cui caricamento, in base ai valori che gli passo, filtra i relativi dati che mi interessano. Se non viene passato nessun dato o viene aperto in modo indipendente, cioè senza passare per la ricerca il form seritv si apre senza filtri, visualizzando tutte le serie tv inserite ed è pronto per l'inserimento di una nuova serie tv, oppure navigare su tutte le relative serie.
Ora quello che ci interessa è come funziona la combobox stato ed il relativo codice, sia lato form ricerche, sia lato form serietv quando viene caricato.
vediamo i valori che contiene la combo stato. Valori che posso tranquillamente aggiungere, cancellare o modificare, senza che questo vada ad influire sulla ricerca o che necessitano di modifiche al codice vba.
La combo box stato ricava i dati da una tabella dove sono contenute tutte le voci corrispondenti.
Quindi molto simile al tuo scenario.
Quindi se vado a selezionare la voce Vista, il form serie tv si aprirà con tutte e solo le serie che ho già visto e così via per tutte le altre voci.
vediamo ora come funziona sia a livello logico che strutturale.
La combo non è associata, quindi significa che devo gestire tutto manualmente
Per far funzionare la ricerca e passare i valori al form serie tv che andrò ad aprire, mi avvalgo della funzione nativa “openargs” del metodo openform. Praticamente openarg funziona come una variabile globale o una vartemp, ma è molto più semplice e funzionale da usare perchè:
- lo si dichiara al momento quando occorre, quindi rende più semplice per il programmatore la lettura e la comprensione del codice. E se lo si deve modificare, non bisogna andarlo a ricercare tra i vari moduli o altri codici, proprio perchè viene dichiarato prima della chiamata openform, sta li, proprio una riga sopra.
- e' temporaneo e vale solo per la chiamata per il quale lo si usa. Quindi nessuna confusione in caso ci si dimentichi di azzerarlo o lo si usi in modo improprio, cosa invece che accade spesso con le vartemps o le variabili globali.
- non usa grandi quantità di risorse ed una volta usato non esiste più.
- con particolari accortezze (come vedremo) si possono passare tutti i valori desiderati.
Fatte queste premesse vediamo i vari codici vba che stanno dietro.
Se non conosci o capisci qualche comando che ho usato, ti consiglio di ricercarlo su internet. Non conosco le tue competenze e dovendo spiegare tutto, praticamente ci passiamo la notte.
Questo è il codice che sta dietro alla combo box stato.
Private Sub Testo17_AfterUpdate()
Dim casella As String
If IsNull(casella = Me.Testo17.Value) Then
Exit Sub
Else
casella = ("3" & Me.Testo17.Value)
End If
DoCmd.OpenForm "Serie_tv2", , , , , , casella
End Sub
Allora.
testo17 è il nome della combobox “stato”
Casella è una variabile che uso per costruire la stringa che mi servirà per passare i valori con il quale voglio che venga fatta la ricerca su serie tv.
E' una variabile che è valida esclusivamente per questa sub, quindi non visibile agli altri elementi del progetto ed una volta usata sparisce.
Naturalmente potresti obiettare che potrei usare una globale o una vartemp.
Certo, potrei farlo, ma se usassi una variabile globale, ogni volta che la uso, dovrei sapere come è stata dichiarata e ricordarmi di azzerarla se non deve rimanere con un valore, e se per un qualsiasi motivo mi dimenticassi in fase di stesura del codice di fare una di queste operazioni, avrei un valore sbagliato, che mi sballerebbe la ricerca. E' facile fare il debug di 4 righe di codice, ma quando si hanno migliaia di righe di codice e centinaia di form e tabelle e query, collegate tra di loro, se ci si dimentica di riassegnare una variabile globale, fare il debug diventa una cosa complessa da far vedere i sorci verdi e prendere il calendario in mano, nominando tutti i santi scritti, compresi quelli minori per ogni giorno che si trovano sul calendario di Barbanera.
Come avrai notato la variabile casella viene costruita in un modo un po' particolare.
casella = ("3" & Me.Testo17.Value)
Praticamente è una stringa costruita composta da due elementi
“3” che è un mio indice personalizzato e che non è salvato da nessuna parte, se non nel codice VBA
Me.testo17.value è il dato effettivo che userò per filtrare in apertura i dati del form serie tv.
Perchè ho bisogno di un indice?
Il form serietv è un form, come detto, multifunzione che riceve comandi diversi da diversi form o controlli esterni, quindi come vedremo poi, ad ogni azione che voglio che venga effettuata, usando un indice personalizzato, con una select andrò ad attivare il relativo codice che venga usato.
Quindi nel codice degli altri controlli combobox, avremo una variabile casella costruita con un indice “1", ”2" e così via, per selezionare il codice lato form serietv, corrispondente all'azione preposta.
Naturalmente se dovessi aggiungere un ulteriore controllo che mi fa una ricerca diversa, devo aggiungere anche il relativo indice ed il relativo codice di attivazione sul form serie tv, ma è una modifica strutturale indispensabile anche se non usassi un indice, diversa dal problema che ti ritroveresti con il tuo codice se vai ad inserire un nuovo identificativo delle società.
veniamo quindi al comando openform e i relativi metodi:
OpenForm (FormName, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs)
io ho scritto questo:
DoCmd.OpenForm "Serie_tv2", , , , , , casella
Serie_tv2 è il form che andrò ad aprire
tutte le virgole servono per specificare che tutti i metodi (come View, filtername…) non verranno utilizzati e casella è la variabile composta che andrò ad usare per il metodo OpenArgs.
Cioè il form serietv, verrà aperto in base ai valori di casella che vengono passati tramite openargs.
ora vediamo il codice vba lato form serietv che viene eseguito al caricamento del form.
Private Sub Form_Load()
Dim variabile As String
Dim controllo As String
Dim dato As String
If IsNull(variabile = Me.OpenArgs) Then Exit Sub
variabile = Me.OpenArgs
controllo = Left(variabile, 1)
dato = Mid(variabile, 2)
Select Case controllo
Case "1"
Me.Filter = "ID_serietv =" & dato
Case "2"
dato = Chr(34) & dato & Chr(34)
Me.Filter = "avanzamento =" & dato
Case "3"
dato = Chr(34) & dato & Chr(34)
Me.Filter = "stato =" & dato
Case "4"
dato = Chr(34) & dato & Chr(34)
Me.Filter = "Nome_serie =" & dato
End Select
Me.FilterOn = True
End Sub
Da chiarire immediatamente che in questo codice non ho usato la funzione split, cosa che mi avrebbe facilitato molto le cose. Ma purtroppo all'epoca, mi ero proprio dimenticato della sua esistenza e quindi ho usato il metodo arcaico che si usava prima della sua introduzione, cioè usare una serie di variabili, e la manipolazione delle stringhe in base ai dati da dividere ed assegnare alle varie variabili.
Ma il concetto è praticamente lo stesso.
variabile = Me.OpenArgs
Con Me.openArgs, recupero i dati che ho passato dal form ricerche e li assegno alla variabile, “variabile”. (mai chiamare una variabile, con il nome variabile, crea solo confusione, ma come detto il codice è scritto a coda di gatto)
controllo = Left(variabile, 1)
dato = Mid(variabile, 2)
in questa porzione di codice divido l'indice, che assegno alla variabile controllo, ed il valore da ricercare che assegno alla variabile dato, che userò per eseguire il filtro.
Dopo di che uso il select per selezionare il codice da eseguire in base al mio indice.
Il codice chr(34) è solo una formattazione per evitare determinati errori se si usa una stringa invece che un valore numerico.
Visto che il form serietv ha una sua fonte dati, mi basta usare il metodo filter per selezionare i record che mi interessano.
Se il form non avesse una fonte dati, basterebbe semplicemente usare una query per ogni casistica, anche se il codice si complicherebbe.
Quindi se possibile, per semplicità è meglio usare una fonte dati già preimpostata.
I quattro indici del codice naturalmente fanno riferimento ai 4 controlli del form di ricerca, cioè “serie tv”, “avanzamento”, “stato”, e “ricerca per testo”.
Questo è solo uno dei tanti metodi che si possono usare per fare quello che vuoi realizzare e tra parentesi è anche uno dei meno funzionali, ma più basici a livello di codice.