RISOLTO: Accodamento selettivo record

di il
12 risposte

RISOLTO: Accodamento selettivo record

Ciao a tutti.
Come da oggetto ho un problema nei record che vengono accodati in una tabella.
Il lavoro che sto facendo è gestire una pianificazione di attività quando viene aperto un nuovo progetto. Le tipologie di attività sono elencate in una tabella "tblTipoAtt".
Quando si crea un nuovo progetto, si devono scegliere quali attività devono essere fatte, selezionandole appunto da questa tabella, si devono inoltre indicare delle date di inizio e fine (previste) per creare un semplice Gantt in un report.
Per gestire il tutto, ho creato una struttura che funziona così:

12 Risposte

  • Re: RISOLTO: Accodamento selettivo record

    A che serve una tabella temporanea?
    Puoi accodare i record con il flag true con una semplice query di accodanento.
    Ad occhio, dlookup si ferma al primo valore valido es ignora i successivi
  • Re: RISOLTO: Accodamento selettivo record

    oierpa ha scritto:


    
    t1 = "tblAppoggioAtt" 'tabella che elenca le attività è una tabella di appoggio
    t2 = "tblAttProg" 'qui devono essere accodate le attività selezionate
    
    Set rst1 = New ADODB.Recordset 't1
    Set rst2 = New ADODB.Recordset 't2
    
    rst1.Open t1, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    rst2.Open t2, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    p = rst1.RecordCount 'mi serviva per verificare che il numero di record fosse corretto
    
    'creo un recordset temporaneo filtrando i dati
    Set rst1 = filtroLike(rst1, "si_no", "S")
    d = rst1.RecordCount
    
    Crea il recordset rst1 con annesso il filtro like : "select * from t1 where ..."
    Rst1 è in sola lettura : non serve il lock, può essere un recordset di tipo snapshot

    Crea Rst2 come recordset di tipo Dynaset, con lock ottimistico, valuta quale tipo di cursore è migliore (Server o Client)
  • Re: RISOLTO: Accodamento selettivo record

    max.riservo ha scritto:


    oierpa ha scritto:


    
    t1 = "tblAppoggioAtt" 'tabella che elenca le attività è una tabella di appoggio
    t2 = "tblAttProg" 'qui devono essere accodate le attività selezionate
    
    Set rst1 = New ADODB.Recordset 't1
    Set rst2 = New ADODB.Recordset 't2
    
    rst1.Open t1, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    rst2.Open t2, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    p = rst1.RecordCount 'mi serviva per verificare che il numero di record fosse corretto
    
    'creo un recordset temporaneo filtrando i dati
    Set rst1 = filtroLike(rst1, "si_no", "S")
    d = rst1.RecordCount
    
    Crea il recordset rst1 con annesso il filtro like : "select * from t1 where ..."
    Rst1 è in sola lettura : non serve il lock, può essere un recordset di tipo snapshot

    Crea Rst2 come recordset di tipo Dynaset, con lock ottimistico, valuta quale tipo di cursore è migliore (Server o Client)
  • Re: RISOLTO: Accodamento selettivo record

    oierpa ha scritto:


    
    t1 = "tblAppoggioAtt" 'tabella che elenca le attività è una tabella di appoggio
    t2 = "tblAttProg" 'qui devono essere accodate le attività selezionate
    
    Set rst1 = New ADODB.Recordset 't1
    Set rst2 = New ADODB.Recordset 't2
    
    rst1.Open t1, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    rst2.Open t2, CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdTable
    p = rst1.RecordCount 'mi serviva per verificare che il numero di record fosse corretto
    
    'creo un recordset temporaneo filtrando i dati
    Set rst1 = filtroLike(rst1, "si_no", "S")
    d = rst1.RecordCount
    
    Crea il recordset rst1 con annesso il filtro like : "select * from t1 where ..."
    Rst1 è in sola lettura : non serve il lock, può essere un recordset di tipo snapshot

    Crea Rst2 come recordset di tipo Dynaset, con lock ottimistico, valuta quale tipo di cursore è migliore (Server o Client)
  • Re: RISOLTO: Accodamento selettivo record

    Oltre al consiglio di sistemare i recordsets aggiungo che io adotto questo stile per scorrere un recordset :
    - creo rs (in sola lettura - readonly o dinamico - lock appropriato)
    - (eventuale) posizionamento su primo record : rs.movefirst
    - loop di scorrimento : do while not rs.eof
    - elaborazione : codice specifico
    - record successivo : rs.movenext
    - fine loop : loop

    Per quanto riguarda il test per fine loop (o per determinare se il recordset è vuoto) io ho sempre e solo usato EOF e (almeno fino ad ora) non ho mai riscontrato problematiche, esistono alcuni che sono molti più cautelativi e testano contemporaneamente BOF e EOF
  • Re: RISOLTO: Accodamento selettivo record

    max.riservo ha scritto:


    Crea il recordset rst1 con annesso il filtro like : "select * from t1 where ..."
    Rst1 è in sola lettura : non serve il lock, può essere un recordset di tipo snapshot
    Crea Rst2 come recordset di tipo Dynaset, con lock ottimistico, valuta quale tipo di cursore è migliore (Server o Client)
    Quello con l'occhiale scuro integrale ha occhio. Quando c'è luce accecante. Son serviti 3 post per scrivere qualcosa di leggibile! Viva Max.

    oierpa ha scritto:


    ...
    Do Until rst1.EOF
    ...
       With rst2
             .AddNew
             .Fields("id_prog_n") = Me.ctlProgNum
             .Fields("id_prog_T") = DLookup("[ID_progetto]", "Anagrafica_progetti", "ID_CS =" & Me.ctlProgNum)
             .Fields("tipo_out") = Me.ctlIDAtt
             .Fields("data_inizio") = Me.ctlDataInizio
             .Fields("data_prog") = Me.ctlDataFine
             ...
             .Update
          End With
    rst1.MoveNext
    Loop
    Quando vedo ADO mi vengono i brividoni, perché non ci capisco granché. Quindi la prima osservazione è: serve proprio ADO? non si può usare DAO?
    Secondo me sta tutto nel modo in cui aggiungi i record: non lo fai da rst1 ma prendendo i dati che "compaiono" sulla maschera.
    Sostituisci tutti i "Me" con "rst1" e guarda come reagisce.
  • Re: RISOLTO: Accodamento selettivo record

    Philcattivocarattere ha scritto:


    Quello con l'occhiale scuro integrale ha occhio. Quando c'è luce accecante. Son serviti 3 post per scrivere qualcosa di leggibile! Viva Max.
    Purtroppo non avevo ancora inserito gli occhiali bionici e ho fatto qualche click di troppo
  • Re: RISOLTO: Accodamento selettivo record

    Ragazzi grazie 1000 per le risposte.
    Non sono riuscito a scrivere prima perché non ho avuto un secondo libero.
    Ad ogni modo il problema fondamentale è che viene accodato n volte solo l'ultimo record filtrato.
    Se dall'elenco seleziono 3 o 5 attività, vengono accodate 3 o 5 volte ma solo l'ultimo record a cui ho messo la spunta.

    Per rispondere a tutti e ringraziarvi:
  • Re: RISOLTO: Accodamento selettivo record

    Ho un dubbio.
    Ma prima finisce tutto il for next e poi scrive?
    E poi ripeti la procedura ?
    Forse e per questo che hai sempre l ultimo record?
  • Re: RISOLTO: Accodamento selettivo record

    oierpa ha scritto:


    ...
    Il mio intervento aveva due contenuti, uno ADO/DAO, l'altro riguardante l'uso di Me con suggerimento di sostituirlo con rst1. L'hai provato questo?
  • Re: RISOLTO: Accodamento selettivo record

    Eccomi.
    Ho provato ora il suggerimento di @philcattivocarattere e ha funzionato.
    Devo rifinire un po' il tutto ma il comportamento voluto c'è.
    Non sono sicuro di aver capito il motivo fino in fondo, provo a dare una spiegazione che spero commenterete.

    Secondo me il programma scorre un record per volta, ma se metto i riferimenti ai campi della maschera con "Me", prende appunto l'ultimo record (non mi è completamente chiaro perché viene scelto l'ultimo record selezionato, anche se non è l'ultimo record della tabella). Invece usando il riferimento ad rst1 vengono usati i dati del record che il programma sta effettivamente analizzando, i comandi di accodamento sono all'interno di un ciclo Do ... Loop, quindi le istruzioni di accodamento, essendo alla fine del blocco di istruzioni, ma ancora dentro il Loop, non possono saltare ad un record arbitrario.

    In merito a quanto scrive @fratac nell'ultimo messaggio: il For ... Next cicla sui campi all'interno di un record, in sostanza ci sono 2 cicli un Do ... Loop (esterno) e un For ... Next (interno). Dopo che il Do ... Loop ha preso in esame un record, la palla passa al For ... Next che spazzola un campo alla volta per controllare che 2 campi (quelli per noi importanti) non siano nulli, ma in realtà li "guarda" tutti e si "sofferma" solo su questi 2. Penso che lo stesso controllo si possa fare anche in altri modi, direttamente con un IF ... Then che analizza i singoli dati, senza ciclare fra i campi. Nel caso di tabelle con molti campi e su database più strutturati, potrebbe notarsi una sensibile riduzione del tempo di elaborazione, appena ho un attimo provo a farlo funzionare così, ma non ho nessuno strumento per capire se il tempo di elaborazione si accorcia, anche perché si tratta di frazioni di secondo.

    Risolto questo nodo, vado a provare gli altri accorgimenti che mi avete suggerito.
    Grazie 1000 a tutti.
  • Re: RISOLTO: Accodamento selettivo record

    oierpa ha scritto:


    Ho provato ora il suggerimento di @philcattivocarattere e ha funzionato.
    Mi sarei stupito del contrario (modestia dove stai di casa?)

    oierpa ha scritto:


    Devo rifinire un po' il tutto ma il comportamento voluto c'è.
    Non sono sicuro di aver capito il motivo fino in fondo
    Come dicevo c'è di mezzo ADO e rischio di dire qualche scempiaggine. Non so a che origine dati la maschera è associata. In situazioni più "classiche" avrei suggerito di usare il RecordsetClone della maschera senza aprire un recorset apposito.
    Con il Me, che fa riferimento all'oggetto in cui si trova, quindi nel caso specifico alla maschera, accedi ad 1 solo record, quello sul quale si trova in quel momento, ma sempre e solo uno. Il ciclo deve essere fatto su un recorset, quindi se rst1 avesse fatto riferimento alla proprietà Recordset della maschera potevi continuare ad usare il Me, ma avresti visto "muoversi" il record selezionato ad ogni MoveNext. Per questo parlavo del RecordsetClone che lascia inalterato il record corrente nella maschera. Ovviamente nell'accodamento, in questo caso, avresti comunque dovuto usare il riferimento al recorset(clone) e non certo alla maschera tramite il Me.
    E' più facile da "vedere mentalmente" che da spiegare, una volta capito cosa sta nella maschera e sotto la maschera.
    Per il resto... che dire, funziona già così, il problema non si pone, o no?
Devi accedere o registrarti per scrivere nel forum
12 risposte