Maschera continua e filtri concatenati

di il
13 risposte

Maschera continua e filtri concatenati

Buongiorno a tutti, sono nuovo e principiante con il VBA.

Mi scuso in anticipo per la scarsa terminologia tecnica e se per molti di voi il problema sembrerà banale, ma non riesco a togliere il ragno dal buco.

Purtroppo mi trovo impantanato da giorni su un'algoritmo che sembrava banale e invece mi sta creando grossi problemi. Gira e rigira non riesco ad uscirne.

SITUAZIONE:

13 Risposte

  • Re: Maschera continua e filtri concatenati

    Candy91 ha scritto:


    ...Voglio inoltre poter filtrare ogni campo in abbinamento con l'anno, ad esempio se seleziono un nominativo dalla cboVisitsCustomerFilter e il valore "2018" dalla cboVisitsYear mi deve restituire tutti i record relativi al cliente selezionato, nell'anno 2018.
    Dai una bella sfoltita al codice, come prima cosa e prendi spunto da qui
    **
    Anzi... facciamo che lo riporto io, pari pari, tanto è breve, lo si vede per esteso

    @Alex ha scritto:


    Un filtro composito, ovvero con più condizioni/criteri si semplifica in modo semplice con un'ottica di questo tipo:
    
    Dim strWH As String
    If Len(Me!Controllo1.Value & vbNullstring)>0 Then strWH=strWH & "Campo1=" & Me!Controllo1.Value& " AND "
    If Len(Me!Controllo2.Value & vbNullstring)>0 Then strWH=strWH & "Campo2=" & Me!Controllo2.Value & " AND "
    [COLOR="#FF0000"].... ' aggiungi le altre 1000 condizioni...[/COLOR]
    If Len(strWH)>0 then strWH=Mid$(strWH,1,Len(strWH)-5)
    Me.Filter=strWH
    Me.FilterON=True
    Quindi formatta i Criteri in base al fatto siano Stringa(apicetti) o Data(#inversione mm/gg...#) ecc...!
    Dici che è una sottomaschera. Cosa c'è nella maschera principale? con quale campo sono collegate la maschera principale e la sottomaschera?
  • Re: Maschera continua e filtri concatenati

    Grazie per il suggerimento, vedo cosa riesco a combinare.

    Philcattivocarattere ha scritto:


    Dici che è una sottomaschera. Cosa c'è nella maschera principale? con quale campo sono collegate la maschera principale e la sottomaschera?
    Le maschere non sono collegate tramite alcun campo. Nella maschera principale ci sono una serie di textbox con Username, Userlevel e Area, le quali fungono come parametri per l'esecuzione della query che poi viene visualizzata nella sottomaschera continua di cui sopra.

    Il database sul quale sto lavorando prevede un sistema di login per l'appunto e vari livelli di accesso che consentono o meno di visualizzare determinati dati.
  • Re: Maschera continua e filtri concatenati

    Candy91 ha scritto:


    ...Le maschere non sono collegate tramite alcun campo. ..
    Bon, gestione dei filtri non influenzata dal fatto di essere una sottomaschera.
  • Re: Maschera continua e filtri concatenati

    Candy91 ha scritto:


    Le maschere non sono collegate tramite alcun campo. Nella maschera principale ci sono una serie di textbox con Username, Userlevel e Area, le quali fungono come parametri per l'esecuzione della query che poi viene visualizzata nella sottomaschera continua di cui sopra.
    Piuttosto che usare maschera/sottomaschera (più rognoso da gestire per quel meccanismo di filtri che avresti progettato), non ti conviene sfruttare l'Intestazione maschera (quella della tua attuale sottomaschera) per mettere i controlli textbox?
  • Re: Maschera continua e filtri concatenati

    Ok, a quanto pare sono riuscito a far funzionare correttamente l'algoritmo:
    
    Private Sub cmdVisitsFilter_Click()
    Dim VisitFilter As String
    If Len(Me.cboVisitsCustomerFilter.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "IDCustomer=" & Me.cboVisitsCustomerFilter.Value & " AND "
    End If
    If Len(Me.cboVisitsAgentFilter.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "UserID=" & Me.cboVisitsAgentFilter.Value & " AND "
    End If
    If Len(Me.cboVisitsFilterArea.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "Area=" & Me.cboVisitsFilterArea.Value & " AND "
    End If
    If Len(Me.cboVisitsYear.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "Anno=" & Me.cboVisitsYear.Value & " AND "
    End If
    If Len(VisitFilter) > 0 Then
       VisitFilter = Mid$(VisitFilter, 1, Len(VisitFilter) - 5)
    End If
    Me.Filter = VisitFilter
    Me.FilterOn = True
    End Sub
    
    Anche se non ho capito molto di quello che ho fatto onestamente, ma ci devo dedicare tempo, non ci son santi che tengano.

    Sto smanettando e facendo varie prove, il programma finora non sembra restituire errori fortunatamente.

    Grazie mille per la dritta

    OsvaldoLaviosa ha scritto:


    Candy91 ha scritto:


    Le maschere non sono collegate tramite alcun campo. Nella maschera principale ci sono una serie di textbox con Username, Userlevel e Area, le quali fungono come parametri per l'esecuzione della query che poi viene visualizzata nella sottomaschera continua di cui sopra.
    Piuttosto che usare maschera/sottomaschera (più rognoso da gestire per quel meccanismo di filtri che avresti progettato), non ti conviene sfruttare l'Intestazione maschera (quella della tua attuale sottomaschera) per mettere i controlli textbox?
    Giusta osservazione. Ho usato le intestazioni delle varie finestre per i loghi dell'azienda per cui lavoro, per dare un aspetto più professionale all'applicazione. Nel resto delle maschere principali, oltre alle textbox per i controlli delle query, ho anche una serie di altri comandi.
    Questo magari mi ha complicato un pelo la vita, forse un'errore di inesperienza, l'importante è che l'applicazione funzioni..
  • Re: Maschera continua e filtri concatenati

    Intanto se la Stringa di FILTRO è Vuota, il Filtro si deve rimuovere...!

    Io la scriverei così è decisamente più leggibile...!
    
    Private Sub cmdVisitsFilter_Click()
        Dim sWH As String
        If Len(Me.cboVisitsCustomerFilter.Value & vbNullString) > 0 Then sWH = sWH & "IDCustomer=" & Me.cboVisitsCustomerFilter.Value & " AND "
        If Len(Me.cboVisitsAgentFilter.Value & vbNullString) > 0 Then sWH = sWH & "UserID=" & Me.cboVisitsAgentFilter.Value & " AND "
        If Len(Me.cboVisitsFilterArea.Value & vbNullString) > 0 Then sWH = sWH & "Area=" & Me.cboVisitsFilterArea.Value & " AND "
        If Len(Me.cboVisitsYear.Value & vbNullString) > 0 Then sWH = sWH & "Anno=" & Me.cboVisitsYear.Value & " AND "
        If Len(sWH) > 0 Then
            sWH = Mid$(sWH, 1, Len(sWH) - 5)
            Me.Filter = sWH
            Me.FilterOn = True
        Else
            Me.FilterOn = False
        End If
    End Sub
    Per il fatto tu non la comprenda... devi farlo...!
    Attenzione ai FieldType ed alla conseguente SINTASSI di contruzione del Criterio.
  • Re: Maschera continua e filtri concatenati

    @Alex ha scritto:


    Per il fatto tu non la comprenda... devi farlo...!
    Dunque vediamo se ho capito:
    If Len(Me.cboVisitsCustomerFilter.Value & vbNullString) > 0 Then sWH = sWH & "IDCustomer=" & Me.cboVisitsCustomerFilter.Value & " AND "
    Tradotto: Se il numero di caratteri del valore selezionato nella combo è maggiore di 0, allora la variabile sWH è uguale alla variabile sWH stessa concatenata con IDCustomer che corrisponde al valore della combo.

    Non ho capito perché all'interno della funzione Len hai concatenato il cbo.Value con vbNullString.
    If Len(sWH) > 0 Then sWH = Mid$(sWH, 1, Len(sWH) - 5)
    Se il numero di caratteri della variabile dopo tutti gli If è maggiore di 0, la variabile è uguale alla variabile stessa ripulita dell' " AND " alla fine.

    @Alex ha scritto:


    Attenzione ai FieldType ed alla conseguente SINTASSI di contruzione del Criterio.
    I campi che devo filtrare sono sia numerici che testo, cosa cambia nella sintassi?
  • Re: Maschera continua e filtri concatenati

    Una TextBox o una Combo possono avere un valore che non è di tipo Stringa, ad esempio possono valere NULL.
    La funzione LEN(...) richiede che il contenuto della Funzione sia una Stringa, che non supporta però il valore NULL.
    Di conseguenza eseguendo LEN(NULL) otterresti un errore.
    In questi casi l'uso della concatenazione è funzionale al CASTING dei dati, ovvero NUL & NullStetring=NullString=Stringa, quyindi è un modo per prevenire un errore FORZANDO il DataType a Stringa.

    Il Criterio è divoso in 3 TIPI:
    NUMERI
    TESTO
    DATE

    Per formattare correttamente ci sono 2 metodi:
    1) Sai il Type... e strutturi di conseguenza(quì basta che fai una ricerca nel WEB e lo vedi)
    2) Non lo conosci a prescindere, o meglio deve essere flessibile... usi BuildCriteria, funzione nativa di Access.
  • Re: Maschera continua e filtri concatenati

    Grazie della spiegazione. Ci guardo con calma.
  • Re: Maschera continua e filtri concatenati

    Candy91 ha scritto:


    ...
    Non ho capito perché all'interno della funzione Len hai concatenato il cbo.Value con vbNullString.
    Oltre a quanto spiegato da @Alex con riferimento al Null, usare il Len ti permette di trattare con lo stesso codice il Null & vbNullString e una stringa di lunghezza zero. Forse questa non è la situazione più adatta per fare questa precisazione ma saperlo fa semre comodo.
    L'uso della funzione Len è dovuto a come VBA memorizza le stringhe di testo: è più veloce verificare se una stringa è di lughezza zero invece di verificare se è uguale a "".

    Candy91 ha scritto:


    ...
    If Len(sWH) > 0 Then sWH = Mid$(sWH, 1, Len(sWH) - 5)
    Se il numero di caratteri della variabile dopo tutti gli If è maggiore di 0, la variabile è uguale alla variabile stessa ripulita dell' " AND " alla fine.
    sWH è la stringa che costituisce la WHERE condition. Se la lunghezza di quella stringa è superiore a zero significa che uno degli IF precedenti era vero e che quindi è stata creata la where condition in cui viene sempre apposta alla fine un " AND " (spazio+AND+spazio = 5 caratteri).
    Indipendentemente dal fatto che i criteri impostati siano 1 o più di uno, la stringa sWH conterrà sempre, alla fine, un " AND " di troppo, quindi via i 5 caratteri finali.
  • Re: Maschera continua e filtri concatenati

    Un'ultima cosa. Sto facendo varie prove per cercare di avere un'interfaccia più "pulita" e minimale possibile.

    Mi ritrovo con le maschere descritte sopra: quella principale "frmVisitsExtended" , e la sottomaschera "fsubVisits" in forma di maschera continua con le varie combobox e il pulsante per filtrare i record.

    Ho spostato tutte le combo e il pulsante in una terza maschera "frmVisitsFilter", la quale si apre in forma popup a scelta obbligatoria tramite un altro pulsante nella maschera principale. Da qui logicamente vorrei filtrare i record di "fsubVisits".

    Il problema è che non riesco a dare i giusti riferimenti alla maschera da filtrare, oppure mi sfugge qualcos'altro:
    
    Private Sub cmdVisitsFilter_Click()
    Dim VisitFilter As String
    If Len(Me.cboVisitsCustomerFilter.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "IDCustomer=" & Me.cboVisitsCustomerFilter.Value & " AND "
    End If
    If Len(Me.cboVisitsAgentFilter.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "UserID=" & Me.cboVisitsAgentFilter.Value & " AND "
    End If
    If Len(Me.cboVisitsFilterArea.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "Area=" & Me.cboVisitsFilterArea.Value & " AND "
    End If
    If Len(Me.cboVisitsYear.Value & vbNullString) > 0 Then
       VisitFilter = VisitFilter & "Anno=" & Me.cboVisitsYear.Value & " AND "
    End If
    If Len(VisitFilter) > 0 Then
       VisitFilter = Mid$(VisitFilter, 1, Len(VisitFilter) - 5)
       Forms![frmVisitsExtended]![fsubVisits].Form.Filter = VisitFilter
       Forms![frmVisitsExtended]![fsubVisits].Form.FilterOn = True
    Else
       Forms![frmVisitsExtended]![fsubVisits].Form.FilterOn = False
    End If
    End Sub
    
    Mi da errore di sintassi (operatore mancante) nell'espressione della query. Quindi a naso, o devo rivedere il codice all'interno delle varie condizioni, ma mi pare un po' strano, oppure il problema è nell'ultimo If in cui do i riferimenti alla sottomaschera. Oppure sono proprio fuori strada..

    Dove sto sbagliando?
  • Re: Maschera continua e filtri concatenati

    Candy91 ha scritto:


    Un'ultima cosa. Sto facendo varie prove per cercare di avere un'interfaccia più "pulita" e minimale possibile.
    ...
    Mi da errore di sintassi (operatore mancante) nell'espressione della query. Quindi a naso, o devo rivedere il codice all'interno delle varie condizioni, ma mi pare un po' strano, oppure il problema è nell'ultimo If in cui do i riferimenti alla sottomaschera.
    Mi sono perso tra maschere, sottomaschere e maschere popup a scelta obbligata (che credo sia una maschera modale che nel codice spesso si riconosce dalla presenza della costante acDialog in DoCmd.OpenForm)
    Con qui criteri di filtro così "articolati" risulta utilissimo il Debug.Print nomestringafiltro per vedere nella finestra immediata cosa c'è in questa stringa.
    Rispieghi dov'è scritto quel codice, come e quando apri la maschera da filtrare e che origine dati ha?
  • Re: Maschera continua e filtri concatenati

    Philcattivocarattere ha scritto:


    Candy91 ha scritto:


    Un'ultima cosa. Sto facendo varie prove per cercare di avere un'interfaccia più "pulita" e minimale possibile.
    ...
    Mi da errore di sintassi (operatore mancante) nell'espressione della query. Quindi a naso, o devo rivedere il codice all'interno delle varie condizioni, ma mi pare un po' strano, oppure il problema è nell'ultimo If in cui do i riferimenti alla sottomaschera.
    Mi sono perso tra maschere, sottomaschere e maschere popup a scelta obbligata (che credo sia una maschera modale che nel codice spesso si riconosce dalla presenza della costante acDialog in DoCmd.OpenForm)
    Con qui criteri di filtro così "articolati" risulta utilissimo il Debug.Print nomestringafiltro per vedere nella finestra immediata cosa c'è in questa stringa.
    Rispieghi dov'è scritto quel codice, come e quando apri la maschera da filtrare e che origine dati ha?
    Apro la maschera principale "frmVisitsExtended" - clicco un pulsante - mi si apre una finestra popup "frmVisitsFilter" con all'interno tutte le combo - seleziono dalle combo i valori che mi interessa filtrare - clicco sul pulsante filtra, sempre all'interno della finestra popup - mi si chiude la finestra popup e mi vengono filtrati i record nella sottomaschera "fsubVisits"

    Questo sarebbe idealmente quello che sto cercando di fare.

    Il codice è scritto sul comando "cmdVisitsFilter" all'interno della maschera con le combo "frmVisitsFilter".

    La sottomaschera da filtrare "frmsubvisits" è all'interno della maschera principale "frmVisitsExtended" e come origine dati ha una query. Maschera principale e sottomaschera non sono collegate tramite alcun campo.
Devi accedere o registrarti per scrivere nel forum
13 risposte