Newsgroup: it.comp.appl.access
Titolo: Un problema di alunni e assenze alle lezioni

Ebbene sì, siamo a scuola!
Ho una tab. Lezioni:
ID_Lezione
Data_Lezione
e una tab. Assenze:
ID_Lezione
ID_Alunno
oltre alla tab Alunni s'intende
ID_Alunno
Cognome
Nome
Vorrei, in corrispondenza di ogni lezione, presentare per il data-entry,
affiancata all'elenco delle lezioni, una lista di tutti gli alunni con una
casella di tipo sì/no in cui annotare se l'alunno è assente con un click del
mouse.
Attualmente mi sono organizzato con maschera e sottomaschera e la cosa
funziona. Solo che logicamente ad ogni lezione mi tocca aggiungere dei
record della parte assenze e la cosa è un po' scomoda.
Insomma, per ogni lezione io dovrei presentare tutte le righe relative agli
alunni, (prodotto cartesiano della lezione con la tab alunni), ma salvare
solo le righe in cui compare spuntata l'assenza.
Qual'è il modo più semplice per farlo?
-- 
----------------
saluti
Giuseppe

 Ebbene sì, siamo a scuola!
Bei tempi!! :))

Ti sottopongo una soluzione che però, aziché darti l'elenco di tutti gli
alunni in una sottomaschera, te lo dà in una casella di riepilogo; in questa
casella di riepilogo ti compariranno tutti gli alunni in ordine alfabetico e
per gli alunni assenti (ovvero per coloro che per quella lezione hanno un
record nella tabella Assenze) comparirà a fianco al nome la scritta
"Assente".
Facendo clic con il mouse su un nominativo presente (ovvero che NON ha la
scritta "Assente") questo diventerà assente (ovvero verrà registrato nella
tabella Assenze un record per quell'alunno e per quella lezione); se, al
contrario, farai clic su un nomonativo assente (ovvero che ha la scritta
"Assente") questo diventerà presente (ovvero verrà cancellato nella tabella
Assenze il record di quell'alunno per quella lezione).
Se per te questa soluzione va bene fai quanto segue:
1) creati una query chiamata Query1 che abbia il seguente codice SQL:
SELECT Pippo.ID_Lezione, Pippo.Data_Lezione, Pippo.ID_Alunno, Pippo.Cognome,
Pippo.Nome, IIf(IsNull([Assenze].[ID_Lezione]),Null,"Assente") AS Assente
FROM [SELECT Lezioni.ID_Lezione, Lezioni.Data_Lezione, Alunni.ID_Alunno,
Alunni.Cognome, Alunni.Nome
FROM Alunni, Lezioni
ORDER BY Lezioni.Data_Lezione, Alunni.Cognome, Alunni.Nome;]. AS Pippo LEFT
JOIN Assenze ON (Pippo.ID_Lezione = Assenze.ID_Lezione) AND (Pippo.ID_Alunno
= Assenze.ID_Alunno)
WHERE (((Pippo.ID_Lezione)=[Forms]![Maschera1]![ID_Lezione]))
ORDER BY Pippo.Data_Lezione, Pippo.Cognome, Pippo.Nome;
2) Creati una maschera chiamata Maschera1 che abbia come origine record la
tabella Lezioni. In questa maschera inserisci anche una casella di riepilogo
non associata chiamata ElencoAlunni; detta casella di riepilogo deve avere 5
colonne di cui visibili solo le ultime tre; come origine riga della casella
di riepilogo usa il seguente codice SQL:
SELECT DISTINCTROW [ID_Lezione], [ID_Alunno], [Cognome], [Nome], [Assente]
FROM [Query1];
A fronte dell'evento "Su corrente" di Maschera1 genera il seguente codice
VBA;
Private Sub Form_Current()
Me!ElencoAlunni.Requery
End Sub
Al fine di generare l'elenco degli alunni anche dopo l'inserimento di un
nuovo record lezione, a fronte dell'evento "Dopo aggiornamento" della
casella di testo Data_Lezione, associata al campo Data_Lezione della tabella
Lezioni, genera il seguente codice VBA:
Private Sub Data_Lezione_AfterUpdate()
DoCmd.RunCommand acCmdSaveRecord
Me!ElencoAlunni.Requery
End Sub
Infine, a fronte dell'evento "Su clic" della casella di riepilogo genera il
seguente codice VBA:
Private Sub ElencoAlunni_Click()
Dim DepLez As Long
Dim DepAlu As Long
DepLez = Me!ElencoAlunni.Column(0)
DepAlu = Me!ElencoAlunni.Column(1)
DoCmd.SetWarnings False
If Me!ElencoAlunni.Column(4) = _
    "Assente" Then
    DoCmd.RunSQL "DELETE * FROM " & _
    "Assenze WHERE ID_Lezione =" & _
    DepLez & " And ID_Alunno =" & _
    DepAlu & ";"
Else
    DoCmd.RunSQL "INSERT INTO Assenze " & _
    "( ID_Lezione, ID_Alunno ) SELECT " _
    & DepLez & ", " & DepAlu & ";"
End If
DoCmd.SetWarnings True
Me!ElencoAlunni.Requery
End Sub
Dovrebbe funzionare.
Se non vuoi modificare in alcun modo i codice SQL che ti ho consigliato, è
necessario che la query si chiami Query1 e la maschera si chiami Maschera1,
in caso contarrio cambia tali nomi all'interno dei codice SQL di cui sopra.
-- 
Roberto
---------------------------------------------
il Sito Comune di it.comp.appl.access:
http://www.sitocomune.com
---------------------------------------------

 ORDER BY Pippo.Data_Lezione, Pippo.Cognome, Pippo.Nome;
Questa mi ha dato abbastanza filo da torcere!
Pensa che per capire come funziona mi sono dovuto costruire la query in
modalità struttura e lo strano della cosa è stato che access 2002 pur
facendola girare non ha voluto che saperne di salvarla.
Cmq siccome mi è abbastanza ostica da comprendere l'ho sostituita da una
cascata di due query:
la prima fa un prodotto cartesiano tra lezioni e alunni, così ottengo una
combinazione delle lezioni con tutti gli alunni.
SELECT Alunni.ID_Alunno, Alunni.Cognome, Alunni.Nome, Lezioni.ID_Lezione,
Lezioni.Data_Lezione
FROM Alunni, Lezioni;
successivamente faccio un join esterno sin tra quest'ultima query e la tab
Assenze inserendo un campo come hai fatto tu con valore "Assente" per
ID_Lezione non Null. in questo modo si ottiene una tabella che contiene
tutte le combinazioni Lezioni-Alunni abbinate con le Assenze
SELECT AxL.ID_Lezione, AxL.Data_Lezione, AxL.ID_Alunno, AxL.Cognome,
AxL.Nome, IIf(IsNull(Assenze.ID_Lezione),Null,"Assente") AS Assenza
FROM AxL LEFT JOIN Assenze ON (AxL.ID_Alunno = Assenze.ID_Alunno) AND
(AxL.ID_Lezione = Assenze.ID_Lezione);
La tua soluzione brillante mi appare dura da digerire!
Adesso senti, qundo spengo o accendo Assente su un Alunno la riga
selezionate appare senpre la prima della casella di riepilogo. occorre
memorizzare la posizione corrente della riga manipolata per poi rendere
questa attiva dopo il requery. A parole è facile ma c'è un metodo per
memorizzare. ho usato una var long per memorizzare la proprietà:
memRiga = Me.ElencoAlunni.ListIndex
e poi per ripristinare selezione sulla stessa riga ho usato:
Me.ElencoAlunni.Selected(memRiga) = True
Ma accadono stranezze: il pulsante di chiusura maschera nn chiude più e
chiudendo la fin dal pulsante di chiusura e come se partisse un clic sulla
selezione invertendone lo stato.
che sarà mai?

 che sarà mai?
Spero di essere stato chiaro, in caso contrario rifatti vivo.
