Newsgroup: it.comp.appl.access
Titolo: Query di accodamento-casella di controllo

Ciao a tutti, premettendo che sono inespertissima (sia per quanto riguarda i 
DB che i NG), provo a spiegarvi il mio problema.
Sto creando un DB per ricette di tisane, ho due maschere e tabelle 
principali: Ingredienti (con relativi apparati/target su cui agiscono) e 
Ricette (con relativi ingredienti). Per facilitare la scelta degli 
ingredienti per ricette nuove, ho bisogno di selezionare gli ingredienti in 
base all'apparato che voglio colpire. Tramite consigli trovati in questo ng, 
ho creato una maschera continua che fa al caso mio, selezionando l'apparato 
target tramite una casella combinata, che dopo aggiornamento esegue questo 
codice
Private Sub CasellaCombinata18_AfterUpdate()
Me.Filter = "[ID-nomeTarget] = " & Me![CasellaCombinata18]
Me.FilterOn = True
End Sub
Ho provato a mettere una casella di controllo affianco al nome 
dell'ingrediente (l'idea era di far partire, tramite pulsante, una query che 
accodasse alla tabella ricette, in corrispondenza di una ricetta vuota, gli 
ingredienti con controllo selezionato), ma la casella non è selezionabile... 
e comunque non saprei come proseguire.
Ho preparato anche una tabella "checkList", collegata alle tabelle Ricette e 
Ingredienti
IDcheckList = chiave primaria
CheckList= Si/No
ID-ingrediente
ID-ricetta
e ho fatto la relativa maschera, funziona, ma se provo a filtrare gli 
ingredienti in base all'apparato target (collegando la relativa tabella) le 
caselle di controllo si bloccano.
Insomma, aiuuuuuuutooooooooooo (come avrete notato non ne capisco niente, 
sono totalmente autodidatta, della serie "guide for dummies").
Grazie :-) 

Ciao, spero di poterti aiutare:
(Sostituisci i nomi con quelli che hai tu / che più ti aggradano)
allora io risolverei così:
Metti il campo Check dentro alla tabella Ingredienti (o come si chiama
da te), e colleghi la casella di controllo al campo Check della tabella
Ingredienti( maschera in visualizzazione struttura, tasto destro ->
proprietà, scheda Dati, riga "Origine controllo", dal menù a cascata
scegli Check).
Poi devi crearti 2 query di aggiornamento per il campo Check della
tabella Ingredienti: Scegli "crea query in visualizzazione struttura" ;
dalla finestra Mostra Tabella aggiungi la tabella Ingredienti.
Chiudi la maschera e poi vai sulle barre degli strumenti a scegliere
"tipo di query": scegli query di aggiornamento.
Nella finestrella che ti mostra la tabella Ingredienti  fai doppio
click su Check; ora vai su Aggiorna a e scrivici dentro: falso. Salva
col nome QTuttiFalso.
Ripeti l'operazione pe un'altra query, che questa volta aggiorna il
campo a: vero; salvala con nome QTuttiVero.
Che cosa ti ho fatto fare per ora? (i maligni penseranno un casino, ma
lasciamo perdere :-):
la casella di controllo è così collegata ad ogni singolo record,
sicchè quando apri la maschera non ti compare il quadratino nero,
dovrebbe apparire tutto bianco.
Hai preparato due query, una per aggiornare tutti i campi a falso e una
per aggiornarli tutti a vero: ti servono perchè normalmente puoi
decidere di aggiungere / togliere tutto.
Ora devi aggiungere un po' di codice:
Maschera aperta in visualizzazione struttura, tasto destro ->
proprietà, nella scheda "Evento" vai su "su apertura" e clicchi
l'icona con tre puntini (...), ora scegli generatore di codice e poi
scrivi sta roba:
Private Sub Form_Open(Cancel As Integer)
    If IsNull(Me.OpenArgs) Then
        DoCmd.OpenQuery ("QTuttiFalso")
    End If
End Sub
Poi torni sulla maschera ed inserisci 2 pulsanti (non con
l'autocomposizione possibilmente) che chiameremo "ScegliTutti" e "
CancellaTutti"
Stesso discorso tasto destro -> proprietà -> evento; per entrambi
l'evento da scegliere è "su click"
e ci incolli sta roba:
Private Sub CancellaTutti_Click()
 DoCmd.Close
 DoCmd.OpenForm ("fabio")
End Sub
Private Sub ScegliTutti_Click()
 DoCmd.Close
 DoCmd.OpenQuery ("QTuttiVero")
 DoCmd.OpenForm "fabio", , , , , , 1
End Sub
Cosa fanno: il primo ovviamente chiude e riapre la maschera: siccome
l'evento "su apertura" dice ad access di lanciare la query QTuttiFalso,
questa setta Check su falso, poi la maschera può aprirsi e visualizza
tutte le caselle vuote.
Il secondo invece chiude la maschera, poi lancia la query QTuttiVero e
riapre la maschera con l'argomento OpenArgs = 1, che a noi basta non
sia nullo (le virgole indicano altre cosette che puoi impostare
all'apertura, ma a noi non interessano ed io non saprei spiegartele
tutte :-): così facendo access all'apertura della maschera legge il
valore 1 e dichiara falsa IsNull(Me.OpenArgs), evitando di cancellarti
i segni di spunto.
Una volta fatto ciò, potrai crearti la query che ti accoda tutti gli
ingredienti con Check = vero. Ricorda di aggiungere la riga:
Me.Refresh
all'interno dell'evento "su click" che lancia la query di accodamento,
prima dell'istruzione  che lancia la query: così facendo Access
registra in tabella Ingredienti la situazione che hai a video,
altrimenti perderesti l'ultima casella sulla quale hai segnato la
spunta (se ne spuntassi 4, te ne accoderebbe 3 in pratica).
Bene dovrebbe essere tutto, spero di essere stato chiaro e di esserti
stato utile.
Ciao
Fabio

 Me.Refresh
Il codice che ho scritto (inserendo la query con la creazione guidata del
pulsante e aggiungendo quello che mi hai detto tu) è:
Private Sub AccodaIngr_Click()
On Error GoTo Err_AccodaIngr_Click
Me.Refresh
    Dim stDocName As String
    stDocName = "AccodaIngredienti"
    DoCmd.OpenQuery stDocName, acNormal, acEdit
Exit_AccodaIngr_Click:
    Exit Sub
Err_AccodaIngr_Click:
    MsgBox Err.Description
    Resume Exit_AccodaIngr_Click
End Sub
Risultato? A volte funziona, altre volte mi dà l'errore scritto sotto, e poi
se clicco
sul sì non accoda tutti i record selezionati (a volte non ne accoda neanche
uno).
"Impossibile accodare tutti i record nella query di accodamento
....  numero di record non aggiunti causa violazioni di chiave: 1;..."
(oppure "....  numero di record non aggiunti causa violazioni di chiave: 2")
Sono convinta di aver fatto un errore stupido. Forse ho sbagliato la
posizione di Me.Refresh?
Ah, se può essere d'aiuto, l'origine record della mia maschera (che si
chiama "SelezionaIngr_xTarget") è:
SELECT [Tab_Target-Ingr].[ID-nomeTarget], [Tab_Target-Ingr].IDingrediente AS
[Tab_Target-Ingr_IDingrediente], [Tab_Target-Ingr].Proprietà,
Tab_Ingredienti.IDingrediente AS Tab_Ingredienti_IDingrediente,
Tab_Ingredienti.DenominazioneIngr, Tab_Ingredienti.[ID-nomericetta],
Tab_Ingredienti.Check, Tab_Ingredienti.Controindicazioni,
Tab_Ingredienti.Interazioni, Tab_Ingredienti.EffettiCollaterali,
Tab_Ingredienti.Note FROM Tab_Ingredienti INNER JOIN [Tab_Target-Ingr] ON
Tab_Ingredienti.IDingrediente=[Tab_Target-Ingr].IDingrediente;
Naturalmente, non è proprio opera mia: è venuta fuori creando la maschera in
creazione guidata a partire da
Tab_Ingredienti e Tab_Target-Ingr (avevo già detto non ne capisco niente di
DB? :-) )
Un'altra cosina: se cerco di aprire questa maschera a partire dalla maschera
ricette (con un pulsante, o come sottomaschera che ha lo stesso IDricetta),
non funziona più niente, nè le caselle di controllo nè la casella combinata
per la scelta dell'apparato target.
Ciao
Roxy 


[CUT]

Ciao,
allora faccio il posibile per aiutarti nei limiti delle mie competenze:
questo ti causerà frustrazione, ma spero ti sproni a cercare di
comprendere meglio il funzionamento del tutto.
Pertanto la doverosa premessa è: non sono sicuro di quello che
dico/faccio, in quanto non mi baso su tanni di esperienza ed autorevoli
testi, ma solo su un periodo di prove e consultaizone di risorse in
rete (beh, verament i consigli di questo NG spesso sono meglio della
carta stampata). Riassunto: se mi parli di integrità referenziale o
mparli in arabo per me è quasi lo stesso :-).
Io però in linea di principio non metterei IDRicetta dentro
ingredienti: fa casino e basta.
Secondo me metti IDIngrediente in ricette: in linea di principio, il
sale lo metti sia sulla carne she sulle patate, ma quando compri il
sale non compri "sale da carne" e "sale da patate": perchè dovresti
mettere un riferimento alla ricetta dentro la tabella ingredienti?
Però se leggi la ricetta della carne arrosto e quella delle patate
bollite ci trovi "sale quanto basta".
Se fai una tabella per il check, devi collegarle l' IDIngrediente...
non ti serve a niente e ti complica la vita.
Ho il tremendo sospetto (ebbene sì, sono un sospettoso) che il
problema nell'esecuzione della tua query risieda nell'uso
indiscriminato di IDvari e chiavi primarie, ma potrei sbagliarmi. Da
quanto ho capito vuoi avere:
1) gli ingredienti
2) le ricette
3) delle composizioni di ricette (in pratica, la combinazione per
l'ulcera potrebbe essere tisana alle ortiche ( e qui segue la ricetta)
più tisana al peperoncino (e qui segue l'altra ricetta), giusto?
Altrimenti credo ti diventi inutile questa tabella, ricette ed
ingredienti ti dovrebbero bastare
Allora io farei così:
tabella Ingredienti, chiave primaria IDIngrediente (campo contatore)
tabella Ricette, chiave primaria IDRicetta (campo contatore) con in
più un campo numerico che chiami magari NumeroIngrediente
tabella Composizioni, chiave primaria IDComposizione (campo contatore)
con in più un campo numerico che chiami magari NumeroRicetta
In fin dei conti, nella "composizione", se sai qual è la ricetta,
automaticamente sai quali sono gli ingredienti (raddoppiando
IDIngrediente (uno in tabella Ingredienti ed uno in Ricette) perdi il
senso di raggruppare i dati in tabelle).
Sospetto pertanto che, semplificando un pochino così, le cose
migliorino
Ricapitolando:
- la query di accodamento deve inserire IDIngrediente (e solo questo
dalla tabella Ingredienti) insieme a tutti i commenti che ti servono
nella tabella Ricette
- la tabella Ingredienti non deve avere riferimenti alle ricette
- la tabella ricette deve ovviamente avere un riferimento ala tabella
Ingredienti, sennò la query fatica a funzionare
Problemi di maschera: non capisco bene cosa tu voglia intendere, ma
intanto prova a mettere in ordine quello che ci sta sotto... Inutile
domandarsi perchè i muri di casa sono scrostati, se le fondamenta
cedono.
In bocca al lupo
Fabio

 ingredienti ti dovrebbero bastare
La tab_composizione mi serve per creare una relazione "molti a molti" tra 
IDingrediente e IDricetta, perchč un ingrediente puň stare in piů di una 
ricetta e una ricetta puň contenere pů di un ingrediente.
Come ti dicevo nel post precedente, attualmente la mia Tab_composizione č 
fatta cosě:
Tab_Composizioni:
IDingrediente= chiave primaria (in relazione "molti a uno")
IDricetta= chiave primaria (in relazione "molti a uno" con l'IDricetta 
dellatab_ricette)
Dose% (% del relativo ingrediente nella relativa ricetta)
Ci vorrebbe qualcosa ad incrocio (query a campi incrociati?), con tutte le 
ricette come intestazione di colonna, tutti gli ingredienti com intestazioni 
di riga (o viceversa) e il check/la dose all'incrocio... non so se sono 
riuscita a spiegarmi, e comunque non saprei come fare.
Ciao
Roxy 

 saprei come fare.
Dopo un attento studio :-) ho capito che la difficoltà sta proprio nel dover 
accodare ad una tabella di appoggio (creata appositamente per la relazione 
molti a molti) dati provenienti da tabelle diverse (le due tabelle che tra 
loro sono in relazione molti a molti)
Infatti io dovrei accodare l'IDingrediente della tab-ingredienti + 
l'ID-Ricette della tab_Ricette, alla tab_composizioni.
Aiuuuuuuuuuuuuuutoooooooooooooo, sos, help, sto impazzendo
Ciao
Roxy 

Ciao non aver paura non ti abbandono :-), solo non ho avuto tempo per
scriverti!
Allora risolviamo così:
Hai ragione per le tabelle
tabella Ricette
tabella Ingredienti
tabella Composizioni con i due campi IDRicetta ed IDIngrediente
Cosa fare: semplicemente ti crei una maschera per la tabella Ricette,
le inserisci la sottomaschera che ti mostra gli Ingredienti ( non
collegarla alla maschera principale)
e fai un query ad hoc:
chiamiamo la maschera MRicette, ok?
Questa maschera avrà il controllo IDRicetta, collegato al campo
IDRicetta della tabella Ricette.
La query creala in visualizzazione struttura, ti fa meno casini: alla
finestra Mostra tabella clicca chiudi, non aggiungere niente, avrai una
finestra vuota: tasto destro -> visualizzazione sql e ci incolli sta
roba (cambiaci i nomi con i tuoi...):
INSERT INTO Composizioni ( IDIngrediente, [Check], IDRicetta )
SELECT Ingredienti.IDIngrediente, Ingredienti.Check,
Forms!MRicette!IDIngrediente AS Espr1
FROM Ingredienti
WHERE (((Ingredienti.Check)=True));
Ora non fai altro che aggiungere un pulsante sulla maschera MRicette,
che esegue Me.Refresh e poi lancia la query appena creata.
Ho stretto all'osso, ma puoi aggiungerci tutti i campi che vuoi, basta
capire il sistema.
Ricorda che i pulsanti che selezionano/deselezionano tutto devono
essere aggiornati... devi chiudere e riaprire la maschera principale
ora. Infine ti suggerirei di andare sulle proprietà della maschera
alla scheda Dati e di impostare immissione dati su si: ogni volta che
apri vai al nuovo record, sennò se clicchi il pulsante aggiungi record
già immessi.
Prova e facci sapere
Ciao
Fabio

 Allora risolviamo così:[Cut]
Ho provato a fare quello che mi avevi suggerito, ma non ci capisco niente. 
Comunque ho risolto in un modo che per ora mi va bene. Poi proverò a 
riempire il db per vedere come funziona.
In pratica la maschera per selezionare gli ingredienti in base al target 
contiene una casella combinata con l'elenco dei target, che filtra in base 
al codice seguente:
Private Sub SelezionaTarget_AfterUpdate()
Me.Filter = "[ID-nomeTarget] = " & Me![SelezionaTarget]
Me.FilterOn = True
End Sub
Preferirei avere la possibilità di filtro in base ad una selezione multipla, 
ho provato a cambiare la casella combinata in casella di riepilogo con 
selezione multipla, ma mi dà errore sul filtro
Ho eliminato il pulsante "Scegli tutti" perchè mi chiudeva la maschera e la 
riapriva senza filtrarla in base al target.
Ho modificato la query QtuttiFalso in Qresetta
UPDATE Tab_Ingredienti SET Tab_Ingredienti.[Check] = False, 
Tab_Ingredienti.[ID-Ricetta] = Null;
e il relativo pulsante
Private Sub Resetta_Click()
'Chiude e riapre la maschera resettata
 DoCmd.Close
 DoCmd.OpenForm ("SelezionaIngr_xtarget")
 'Avvisa che bisogna selezionare il Target
MsgBox ("Seleziona Il target"), vbInformation
End Sub
Come si toglie quel "bip" (snervante) al messaggio?
Nella maschera Ricette ho inserito un pulsante che apre la relativa maschera 
SelezTarget. Sull'evento apertura di quest'ultima ho inserito il codice 
seguente
Private Sub Form_Open(Cancel As Integer)
'resetta la tabella
If IsNull(Me.OpenArgs) Then
        DoCmd.OpenQuery ("Q_Resetta")
    End If
'Imposta il nome della Ricetta (controllo non associato) in base alla 
Ricetta visualizzata nella maschera principale
Me.RicettaDaAggiornare.Value = Forms![Ricette]![NomeRicetta].Value
End Sub
Affianco al nome dell'ingrediente ho aggiunto il controllo IDricetta, 
invisibile. Su click del relativo check, ho inserito il codice seguente
Private Sub CasellaControllo22_Click()
'Imposta IDricetta in base alla ricetta visualizzata nella maschera 
principale
Me.ID_Ricetta.Value = Forms![Ricette]![IDricetta].Value
End Sub
E su click del pulsante che accoda gli ingredienti alla ricetta
Private Sub AccodaIngr_Click()
On Error GoTo Err_AccodaIngr_Click
'Aggiorna la maschera
    Me.Refresh
'Lancia la query che Accoda gli ingredienti alla composizione
    Dim stDocName As String
    stDocName = "AccodaIngredienti"
    DoCmd.OpenQuery stDocName, acNormal, acEdit
    DoCmd.Close
    DoCmd.OpenForm ("SelezionaIngr_xtarget")
Exit_AccodaIngr_Click:
    Exit Sub
Err_AccodaIngr_Click:
    MsgBox Err.Description
    Resume Exit_AccodaIngr_Click
'Avvisa che bisogna selezionare il Target
MsgBox "Seleziona Il target", vbInformation
End Sub
Lo so, è un po' contorto, ma per ora funziona!
Senti, approfitto per chiedere ,a te o chiunque voglia darmi una mano, 
un'altra cosa: vorrei inserire nella maschera Ingredienti un codice che fa 
aprire una finestra messaggio del tipo "vuoi modificare le ricette che 
contengono questo ingrediente?", nel momento in cui si modifica i dati nel 
casella di testo "controindicazioni". La finestra dovrebbe contenere un 
pulsante "No" che chiude semplicemente il messaggio, e un pulsante "Sì" che 
apre la maschera "Ricette" filtrata in base all'ingrediente modificato. 
Chiedo troppo?
Intanto, grazie per l' aiuto davvero indispensabile che mi hai dato finora
Ciao ciao
Roxy