Aggiornamento tabella attraverso VBA - errore memoria

di il
13 risposte

Aggiornamento tabella attraverso VBA - errore memoria

Ciao a tutti,
Ho la necessità di aggiornare un campo(stringa) di una tabella attraverso VBA. La tabella deve essere letta record per record andando ad aggiornare il campo con una stringa ottenuta da un'altra tabella in base a determinate condizioni(per questo utilizzo uno script piuttosto che una semplice query di update).
Dopo l'esecuzione dello script, il database cresce di dimensioni notevolmente e andando ad analizzare la tabella modificata(ad esempio con una query) compaiono errori di memoria("memoria insufficiente"). Provando ad esportare in Excel la tabella modificata, ottengo lo stesso errore.
La tabella ha circa 150000 record.

Riporto un esempio del codice VBA che utilizzo, tralasciando la logica con cui ottengo la stringa da scrivere:

Public Sub Prova()

Dim DBCorrente As Dao.Database
Dim Tabella As Dao.Recordset
Dim i As Long
Dim s As String
Set DBCorrente = CurrentDb
Set Tabella = DBCorrente.OpenRecordset("SKU", dbOpenDynaset)
i = 1
Tabella.MoveNext
Do Until Tabella.EOF
Tabella.Edit
Tabella.Fields("IDTRENO") = "COD_" & i & "_END" 'La stringa da inserire ha questo formato
Tabella.Update
i = i + 1
Tabella.MoveNext
Loop
Tabella.Close
DBCorrente.Close
End Sub


Ho il sospetto che la mia procedura allochi delle risorse che non vengono rilasciate. Suggerimenti?

Grazie.

13 Risposte

  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    È una operazione che devi fare una volta sola perchè ti sei accorto di un baco progettuale? Oppure vuoi una cosa sistematica?
    Nella prima ipotesi, io spesso provo a cavarmela con più passaggi "spartani" a mano.
    Nella seconda ipotesi...sospetto qualche errore di progettazione database.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    La procedura vba che esponi non mostra errori strutturali... puoi forzare la distruzione delle 2 variabili oggetto alla fine ... settando a Nothing.... ma poca roba che non giustifica.
    Non capisco il primo MoveNext prima del ciclo... sicuro non sia un MoveFirst..?

    In ogni modo essendo 150000 Records potresti valutare di inserire il processo in una transazione...migliorerebbe le prestazioni...

    Purtroppo per l'errore che ricevi escludo dipenda dal codice... ti suggerirei di provare a creare un Db vuoto ed importi tutto dal vecchio compattando e compilando il codice in quanto sospetto possa essere un principio di corruzione del db.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    Grazie per le risposte immediate.
    Il database è molto semplice, creato da poco. Escludo l'errore progettuale, forse si sarà corrotto.

    Per conoscenza personale, qual'e la differenza(tecnica) tra fare questo aggiornamento tramite transazione o tramite script? Perché è più efficiente?

    Vi presento il mio caso(è un esempio):

    - Ipotizziamo di avere una tabella con gli orari dei treni:
    COD DA A COD2
    ------------------------
    A 09:00 10:00 xxx
    A 10:00 12:00 yyy
    ..
    B 08:00 10:00 kkk
    B 10:00 13:00 zzz
    ..

    - L'altra tabella(quella che nel mio caso ha 150K record) è invece fatta cosi:
    COD H
    ----------------------
    A 08:30
    A 09:45
    ..
    B 13:40
    ..

    Il mio obiettivo è quello di individuare per la secondo tabella in quale fascia oraria rientra il treno con la codifica(COD) e quindi individuare COD2.
    Secondo voi è fattibile con una transazione(in Access)?

    Grazie.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    fmara ha scritto:


    ...
    Per conoscenza personale, qual'e la differenza(tecnica) tra fare questo aggiornamento tramite transazione o tramite script? Perché è più efficiente?
    ...
    Che cosa intendi per script? La domanda è dovuta al fatto che lo contrapponi alla transazione quindi sembra che per te siano due vie alternative.
    Per capirci: il codice che hai indicato nel primo post è normale codice vba e può inserito in una transazione (anzi, citando Gibra: "qualsiasi azione CRUD deve, e ribadisco deve, essere eseguita all'interno di una transaction")
    (a solo titolo d'esempio)
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    Grazie per la risposta.
    Non avevo ben chiaro il concetto di transazione(o meglio, nel caso sopra, intendevo porre la logica di ricerca all'interno di una query di aggiornamento, che poi posso committare o meno). Dopo aver letto l'articolo allegato, in termini di consistenza è di certo migliore l'uso di una transazione, ma non capisco perché sia migliore in termini di efficienza delle prestazioni.

    Tornando al mio esempio, e qui pongo la domanda in modo diverso, il mio esempio sopra è fattibile con una query di update?
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    fmara ha scritto:


    ...non capisco perché sia migliore in termini di efficienza delle prestazioni...
    In parole super povere che ho letto da qualche parte, oltre ai benefici in termini di sicurezza per l'integrità dei dati, la transazione accede al disco per salvare i dati una volta sola, non dopo ogni record.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    In sostanza salva sempre e non solo una volta... ma in memoria o meglio in quell'area che il begin si riserva... non fisicamente sull'origine spostando poi la copia in blocco alla fine... in questo modo le continue richieste di accesso ed Update vengono riservate ad un'area di memoria temporanea che può risultare più performante...

    Tuttavia l'oggetto del problema mi risulta estremamente poco chiaro.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    Grazie per la spiegazione.
    Cosa non ti è chiaro? Il mio problema di esempio?

    Quando ho aperto questo thread, pensavo di aver sbagliato qualcosa nello script per i problemi di prestazione che ottenevo(il primo post).
    Ora che mi avete chiarito li idee(e vi ringrazio ancora una volta), vi chiedevo, se ci fosse qualche maniera più efficiente per risolvere il mio problema(di cui ho riportato un esempio sul secondo post, è poco chiaro?).
    Non che mi serva, ma è una questione di curiosità personale. Se avete qualche idea, sono lieto di ascoltarla.
    Grazie ancora.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    fmara ha scritto:


    ...vi chiedevo, se ci fosse qualche maniera più efficiente per risolvere il mio problema(di cui ho riportato un esempio sul secondo post, è poco chiaro?).
    Stavo proprio rileggendo l'intero thread ed ho visto nel frattempo questo intervento che è servito a confermare... il dubbio.
    Quello che non ci è chiaro (credo che anche @Alex si trovi in questa situazione) è come ricondurre il tuo primo post con l'esempio che hai fatto. Sembrano applicarsi a due situazioni completamente diverse.
    Non potresti mai fare una query di update per ottenere la stessa cosa che fa il codice del primo post.
    Poi nell'esempio si parla di trovare COD2 in base all'orario e quello non lo ottenevi comunque con quel codice iniziale. Quello sì, si può fare con una query di update.
    Cosa è meglio? dipende dalla situazione, perché sono due situazioni diverse.
    Preciso comunque che anche la query di update può essere fatta da codice ed inserita in una transazione.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    Il mio esempio iniziale è privo della logica di ricerca nella seconda tabella. In sostanza, al posto di:

    Tabella.Fields("IDTRENO") = "COD_" & i & "_END" 'La stringa da inserire ha questo formato

    Avevo fatto una "Find" su un'altra tabella ed ottenevo quello che nell'altro post ho chiamato COD2.

    All'inizio temevo fosse solo un problema di scrittura sulla tabella, per cui non ho riportato l'esempio completo.

    Al di la del codice iniziale, pensi che si possa fare una query di update per risolvere il mio secondo esempio(il caso degli orari)?
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    fmara ha scritto:


    Il mio esempio iniziale è privo della logica di ricerca nella seconda tabella...
    Non era un dettaglio trascurabile.

    fmara ha scritto:


    ... pensi che si possa fare una query di update per risolvere il mio secondo esempio(il caso degli orari)?
    Sì.
    Parti dall'ottenere una query di selezione che per ogni record della seconda tabella trovi il corrispondente COD2 della prima. Solo dopo si passa all'update. Una query di selezione è abbastanza semplice, devi farcela da solo, o almeno scrivere fino a dove arrivi e che cosa non ti soddisfa.
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    Effettivamente la soluzione è più facile del previsto.
    Ho provato a fare la query in due modi.
    1)
    UPDATE TAB2 T2
    SET T2.COD2 = (SELECT T1.COD2 FROM TAB1 T1 WHERE T1.COD=T2.COD AND T1.DA<=T2.H AND T2.H<T1.A);
    Access mi da un errore "Operation must use an updateable query".
    2)
    UPDATE TAB2 T2 INNER JOIN TAB1 T1 ON T1.COD = T2.COD SET T2.COD2 = T1.COD2
    WHERE (T1.DA<=T2.H AND T2.H<T1.A);
    E' OK.

    Che differenza c'è tra le due?
  • Re: Aggiornamento tabella attraverso VBA - errore memoria

    fmara ha scritto:


    ...
    Ho provato a fare la query in due modi.
    ...
    Che differenza c'è tra le due?
    La differenza è quella che hai riscontrato tu: la prima non funziona, la seconda sì. Sembra una ovvietà ma è così. Riporto alcuni link con un elenco dei motivi per cui una query non è aggiornabile
    Why is my query read-only?
    Why is my query not updateable?
    This Recordset Is Not Updateable. Why?
Devi accedere o registrarti per scrivere nel forum
13 risposte