Evitare possibili duplicato caso particolare.

di il
13 risposte

Evitare possibili duplicato caso particolare.

Buongirono a tutti, vi chiedo una mano per quanto riguarda un problema che riguarda un controllo su un possibile duplicato.

Ho una tabella di nome tblRedazioneRapportoDiLavoro dove confluiscono i rapporti di lavoro in base alla data e al lavoro. Per esempio suuponiamo di avere tre lavori, diciamo Lavoro1, Lavoro2, Lavoro3. Ogni giorno si fa il rapporto di lavoro in base alla data. 

Esmepio 

04/07/2023 rapporto per il Lavoro1

04/07/2023 rapporto per il Lavoro2

04/07/2023 rapporto per il Lavoro 3

e ogni giorno la stessa storia. 

Supponiamo che uno sia così sbadato da inserire due volte lo stesso rapporto o magari sbaglia la data e quindi avere due volte lo stesso rapporto relativo alla stessa data e allo stesso Lavoro, questo vorrei che non fosse possibile. 

Non vi chiedo di scrivermi codici o raba del genere, ma solo dove e come agire. Vi ringrazio, un saluto.

13 Risposte

  • Re: Evitare possibili duplicato caso particolare.

    Approfondisci il concetto di chiave primaria, cercando di crearne una composta (o multicampo che dir si voglia).

  • Re: Evitare possibili duplicato caso particolare.

    Se non e' mai possibile avere stessa data e stesso lavoro, puoi creare un indice composto in tabella come nell'esempio sottostante. Per evitare di inserire uno stesso documento due volte in una tabella in cui salvo le bolle fornitori, ho concatenato ID fornitore, numero bolla e data bolla.

    La chiave primaria invece e' un altro campo con contatore automatico.

    Questo e' un metodo, pero' sarebbe meglio inserire un controllo in fase di inserimento record direttamente da maschera, sull' evento Before update della form che supporta il Cancel nel caso di errore. Nel forum ci sono centinaia di esempi su questo argomento…..

  • Re: Evitare possibili duplicato caso particolare.

    Ciao Nat,

    concordo con chi è già intervenuto e ti proporrei una possibile soluzione:

    Se ho capito bene, vorresti non inserire da form un record già esistente nella tabella

    Potresti in evento Form_BeforeUpdate inserire il controllo e il relativo messaggio di errore

    Esempio:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & " AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub
    
    Puoi anche scriverla in questo modo:
    
    Private Sub Form_BeforeUpdate(Cancel As Integer)
    Cancel = Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & " AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF 
    If Cancel Then MsgBox "Elemento già Inserito!", vbCritical, "Error"
    End Sub
    

    Dove:

    • con dbengine openrecordset esegui una Select/Where e vai a ricercare nella Tabella se già esiste il record che stai inserendo
      • se Eof restituisce False allora il record è già presente in tabella e con Cancel True abortisci l'inserimento 
      • se Eof restituisce True allora il record non esiste e viene inserito

     Una cosa del genere che a mio avviso è semplice e veloce in certi scenari

    Tra l'altro ebbi modo di verificarne le prestazioni su qualche migliaio di records ed è più performante di una DlooKup

  • Re: Evitare possibili duplicato caso particolare.

    04/07/2023 - By65Franco ha scritto:


    Ciao Nat,

    concordo con chi è già intervenuto e ti proporrei una possibile soluzione:

    Se ho capito bene, vorresti non inserire da form un record già esistente nella tabella

    Potresti in evento Form_BeforeUpdate inserire il controllo e il relativo messaggio di errore

    Esempio:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & "' AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub
    
    Puoi anche scriverla in questo modo:
    
    Private Sub Form_BeforeUpdate(Cancel As Integer)
    Cancel = Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & "' AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF 
    If Cancel Then MsgBox "Elemento già Inserito!", vbCritical, "Error"
    End Sub
    

    Dove:

    • con dbengine openrecordset esegui una Select/Where e vai a ricercare nella Tabella se già esiste il record che stai inserendo
      • se Eof restituisce False allora il record è già presente in tabella e con Cancel True abortisci l'inserimento 
      • se Eof restituisce True allora il record non esiste e viene inserito

     Una cosa del genere che a mio avviso è semplice e veloce in certi scenari

    Tra l'altro ebbi modo di verificarne le prestazioni su qualche migliaio di records ed è più performante di una DlooKup

    Grandeee! Sei il migliore!

  • Re: Evitare possibili duplicato caso particolare.

    05/07/2023 - Nat ha scritto:


    Grandeee! Sei il migliore!

    Maccheeeeeeèèèèè … il Vba non è il mio linguaggio di riferimento… ;-)

    Ma poi valuta bene perchè io non conosco il tuo Db, ho solo fatto un esempio… e tu non devi fare il copia incolla…  se lo fai poi a fine mese ti mandiamo fatturazione ;-))

    (scherzooo)

  • Re: Evitare possibili duplicato caso particolare.

    05/07/2023 - By65Franco ha scritto:


    05/07/2023 - Nat ha scritto:


    Grandeee! Sei il migliore!

    Maccheeeeeeèèèèè … il Vba non è il mio linguaggio di riferimento… ;-)

    Ma poi valuta bene perchè io non conosco il tuo Db, ho solo fatto un esempio… e tu non devi fare il copia incolla…  se lo fai poi a fine mese ti mandiamo fatturazione ;-))

    (scherzooo)

    Per non essere il tuo linguaggio di riferimento ne sai di cosine! ahha

  • Re: Evitare possibili duplicato caso particolare.

    04/07/2023 - By65Franco ha scritto:


    Ciao Nat,

    concordo con chi è già intervenuto e ti proporrei una possibile soluzione:

    Se ho capito bene, vorresti non inserire da form un record già esistente nella tabella

    Potresti in evento Form_BeforeUpdate inserire il controllo e il relativo messaggio di errore

    Esempio:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & "' AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub
    
    Puoi anche scriverla in questo modo:
    
    Private Sub Form_BeforeUpdate(Cancel As Integer)
    Cancel = Not DBEngine(0)(0).OpenRecordset("SELECT tuoId FROM tuaTabella WHERE tuoIdLovaro=" & Me.tuoIdLavoro & "' AND tuaData=" & CStr(CLng(Me.tuaData)) & ";", dbReadOnly).EOF 
    If Cancel Then MsgBox "Elemento già Inserito!", vbCritical, "Error"
    End Sub
    

    Dove:

    • con dbengine openrecordset esegui una Select/Where e vai a ricercare nella Tabella se già esiste il record che stai inserendo
      • se Eof restituisce False allora il record è già presente in tabella e con Cancel True abortisci l'inserimento 
      • se Eof restituisce True allora il record non esiste e viene inserito

     Una cosa del genere che a mio avviso è semplice e veloce in certi scenari

    Tra l'altro ebbi modo di verificarne le prestazioni su qualche migliaio di records ed è più performante di una DlooKup

    Comunque ho da dirti una cosa.  Scrivendo questo 

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT IDRedazioneRapporto FROM tblRedazioneRapportoDiLavoro WHERE IDLavoro=" & Me.cboLavoro & "' AND DataRapporto=" & CStr(CLng(Me.Testo39)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub

    Mi da errore di run-time ‘3075’. Errore di sintassi nella stringa nell'espressione della query. ‘IDLavoro=19' AND DataRapporto=45090. Se tolgo la parte che riguarda il lavoro cioè la parte IDLavoro=" & Me.cboLavoro & "' AND allora funziona. Sai dirmi dove risiede il problema?

  • Re: Evitare possibili duplicato caso particolare.

    06/07/2023 - Nat ha scritto:


    WHERE IDLavoro=" & Me.cboLavoro & "' AND

    Ciao Nat,

    vedi che c'è un apicino isolato primo della AND…  sicuramente un refuso per via di un confronto stringa e non numerico… mi è rimasto per sbaglio ;-)

    L'ho sistemato nel post originale

    e questo dovrebbe essere il tuo:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT IDRedazioneRapporto FROM tblRedazioneRapportoDiLavoro WHERE IDLavoro=" & Me.cboLavoro & " AND DataRapporto=" & CStr(CLng(Me.Testo39)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub
  • Re: Evitare possibili duplicato caso particolare.

    06/07/2023 - By65Franco ha scritto:


    06/07/2023 - Nat ha scritto:


    WHERE IDLavoro=" & Me.cboLavoro & "' AND

    Ciao Nat,

    vedi che c'è un apicino isolato primo della AND…  sicuramente un refuso per via di un confronto stringa e non numerico… mi è rimasto per sbaglio ;-)

    L'ho sistemato nel post originale

    e questo dovrebbe essere il tuo:

    Private Sub Form_BeforeUpdate(Cancel As Integer)
    If Not DBEngine(0)(0).OpenRecordset("SELECT IDRedazioneRapporto FROM tblRedazioneRapportoDiLavoro WHERE IDLavoro=" & Me.cboLavoro & " AND DataRapporto=" & CStr(CLng(Me.Testo39)) & ";", dbReadOnly).EOF Then
       MsgBox "Elemento già Inserito!", vbCritical, "Error"
       Cancel = True
    End If
    End Sub

    Grazie tante per la pazienza!

  • Re: Evitare possibili duplicato caso particolare.

    @Nat evita l'overquoting per piacere. Rende la discussione difficile da leggere.

  • Re: Evitare possibili duplicato caso particolare.

    07/07/2023 - Sgrubak ha scritto:


    @Nat evita l'overquoting per piacere. Rende la discussione difficile da leggere.

    Se mi spieghi cortesemente questo termine “overquoting” non lo faccio più. Grazie!

  • Re: Evitare possibili duplicato caso particolare.

    07/07/2023 - Nat ha scritto:


    Se mi spieghi cortesemente questo termine “overquoting” non lo faccio più. Grazie!

    Over (tutto, troppo, esagerato)… ;-))  non è necessario citare tutto il post, magari o una piccola parte o solo l'utente…  una cosa di questo tipo.

  • Re: Evitare possibili duplicato caso particolare.

    By65Franco

    Ho capito!

Devi accedere o registrarti per scrivere nel forum
13 risposte