Vorrei creare, in un db access 2010, una struttura ad albero per la tabella delle funzioni di un'applicazione che sono organizzate a più livelli (ne ho previsti fino a 10, hai visto mai).
Alex mi ha suggerito il controllo treeview e in effetti ho potuto constatare che è molto interessante.
Allora mi sono impegnato, giuro, a studiare, ma niente da fare.
Ho visto sul tubo un esempio fatto su Nordwind da Emanuele Lana e l'ho ricopiato passo passo. Questo l'indirizzo:
Dice che lui lo fa su access 2013 ma va bene anche su 2010. Nell'esempio citato a lui funziona.
Su una maschera vuota ha creato un controllo TreeVeiw versione 6.0 con nome "tv" e un pulsante con nome "CaricaTreeView".
All'evento click ha scritto il codice.
Però, tanto per cominciare nel mio NW i nomi delle tabelle sono diversi e quelli dei campi oltre ad essere diversi a volte anche inframezzati da spazi (avrà una versione diversa di Northwind). Poco male perché ho sostituito i nomi, usando parentesi quadre ove necessitava, sperando di aver fatto bene.
Mi dà Errore run-time '35601': Element not found
Eseguendo il debug si posiziona sulla riga evidenziata con "!!!!!!!!!!!!!!!ERRORE!!!!!!!!!!!!!!!".
Questo il codice da lui usato e da me modificato con i nomi di tabelle e campi del MIO Northwind:
Private Sub cmdCaricaTreeView_Click()
Dim tempNode As MSComctlLib.Node
Dim rsC As DAO.Recordset 'contiene i record dei clienti
Dim rsO As DAO.Recordset 'contiene i record degli ordini
tv.Nodes.Clear 'svuota il controllo treeview
Set tempNode = tv.Nodes.Add(,, "C", "Clienti")
' il primo argomento rappresenta il primo livello dei nodi e si può lasciare vuoto
' il secondo argomento è il tipo di relazione e si può lasciare vuoto
Set rsC = CurrentDb.OpenRecordset("SELECT ID,Società FROM Clienti ORDER BY Società", , dbReadOnly)
Do While Not rsC.EOF
Set tempNode = tv.Nodes.Add("C", tvwChild, "CL" & rsC.Fields("ID"), rsC.Fields("Società")) "!!!!!!!!!!!!!!!ERRORE!!!!!!!!!!!!!!!"
' carico gli ordini del cliente
Set rsO = CurrentDb.OpenRecordset("SELECT [ID Ordine] as ChiaveOrdine,[Data Ordine] FROM Ordini WHERE [ID Cliente]=""" & rsC.Fields("ID") & """ ORDER BY [Data Ordine] DESC", , dbReadOnly)
Do While Not rsO.EOF
Set tempNode = tv.Nodes.Add("CL" & rsC.Fields("ID"), tvwChild, "O" & rsO.Fields("ChiaveOrdine"), rsO.Fields("[Data Ordine]"))
rsO.MoveNext
Loop
rsO.Close
rsC.MoveNext
Loop
rsC.Close
tv.Nodes.Item(1).Expanded = True
' per espandere automaticamente il primo livello
End Sub
Vabbè. Non ho risolto l'errore però non mi sono perso d'animo e ho riprodotto il codice sul mio db, caso mai il problema sia la versione di Northwind e/o di Access.
Ho creato una maschera nuova, il controllo treeview versione 6.0 e il pulsante con gli stessi nomi dell'esempio e all'evento click ho scritto questo codice inserendo anche stringhe SQL un po' più complesse, volendo visualizzare più campi e selezionare il livello, per i primi due livelli delle funzioni, tanto per provare e iniziare, e mi dà Errore run-time '35603': Invalid key alla riga evidenziata con "!!!!!!!!!!!!!!!ERRORE!!!!!!!!!!!!!!!".
Questa è la struttura della mia tabella "Accesso_Funzioni_Applicazione":
Nome Tipo dati Lunghezza
CODICE_FUNZIONE Testo 20
DESCRIZIONE_FUNZIONE Testo 50
LIVELLO Numerico Intero lungo-Generico-Decimali 0
TIPO_FUNZIONE Testo 1 - Valido se: "M" Or "P" - MsgErrore: Il valore deve essere "M"=Menù "P"=Programma
CODICE_FUNZIONE_PADRE Testo 20
Private Sub cmdCaricaTreeView_Click()
Dim tempNode As MSComctlLib.Node
Dim rs0 As DAO.Recordset 'contiene i record del livello 0
Dim rs1 As DAO.Recordset 'contiene i record del livello 1
tv.Nodes.Clear 'svuota il controllo treeview
Set tempNode = tv.Nodes.Add(, , "0", "Livello0") "!!!!!!!!!!!!!!!ERRORE!!!!!!!!!!!!!!!"
' il primo argomento rappresenta il primo livello dei nodi e si può lasciare vuoto
' il secondo argomento è il tipo di relazione e si può lasciare vuoto
Set rs0 = CurrentDb.OpenRecordset("SELECT LIVELLO,CODICE_FUNZIONE,DESCRIZIONE_FUNZIONE,TIPO_FUNZIONE FROM Accesso_Funzioni_Applicazione WHERE LIVELLO=0 ORDER BY CODICE_FUNZIONE", , dbReadOnly)
Do While Not rs0.EOF
Set tempNode = tv.Nodes.Add("0", tvwChild, "00" & rs0.Fields("CODICE_FUNZIONE"), rs0.Fields("DESCRIZIONE_FUNZIONE"))
' carico il livello 1
Set rs1 = CurrentDb.OpenRecordset("SELECT LIVELLO,CODICE_FUNZIONE,DESCRIZIONE_FUNZIONE,TIPO_FUNZIONE FROM Accesso_Funzioni_Applicazione WHERE LIVELLO=1 ORDER BY CODICE_FUNZIONE", , dbReadOnly)
Do While Not rs1.EOF
Set tempNode = tv.Nodes.Add("00" & rs0.Fields("CODICE_FUNZIONE"), tvwChild, "01" & rs1.Fields("CODICE_FUNZIONE"), rs1.Fields("[DESCRIZIONE_FUNZIONE]"))
rs1.MoveNext
Loop
rs1.Close
rs0.MoveNext
Loop
rs0.Close
tv.Nodes.Item(1).Expanded = True
' per espandere automaticamente il primo livello
End Sub
Dove sbaglio?
Grazie.
Alex66