[RISOLTO] query con diversi filtri da combobx

di il
20 risposte

[RISOLTO] query con diversi filtri da combobx

Buonasera!

ho creato una query e una maschera su questa. nella maschera ci sono 3 combobox: barcode, data, fornitori.

vorrei filtrare i risultati della query in fuzione delle tre combobox presenti, sia in termini "AND" sia in termini "OR", ovvero: se viene selezionato un valore da una solo combobx allora si terrà conto solo di quella (OR), altrimenti, se si selezionano valori da diverse combobx si terrà conto di tutte (AND).

ho associato la maschera alla query (i campi vengono compilati); query>criteri>casellacombinataX;
casellacombinataX > dopoaggiornamento> maschera.requery.

però non funziona, ovvero non i dati non mi vengono filtrati. dovrei forse costruire 3 diverse query?

20 Risposte

  • Re: [RISOLTO] query con diversi filtri da combobx

    Io mi giocherei la carta del "filtro in base a maschera". Effettua esattamente quello che vorresti tu senza mettere in gioco espressioni particolari.
  • Re: [RISOLTO] query con diversi filtri da combobx

    Sicuro si possa realizzare L'OR dei criteri in quel modo..?
  • Re: [RISOLTO] query con diversi filtri da combobx

    Grazie delle risposte. ho quasi risolto.

    @osvaldo: purtroppo non sono riuscito a gestire i filtri maschera. ovvero non so come fare per non selezinare manualmente ogni volta filtro avanzato>filtro maschera>ecc...; vorrei avere una cosa intuitiva per l'utente finale;

    @alex: per OR intendi organizzazione?

    ad ogni modo il problema era la query base, che era organizzata tipo foglio excel nella quale facevo di tutto: raggruppamenti, somme, calcoli tra campi e in più pretendevo di poterci mettere 3 filtri!

    il problema che mi si pone ora è come gestire 3 filtri (combobox) in contemporanea in modo che non tutti siano attivi allo stesso momento (OR) oppure (SE) ce ne sono di attivi più di uno combinarli (AND).
    in ogni combobx ho aggiunto la voce 0 in modo che se selezionato mostri tutti i record. quello che manca è il legame con gli altri 2 filtri.

    credete sia il caso di utilizzare del codice per codificare ogni possibile opzione (if filtro 1&filtro2&filtro3 then...else if filtro &filtro2 ecc)?


    EDIT (14/12/14 14:01): seguendo l'ipotesi codice VB, avrei 4 opzioni: filtri tutti spenti, filtri tutti accesi, 1 filtro spento e 2 accesi, 1 acceso e 2 spenti. credo sia tutto.

    questo è lo pseudocodice che adotterei
    
    'filtro1 filtro2 filtro3
    'if (filtro1 filtro2 filtro3) = 0
    ' then showall
    'Else
    'if (filtro1 filtro2 filtro3)>0
    'then query filtro1 filtro2 filtro3
    'else
    ' if filtro 1 = 0 and (filtro2 e filtro3)>0
    'then query filtro 2 e filtro3
    'Else
    ' if filtro 2 = 0 and (filtro1 e filtro3)>0
    'then query filtro1 e filtro3
    'else
    ' if filtro 3 = 0 and (filtro1 e filtro2)>0
    'then query filtro 1 e filtro2
    'else
    'if filtro1 > 0 and (filtro2 e filtro3)=0
    'then query filtro1
    'else
    'if filtro2 > 0 and (filtro1 e filtro3)=0
    'then query filtro2
    'else
    'if filtro3 > 0 and (filtro1 e filtro2)=0
    'then query filtro3
    'End If
    
    dove il valore 0 corrisponde alla voce nulla in combobox che permettere di spegnere i lfiltro e far vedere tutti i risultati (è riferito agli ID [chiave primaria]) 
    

    EDIT2 (20:11)
    
    
    
    Me.FilterOn = False
    
    
    
    If ordine_data = 0 And ordine_barcode = 0 And ordine_fornitore = 0 Then
    MsgBox "nessun filtro selezionato"
    
    DoCmd.ShowAllRecords
    
    ElseIf ordine_data > 0 And ordine_barcode > 0 And ordine_fornitore > 0 Then
    MsgBox "tutti i filtri selezionati"
    Me.FilterOn = True
    Me.Filter = ordine_data
    Me.Filter = ordine_barcode
    Me.Filter = ordine_fornitore
    
    ElseIf ordine_data = 0 And ordine_barcode > 0 And ordine_fornitore > 0 Then
    MsgBox "data=0, barcode e fornitore selezionati"
    Me.FilterOn = True
    Me.Filter = ordine_barcode
    Me.Filter = ordine_fornitore
    
    ElseIf ordine_barcode = 0 And ordine_data > 0 And ordine_fornitore > 0 Then
    MsgBox "barcode=0, data e fornitore selezionati"
    Me.FilterOn = True
    Me.Filter = ordine_data
    Me.Filter = ordine_fornitore
    
    ElseIf ordine_fornitore = 0 And ordine_data > 0 And ordine_barcode > 0 Then
    MsgBox "fornitorre=0, barcode e data selezionati"
    Me.FilterOn = True
    Me.Filter = ordine_data
    Me.Filter = ordine_barcode
    
    ElseIf ordine_data > 0 And ordine_barcode = 0 And ordine_fornitore = 0 Then
    MsgBox "data selezionato, fornitore e barcode=0 "
    
    Me.FilterOn = True
    Me.Filter = ordine_data
    
    ElseIf ordine_barcode > 0 And ordine_data = 0 And ordine_fornitore = 0 Then
    MsgBox "barcode selezionato, fornitore e data=0 "
    
    Me.FilterOn = True
    Me.Filter = ordine_barcode
    
    Else
    If ordine_fornitore > 0 And ordine_data = 0 And ordine_barcode = 0 Then
    MsgBox "fornitore selezionato, barcode e data=0 "
    
    Me.FilterOn = True
    Me.Filter = ordine_fornitore
    End If
    End If
    
    me.requery
    
    per ora questo è quanto sono riuscito a produrre (nota: il comando msgbox serviva a me per verifica).
    questo il codice associato al command buttone "applica filtri". nella query devo mettere tale pulsante come criterio giusto?
  • Re: [RISOLTO] query con diversi filtri da combobx

    Quando si dice OR si intende che le condizioni Logiche siano in ALTERNATIVA.
    
    Valore=1 OR Valore=2
    I criteri di Filtro quindi possono assurmere la concatenazione esclusiva con AND o con OR...
    
    Valore=1 OR Valore=2
    Valore=1 AND Valore=2
    Credo sia semplice intuirne la differenza...

    Per costruire una concatenazione di CRITERI e la possibilità di identificarli in AND oppure in OR la gestione diventa più complessa...!

    Un filtro in tutti i casi si costruisce così
    
    Dim strWH As String
    Dim strCONC As String
    StrCONC=" AND "  ' Quì eventualmente puoi valutare la Questione AND/OR
    If Len(Me!Combo1.Value & vbNullstring)>0 Then strWH=strWH & "Campo1='" & Me!Combo1.Value & "'" & strCONC
    If Len(Me!Combo2.Value & vbNullstring)>0 Then strWH=strWH & "Campo2='" & Me!Combo2.Value & "'" & strCONC
    If Len(Me!Combo3.Value & vbNullstring)>0 Then strWH=strWH & "Campo3='" & Me!Combo3.Value & "'" & strCONC
    
    If Len(strWH)>0 Then strWH=Mid$(strWH,1,Len(strWH)-Len(StrCONC)
    Nella stringa Finale [strWH] hai la condizione di CRITERIO COMPOSITA.

    Eventualmente puoi valutare la Questione AND/OR chiaro che se devi definire per ogni PARTE di criterio la possibilità di AND/OR vedrei bene l'uso di una CheckBox per ogni condizione dove se TRUE=OR e se FALSE=AND o come credi...
    A quel punto si potrebbe implementare così:
    
    Dim strWH As String
    If Len(Me!Combo1.Value & vbNullstring)>0 Then strWH=strWH & "Campo1='" & Me!Combo1.Value & "'" & IIF(ME!ckOPT1.Value," OR "," AND ")
    If Len(Me!Combo2.Value & vbNullstring)>0 Then strWH=strWH & "Campo2='" & Me!Combo2.Value & "'" & IIF(ME!ckOPT2.Value," OR "," AND ")
    If Len(Me!Combo3.Value & vbNullstring)>0 Then strWH=strWH & "Campo3='" & Me!Combo3.Value & "'" & IIF(ME!ckOPT3.Value," OR "," AND ")
    
    If Len(strWH)>0 Then 
        If strWH LIKE "* OR " Then strWH = Mid$(strWH, 1, Len(strWH) - 4)
        If strWH LIKE "* AND " Then strWH = Mid$(strWH, 1, Len(strWH) - 5)
    End If
  • Re: [RISOLTO] query con diversi filtri da combobx

    Ciao Alessandro,
    se nella query impostata come recordsource della maschera si impostano i criteri risultanti dalle selezioni delle tre combobox, non si potrebbero filtrare i dati in modo più semplice?
    con un me.requery dopo l'aggiornamento delle tre combo oppure invocato da un command button.
    I criteri devono gestire il null con NZ e lo stesso i campi della query su cui i criteri sono impostati.
    che dici?

    un saluto.
  • Re: [RISOLTO] query con diversi filtri da combobx

    Dal punto di vista concreto, nella query le definizioni sono vincolate, quindi non potresti più ridefinire se i CRITERI sono in AND o in OR... nè aggiungerne o toglierne se non riscrivere il PREDICATO SQL, e sinceramente non la vedo una soluzione ideale dal momento che la proprietà FILTER di FORM agevola proprio in questo.

    C'è poi un secondo aspetto più tecnico, di ottimizzazione e performance, dovuto proprio al fatto di ipotizzare che aggiungendo 1÷n criteri provenienti da COMBO, questi non impattino nel caso in cui il valore del Criterio sia NULLO.
    Riassumendo se non scrivo NULLA nelle combo, voglio vedere TUTTI i Records.
    Questo è semplice da capire, ma l'applicazione ne complica gli effetti, perchè serve scrivere queries che ne tengano conto...

    Esempio prendiamo questa Query
    
    SELECT *
    FROM T1
    Affinchè si ipotizzi solo 1 CRITERIO da COMBO che abbia gli effetti sopracitati la possiamo scrivere così:
    
    SELECT *
    FROM T1
    WHERE [CampoX]=Forms!NomeForm!NomeCombo OR Forms!NomeForm!NomeCombo IS NUll
    Per JET è ovviamente piu semplice risolvere la 1° Query che la 2° anche perchè la 2° contiene 2 condizioni in realtà e non 1... che vengono eseguite ogni Record.

    Ecco quindi che nel caso di COMBO VUOTA, se si gestisce questo con l'ottimizzazione del FILTRO FORM SIDE abbiamo modo di ottimizzare sempre la gestione dei criteri.

    Capisci bene che applicando una gestione VBA dei Criteri, se servono li attivo e li inserisco, se non servono li SKIPPO... e non hanno effetto...
  • Re: [RISOLTO] query con diversi filtri da combobx

    Grazie delle risposte e dell'aiuto!

    però non ho ben capito cosa fa il codice
    If Len(Me!Combo1.Value & vbNullString) > 0 Then strWH = strWH & "Campo1='" & Me!Combo1.Value & "'" & strCONC
    1) a cosa serve il vbnullstring?
    2) cosa gli apici tra virgolette?
    3) non ho capito come definire AND/OR nel senso che io non devo specificare a priori una di queste due ma devo impostare la funzione logica in base alle scelte dell'utente (se seleziona solo 1 filtro su 3, 0/3 o 3/3 ecc)
  • Re: [RISOLTO] query con diversi filtri da combobx

    denial ha scritto:


    grazie delle risposte e dell'aiuto!

    però non ho ben capito cosa fa il codice
    If Len(Me!Combo1.Value & vbNullString) > 0 Then strWH = strWH & "Campo1='" & Me!Combo1.Value & "'" & strCONC
    1) a cosa serve il vbnullstring?
    2) cosa gli apici tra virgolette?
    3) non ho capito come definire AND/OR nel senso che io non devo specificare a priori una di queste due ma devo impostare la funzione logica in base alle scelte dell'utente (se seleziona solo 1 filtro su 3, 0/3 o 3/3 ecc)
    Purtroppo un minimo di basi di VBA serve averle altrimenti si complica la situazione per noi che cerchiamo di dare supporto, ma anche per te che ricevi indicazioni complesse da attuare...!

    Vedo di spiegarti il codice per fornirti una chiave di studio.

    Prima di tutto [strCONC] è una stringa che contiene il CONCATENATORE che può essere AND oppure OR come dicevamo...
    Se guardi l'esempio che ti ho proposto, il primo, troverai
    
    StrCONC=" AND "
    Ne consegue che ad ogni CRITERIO inserisco anche in fondo il concatenatore in modo da predisporre la stringa a ricevere il CRITERIO successivo.
    Questa è solo questione di praticità...
    If Len(Me!Combo1.Value & vbNullString) > 0 Then strWH = strWH & "Campo1='" & Me!Combo1.Value & "'" & strCONC
    Se la Combo1(legata al criterio 1) non contiene alcun dato skippo il CRITERIO, mentre se il LEN(Controllo)>0 significa che contiene un valore che dobbiamo usare nel criterio da costruire... basato sul CAMPO1.

    Gli apici si mettono SOLO se il Campo1 in questione è di tipo TESTO, se fosse Numerico non si usano e se fosse Data andrebbe usata una sintassi diversa...

    Mettendo in elenco il Test dei Criteri basati su COMBO e Campi andiamo a costruire il Criterio finale... ovviamente ti troverai con una string che, per come abbiamo detto prima, conterrà " AND " in coda... quindi poi va eliminato... e quello è l'azione dell'ultima riga.

    Nel 2° sesempio le cose un pochetto si complicano... ma devi imparare a fare DEBUG per controllare passo passo le evoluzioni delle variabili e la costruzione della Stringa finale.
  • Re: [RISOLTO] query con diversi filtri da combobx

    Ciao Alessandro,

    Goku ha scritto:


    Capisci bene che applicando una gestione VBA dei Criteri, se servono li attivo e li inserisco, se non servono li SKIPPO... e non hanno effetto...
    quindi...sostanzialmente....dovendo mostrare in una form un recordset in base a criteri acquisiti della form stessa, la soluzione migliore sotto tutti gli aspetti (performance/ottimizzazione), è quella di impostare un filtro nella form anziché farsi che sia la query a mostrare nella form stessa il risultato del recordset con i criteri in essa impostati?
    Ho capito bene ? A maggior ragione se i criteri come in questo caso sono più di uno, quindi.
    Il risultato ottenuto è lo stesso ma raggiunto "tecnicamente" in modo maggiormente efficiente/efficace.

    grazie.
  • Re: [RISOLTO] query con diversi filtri da combobx

    Si esattamente hai capito molto bene.
    Ci sono poi altri vantaggi pratici, quello di sapere sempre qual'è il CRITERIO applicato, e, nel caso tu volessi stampare i soli RECORD FILTRATI, ti basterebbe passare al parametro WHERE del metodo OPENREPORT la propietà Me.Filter per ottenere una rispondenza immediata senza grosse complicazioni...

    Anche nel caso si lavori con SQL_SERVER un filtro applicato CLIENT SIDE, verrebbe ottimizzato alla stessa stregua di una Query sempre CLIENT SIDE...

    Un'altra considerazione è nel caso si voglia Filtrare per ID Multipli... (1,6,9,15...) in questo caso gestirlo verrebbe complesso in quanto spesso si opera con una LISTBOX in MultiSelect...

    Da dire poi che andare a modificare una Stringa SQL impone forzatamente di avere la Stringa definibile VERGINE alla quale applicare poi i criteri...
    In questo ho provato a fare diversi esperimenti costruendo anche un ENGINE per il PARSING dei CRITERI, che trovi in questo demo discretamente complesso:
    http://forum.masterdrive.it/access-79/vba-access-utility-per-filtrare-forms-report-runtime-17431/

    Per capire meglio un po come reputo sia la strada giusta, prova a vedere questi esempi se vuoi che mostrano come costruire Filtri molto complessi

    http://forum.masterdrive.it/access-79/listbox-selezione-multipla-estesa-per-filtrare-form-73537/

    Stavo realizzando un Demo che consentiva di avere una FORM FLESSIBILE che leggendo i Fields della Form da Filtrare, offrisse l'elenco dei campi(per un massimo di 4 opzioni direi sufficienti) e le possibilità di gestire il Confronto con un valore inserito... una sorta del 1° esempio che ti ho esposto ma quello è CUSTOM per la maschera, io lo volevo rendere UNIVERSALE...
    Purtroppo da anni non ho più tempo ed anche voglia di mettermi a giocare con queste cose non essendo il mio lavoro, ma mi piace ancora moltissimo...
  • Re: [RISOLTO] query con diversi filtri da combobx

    Ciao Alessandro,
    molto interessante il tuo intervento e ricco di spunti di riflessione, grazie ancora.
    Stasera guardo tutto con molta attenzione....
    Anche se centra poco...qui io procedevo nel modo seguente....una bella If a controllare se concatenare la "," oppure no...molto meglio la tua soluzione, controllo post ciclo...
    
    Private Function FillItems(lst As Access.ListBox) As String
        Dim varItem As Variant
        Dim strItems As String
        
        strItems = ""
        For Each varItem In lst.ItemsSelected
            If strItems <> "" Then strItems = strItems & ","
            'strItems = strItems & lst.Column(0, varItem) & ","
            strItems = strItems & lst.Column(0, varItem)
        Next
            
        'If Len(strItems) > 0 Then strItems = Mid$(strItems, 1, Len(strItems) - 1)
        FillItems = strItems
    End Function
    
    

    Goku ha scritto:


    Purtroppo da anni non ho più tempo ed anche voglia di mettermi a giocare con queste cose non essendo il mio lavoro, ma mi piace ancora moltissimo...
    piace molto il tutto pure a me, ma sfortunatamente i risultati che ottengo non sono nemmeno paragonabili a ciò che vedo.
    Complimenti per la preparazione e la maniacale pulizia del codice.
    in senso positivo ovviamente, non mi permetterei mai...
    Grazie ancora, un saluto.
  • Re: [RISOLTO] query con diversi filtri da combobx

    Goku ha scritto:


    ciao Alessandro,
    molto interessante il tuo intervento e ricco di spunti di riflessione, grazie ancora.
    Stasera guardo tutto con molta attenzione....
    Anche se centra poco...qui io procedevo nel modo seguente....una bella If a controllare se concatenare la "," oppure no...molto meglio la tua soluzione, controllo post ciclo...
    La differenza è solo che il controllo viene fatto 1 sola volta alla fine, ma in sostanza è l'unica che veramente serve...

    Goku ha scritto:


    Purtroppo da anni non ho più tempo ed anche voglia di mettermi a giocare con queste cose non essendo il mio lavoro, ma mi piace ancora moltissimo...

    piace molto il tutto pure a me, ma sfortunatamente i risultati che ottengo non sono nemmeno paragonabili a ciò che vedo.
    Complimenti per la preparazione e la maniacale pulizia del codice.
    in senso positivo ovviamente, non mi permetterei mai...
    Grazie ancora, un saluto.
    Concordo sul maniacale... è una questione che mi ha sempre catturato...
    Ciao
  • Re: [RISOLTO] query con diversi filtri da combobx

    @alex: complimenti per l'eleganza del codice. se l'ho decifrato correttamente hai risolto in tre righe tutte le opzioni "if...else..." che avevo creato io.

    ma non capisco come usarlo. cioè alla fine ottengo una stringa di testo (strWH) del tipo:
    Campo1=80007920 AND Campo2=1 AND Campo3=3 [con selzione su tutte e 3 le combobox] ma ora come filtro i dati?
  • Re: [RISOLTO] query con diversi filtri da combobx

    Applicando quella stringa alla proprietà FILTER della Maschera...
    
    Me.FilterOn=False
    ' quì ci metti tutto il codice di prima per ottenere strWH
    Me.Filter=strWH
    Me.FilterON=True
Devi accedere o registrarti per scrivere nel forum
20 risposte