Newsgroup: it.comp.appl.access
Titolo: Filtro su griglia QBE.

Nel db che sto creando l'origine dei dati di quasi tutte le maschere è 
basato su di una query. Ora mi si pone il problema di filtrare i dati di un 
campo di queste query (è lo stesso campo per tutte) in base a parametri che 
possono variare di volta in volta.
Ho quindi creato una apposita Public Function che richiamo sull'opzione 
"Criterio" del campo da filtrare sulla griglia QBE della query.
Il tutto funziona finchè il criterio è uno solo, mentre la query non 
restituisce nessun record se il criterio è multiplo. Per esempio, funzione 
se metto Cognome = "Mario", mentre non funzione se il criterio è "Mario" Or 
"Pino".
Si tratta sicuramente di un problema di sintassi ma nonostante mille 
tentativi non ne sono venuto a capo.
Faccio un piccolo esempio della sintassi che ho usato:
Public Funtion FiltroQBE() as String
Dim Nome_1 as String, Nome_2 as String
Nome_1 = "Mario"
Nome_2 = "Pino"
COSI' NON FUNZIONA:
FiltroQBE = Nome_1 & " Or " & Nome_2
COSI' FUNZIONA:
FiltroQBE = Nome_1
Grazie a chi mi potrà essere di aiuto.
 

 
Se non ho capito male, nella tua query nel criterio relativo al campo Cognome hai scritto
=FiltroQBE()
In questo modo, l'istruzione SQL corrispondente è la seguente:
SELECT * FROM TuaTabella WHERE Cognome=FiltroQBE()
Ora, la tua funzione nel caso di un solo nominativo restituisce il valore contenuto nella variabile Nome_1 cioè 'Mario',
quindi l'istruzione SQL che viene eseguita è
SELECT * FROM TuaTabella WHERE Cognome='Mario'
Invece nel caso con due nominativi la tua funzione restituisce la stringa 'Mario Or Pino' e quindi l'istruzione SQL che
viene eseguita è
SELECT * FROM TuaTabella WHERE Cognome='Mario Or Pino'
ed è ovvio che non funzioni, a meno che tu non abbia in tabella una persona il cui cognome sia 'Mario Or Pino' !
Provare per credere !
Una possibile soluzione potrebbe essere quella di usare l'operatore IN:
SELECT * FROM TuaTabella WHERE Cognome IN('Mario', 'Pino')
e quindi la tua funzione dovrebbe diventare qualcosa del genere (fai molta attenzione agli apici singoli e doppi):
Public Funtion FiltroQBE() as String
Dim Nome_1 as String, Nome_2 as String
  Nome_1 = "Mario"
  Nome_2 = "Pino"
  FiltroQBE = "IN('" & Nome_1 & "','" & Nome_2 & "')"
End Function
Però cosa accade se il numero dei valori da utilizzare nel criterio è variabile e non noto a priori ?
HTH
Vincenzo Turturro
---------------------------------------------
il sito comune di it.comp.appl.access:
http://www.sitocomune.com/
---------------------------------------------
E quello di it.comp.as400
http://www.faq400.com/
---------------------------------------------

 Vincenzo Turturro
Ti ringrazio ma non va.
Funziona, solo con un criterio di filtro, se nella griglia QBE scrivi IN 
(FiltroQBE()) e nella funzione metti solamente FiltroQBE = Nome_1
Se la complichi scrivendo FiltroQBE = Nome_1 & "," & Nome_2 non restituisce 
nessun record.
Misteri di Access!


LA tua funzione FiltroQBE per come hai scritto la query  deve restituire 
questa stringa "'mario','Pino'"
se nel qbe scrivi "IN (FiltroQBE())"
quello che ottieni come risultato e'
IN(IN('mario','pino'))
ora il "misterioso" access in questo caso cosa faccia e' un "mistero" ;<)
--
a.cara

 ora il "misterioso" access in questo caso cosa faccia e' un "mistero" ;<)
--
ho fatto un po di confusione con quello che ti suggeriva VT
cmq FiltroQBE deve restituire
FiltroQBE = "'" & Nome_1 & "','" & Nome_2 & "'"
e ricordati di star attento agli apici se per caso Nome_x li contiene.
--
a.cara

 Misteri di Access!
Ciao Maurizio,
non è un mistero dai :-)
la funzione ritorna una stringa non un'istruzione Sql, puoi inserirci anche
"SELECT * FROM" ma rimarrà sempre e solo una stringa.
io farei la query così...
---
SELECT *
FROM TuaTabella
WHERE Instr(FiltroQBE(),"|" & Cognome & "|")<>0
--
e la funzione così
--
Public Funtion FiltroQBE() as String
Dim Nome_1 as String, Nome_2 as String
Nome_1 = "Mario"
Nome_2 = "Pino"
FiltroQBE = "|" & Nome_1 & "|" & Nome_2 & "|"
End function
--
quindi la funzione rende i nomi separati dal carattere pipe e la Instr
renderà un valore diverso da 0 se il cognome è presente in essa.
Ciao Giorgio


Caro Giorgio,
ti ringrazio infinitamente perchè, come tu già sapevi, funziona alla 
perfezione!
Ti confesso però che le mie attuali conoscenze di Access, e in particolare 
di SQL, non mi hanno permesso di comprendere appieno la sintassi del tuo 
codice (per esempio non ho mai usati i pipe prima d'ora). Pazienza...
Ciao.

Misteri di Access!
Due premesse:
- visto le castronerie che ho scritto, l'altra sera sarebbe stato meglio se fossi andato a dormire
- nelle condizioni di filtro delle query non ho mai usato UDFs (User Defined Functions) quindi ho dato per scontato
alcune cose non tanto ovvie.
Ciò detto, stamani ho fatto numerose prove.
Intanto, per rimediare alla castroneria dell'altra sera, la funzione dovrebbe essere questa, come suggerito da A. Cara:
Public Funtion FiltroQBE() as String
Dim Nome_1 as String, Nome_2 as String
  Nome_1 = "Mario"
  Nome_2 = "Pino"
  FiltroQBE = "'" & Nome_1 & "','" & Nome_2 & "'"
End Function
e nell'espressione criterio dovresti scrivere
IN(FiltroQBE())
Però non funziona !
Infatti nonostante FiltroQBE restituisca 
'Mario','Pino'
che è proprio ciò che scriveresti tu a mano nel criterio se questo fosse fisso, il criterio risultante è qualcosa del
tipo
IN("'Mario','Pino'")
e quindi si ricasca proprio in ciò che si voleva evitare, cioè che in definitiva si cerchi un record che nel campo
contiene proprio il valore 'Mario','Pino' .
Ho fatto numerosi tentativi anche abbastanza contorti per fare sì che Access non incapsulasse fra doppi apici il valore
restituito dalla funzione o che al più, visto che lo fa sempre e comunque, questo alla fine non alterasse il criterio
desiderato.
Niente da fare ! 
O si casca nell'errore di sintassi o si casca nel criterio sintatticamente corretto ma non corrispondente a quello
desiderato.
A questo punto non resta che l'impostazione via codice dell'intera clausola WHERE della query oppure soluzioni
alternative come quella già suggerita da G. Rancati.
Mi dispiace averti portato fuori strada e averti fatto perdere tempo.



Ciao VT ogni tanto @work or @home rispunti :<)
Mi hai incuriosito. Quando avro' un po' di tempo faro' le prove che 
elenchi. Giuro che quello che riporti mi lascia veramente perplesso.
Voglio dire che il valore ritornato dalla funzione non mi ha mai fatto 
lo "scherzetto" che citi. E' vero che, forse, non ho mai usato una 
funzione pubblica in una query per farmi restituire la lista della IN ma 
mi e' capitato spesso di costruire dinamicamente la query ricevendo, 
appunto, correttamente la lista da applicare alla IN (al piu' tardi ieri).
Mi dirai che da quello che suggerisce Giorgio il problema e' legato al 
fatto che la ricerca e' piu una LIKE "* nome *" or ..... e via dicendo 
che non una IN.
A tal proposito, rivolto anche a Giorgio, fra le due quale (like vs 
instr) e' piu' performante?
Fermo restante che per problemi di compatibilita',malgrado l'uso degli 
asterischi, forse, userei sempre la LIKE.
--
a.cara
--
a.cara

 Ciao.
Ciao Maurizio, il carattere pipe è solo un separatore di comodo e serve a
non creare ambiguità, potresti utilizzare qualsiasi carattere, l'importante
è che non sia presente nei nominativi da cercare, per essere sicuro al 100%
puoi usare il CHR(1).
Per il resto il linguaggio Sql non c'entra niente :-)
puoi verificare anche dalla finestra immediata di VBA il funzionamento della
funzione instr
---
? INSTR("|PLUTO|PAPERINO|PIPPO|","|PIPPO|")
= 16
? INSTR("|PLUTO|PAPERINO|PIPPO|","|PLUTO|")
= 1
? INSTR("|PLUTO|PAPERINO|PIPPO|","|TOPOLINO|")
= 0 perchè tolopino non esiste nella stringa oggetto della ricerca
---
Ciao Giorgio

 asterischi, forse, userei sempre la LIKE.
se ti riferisci alle incompatibilità tra i caratteri jolly di ADO e di JET
per l'operatore Like, potresti usare ALike e i caratteri Jolli ANSI
Vedi
*Using ADO wildcards in the query design grid*
in questo articolo
---
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnima01/html/ima0601.asp
---
Ciao Giorgio

 perfezione!
Ciao Maurizio,
lasciando così come è la funzione FiltroQBE(), prova anche questa query
---
SELECT *
FROM TuaTabella
WHERE FiltroQBE() ALIKE "%|" & Cognome & "|%";
---
(se hai Acc97)
---
SELECT *
FROM TuaTabella
WHERE FiltroQBE() LIKE "*|" & Cognome & "|*"
---
anche se è una like al contrario è sempre più leggibile della instr.
Ciao Giorgio

 l'indice viene utilizzato.
A proposito della Like, possiamo anche usarla al contrario, ovvero, con la
costante a sinistra e il campo a destra.
----
SELECT *
FROM TuaTabella
WHERE FiltroQBE() ALIKE "%|" & Cognome & "|%";
----
gli indici non vengono usati lo stesso ma è più leggibile di quella con la
Instr.
Ciao Giorgio

 per l'operatore Like, potresti usare ALike e i caratteri Jolli ANSI
veramente pensavo a DB non Microsoft, che credo non posseggano la ALIKE
(di cui ignoravo completamente l'esistenza)
A proposito del piano di applicazione. Avevo letto da qualche parte il 
modo di poterlo osservare. Ma non mi ricordo ne dove ne quando ne come.
Potresti rinfrescarmi(ci) la memoria?
E grazie delle delucidazioni e buongiorno eh!
--
a.cara

a.cara
www.sitocomune.com
Sezione General
FAQ 6.158


Non ni hai portato fuori strada e non mi hai assolutamente fatto perdere 
tempo. Al limite è vero il contrario visto che TU hai perso tempo per un 
problema mio.
Ciao e grazie!


Grazie per l'ulteriore delucidazione, sei molto gentile.
Ciao Maurizio. 

 --
Grazie a te :-)
Ciao Giorgio

se e' cosi' allora se restituissi Mario","Pino (o Mario','Pino) che succede?
Si incazza come una biscia !
E' uno dei tentativi a cui ho accennato in uno dei miei post precedenti.
Non va bene perchè diventa IN("Mario','Pino") e quindi non riesce a risolvere gli apici.
Partendo da qui ho cercato con alchimie strane (Eval di stringhe infarcite di Chr$(34)) di bilanciare apici singoli e
doppi, ma alla fine ho dovuto gettare la spugna.


 doppi, ma alla fine ho dovuto gettare la spugna.
e perchè si deve arrabbiare ?
stiamo parlando di una query memorizzata in questo modo
---
SELECT *
FROM TuaTabella
WHERE Cognome IN (FiltroQBE())
---
la funzione FiltroQBE può rendere qualsiasi cosa e la query non va in
errore, semplicemente non filtra.
Ciao Giorgio

 errore, semplicemente non filtra.
yes. Anche se e' vero al 99,99%
Con un solo valore filtra e come. Solo che in quel caso e' ovvio che la 
IN e' inutile.
--
a.cara