Newsgroup: it.comp.appl.access
Titolo: Caselle di riepilogo con multiselezione

Ciao a tutti,
in una form ho diverse caselle di controllo che utilizzo come parametri
per filtrarmi i dati tramite una query parametrizzata con criteri like
nz(casella 1);"*" ecc..., il tutto funzionava finchè non ho impostato
la proprietà multiselezione a estesa o semplice delle caselle di
riepilogo, come faccio a leggermi i valori delle caselel di controllo
con queste proprietà?
Tommy

tom ha scritto:

Ti metto un esempio in cui i dati selezionati da una casella di
riepilogo Elenco28 (bel nome, vero?) sono usati per l'apertura di un
report.
    Dim NomeReport As String
    Dim filtro as String
    Dim piano As Variant
    Dim piani as String
' il prospetto di destinazione dei dati
    NomeReport = <il tuo prospetto di destinazione>
        If Elenco28.ListCount > 0 Then
' cioè, se ho almeno una selezione
            For Each piano In Elenco28.ItemsSelected
' scrivo i dati in una stringa, separandoli con virgole e mettendoli
fra virgolette singole perché sono valori stringa.
                piani = piani & "'" & Elenco28.Column(0, piano) & "',"
            Next
' tolgo l'ultima virgola
            piani = Left(piani, Len(piani) - 1)
' il mio prospetto contiene ovviamente un campo [piano] sul quale
eseguo il filtro
            Filtro = "[piano] IN (" & piani & ")"
' visualizzo in anteprima stampa un prospetto con i dati selezionati
            DoCmd.OpenReport NomeReport, acViewPreview, , Filtro
        Else
             MsgBox "Seleziona almeno un piano!"
        End If
Qui invece c'è una query che usa la clausola IN per il filtraggio dei
record di Tabella1 in cui [codice] è uguale a 1 o 3.
dim filtro as string
filtro = "1; 3" ' senza le virgolette perchè sono numeri
currentdb.execute ("SELECT Tabella1.codice, " & _
   "Tabella1.testo, Tabella1.altrodato " & _
   "FROM Tabella1 " & _
   "WHERE (((Tabella1.codice) In (" & filtro & ");")
Spero di non avere frainteso e che gli esempi ti vadano bene.
Riccardo Baldinotti

Riccardo Baldinotti ha scritto:

ho provato a fare qualche esempio sulla prima soluzione ma non mi
filtra niente anche perchè la clausola WHERE che attualmente utilizzo
io nella mi aquery di accodamento è la seguente:
WHERE (((Back_Office.Provincia) Like
nz([Forms]![MMaster]![Wizard1].[Form]![elenco province],"*")) AND
((Back_Office.Categoria) Like
nz([Forms]![MMaster]![Wizard1].[Form]![Elenco Categorie],"*")) AND
((Back_Office.CAP) Like nz([Forms]![MMaster]![Wizard1].[Form]![Elenco
Cap],"*")) AND ((Back_Office.Localita) Like
nz([Forms]![MMaster]![Wizard1].[Form]![Elenco Localita],"*")));
cioè parametrizzata su 4 diverse caselle che possono essere
selezionate o deselezionate,
qualche idea?
tommy

tom ha scritto:
[CUT]
Ho preparato delle tabelle,
tProv con i campi tProv.codprov e tProv.provincia,
tCategorie con tCategorie.codcat e tCategorie.categoria,
tCAP con tCAP.codcap e tCAP.cap,
tLocalita con tLocalita.codloc e tLocalita.localita.
Ho riempito una tabella tDati
Con un tDati.codice a contatore,
tDati.pro, tDati.cat, tDati.cap e tDati.loc,
riempiti dai campi delle altre tabelle.
Ho fatto una Maschera2 con quattro caselle di riepilogo impostate su
selezione multipla che elencano i dati delle quattro tabelle di origine
Elenco province
Elenco categorie
Elenco CAP
Elenco localita
Alla Maschera2 ho aggiunto una sottomaschera smDati la cui RecordSource
è impostata a tDati, ma potrebbe essere anche vuota.
Nella Maschera2 è un pulsante Comando10 che SuClick ha il seguente
codice:
----------
Private Sub Comando10_Click()
    Dim bop As String, boc As String, cap As String, bol As String,
filtro As String
    Dim u As Variant
    bop = ""
    boc = ""
    cap = ""
    bol = ""
    filtro = ""
    For Each u In Forms!maschera2![elenco province].ItemsSelected
        bop = bop & "'" & Forms!maschera2![elenco province].Column(1,
u) & "', "
    Next
    bop = Left(bop, Len(bop) - 2)
    For Each u In Forms!maschera2![Elenco Categorie].ItemsSelected
        boc = boc & "'" & Forms!maschera2![Elenco Categorie].Column(1,
u) & "', "
    Next
    boc = Left(boc, Len(boc) - 2)
    For Each u In Forms!maschera2![elenco cap].ItemsSelected
        cap = cap & "'" & Forms!maschera2![elenco cap].Column(1, u) &
"', "
    Next
    cap = Left(cap, Len(cap) - 2)
    For Each u In Forms!maschera2![Elenco Localita].ItemsSelected
        bol = bol & "'" & Forms!maschera2![Elenco Localita].Column(1,
u) & "', "
    Next
    bol = Left(bol, Len(bol) - 2)
' creo l'equivalente della tua clausola WHERE...
    filtro = " WHERE (((pro) in (" & bop & _
        ")) AND ((cat) in (" & boc & _
        ")) AND ((CAP) in (" & cap & _
        ")) AND ((loc)  in (" & bol & _
        ")));"
' ... e la aggiungo alla SELECT
    Forms!maschera2!Figlio8.Form.RecordSource = "SELECT tDati.codice,
tDati.pro, " & _
        "tDati.cat, tDati.cap, tDati.loc " & _
        "FROM tDati " & filtro
End Sub
----------
Dopo avere selezionato uno o più dati dalle quattro caselle di
riepilogo premo Comando10 e la smDati è automaticamente popolata.
Prova a sistemare il codice per le tue esigenze.
Ciao.
Riccardo Baldinotti

[CUT]
cioč parametrizzata su 4 diverse caselle che possono essere
----------------
prova con solo 3 e vedrai che funziona.
Con 4 non funzionerŕ mai.
Ciao
Paolo

 Paolo
Ciao
RB

 Paolo
Ciao
RB
------------
perchè ho già sbattuto la testa, scusa ma con 3 funziona?
Ciao
Paolo

         "FROM tDati " & filtro
il secondo è che tutte le caselle devono essere selzionate, invece se
io non seleziono una casella la funzione mi torna l'errore..
tommy

tom ha scritto:

Mi sono perso un pò tutta la questione, ma in caso di ListBox a
selezione Multipla
la cosa andrebbe gestita in questo modo:
SELETC * FROM T1
   WHERE
         NomeCampo1 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo2 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo3 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo4 IN (Valore1, Valore2, Valore3...)
A questo punto come vedi devi solo ricostruirti quello compreso nelle
parentesi
ciclando la collection ItemSelected delle ListBox, ma valutando la
proprietà ListIndex<>-1
poichè in quel caso significa che nessun Item è selezionato...!
Dim varIT
Dim sWhere as string
Dim sSQL as string
Dim sSQL1 as string
Dim sSQL2 as string
Dim sSQL3 as string
Dim sSQL4 as string
If List1.ListIndex<>-1 then
  For each varIT in list1.Itemselected
        ' se è numerico
        sSQL1=sSQL1 & list1.ItemData(varIT) & ","
        ' se è un campo stringa
        sSQL1=sSQL1 & "'" & list1.ItemData(varIT) & "',"
  Next
  sSQL1=Mid$(sSQL1,1, len(sSQL1)-1)
End if
If List2.ListIndex<>-1 then
  For each varIT in list2.Itemselected
        ' se è numerico
        sSQL2=sSQL2 & list2.ItemData(varIT) & ","
        ' se è un campo stringa
        sSQL2=sSQL2 & "'" & list2.ItemData(varIT) & "',"
  Next
  sSQL2=Mid$(ssql2,1, len(sSQL2)-1)
End if
ecc...!
ora devi legarle per ottenere :
SELETC * FROM T1
   WHERE
         NomeCampo1 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo2 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo3 IN (Valore1, Valore2, Valore3...) AND
         NomeCampo4 IN (Valore1, Valore2, Valore3...)
sSQL="SELECT * FROM T1 WHERE "
If sSQL1<>"" Then
   sSQL1="NomeCampo1 IN (" & sSQL1 & ") AND "
End if
If sSQL2<>"" Then
   sSQL2="NomeCampo2 IN (" & sSQL2 & ") AND "
End if
ecc....!
sSQL=sSQL & sSQL1 & sSQL2 & sSQL3 & sSQL4
' se qualche condizione successiva alla 1° è vuota mi trovo
' un AND alla fine di troppo che devo tagliare
If Mid$(sSQL,Len(sSQL)-5," AND ") then
  sSQL=Mid$(sSQL,1,Len(sSQL)-5)
End if
' quì devi avere la stringa SQL corretta con le condizioni
Msgbox sSQL
Non ci sono limiti di nessuna sorta, puoi mettere anche 45 ListBox a
selezione
multipla e 45 campi di condizione.....!
Ovviamente mettici un pò del tuo ora per ricostruire il codice
completo.
Saluti
@Alex

 [CUT]

selezionando la casella mi ripete due volte il valore sSQL1="Sicilia,'
Sicilia'"


mi da errore: Tipo non corrispondente
Tommy

 > End if
Spero tu abbia disabilitato la riga non corrispondente al tipo dati....
come vedi nel codice, ho messo 2 volte la composizione della stringa
sSQL1, ma
una va usata se il campo è numerico l'altra per il Testo, come ti ho
anche
scritto nei commenti(che avresti dovuto leggere), pertanto cancella
quella che non
serve...
L'errore che ottieni è conseguente al fatto che il criterio è stato
erroneamente composto
dalla riga non utile.
@Alex

 @Alex

 Grazie Tommy
Personalmente userei una stringa SQL tramite il metodo Execute membro
dell'oggetto
Database(DAO)
Per gli esempi, ho il sospetto che tu abbia un pò di avversione
all'Help o sbaglio...???
Ti passo il mio Help magari ti piace di più......
;-)
Sub InsertIntoX1()
	Dim dbs As Database
	' Modifica questa riga per includere il percorso
	' di Northwind sul computer.
	Set dbs = OpenDatabase("Northwind.mdb")
	' Seleziona tutti i record nella tabella Nuovi
	' clienti e li aggiunge alla tabella Clienti.
	dbs.Execute "INSERT INTO Clienti " _
		& "SELECT * " _
		& "FROM [Nuovi clienti];"
	dbs.Close
End Sub
Nel seguente esempio si crea un nuovo record nella tabella Impiegati.
Sub InsertIntoX2()
	Dim dbs As Database
	' Modifica questa riga per includere il percorso
	' di Northwind sul computer.
	Set dbs = OpenDatabase("Northwind.mdb")
	' Crea un nuovo record nella tabella Impiegati.
	' Il nome è Marco, il cognome è Fazio
	' e la posizione è In addestramento.
	dbs.Execute "INSERT INTO Impiegati " _
		& "(Nome, Cognome, Posizione) VALUES " _
		& "('Marco', 'Fazio', 'In addestramento');"
	dbs.Close
End Sub
Per eseguire l'esempio riportato di seguito, creare una copia della
tabella Clienti e chiamarla NuoviClienti. In questo esempio si
selezionano tutti i record della tabella NuoviClienti e si aggiungono
alla tabella Clienti. Se le singole colonne non sono definite, i nomi
delle colonne della tabella SELECT devono corrispondere esattamente a
quelli della tabella INSERT INTO.
INSERT INTO Clienti SELECT * FROM NuoviClienti;
Nell'esempio successivo si crea un nuovo record nella tabella
Impiegati:
INSERT INTO Impiegati (Nome,Cognome, Posizione) VALUES ('Harry',
'Washington', 'In addestramento');
Nell'esempio riportato di seguito si selezionano da una tabella
ipotetica Personale in addestramento tutto il personale in
addestramento assunto da oltre 30 giorni e si aggiungono i relativi
record nella tabella Impiegati.
INSERT INTO Impiegati SELECT Personale in addestramento.* FROM
Personale in addestramento WHERE DataAssunzione < Now() - 30;
La proposizione INSERT INTO può essere utilizzata per eseguire una
copia di backup delle informazioni prima di modificare il database. È
possibile, ad esempio, eseguire una copia delle informazioni in una
tabella Impiegati immediatamente prima di modificarne i dati.
Per eseguire l'esempio riportato di seguito, nella finestra del
database copiare la tabella Impiegati in una nuova tabella chiamata
StoriaImpiegati. Per effettuare tale operazione, fare clic sulla
tabella, fare clic su Copia  sulla barra degli strumenti, quindi fare
clic su Incolla . Nel riquadro Opzioni di incollamento della finestra
di dialogo Incolla tabella con nome, fare clic su Solo struttura. In
questo modo, viene copiata solo la struttura della tabella e non i
dati. Copiare la seguente istruzione SQL in una nuova query e salvare
quest'ultima con il nome QueryBackup:
INSERT INTO StoriaImpiegati (Nome, Cognome, Posizione)
VALUES (Forms!Employees!Nome,
Forms!Employees!Cognome,Forms!Employee!Posizione);
Aprire la maschera Impiegati nella visualizzazione Struttura della
maschera e impostare la proprietà PrimaDiAggiornare a [Routine
evento]. Nella routine evento PrimaDiAggiornare, immettere il codice
riportato di seguito:
DoCmd.OpenQuery "QueryBackup"
I dati della tabella Impiegati verranno copiati nella tabella di backup
ogni volta che l'utente effettua delle modifiche.
@Alex

 ;-)
proviamo ....
;-)

mi metto all'opera....
grazie ancora...
Tommy

 tommy
Buon lavoro
Riccardo Baldinotti

Riccardo Baldinotti ha scritto:

Grazie lo stesso
Tommy