29/09/2023 - silverado60 ha scritto:
Ciao.... piccolo (o grande) problema:
ho una tabella con dei codici fiscali (univoci) ed una query (che prende i dati da un'altra tabella) univoca per cf, anno procedura e numero procedura.
Facendo un'altra query tra le due, ottengo un elenco con cf anno procedura e numero procedura.
Capita che un cf abbia più di una procedura e le devo raggruppare su un'unica riga (nella prima tabella dei cf univoci c'è un campo apposito):
cf annoproc-numproc / annoproc-numproc / annoproc-numproc etc
Ho provato a farlo via codice ma impiega 50 minuti solo per questa operazione e ne devo fare una decina.....
Si può ovviare?
Grazie mille
Ciao,
premettendo che concordo da quanto esposto da Fratac in quanto è difficile dare una soluzione adeguata senza info di un certo tipo…
ti chiedo una semplice cosa con qualche osservazione che magari, se lo ritieni, potrebbe tornarti utile:
- Perchè raggruppare da A_Q01 i valori per quel codicefiscale e scriverli nella tabella CF_UNIVOCI
- i dati che interessano li hai già e in un database relazionale una delle prime regole è quella di non ridondare le informazioni
- metti che i dati su A_Q01 siano errati e vengono aggiornati
- metti che nei dati su A_Q01 venga inserita una nuova procedura con nuovo anno
- metti che in A_Q01 deve essere eliminata una procedura perchè inserita erroneamente
- metti il caso che non sai quali sono i record aggiornati o eliminati o implementati
- In questi e altri casi possibili, cosa farai ? esegui una procedura per ripulire il campo di raggruppamento in CF_UNIVOCI e rifai tutto il ciclo per ricreare nuovamente i raggruppamenti da salvare ?
- Pertanto l'approccio, a mio avviso, è del tutto errato al di là dello scopo che avrà tale soluzione. in altre parole … così non si fa ;-)
- Un approccio corretto a tal fine è quello di mettere in relazione le due tabelle per codice fiscale
- CF_UNIVOCI (FK Id di A_Q01) in relazione uno a molti con A_Q01 (PK Id)
- richiamando il codice fiscale dalla tabella CF_UNIVOCI con una semplice Where oppure da una query qualsiasi, puoi elencare tutte le procedure ad esso collegate
- se non vuoi avere un elenco di procedure e leggerle nella stessa riga, sarà sufficiente concatenarle nel momento in cui si rende necessario esporre i dati…. in una Form, in un Report, etc etc etc…
- A fronte di una Relazione tra le due tabelle, ogni modifica alle procedure in A_Q01 sarà automaticamente riflessa quando si richiama uno o più codici fiscali dalla tabella CF_UNIVOCI
- Insomma … in tutti questi casi non hai bisogno di ridondare i dati che esistono già in una tabella per inserirli in una seconda… non si fa! ;-)
- Perchè usare nelle fields nomi riservati come procedure ? ( non si fa ;-)… )
- ti consiglio di rinominare tale nome per non avere problemi sia nelle stringhe sql che in altre parti del progetto
- Quando si esegue un ciclo per leggere un recordset appena aperto non è necessario impostare una If per controllare se esistono records, a quello ci pensa la while con il EOF
- Quando si esegue un ciclo per leggere un recordset appena aperto non è necessario spostarsi sul primo record in quanto già in fase di open è posizionato sul primo record
- Quando si aprono i Recordset in DAO o ADODB , etc…. è sempre bene indicare se la open è di sola lettura, se di lettura e aggiornamento, etc etc… anche queste cosine sono importanti da tenere in considerazione oltre a facilitare la rilettura del codice e altre cosucce se si è in condivisione multiutenza, etc etc …
- Perchè aggiornare un record (rss2.Fields("procedure") = txt) quando non esistono record procedure ?
Per esempio un ciclo del genere dovrebbe essere impostato in questo modo;
Dim rss2 As DAO.Recordset
Dim rss3 As DAO.Recordset
Dim strText As String
' open recordset
Set rss2 = DBEngine(0)(0).OpenRecordset("SELECT * FROM CF_UNIVOCI;", dbOpenDynaset)
' read
Do While Not rss2.EOF
' open recordset
Set rss3 = DBEngine(0)(0).OpenRecordset("SELECT * from A_Q01 WHERE Cfis = '" & rss2.Fields("Cfis") & "';", dbReadOnly)
' reset variable
strText = vbNullString
' read
Do While Not rss3.EOF
If strText <> vbNullString Then strText = strText & " - "
strText = strText & rss3.Fields("NFAS").Value & "/" & rss3.Fields("DANNFAS").Value
' next record
rss3.MoveNext
Loop
' check to update record
If strText <> vbNullString Then
' update record
rss2.Edit
rss2.Fields("CfisProcedure").Value = strText
rss2.Update
End If
' next record
rss2.MoveNext
Loop
' dispose
Set rss2 = Nothing
Set rss3 = Nothing
In questi cicli si cerca di leggere, all'occorrenza, il recordset meno corposo per limitare le letture all'indispensabile… per esempio potrebbe essere una cosa di questo tipo se la tabella delle procedure contiene meno records: (ma io questo non lo)
Dim rss3 As DAO.Recordset
Dim strText As String
Dim strCfis As String
' open recordset
Set rss3 = DBEngine(0)(0).OpenRecordset("SELECT * from A_Q01 ORDER BY Cfis;", dbReadOnly)
' read
Do While Not rss3.EOF
' check to update record
If strText <> vbNullString And rss3.Fields("Cfis").Value <> strCfis Then
' update record
DBEngine(0)(0).Execute "UPDATE CF_UNIVOCI SET CfisProcedure = '" & strText & "' WHERE Cfis = '" & strCfis & "';"
' reset variables
strText = vbNullString
End If
' procedure grouping
strCfis = rss3.Fields("Cfis").Value
If strText <> vbNullString Then strText = strText & " - "
strText = strText & rss3.Fields("NFAS").Value & "/" & rss3.Fields("DANNFAS").Value
' next record
rss3.MoveNext
Loop
' dispose
Set rss3 = Nothing
Alla fine come all'inizio ;-)) devo però considerare e ribadire che a mio avviso l'approccio non è corretto e consono in un database relazionale.
Ti consiglio, se vuoi, di cambiare strategia nel tuo progetto.
P.s.
Probabilmente quanto ti ho suggerito sarà del tutto errato, abbi pazienza perchè, come premesso, avendo poche informazioni sulle strutture e sullo scopo specifico dell'applicazione, ci può stare
;-)