Aggiornare indice in tabella Access

di il
29 risposte

Aggiornare indice in tabella Access

Buongiorno, 

lavoro su un db frontend con tabelle collegate a un backend.

Ho una tabella relazionata, con il campo “ID” impostato a numerazione automatica.

Attraverso una routine eseguo 'db.Execute "INSERT INTO " per reinserire eventuali ID cancellati per errore, e fin qui tutto bene.

Il problema nasce dopo aver eseguito il comando   ‘db.Execute "INSERT INTO ", in quanto l’indice della tabella, riparte dall'ID che ho inserito.

Infatti in altre routine del DB ho delle funzioni di “rs.AddNew” che all'esecuzione inserisce il nuovo record partendo dall'indice che si è creato dopo l'utilizzo di   ‘db.Execute "INSERT INTO ".

Per ovviare a questa problematica, nel codice rieseguo un  ‘db.Execute "INSERT INTO " calcolando l'ultimo ID +1, per poi cancellarlo.

Nel suo insieme “arrangiato” funziona, ma volevo sapere se ci fosse un modo per “reimpostare” l'indice senza eseguire quanto nel paragrafo precedente.

Ho iterato gli indici della tabella che sono:

IDconsuntivo
IDDDT
IDDDT1
IDDDTconsegna
IDLotusvalvole
IDoacq
IDvalvoleReg
Numero_oacq
NumeroReso
PrimaryKey
Utentecreazione

Questo è il codice che utilizzo:

 Function VerificaEInserisciID(ByVal IDDaVerificare As Integer, ByVal NomeTabella As String, ByVal NomeCampo As String) As Boolean
   On Error GoTo ErrorHandler
   
   Dim db As Database
   Dim rs As Recordset
   Dim UltimoID As Integer
   Dim CampoID As Variant
   
   CampoID = NomeCampo 
   ' Apri il database corrente
   Set db = CurrentDb
   
   ' Seleziona l'ultimo ID dalla tabella
   Set rs = db.OpenRecordset("SELECT MAX" & "(" & CampoID & ") AS UltimoID FROM " & NomeTabella)
   If Not rs.EOF Then
       UltimoID = rs("UltimoID").Value
   Else
       UltimoID = 0
   End If
   rs.Close
   
   ' Verifica se l'ID da verificare esiste già
   Set rs = db.OpenRecordset("SELECT * FROM " & NomeTabella & " WHERE " & CampoID & " = " & IDDaVerificare, dbOpenSnapshot)
   If rs.RecordCount > 0 Then
       MsgBox "L'ID specificato esiste già nella tabella.", vbExclamation
       VerificaEInserisciID = False
       Exit Function
   ElseIf IDDaVerificare > UltimoID Then
       MsgBox "L'ID specificato è maggiore dell'ultimo ID presente nella tabella.", vbExclamation
       VerificaEInserisciID = False
       Exit Function
   Else
       ' Inserisci l'ID nella tabella
       db.Execute "INSERT INTO " & NomeTabella & " (" & CampoID & ") VALUES (" & IDDaVerificare & ")"
   
   End If
   rs.Close
   
   Set rs = db.OpenRecordset("SELECT * FROM " & NomeTabella & " WHERE " & CampoID & " = " & IDDaVerificare, dbOpenSnapshot)
   If rs.RecordCount > 0 Then
   
       ' Costruisci l'istruzione SQL per reimpostare il contatore dell'ID
       db.Execute "INSERT INTO " & NomeTabella & " (" & CampoID & ") VALUES (" & UltimoID + 1 & ")"
       
        ' Costruisci l'istruzione SQL per cancellare l'ultimo record inserito
       db.Execute "DELETE FROM " & NomeTabella & " WHERE " & CampoID & " = " & UltimoID + 1
       
       MsgBox "L'ID è stato inserito correttamente nella tabella.", vbInformation
   
   
   Else
   MsgBox "L'ID non è stato inserito.", vbCritical
   VerificaEInserisciID = False
   
   End If
   rs.Close
   
   Set rs = Nothing
   Set db = Nothing
   Exit Function
   
ErrorHandler:
   MsgBox "Si è verificato un errore durante la verifica e l'inserimento dell'ID.", vbCritical
   If Not rs Is Nothing Then rs.Close
   Set rs = Nothing
   Set db = Nothing
   VerificaEInserisciID = False
End Function

Grazie a tutti.

29 Risposte

  • Re: Aggiornare indice in tabella Access

    13/03/2024 - SempreFresco ha scritto:


    Attraverso una routine eseguo 'db.Execute "INSERT INTO " per reinserire eventuali ID cancellati per errore, e fin qui tutto bene.

    Vediamo Se ho capito bene… Se il campo ID di cui tu parli ha numerazione automatica, mi spieghi come fai a reinserirlo dopo averlo cancellato?

  • Re: Aggiornare indice in tabella Access

    In realtà non so se sia possibile. Non ho mai provato. Ma pure se fosse è una cosa pericolosa. La numerazione automatica è stata concepita proprio per salvaguardare l' integrità relazionale.

  • Re: Aggiornare indice in tabella Access

    Bhe, anch'io pensavo che non fosse possibile farlo, infatti al 99,9% delle routine utilizzo sempre il comando rs.AddNew.

    Avevo necessità di recuperare “numerazioni”  e con il comando sotto lo esegue:

     ' Inserisci l'ID nella tabella
           db.Execute "INSERT INTO " & NomeTabella & " (" & CampoID & ") VALUES (" & IDDaVerificare & ")"

    Quindi mi inserisce i record mancanti, ma l'indice riparte dall'ultimo record record inserito con il comando 'db.Execute "INSERT INTO " 

    P.e. se richiedo di inserire il record ID “4”, il comando lo inserisce, per poi successivamente qualora utilizzassi la funzione rs.AddNew, questa inserisce il record co ID “5” e non “143”. 

    ID Tag
    1
     
    2
     
    3
     
    12
     
    14080-PSV-204
    14180-PSV-303B
    14280-PSV-302B
     

    13/03/2024 - Antony73 ha scritto:


    Vediamo Se ho capito bene… Se il campo ID di cui tu parli ha numerazione automatica, mi spieghi come fai a reinserirlo dopo averlo cancellato?

    Come faccia a farlo non lo so, verrei semplicemente sapere se ci fosse un metodo per “reimpostare” l'indice .

  • Re: Aggiornare indice in tabella Access

    13/03/2024 - SempreFresco ha scritto:


    metodo per “reimpostare” l'indice

    Cosa intendi per “reimpostare”?

  • Re: Aggiornare indice in tabella Access

    Quello che fai è nella sostanza errato, si funziona perchè forzi la scrittura dell'ID ma non è una cosa da sfruttare per quello che fai.

    Innanzitutto ci sarebbe da capire se nelle Relazioni hai attivato il DELETE CASCADE, cosa che ovviamente agisce sulle altre tabelle, questo rende inutile andare a riciclare il valore di ID precedente.

    Se non avessi attivato il DELETE CASCADE non potresti cancellare lato 1, in quanto si avrebbe VIOLAZIONE di dati lato M senza il Record correlato.

    Sicchè devi prima reinserire i records lato 1 e poi quelli lato M, puoi spiegare perchè e che senso ha RICICLARE il veccio ID…? Non dire che vuoi tappare i BUCHI, la discussione si chiederebbe prima di iniziarla.

    Ti rispondo io NESSUNO.

    Aggiungo che magari si usano le transazioni per annullare l'errore di Cancellazione, oppure si usa un Campo Boolean che forzi a 1 quando vuoi cancellare, ma semplicemente senza cancellare non li visualizzerai…

    Insomma si possono fare tante cose quello che fai tu non ha senso.

  • Re: Aggiornare indice in tabella Access

    Permettimi di rispondere, 

    ha senso nel contesto del mio db, nella sua funzione, e nella sua implementazione che sicuramente permette di cancellare gli ID, altrimenti sembra ovvio che non avessi aperto questo post se il DB non avesse difetti. Pertanto , ringraziandoti sul fatto che tu ritenga il mio operato senza senso, il focus della discussione del post è se è possibile o meno aggiornare l'indice della tabella.  Come già scritto nel post precedente, non sapevo che fosse possibile forzare la scrittura, però è possibile a quanto pare. Il recuperare ID, cosa tra l'altro sporadica e che sto sperimentando in questi giorni, mi permette di sopperire a quelle eventualità in caso di cancellazione avvenuta in passato, per contesti di implementazione con documenti esterni al DB, senza dover rinominare file e documenti esterni al DB. 

    Grazie comunque per il tuo pensiero.

  • Re: Aggiornare indice in tabella Access

    Quello che fai tu non si fa, ora lascio a te, o hai scoperto l'acqua calda o noi siamo tutti lenti.

    Se pensi fatti qualche domanda.

    Buon lavoro.

  • Re: Aggiornare indice in tabella Access

    Osservo che le tue risposte si rivolgono sempre sul personale e non sul focus del post, “quello che fai tu non ha senso”, “se pensi….”.

    Credo che la mia domanda di apertura al post sia abbastanza chiara, ovvero vi è la possibilità di reimpostare/modificare/aggiornare l'indice interno di una tabella? L'utilizzo di questa funzionalità di aggiornamento indice si può lasciare a discrezione dell'utente? 

    Che tu ritenga che sia sbagliato, non è da fare è chiaro, ma la domanda era un'altra.

  • Re: Aggiornare indice in tabella Access

    Non sono personali sono tecniche, stai operando in modo non usuale e non corretto, come ti ho detto… il suggerimento è di riflettere, ma sembri sicuro di saperla lunga quindi chiudo.

  • Re: Aggiornare indice in tabella Access

    Quello che chiedi è concettualmente sbagliato ma se a te piace eccoti servito :

    Function ReadSeedFromTable(sTable, sCol) As Long
    Dim cat         As New ADOX.Catalog
    Dim col         As ADOX.Column
    Dim lSeed       As Long
    
    On Error GoTo ErrLbl
        
    Set cat.ActiveConnection = CurrentProject.Connection
    Set col = cat.Tables(sTable).Columns(sCol)
    If col.Properties("Autoincrement") And col.Type = adInteger Then
        lSeed = col.Properties("Seed")
    Else
        lSeed = -999
    End If
    Set col = Nothing
    Set cat = Nothing
    ReadSeedFromTable = lSeed
    
    Exit Function
    
    ErrLbl:
    MsgBox "Errore" & Err.Description
    End Function

    Con questa funzione puoi ricavare il valore corrente del campo autoincrement

    Se poi vuoi aggiornare il suo valore a quello che più ti piace esegui questa query :

     ALTER TABLE TableThatIncrements
       ALTER COLUMN Id AUTOINCREMENT(NewSeed,1)

    Sostituisci Newseed con il nuovo valore, 1 è l'incremento.

    Queste operazioni vanno fatte con molta cautela e soprattutto in ‘monoutenza’. 

    Ho dato per scontato che tu abbia un certa dimestichezza con VBA …

    P.S: - MS Access Backend  con altri BE non mi pronuncio.

  • Re: Aggiornare indice in tabella Access

    13/03/2024 - SempreFresco ha scritto:


    Osservo che le tue risposte si rivolgono sempre sul personale e non sul focus del post, “quello che fai tu non ha senso”, “se pensi….”.

    Credo che la mia domanda di apertura al post sia abbastanza chiara, ovvero vi è la possibilità di reimpostare/modificare/aggiornare l'indice interno di una tabella? L'utilizzo di questa funzionalità di aggiornamento indice si può lasciare a discrezione dell'utente? 

    Che tu ritenga che sia sbagliato, non è da fare è chiaro, ma la domanda era un'altra.

    L'indice di una tabella appartiene alla struttura del database non è un dato da archivio. I dati sono quelle informazioni che seve archiviare, consultare e manipolare. Per fare queste operazioni ci si avvale di indici e chiavi primarie e esterne.

    Purtroppo, l'eredità degli arbori della programmazione hanno dato a questi campi un valore di dato. Così sentiamo dire “il cliente 107” "l'articolo 2357" e così via…

    In realtà in nr 107 del cliente pippo serve per identificare il record di pippo franco piuttosto che di pippo baudo.

    Andare a toccare le chiavi, come ti è stato suggerito, non ha senso. Se noti la rubrica del tuo cellulare hai un elenco di nomi non di id. Anche tu, in realtà dovresti nascondere all'utente il codice (chiave primaria o esterna).

    In tutto questo, andare a recuperare un numero id che non è un dato immesso dall'utente (all'utente non frega niente se pippo va inserito come id 3 o id 39), ma su un numero elevato di record, oartire dal record 1 per inserire l'id 368993 

    13/03/2024 - SempreFresco ha scritto:


    MsgBox "L'ID specificato esiste già nella tabella.", vbExclamation VerificaEInserisciID = False Exit Function

    Ti sorbiresti 368993 messaggi fino all'id libero 368994?

    Piuttosto torno a usare carta e penna.

  • Re: Aggiornare indice in tabella Access

    ALTER TABLE [TableThatIncrements] ALTER COLUMN [Id] COUNTER (NewSeed,1)

    Nel caso non funzionasse la query precedente prova con questa …

    P.S. - Prima di fare danni fai il backup!

  • Re: Aggiornare indice in tabella Access

    Buongiorno,

    Risolto. Ho trovato una risposta funzionale alla mia domanda.

    Prima di postare il codice volevo fare alcune precisazioni e dare delle risposte.

    Senza stare troppo a dare spiegazioni del perché mi interessava recuperare la numerazione ID che annoierebbero, la domanda era sul come reimpostare il contatore del campo ID (AutoNumber), dopo che questo si sia spostato. 

    Nell'articolo https://learn.microsoft.com/it-IT/office/troubleshoot/access/error-inserting-table-record-autonumber#resolution  viene descritto dettagliatamente l'errore sul campo AutoNumber, con le relative cause e risoluzioni.

    In quest'altro articolo https://learn.microsoft.com/it-it/office/troubleshoot/access/reset-autonumber-value  vengono forniti altri modi per ripristinare l'errore sul campo AutoNumber, e soprattutto viene indicato anche la metodologia da adottare per le tabelle relazionate.

    Quindi partiamo con le risposte,

    13/03/2024 - Antony73 ha scritto:


    Cosa intendi per “reimpostare”?

    Reimpostare un campo AutoNumber in una tabella, proprio come lo definisce Microsoft.

    13/03/2024 - sihsandrea ha scritto:


    L'indice di una tabella appartiene alla struttura del database non è un dato da archivio. I dati sono quelle informazioni che seve archiviare, consultare e manipolare. Per fare queste operazioni ci si avvale di indici e chiavi primarie e esterne.

    Purtroppo, l'eredità degli arbori della programmazione hanno dato a questi campi un valore di dato. Così sentiamo dire “il cliente 107” "l'articolo 2357" e così via…

    In realtà in nr 107 del cliente pippo serve per identificare il record di pippo franco piuttosto che di pippo baudo.

    Andare a toccare le chiavi, come ti è stato suggerito, non ha senso. Se noti la rubrica del tuo cellulare hai un elenco di nomi non di id. Anche tu, in realtà dovresti nascondere all'utente il codice (chiave primaria o esterna).

    In tutto questo, andare a recuperare un numero id che non è un dato immesso dall'utente (all'utente non frega niente se pippo va inserito come id 3 o id 39), ma su un numero elevato di record, oartire dal record 1 per inserire l'id 368993 

    13/03/2024 - SempreFresco ha scritto:


    MsgBox "L'ID specificato esiste già nella tabella.", vbExclamation VerificaEInserisciID = False Exit Function

    Ti sorbiresti 368993 messaggi fino all'id libero 368994?

    Piuttosto torno a usare carta e penna.

    Sul fatto di inserire gli ID con INSERT INTO è una possibilità che via fornita in SQL. L'utilizzo con le sue implicazioni credo che sia discrezionale. Non mi sorbisco affatto i messaggi fino all'ID libero, in quanto viene passato un unico numero alla Funzione “IDDaVerificare”

    13/03/2024 - max.riservo ha scritto:


    ALTER TABLE [TableThatIncrements] ALTER COLUMN [Id] COUNTER (NewSeed,1)

    Nel caso non funzionasse la query precedente prova con questa …

    P.S. - Prima di fare danni fai il backup!

    Avevo già provato con ALTER TABLE e non funziona per le tabelle relazionate, come specificato da Microsoft, occorrerebbe prima eliminare tutte le relazioni.

    Dunque la domanda che avevo posto era la seguente:

    13/03/2024 - SempreFresco ha scritto:


    Nel suo insieme “arrangiato” funziona, ma volevo sapere se ci fosse un modo per “reimpostare” l'indice senza eseguire quanto nel paragrafo precedente.

    La risposta che ho trovato funzionale è la seguente:

     Function VerificaEInserisciID(ByVal IDDaVerificare As Integer, ByVal NomeTabella As String, ByVal NomeCampo As String) As Boolean
       On Error GoTo ErrorHandler
       
       Dim db As Database
       Dim rs As Recordset
       Dim UltimoID As Integer
       Dim CampoID As Variant
     
       
       CampoID = NomeCampo '"IDvalvole_in_attesa"
       ' Apri il database corrente
       Set db = CurrentDb
       
      
       
       ' Seleziona l'ultimo ID dalla tabella
       Set rs = db.OpenRecordset("SELECT MAX" & "(" & CampoID & ") AS UltimoID FROM " & NomeTabella)
       If Not rs.EOF Then
           UltimoID = rs("UltimoID").Value
       Else
           UltimoID = 0
       End If
       rs.Close
       
       ' Verifica se l'ID da verificare esiste già
       Set rs = db.OpenRecordset("SELECT * FROM " & NomeTabella & " WHERE " & CampoID & " = " & IDDaVerificare, dbOpenSnapshot)
       If rs.RecordCount > 0 Then
           MsgBox "L'ID specificato esiste già nella tabella.", vbExclamation
           VerificaEInserisciID = False
           Exit Function
       ' Verifica se l'ID da verificare è maggiore a ID MAX
       ElseIf IDDaVerificare > UltimoID Then
           MsgBox "L'ID specificato è maggiore dell'ultimo ID presente nella tabella.", vbExclamation
           VerificaEInserisciID = False
           Exit Function
       Else
           ' Inserisci l'ID nella tabella
           db.Execute "INSERT INTO " & NomeTabella & " (" & CampoID & ") VALUES (" & IDDaVerificare & ")"
       
       End If
       rs.Close
       
       Set rs = db.OpenRecordset("SELECT * FROM " & NomeTabella & " WHERE " & CampoID & " = " & IDDaVerificare, dbOpenSnapshot)
       If rs.RecordCount > 0 Then
       
           ' Costruisci l'istruzione SQL per reimpostare il contatore dell'ID
           db.Execute "INSERT INTO " & NomeTabella & " SELECT * FROM " & NomeTabella & "  WHERE " & CampoID & " = " & UltimoID
           
           MsgBox "L'ID è stato inserito correttamente nella tabella.", vbInformation
           VerificaEInserisciID = True
       
       
       Else
       MsgBox "L'ID non è stato inserito.", vbCritical
       VerificaEInserisciID = False
       
       End If
       rs.Close
       
       Set rs = Nothing
       Set db = Nothing
       Exit Function
       
    ErrorHandler:
       MsgBox "Si è verificato un errore durante la verifica e l'inserimento dell'ID.", vbCritical
       If Not rs Is Nothing Then rs.Close
       Set rs = Nothing
       Set db = Nothing
       VerificaEInserisciID = False
    End Function
    

    Nel codice fornito all'apertura del post eseguivo un  ‘db.Execute "INSERT INTO " calcolando l'ultimo ID +1, per poi cancellarlo.

    Questo reimpostava sì l'indice AutoNumber all'ultimo ID, ma non volevo cancellare l'ID e non volevo lasciarlo vuoto, in quanto la tabella si popola con altre funzioni tramite rs.AddNew.

    Quindi in alternativa alle soluzioni fornite da Microsoft, copio l'ultimo IDMax e lo incollo nella stessa posizione, e questo è sufficiente a reimpostare  l'indice AutoNumber.

    Ringrazio tutti che hanno dedicato del loro tempo alla mia discussione, avrò scoperto pure l'acqua calda, ma per me va bene così.

  • Re: Aggiornare indice in tabella Access

    15/03/2024 - SempreFresco ha scritto:


    13/03/2024 - max.riservo ha scritto:


    ALTER TABLE [TableThatIncrements] ALTER COLUMN [Id] COUNTER (NewSeed,1)

    Nel caso non funzionasse la query precedente prova con questa …

    P.S. - Prima di fare danni fai il backup!

    Avevo già provato con ALTER TABLE e non funziona per le tabelle relazionate, come specificato da Microsoft, occorrerebbe prima eliminare tutte le relazioni.

    Bene che hai risolto e che hai informato il forum, meno bene che tu non abbia segnalato prima che avevi già provato l'Alter table e che non funziona nel tuo caso (magari la prossima volta che scriverai in un forum ‘tecnico’ fornirai maggiori dettagli). Saluti

Devi accedere o registrarti per scrivere nel forum
29 risposte