Newsgroup: it.comp.lang.visual-basic
Titolo: Query annidate

Ciao a tutti!
Ho la necessità di gestire via codice una query annidata. in pratica 2 query
in una, con una singola istruzione.
io devo estrapolare dalla tabella TBFatture il totale IVA per ogni mese.
dapprima ho scritto:
CRITERI = "TBFatture.DataFattura between #" & miaDataDal & "# and #" &
miaDataAl & "#"
miaSQL = "SELECT Format(Sum(TBFatture.Iva), '€ 0.00') AS IvaTotale From
TBFatture " & _
"WHERE " & CRITERI
miaSQL = miaSQL & " GROUP BY TBFatture.DataFattura"
ma non mi restituisce il totale per il mese selezionato, bensì tanti record
quanti sono i giorni di quel mese presenti nella tabella.
allora ho pensato di fare una query nella query; in pratica dovrei unire
alla SQL di cui sopra quella che segue:
miaSQLApp = "SELECT Sum(qrySommaIvaMensile.SommaIva) AS TOTIVA " & _
"FROM qrySommaIvaMensile..."
sapete come si scrivono le query annidate?
--------------------------------
Inviato via 
http://usenet.libero.it

 quanti sono i giorni di quel mese presenti nella tabella.
e che debba fare così lo sai anche tu: gli hai detto di raggrupparle per
giorno.... (sempre che datafattura contenga solo la data, e non anche
l'orario)
prova (se è access, in altri casi non so)
" GROUP BY month(TBFatture.DataFattura)"
salutoni
Sergio

Il DB che uso è Access, ma il mio problema sta nello scrivere la query
annidata, come faccio con le query che ho postato prima?


 annidata, come faccio con le query che ho postato prima?
Select C1, C2, (Select C3 From Tab2 Where ... ) As Colonna3, C4, ... From
Tab1 Where ... Order By ...


Sarò testardo (tanto ci ha già pensato Lupo a risolverti il problema), ma
vorrei capire perchè vuoi utilizzare una query annidata quando non ce n'è
bisogno.

 bisogno.
Ciao Ciao!!! Lupo è stato gentile come te ad aiutarmi, ma non ho risolto il
mio problema, non riesco a fare la query annidata:)
Mi serve la query annidata, perchè la semplice query che calcola l'iva per
un mese (ho tanti importi iva quante sono le date di emissione della
fattura), non mi basta per ottenere il risultato totale del mese. Quindi
penso che mi serva una query annidata, (perchè ho bisogno di trovare la
somma degli importi mensili) e che purtroppo non riesco a fare:(
Grazie cmq per l'interesse!!!


 Grazie cmq per l'interesse!!!
Mi sembrava di averti proposto una soluzione alternativa per risolvere il
tuo problema, hai provato ad usarla?
(perdonami sono un tipo molto testardo...)
Salutoni
Sergio

 Sergio
Eccomi, dunque, la tua soluzione funziona in ACCESS ma con VB no, e non
capisco proprio perchč!!!! :(


 capisco proprio perchè!!!! :(
Ho già detto che sono testardo? ;-)
Cosa vuol dire che in VB non funziona?
Che errore ti dà?
Potresti postare un pezzettino di codice per verificare la sintassi?
Salutoni
Sergio

Bene! allora siamo in due ad essere testardi! ma per quanto mi riguarda, se
continua così va a finire, (passami l'espressione) che inizio a prendere a
capocciate il monitor:) ehehe!!!
Eccoti la funzione:
Function IvaDaPagare(mioAnno, mioMese)
miaDataDal = CDate(Format(mioMese & "/01/" & mioAnno, "mm/dd/yyyy"))
miaDataAL = DateAdd("m", 1, miaDataDal) - 1
 
CRITERI = "TBFatture.DataFattura between #" & miaDataDal & "# and #" &
miaDataAL & "#"
miaSQL = "SELECT Format(Sum(TBFatture.Iva), '€ 0.00') AS IvaTotale From
TBFatture " & _
                 "WHERE (((TBFatture.DataFattura) Between #" & miaDataDal & "# And #" &
miaDataAL & "#))" & _
                 "GROUP BY Month(TBFatture.DataFattura) ORDER BY
Month(TBFatture.DataFattura)"
 
       Dim miors As ADODB.Recordset
        Set miors = New ADODB.Recordset
        miors.Open miaSQL, MiaConn, 1, 3
 
        If IsNull(miors(0)) Or miors(0) = "" Then
                IvaDaPagare = 0
            Else
                IvaDaPagare = miors(0)
        End If
 
        miors.Close
        Set miors = Nothing
end function
Non mi da errori così, ma nella griglia dove poi richiamo la funzione
vengono visualizzati gli importi dell'iva per ogni mese, diversi da quelli
che ottengo in ACCESS! Mi chiedo perchè?


 miaDataAL = DateAdd("m", 1, miaDataDal) - 1
Dissento dal sistema utilizzato per calcolare miaDataAL: č vero che nel
formato date gli interi corrispondono ai giorni, ma io farei l'operazione
utilizzando ancora il DateAdd, una cosa tipo
miaDataAL = DateAdd("m", 1, miaDataDal)
miaDataAl = DateAdd("d", -1,miaDataAl)
Ora che guardo meglio, anche per miaDataDal procederei in un altro modo:
miaDataDal = dateserial(mioAnno,miomese,01)
poi utilizzerei due stringhe per memorizzare il valore delle date formattato
correttamente per access:
dim sMiaDataDal as string
dim sMiaDataAL as string
sMiaDataDal = format(miaDataDal, "mm/dd/yyyy")
sMiaDataAl = format(miaDataAl, "mm/dd/yyyy")
I puristi ti consiglierebbero anche di utilizzare la funzione Format$ invece
di Format
Poi procederei come fai tu
(a parte la stringa CRITERI, che costruisci ma non usi....)
A parte tutto, l'errore era di non utilizzare il formato mm/dd/yyyy per
miaDataAL....
Fammi sapere
Salutoni
Sergio

Grazie mille Sergio, ma non mi funziona!!! GGGGGGGGGRRRRRRRRRRR!!!!!! :)
Dunque, eseguendo il debug mi sono accorta che nella query mi cambia la
formattazione di DataAL, anzichě scrivermi prima il mese e poi il giorno,
mette prima il giorno e poi il mese; credo che ciň avvenga perchč uso la
funzione Cdate, ma se non la uso come faccio a trasformare le stringhe in
data? e poi perchč accade solo per DataAL e non per DataDal?
Cmq a parte qsto, quando arriva al mese di luglio in cui non c'č iva, VB mi
da il seguente errore: "il record corrente corrisponde all'inizio o alla
fine del file oppure č stato eliminato. Per eseguire l'operazione č
necessario disporre di un record corrente" ma che vuol dire?
Rieccoti la funzione:
miaDataDal = DateSerial(mioAnno, mioMese, 1)
miaDataAl = DateAdd("m", 1, miaDataDal) - 1
dMiaDataDal = CDate(Format(miaDataDal, "mm/dd/yyyy"))
dMiaDataAL = CDate(Format(miaDataAl, "mm/dd/yyyy"))
miaSQL = "SELECT Format(Sum(TBFatture.Iva), '€ 0.00') AS IvaTotale From
TBFatture " & _
         "WHERE (((TBFatture.DataFattura) Between #" & dMiaDataDal & "# And #" &
dMiaDataAL & "#))" & _
         "GROUP BY Month(TBFatture.DataFattura) ORDER BY
Month(TBFatture.DataFattura)"
 
        Dim miors As ADODB.Recordset
        Set miors = New ADODB.Recordset
        miors.Open miaSQL, MiaConn, 1, 3
 
        If IsNull(miors(0)) Or miors(0) = "" Then
                ProvaCalcolaIva = 0
            Else
                ProvaCalcolaIva = miors(0)
 
        End If
 
        miors.Close
        Set miors = Nothing
 


 necessario disporre di un record corrente" ma che vuol dire?
Ho risolto il problema delle date!!!! c'era qualche Cdate di troppo ;-) però
rimane il problema del mese di luglio...ummmmmmmmmmmmm!!!!!


         Set miors = Nothing
e va bč, un punticino in puů per esserti ricordato di chiudere il recordset
lo meriti.
Riassumendo: occhio alle variabili e ai loro tipi, la funzione format ha
senso solo se il suo risultato finisce in una stringa
Chiosa finale: mi aspetto un celere invio di una buona bottiglia di birra
presso il mio indirizzo di posta elettronca....
Salutoni.
Sergio.
ps: si, ci avrei messo meno a scriverti il codice della funzione, ma non lo
faccio neanche se mi punti una pistola alla tempia....

Eccomi qua! Funziona tutto ora!!!! almeno così sembra!:)
Però ho risolto il problema del record in un altro modo che più avanti ti
dico, ora rispondo alle tue domande.
 miaDataDal = DateSerial(mioAnno, mioMese, 1)
 Ok, mi piace, ma dove è il dim di miaDataDal, l'OptionExplicit lo usi? non
uso OptionExplicit
 miaDataAl = DateAdd("m", 1, miaDataDal) - 1
 Non mi piace, te l'ho già detto, ma lasciamo perdere.....a me si :P è lo
stesso che fare come fai tu miaDataAL = DateAdd("m", 1, miaDataDal)
miaDataAl = DateAdd("d", -1,miaDataAl)
:)
 
    Dim miors As ADODB.Recordset
 ah, allora, qualche volta, un dim scappa anche a te!!...per forza!
 
   Set miors = New ADODB.Recordset
    miors.Open miaSQL, MiaConn, 1, 3
 Cosa sono quell'uno o quel 3, non è meglio scrivere aduseserver e
 adopenstatic (sempre ammesso che siano le corrispondenze esatte).... è lo
stesso scrivere 1,3 o adopendynamic adlockpessimistic (sono le giuste
corrispondenze)
 
 If IsNull(miors(0)) Or miors(0) = "" Then
 eccoci qui, prima di operare con un recordset, oltre ad aprirlo (cosa che
 dimentico spesso di fare) bisogna verificare che non sia vuoto (cosa che
 invece raramente ometto....) quindi prima di questa istruzione metti un
 bell' if miors.eof = true and miors.bof = true then
 (nota a margine: mi rifiuterò, per quanto ciò possa importare, di rispondere
 a tuoi altri post, se prima non mi dici il significato dell'istruzione che
 ho scritto qui!!)........ su questo controllo hai ragione (serve per
controllare se il recordset è vuoto) però io ho risolto in un altro modo;
controllo se il numero dei record è >0 mi calcola l'iva, altrimenti, mette 0
euro al mese
 Altra osservazione: perchè usare i numeri dei campi al posto dei nomi?
 (credimi, in fase di debug non è una differenza da poco)....si è vero, ma
quando posso uso i numeri.
 Ulteriore osservazione: immagino che il campo Iva sia numerico, a che scopo
confrontarlo con una stringa vuota?..qua non faccio un confronto, ma assegno
alla funzione il valore 0 nel momento in cui l'iva non è presente in un
mese, altrimenti la funzione è uguale al valore dell'importo iva di quel
mese.
                 ProvaCalcolaIva = 0
                Else
                ProvaCalcolaIva = miors(0)
                End If
         miors.Close
         Set miors = Nothing
 e va bè, un punticino in puù per esserti ricordato di chiudere il recordset
 lo meriti.....GRAZIE!
 Riassumendo: occhio alle variabili e ai loro tipi, la funzione format ha
 senso solo se il suo risultato finisce in una stringa
 Chiosa finale: mi aspetto un celere invio di una buona bottiglia di birra
 presso il mio indirizzo di posta elettronca.... ok! eheheheheheh!!!! :)))
 Salutoni.
 Sergio.
 
 ps: si, ci avrei messo meno a scriverti il codice della funzione, ma non lo
 faccio neanche se mi punti una pistola alla tempia.... addirittura!!! ;-)
Sergio ti ringrazio tantissimo per avermi aiutato!!!! sei stato GRANDE!!!!
Ti meriti un bacione!!!! Grazie Grazie Grazie!!!...Kleila


 Ti meriti un bacione!!!! Grazie Grazie Grazie!!!...Kleila
ehm, (scritto piccolo piccolo) sei una femminuccia?.....
se si accetto (sulla gota, però, non vorrei che la mia dolce metà avesse
qualcosa da ridire)
Salutoni
Sergio

Visto che siamo in ballo, finiamo di ballare:)
Per un maggior chiarimento, sono una ragazza alle prime armi con il
fantastico mondo della programmazione, ti ringrazio di nuovo per l'auito e
per i consigli che mi hai dato, ne terrò conto!!!......dato che ci sono,
potrei chiederti una cosina?
Con le somme il formato che si passa ad un campo viene letto?
perchè nella query (Select Format(Sum(TBFatture.Iva), '€ 0.00') AS IvaTotale
ecc) che ho scritto negli altri messaggi c'è il formato, ma nella griglia
non è visualizzato. E' sbagliato?
E' da considerare che in un'altra query (in cui non faccio somme) che
faccio, con un altro campo valuta formattato allo stesso modo, ma non ho
problemi.
Potresti aiutarmi?
Grazie Mille!


 non è visualizzato. E' sbagliato?
Se ti dico che non lo so, ti arrabbi?
Non ho mai provato a formattare un campo direttamente dalla query di
partenza: se ho bisogno di un modo particolare di visualizzare il risultato,
applico il formato sul controllo, utilizzando la proprietà DataFormat del
medesimo, se è un DataGrid quella della colonna.... (sono stato volutamente
impreciso: non ricordo i dettagli dell'operazione e non voglio fare brutte
figure).
<tono cattedratico>
Nel tuo caso, se non l'hai ancora fatto, consiglio l'acquisto di un buon
libro sulla programmazione
</tono cattedratico>
Salutoni
Sergio

Il formato che uso per la query generale senza somme, l'ho visto proprio sul
libro e funziona, ma il mio dubbio č se si puň formattare un campo quando in
una query si richiede il calcolo di una somma....Cmq grazie lo stesso!
