Sub Filtro per Campo Ricerca da rendere "Universale"

di il
12 risposte

Sub Filtro per Campo Ricerca da rendere "Universale"

Buongiorno a tutti.

ho questa Sub che ricorre in diverse maschere del mio Database.
Avevo pensato di trasformarla in una Sub Pubblica o in una Function ma non ne sono capace perché mi sfugge quale parte potrei spostare e con che variabili al fine di renderla "universale".
Qualcuno può darmi qualche spiegazione così ci provo?
grazie
Crodino.

P.s. la Sub l'ho imparata guardando in rete i video di alcuni Youtuber.
Private Sub txtCerca_KeyUp(KeyCode As Integer, Shift As Integer)
Dim lung As Integer
lung = Len(strFiltro)

Select Case KeyCode
    'tastierino
            Case 96
                strFiltro = strFiltro & Chr$(48)
            Case 97
                strFiltro = strFiltro & Chr$(49)
            Case 98
                strFiltro = strFiltro & Chr$(50)
            Case 99
                strFiltro = strFiltro & Chr$(51)
            Case 100
                strFiltro = strFiltro & Chr$(52)
            Case 101
                strFiltro = strFiltro & Chr$(53)
            Case 102
                strFiltro = strFiltro & Chr$(54)
            Case 103
                strFiltro = strFiltro & Chr$(55)
            Case 104
                strFiltro = strFiltro & Chr$(56)
            Case 105
                strFiltro = strFiltro & Chr$(57)
    'altri casi
            Case 20, 16 'Caps Lock e shift (maiuscolo)
                GoTo Aggiorna
            Case 46 'tasto CANC
                strFiltro = "": Me.txtCercaModello.Value = ""
            Case 8  'tasto BACKSPACE
                If lung = 0 Then GoTo Aggiorna
                If lung = 1 Then strFiltro = "": GoTo Aggiorna
                strFiltro = Left$(strFiltro, lung - 1): GoTo Aggiorna
            Case 190, 188, 110 'punteggiatura varia
                strFiltro = strFiltro & Chr$(46): GoTo Aggiorna   'chr$(46) delete
            Case 219 'apostrofo
                    strFiltro = strFiltro & Chr$(39)              'chr$(39) freccia a destra
            Case Else
                    strFiltro = strFiltro & Chr$(KeyCode)
End Select

Aggiorna:
Me.CercaElenco.Form.Requery

End Sub

12 Risposte

  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Mi pare tu abbia bisogno di 4 Parametri...?
    
    1) KeyCode As Integer
    2) Shift As Integer
    3) strTesto As String
    4) frmCaller As Access.Form
    Detto questo la tua Funzione dovrà avere 4 Parametri... in realtà 3 sono sufficienti in quanto la Form_Caller la riesci a sapere usando CodeContextObject.

    Detto questo non stai dichiarando le Variabili come Obbligatorie e questo può generare anomalie... infatti non dichiari da nessuna parte [strFiltro] e tuttavia funziona...!!!!!!

    Prova...
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    In realtà strFiltro è una varabile Pubblica che poi agisce da filtro sulla Query.
    mi scuso, non lo avevo specificato.

    Ero arrivata a KeyCode e StrTesto ora mi studio gli altri parametri che mi hai indicato.
    grazie
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Crodino ha scritto:


    In realtà strFiltro è una varabile Pubblica che poi agisce da filtro sulla Query...
    C'è quell'uso dell'etichetta Aggiorna (e relativi GoTo) che non mi piace.
    Scritto così, il codice esegue sempre quello che avviene in corrispondenza dell'etichetta Aggiorna (cioè il Requery), non hai anteposto una Exit Sub ad esempio.
    Non ha alcun significato richiarmare GoTo Aggiorna, nell'intero blocco Select Case.
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Non ho capito bene il tuo appunto Philcattivocarattere, l'exit sub non deve avvenire se prima non viene eseguito il requery se no l'elenco all'interno della form non viene aggiornato in base al contenuto della stringa di ricerca
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Crodino ha scritto:


    In realtà strFiltro è una varabile Pubblica che poi agisce da filtro sulla Query.
    mi scuso, non lo avevo specificato.

    Ero arrivata a KeyCode e StrTesto ora mi studio gli altri parametri che mi hai indicato.
    grazie
    Meglio agire sulla Proprietà FILTER di MAschera che su tutta la Stringa SQL della QUERY...
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Mi sa che sto cercando di impelagarmi in una cosa per cui non ho ancora le competenze teoriche necessarie... lascerò stare finché non potrò studiare un po' di più.
    Partendo da qualche esempio più facile credevo di potercela fare...
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Crodino ha scritto:


    Non ho capito bene il tuo appunto Philcattivocarattere
    Adesso mi spiego e ne approfitto per aggiungere un'altra nota al codice postato. Parto con la nota al codice.
    Questa parte
        'tastierino
                Case 96
                    strFiltro = strFiltro & Chr$(48)
                ....
                Case 105
                    strFiltro = strFiltro & Chr$(57)
    la sostituirei con un'unica condizione Case
    'tastierino
        Case 96 To 105
            strFiltro = strFiltro & Chr$(KeyCode - 48)
    'altri casi
        Case 20, 16 'Caps Lock e shift (maiuscolo)
    In pratica da 96 a 105 il valore numerico da sottoporre a Chr$ è il keycode diminuito di 48. Doppio beneficio: ho una riga sola di codice che devo eventualmente modificare (manutenzione del codice, la chiamano) ma soprattutto non ci sono n Case da valutare prima di arrivare a quello giusto. Situazione estrema: il keycode 105 prima di trovare il suo Case deve passare per Case 96, saltarlo, il Case 97, saltarlo, e via dicendo. Per poi fare cosa? una cosa che è molto simile in tutte le precedenti situazioni. Quando si deve usare troppo copia incolla deve scattare l'allarme: forse posso rendere il codice più flessibile. Ed in questo caso è abbanza facile.

    Aspetto dell'etichetta Aggiorna
    Che cosa succede quando si esce dal blocco Select Case? Avviene sempre quello che c'è nell'etichetta Aggiorna: che nel tuo caso è il semplice requery.
    Non c'è bisogno che tu lo specifichi in nessuna di queste righe
    Case 20, 16 'Caps Lock e shift (maiuscolo)
         GoTo Aggiorna
    ...
    Case 190, 188, 110 'punteggiatura varia
          strFiltro = strFiltro & Chr$(46): GoTo Aggiorna   'chr$(46) delete
    Una volta eseguito il codice che si trova all'interno del singolo Case non si passa al Case successivo, si esce dal blocco Select, andando ad eseguire quello che c'è dopo End Select. Nel tuo caso specifico Case 20, 16 può essere seguito da una riga bianca, non c'è nulla da fare se non uscire dalla Select e proseguire.
    Un trattamento speciale per
    Case 8  'tasto BACKSPACE
          If lung = 0 Then GoTo Aggiorna
          If lung = 1 Then strFiltro = "": GoTo Aggiorna
          strFiltro = Left$(strFiltro, lung - 1): GoTo Aggiorna
    Qui l'uso del GoTo fa la differenza, perché se non ci fosse l'ultima riga verrebbe sempre eseguita. Facciamo allora che si riscrive meglio la cosa
    Case 8  'tasto BACKSPACE
          If lung > 1 Then 
               strFiltro = Left$(strFiltro, lung - 1)
          ElseIf lung = 1 Then strFiltro = ""
          End If
    
    Per riepilogare il contenuto di entrambe le mie osservazioni tutto quello che hai scritto si può riscrivere in questo modo, ottenendo lo stesso risultato.
    Private Sub txtCerca_KeyUp(KeyCode As Integer, Shift As Integer)
    Dim lung As Integer
    lung = Len(strFiltro)
    
    Select Case KeyCode
        'tastierino
                Case 96 To 105
                    strFiltro = strFiltro & Chr$(KeyCode - 48)
        'altri casi
                Case 20, 16 'Caps Lock e shift (maiuscolo)
                    'per sottrarlo alla Case Else
                Case 46 'tasto CANC
                    strFiltro = ""
                    Me.txtCercaModello.Value = ""
                Case 8  'tasto BACKSPACE
    		If lung > 1 Then 
    			strFiltro = Left$(strFiltro, lung - 1)
    		ElseIf lung = 1 Then 
    			strFiltro = ""
    		End If
                Case 190, 188, 110 'punteggiatura varia
                    strFiltro = strFiltro & Chr$(46)   'chr$(46) delete
                Case 219 'apostrofo
                        strFiltro = strFiltro & Chr$(39)              'chr$(39) freccia a destra
                Case Else
                        strFiltro = strFiltro & Chr$(KeyCode)
    End Select
    
    Me.CercaElenco.Form.Requery
    
    End Sub
    Ho visto poi che fai uso dei duepunti per mantenere su una riga sola codice che andrebbe su due righe. Usa con parsimonia questo stile di scrittura del codice. (chi ha l'occhio fatto su Vb(a)(.Net) non è molto abituato a vedere più di un'istruzione in una riga, eventualmente il contrario, cioè spezzare su più righe una riga unica, se aiuta in lettura).
    Si tratta di suggerimenti applicati al caso specifico ma per niente collegati a quello che stai facendo, cioè la gestione del filtro.
    Con l'esecuzione in debug, una riga alla volta, puoi vedere il diverso comportamento delle due versioni e dei "salti" che fa il codice quando c'è il GoTo.
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Attenzione anche al parametro Shift che non viene mai usato. O non serve nella firma, o manca nel codice...
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    In pratica da 96 a 105 il valore numerico da sottoporre a Chr$ è il keycode diminuito di 48.
    quando le cose banali ti sfuggono ... non ci avevo proprio ragionato!! hai perfettamente ragione.
    Una volta eseguito il codice che si trova all'interno del singolo Case non si passa al Case successivo, si esce dal blocco Select, andando ad eseguire quello che c'è dopo End Select.
    Altro mio errore madornale dovuto a inesperienza, il codice da cui avevo imparato questo tipo di sub era composto da una serie di If, ho ritenuto corretto cambiarlo con il Select Case proprio per evitare che andasse ad analizzare ogni singolo If ma avevo lasciato un evidente errore con l'Aggiorna...
    Per quanto riguarda il case 8 ho capito il tuo codice e in effetti è più corretto (non he potessi avere dubbi al riguardo).
    Ho visto poi che fai uso dei duepunti per mantenere su una riga sola codice che andrebbe su due righe. Usa con parsimonia questo stile di scrittura del codice.
    Grazie, seguirò sicuramente l'indicazione.

    Ti ringrazio molto, ho capito gli errori di un codice che in effetti mi pareva machiavellico ma che avevo "paura" di toccare.
    Cercherò di capire come funzionano le function per spostarlo al di fuori di ogni singola maschera ma non voglio rischiare di fare pasticci.
    Già così è molto più fruibile.

    Crodino
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Sgrubak altra cosa che non capivo, ma che per inesperienza avevo paura di toccare, ho iniziato da poco ad avere consapevolezza di cosa fanno i parametri delle Sub e non oso ancora toccarli se non sono sicura...
    Quindi si può togliere? dal Debug ho visto che il suo valore varia da 0 a 1 solo se si preme shift nel campo Ricerca che genera l'evento, ma in effetti al fine del filtro il maiuscolo o minuscolo è ininfluente.
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Cercherò di essere bravo nelle spiegazioni come Phil:
    Il valore varia, poiché viene passato come parametro nel momento in cui la Subroutine viene chiamata.

    Ovviamente, essendo la Sub il gestore dell'evento Key_Up, non può essere modificato in questo caso specifico. Insomma il compilatore riesce ad associare la Sub [txtCerca_KeyUp(KeyCode As Integer, Shift As Integer)] all'evento, solo perché le firme sono uguali. Infatti se provi a rimuoverlo, ti darà errore di compilazione. (Per firma si intende la combinazione del nome della Routine/Function e dei parametri, sia la quantità, che l'ordine, che i tipi).

    Ma nel caso in cui tu abbia voglia di implementare una funzione, o una Sub che sia richiamabile da altri eventi di altre TextBox, valuta se impiegarlo oppure no.

    I casi sono tre:
    1) lo togli dalla firma dalla futura Sub/Function e in tutte le chiamate alla funzione non lo specifichi;
    2) lo gestisci all'interno della Sub/Function e quindi avrai un Case dedicato, oppure un If che direzioni il codice in maniera opportuna;
    2.1) lo dichiari come opzionale e poi se ti serve specificarlo lo metti, altrimenti va bene anche senza, basta che sia gestito nel corpo.

    Dipende tutto da come poi vorrai impostare il codice.

    Certo che se Alex suggerisce di sfruttare la proprietà FILTER, orienterei i miei studi su quello. Poi puoi sfruttare i consigli di Phil su una funzione che ritorni una String che setti quella proprietà e il gioco è fatto.
  • Re: Sub Filtro per Campo Ricerca da rendere "Universale"

    Grazie, il consiglio di Alex lo stavo valutando per modificare la ricerca per sfruttare la proprietà Filter ma prima di "metterci mano" volevo capire se sono in grado di spostare il tutto in una Function oppure no...
    Per quanto riguarda lo Shift in effetti nel corpo il Case 16 è lo Shift perciò in realtà la sua "analisi" è prevista.
    Crodino
Devi accedere o registrarti per scrivere nel forum
12 risposte