Newsgroup: it.comp.appl.access
Titolo: Query Access con funzioni utente: "select .. from .. where MiaF( ) and ..." : esperimenti e applicazioni

Forse sono banali, non so.
Grazie al bravo Geppo (che anzi approfitto dell' occasione per
ringraziare e salutare) ho visto che e' possibile, per ora nel
query builder di access (ma Geppo dice che funziona anche
con i recordset, e gli credo) scrivere query di questo tipo :
select c1,c2, ... ,cn from T
where
miafunc_01(cj,ck, ...) and
miafunc_02(cj,ck, ...);
Dove miafunc_XX e' una funzione che restituisce true
se (qualcosa in funzione del valore dei campi dati ad
essa come parametri) o false in caso contrario.
Tanto per cominciare accade questo :
"domina" la funzione piu' a destra, la miafunc_02.
Nel senso che se questa restituisce false, la
miafunc_01 non viene valutata nemmeno e il record
corrispondente viene SCARTATO.
Invece la miafunc_02 viene eseguita per ogni record.
Se assume true, allora viene eseguita anche la miafunc_01.
Se restituisce true anche quella, il record non viene scartato.
Il fatto che la miafunc_02 venga effettivamente eseguita
*per ogni* record significa che la cosa si potrebbe sfruttare
ad esempio cosi' :
se la miafunc_02 prende i valori dei campi immessi, li
manipola e lii confronta nei modi piu' disparati, poi il
risultato lo mette in un file di testo (passato come variabile
globale o dato in pasto alla funzione stessa come parametro)
Per cui a query eseguita noi avremmo GIA' caricati in un file
di testo i risultati. Oppure in un file excel, oppure in una altra
tabella, oppure in un VETTORE ... O in una lista, in un albero
... ! Quello che volete. E tali risultati possono essere
semplicemente
i record della tabella messi in un altro formato. E tutti.
Nulla poi impedisce che le elaborazioni vengano fatte dalla
miafunc_01, per cui avremmo una elaborazione condizionata
al fatto che la miafunc_02 abbia restituito true.
... Mi date qualche commento ?

 ... Mi date qualche commento ?
Certo che ti diamo un commento... il mio č :
non ci ho capito nulla...
l'obbiettivo qual'č? 

 ... Mi date qualche commento ?
Non è chiaro dove vuoi arrivare.
Mi sembrano speculazioni eccessive e troppo aleatorie.
Fa dei casi particolari e vediamo se quello che intendi fare è utile o ci 
sono altre soluzioni...
Antonio 

 l'obbiettivo qual'č?
Aggiungo...
L'uso di Access come qulunque altro linguaggio prevede 2 punti fondamentali 
:
1) un problema da risolvere
2) i modi con cui risolverlo
In questo, come spesso in tanti altri tuoi quesiti, non si capisce da cosa 
parti e soprattutto per arrivare dove.
;) te lo dico giusto per capire insieme a te come aiutarti... 

è utile o ci sono altre soluzioni...
*utile* ! Che parola grossa !
Giustamente Alessandro Cara mi disse che dopotutto il
polimorfismo c'e' sempre stato ! Basta considerare i variant !
Eh ! Cos' e' "utile" ? Dai sii un po' aperto, che ti costa ?
Comunque volevo dire questo :
siccome la fx ( ) viene (parlando in generale) valutata per
ogni record, allora se ad esempio uno vuole fare una
query che dopo la ricerca gli spari tutti i dati diciamo
dentro un file excel, allora basta che scriva :
select ... from ... where spara_in_excel( elenco dei campi)
Ma questo e' SOLO *una* applicazione.
Ok ?

 Set rs = db.openrecordset(wow)
(omissis)
E grazie che non accade, ce ne' una sola di funzione
nella tua stringa ! :D
Vedi la risposta (si intende : con calma e per favore eh !)
che ho dato all' ACIDISSIMO Antonio Biso :D
Forse la si capisce meglio. Vedi un po' ...


CUT
oppure usa il
DoCmd.TransferSpreadsheet Method

> Non è chiaro dove vuoi arrivare.
Sto studiando come funziona il sistema e cerco di
coinvolgervi, tutto qui. Non ho un obiettivo particolare.
Bisogna averlo per forza ? No ... Chiedo eh !
---------------
Ma vaaaaaaaaaaaaaa! :D tutto sto papiello per "studio"? :D e io (in verità 
non solo io) che pensavo che ti servisse per qualcosa di specifico! :D
Ok... quindi "studio"... capito... ;) 

 Ok... quindi "studio"... capito... ;)
,.. Non capisco.
Siccome in fondo e' da poco che scrivo qui, per favore spiegami :
c'e' una sorta di (come dire ...) "regola non scritta" per la quale
qui si deve soltanto chiedere soluzioni di problemi specifici ?
Sto chiedendo, eh !

 Ok... quindi "studio"... capito... ;)
,.. Non capisco.
Siccome in fondo e' da poco che scrivo qui, per favore spiegami :
c'e' una sorta di (come dire ...) "regola non scritta" per la quale
qui si deve soltanto chiedere soluzioni di problemi specifici ?
Sto chiedendo, eh !
---------------------
No, in realtà no... però in tutti questi anni (leggi bene, "ANNI") sei il 
primo che scrive sull'NG con questo tipo di spirito... di solito è sempre 
funzionato "mi serve questo, per fare s'altro, come posso fare?"... e giù 
soluzioni e consigli... quindi scusaci tu, non siamo preparati a usare 
usenet come cattedra... però (ovviamente parlo per me), mi piace sta cosa... 
consiglio, dillo prima quando parli giusto per (nel senso di "studio" non a 
"vanvera"), e quando hai invece un problema da risolvere, almeno uno si 
proietta sulla cosa diversamente, partecipandovi come il tema prevede ;)

consiglio, dillo prima quando parli giusto per (nel senso >di "studio" non a "vanvera"), e quando hai invece un problema da >risolvere, almeno uno si proietta sulla cosa diversamente, >partecipandovi come il tema prevede ;)
Capito. Ok, benissimo. Come sempre accetto il consiglio e
porto a casa.
Comunque non c'e' nulla di cui scusarti, non e' che uno qui
debba rispondere "per forza", intendiamoci.
Concludo dicendo : ma allora, se la cosa ti piace, come mi
pare d' aver capito, perche' non fai qualche prova pure tu
e mi dici ? (seeeempre con calma e per piacere, s' intende)
(t' avverto e' LUNGO) :-))
Per tua comodita' riepilogo qui l' esperimento :
------------------------------------------------
nel query builder di access ho scritto
select c1,c2, ...cN from T where
MyF1(c1,c2, ..., cN) and
MyF2(c1,c2, ..., cN);
dove MyF1 e MyF2 sono due funzioni pubbliche fatte
cosi' (ovviamente non e' detto che debbano ricevere
in input *tutti* i  campi della T, ma per maggiore
generalita' io li scrivo tutti)
public MyF1(byref c1 as string, _
            byref c2 as string, _
            ...
            byref cN as string)
if (serie di controlli sui cj) then
   MyF1 = true
endif
' NOTARE L' ISTRUZIONE :
G_My_01 = G_My_01 + 1
end function
public MyF2(byref c1 as string, _
            byref c2 as string, _
            ...
            byref cN as string)
if (serie di controlli sui cj) then
   MyF2 = true
endif
' NOTARE L' ISTRUZIONE :
G_My_02 = G_My_02 + 1
end function
G_My_01 e G_My_02 sono due variabili pubbliche
alquanto paracule, perche' CONTANO le volte che
MyF1 e  MyF2 vengono eseguite, come puoi vedere.
Ritorniamo alla :
select c1,c2, ...cN from T where
  MyF1(c1,c2, ..., cN) and
  MyF2(c1,c2, ..., cN);
Eseguendola  su una tabella di due
campi c1 e c2 e 3 record accade esattamente questo :
PRIMO
la G_My_02 assume valore 3. Quindi la G_My_02 viene
eseguita 3 volte, una per ogni record.
Attenzione : ma la G_My_02 ( ... ) e' stata da me
costruita in modo che UN SOLO record della T e'
tale da fargli restituire true.
E guarda caso, dopo l' esecuzione della query la
G_My_01 e' impostata a 1.
Se pero' scrivo la query invece che cosi' :
select c1,c2, ...cN from T where
MyF1(c1,c2, ..., cN) and
MyF2(c1,c2, ..., cN);
Cosi', invertendo l' ordine delle funzioni come
vedi :
select c1,c2, ...cN from T where
MyF2(c1,c2, ..., cN) and
MyF1(c1,c2, ..., cN);
osservo che la G_My_01 e' ora impostata a TRE,
e G_My_02 a TRE anch' essa.
E guarda caso la G_My_01 e' costruita in modo
da restituire sempre true.
Ne segue (incontrovertibilmente, azzarderei) che
il sistema testa ed esegue SEMPRE, PRIMA la funzione
piu' a "destra", E SOLO SE questa restituisce il valore
true allora va a testare la funzione piu' a sinistra.
(... poteva anche cominciare da quella a sinistra,
invece no).
Ovviamente :
Se ambedue le funzioni danno true, allora il record e'
aggiunto al risultato della query. Altrimenti no.
In generale quindi per ogni record R il sistema e' come
se facesse questo (funzionalmente parlando) :
   if funzione_piu_a_destra( ... ) then
      if prima_funzione_a_sinistra_della_precedente( ... ) then
         if prima_funzione_a_sinistra_della_precedente( ... ) then
               ...
               aggiungi record
         else
      else
   else
In pratica dice : inutile testare tutte le altre funzioni
essendo in AND : se l' ultima a destra e' false, esco
subito ! Ottimizza insomma.
Credo che (ma dovrei verificare) avvenga l' esatto contrario
se al post dell' AND ci fosse l' OR (a connettere le funzioni)
: buona la prima a destra, buono tutto.
Detto questo vediamo le applicazioni pratiche.
Abbiamo visto che le funzioni utente possono tranquillamente
eseguire una serie di controlli sul valore che i campi
della tabella assumono per ogni record.
(come se chiamassi le funzioni tante volte quanti sono
i record passandogli ogni volta parametri diversi : i
valori dei campi)
Ma possono eseguire anche istruzioni di lettura e
scrittura ! Insomma : possono fare tutto.
Quindi noi con questo sistema abbiamo costruito
implicitamente un meccanismo che, mentre preleva record
da una tabella normalmente producendo un risultato, al
contempo chiama le funzioni utente le quali per ogni
record possono, per esempio, aggiornare un file excel,
un vettore, un file di testo, mandare una email ...
O tutte quelle cose insieme.
Il tutto, con una semplice query . :-)
E cosi' via, perche' SE (come immagino, ma vorrei chiederti
di fare la prova) quel modo di scrivere le query (con funzioni
utente dentro) funzionasse anche in fase di apertura di un
recordset, si potrebbe immaginare di fare funzioni utente
che a loro volta emettono query (con diverse funzioni utente
dentro) creando a loro volta report ecc ecc,  a cascata.
SE cioe' fosse possibile scrivere questo :
dim RC           as new adodb.recordset
dim QUERY_UTENTE as string
QUERY_UTENTE = _
"select c1,c2, ...cN from T where " & _
"MyF1(c1,c2, ..., cN) and         " & _
"MyF2(c1,c2, ..., cN)            ;"
' dopodiche' :
RC.open QUERY_UTENTE, Cnn
le cose fattibili sarebbero davvero molte,
a quel punto.
Fammi sapere.

 subito ! Ottimizza insomma.
Sta roba la fanno tutti i sistemi/linguagi (o quasi tutti)
In qualsiasi espressione che e' unita da AND e' inutile proseguire se un 
termine restituisce *False* poiche' il risultato  finale sara' comunque 
*False*
con la OR dovrebbe essere l'esatto contrario al primo risultato *True* 
il risultato finale sara' *True*
--
ac


wrote:

Già.

Sta roba la fanno tutti i sistemi/linguagi (o quasi tutti)
Si lo so, ma non sapevo che l' Access li faceva da destra
verso sinistra.
E per il resto, che mi dite ?

 verso sinistra.
Io non mi fiderei di basare la logica su questa (presunta) regola.
Che io sappia i piani di applicazione dell'sql derivano dalla 
valutazione di diverse variabili. Mai sentita la necessita' di 
approfondire l'argomento.
--
ac


wrote:

Basta mettere funzioni che ti restituiscono msgbox "1", 2, n... così
conosci l'ordine di lettura... fai decisamente prima se ti interessa
sapere sta cosa.

 ha scritto nel messaggio 
news:280bddac-dc9a-45b8...@l6g2000yqb.googlegroups.com...


E cmq non riesco a capire perchè legare al lancio di una funzione dentro una 
query l'esecuzione di altre attività di programmazione
Antonio

 
UCAS
Ufficio Complicazione Affari Semplici
:-)
-- 
Paolo opg
BE AWARE that this post uses a fake reply-to address
to contact me write to:
janickg ( at ) hotmail ( dot ) com
--

 Paolo opg
Ah ecco appunto, non ero io il rincoglionito!!!
:-D
Il lancio di una funzione da query è molto utile quando è fondamentale 
testare come parametro i valori di uno o più campi di ogni record e quindi 
far lavorare il programma di conseguenza.
Ma se poi quello che si fa con la funzione è qualcosa che prescinde dalla 
query, ma perchè complicarmi la vita???
Ciao Pà
Antonio 

 ha scritto nel messaggionews:Xns9E079EB38F4E0sp...@193.43.96.1...

Perchè "è per studio"... lui è curioso, e vuole sapere il perchè delle
cose... che poi non servano ai più, questo è un altro paio di
maniche. :)

che prescinde alla query ma perchè complicarmi la vita???
In modo ridanciano risponderei :
E grazie al kaiser. ;-)

un altro paio di maniche.
Ntz.
Non puoi sapere a *priori* quello che potra' servire.
Inoltre, il concetto di utilita' e' alquanto sfumato.
Dunque sempre meglio esplorare, studiare, condividere.
Poi, si decide in liberta' cosa applicare e cosa no.

 Poi, si decide in liberta' cosa applicare e cosa no.
Ovvissimo...

 perculare nessuno)
Lo so, lo so ... !
Ma poi diciamo la verita' : una perculata ogni tanto fa bene,
e' il modo piu' gentile per riportare le persone alla realta'.
Anche sul resto quoto tutto.

 ha scritto nel messaggio 
news:c88fd682-1286-465c...@i13g2000yqd.googlegroups.com...











L'atteggiamento basito che ha ricevuto è legato al fatto che non ti sei 
spiegato molto bene.
Io riassumo il tutto di nuovo:
se tu stai speculando sulle funzioni nelle query sviscerandone il 
funzionamento, per fare qualcosa che abbia come parametro i record è un 
conto e va benissimo.
Se lo devi fare lanciando applicazioni che non c'entrano nulla con i record 
della query (e ti assicuro che questo sembrava) allora mi sembra una pazzia.
E quindi lo era anche tutti i ragionamenti teorici
Antonio

non ti sei spiegato molto bene.
A beh ... Quello puo' essere.
Anzi,
debbo dire che in genere non sono molto bravo a spiegarmi.