Newsgroup: it.comp.appl.access
Titolo: Impedire duplicati in sottomaschera

Buona domenica a tutti
Ho due tabelle collegate uno a molti fatturevendite e dettaglivendite senza
integrità referenziale. una maschera Fatturevendite e sottomaschera
dettaglivendite per l'inserimento dei dati.
Come potrei impedire l'inserimento di prodotti uguali nella sottomaschera?
Grazie anticipatamente a chi volesse darmi un aiuto.
Saluti Daniele

 Come potrei impedire l'inserimento di prodotti uguali nella sottomaschera?
Per impedire duplicazioni ci sono sempre almeno 2 strade:
1 - impostare il/i campo/i da non duplicare come chiave univoca sulla 
tabella, e in maschera intercettare l'errore che ti da' quando tenti una 
duplicaz.
2 - Prima di ogni effettivo inserimento in tabella 
(BeforeInsert,BeforeUpdate) , fare eseguire una parte di codice che 
verifica che non ci sia gia' e in quel caso inserire effettivamente il 
record.
Ciao
Ux

 ha scritto nel messaggio
news:XD8%9.163518$AA2.6...@news2.tin.it...

Impostando correttamente le Chiavi primarie con Duplicati non ammessi.....!
Ma......!
In realtà per no avere spiacevoli messaggi di avviso ti consiglio di
effettuare
una corretta gestione degli errori nell'evento OnError di Maschera, non
ricordo
se la duplicazione PrimaryKey corrisponde a 3021, in questo caso lo dovresti
gestire in modo che l'utente venga indirizzato, in quanto a lui che venga
duplicata
la PrimaryKey non dice nulla, se non di insultare il programmatore e magari
telefonargli
perchè non va nulla............!!!!
;-)
@Alex.

Ciao Alex e Uranox grazie per la risposta però non ho nessun msg di errore
da gestire.
Cerco di spiegare meglio quello che cerco di fare.
Dovrei poter gestire lo scarico dei prodotti, senza fare fattura, cioè con
scontrino, da una maschera di scarico, basata sulla tblDettaglivendite.
oltre che con maschera e sottomaschera fattura, per regolare fattura. Per
fare questo non ho applicato l'integrità referenziale tra le tbl
fatturevendite e dettaglivendite. Al momento l'unico problema, che ho
rilevato io, era appunto la possibile duplicazione dei prodotti nella
sottomaschera dei dettagli di vendita. Come si dovrebbe impostare IDProdotto
nella tbl dettaglivendite?
saluti Daniele


Non ti sei spiegato male, solo non hai capito il Ns suggerimento.
Il fatto che ti sia possibile inserire Duplicati č la base del tuo problema.
Questo lo risolvi impostando diversamente le PrimaryKey della Tabella.
Ma a questo punto la Mascherina(SubForm) ti restituirŕ errori se
cerchi di inserire doppioni, perchč hai impostato a NO Duplicati Ammessi.
E' quě che devi gestire gli
errori.........................................................
@Alex.

 errori.........................................................
..ed è qui che continuo a non capire. :-))
Scusami Alex, sono un pò duro, ma non riesco ad individuare questi errori
della SubForm. Continuo a dirti che, con le impostazioni attuali, non ho
nessun errore in nessuna maschera. Solo nella sottomaschera della fattura si
può inserire, per errore, lo stesso prodotto, cosa che vorrei evitare.
Nella tbldettaglivendite ho:
IDDettaglivendite PK; IDFatturavendite: duplicati ammessi; IDProdotto:
duplicati ammessi.
Quando inserisco un record dalla maschera Scarico IDFatturavendite è uno
zero.
Non so se questo può portarmi ad eventuali anomalie nel funzionamento del db
per eventuali ricerche e statistiche.
saluti Daniele

 ha scritto nel messaggio
news:fXd%9.165202$AA2.6...@news2.tin.it...

I casi sono veramente 2:
1)Non hai letto bene i POST(nel caso rileggi)
2)La prima che hai detto........... ;-)
Non ho detto che hai errori, ti ho detto che devi modificare il formato dati
nella tabella, dove dici Duplicati Ammessi devi invece inserire Duplicati
NON Ammessi.
Quando avrai fatto questa modifica, allora si che vedrai gli
ERRORI.............!!!
A questo punto per evitare di incasinare l'utente devi gestirli questi
errori, e come si
gestiscono....??? Intercettandoli, cioè inserendo un controllo nell'EVENTO
ONERROR
della SubForm, in quanto gli ERRORI vengono generati solo dopo il tentativo
di UPDATE, ma allora è già tardi, quindi o controlli tutti gli
inserimenti(troppi) oppure
più genericamente su evento ONERROR gestisci l'errore relativo, che come ti
dicevo
dovrebbe essere 3021.
Ci siamo.....................................
@Alex.
P.S. non ti offendere sto scherzando, se non sono stato chiaro lo ripeto
volentieri un Copia/Incolla
non mi scoccia.........!!!


Ma figurati... per così poco...ti conosco ... sono due anni che seguo questo
NG :-))
Se avevi capito il mio problema potevi anche dirmi come risolvere la
gestione degli errori.
detto questo ho messo: a Duplicati non ammessi  idprodotto nella tabella
Dettaglivendite. inserisco un nuovo record e mi viene fuori il solito
messaggio di avviso di valori duplicati. Nessun numero di errore.
Speriamo che la notte mi porti consiglio...:-)))
saluti Daniele

 messaggio di avviso di valori duplicati. Nessun numero di errore.
[...]
        Event Error(DataErr As Integer, Response As Integer)
            Membro di Access.Form
--
Ciao :-)
Maurizio
--------
?SPQR(C)
 X
--------

 ha scritto nel messaggio
news:b1klmk$1470id$1...@ID-52090.news.dfncis.de...

Ciao Maurizio, ti ringrazio per la risposta, ma non ho la necessaria
preparazione per poter capire come dovrei fare.
Ti sarei molto grato se potessi darmi maggiori delucidazioni.
saluti Daniele
---

 Ti sarei molto grato se potessi darmi maggiori delucidazioni.
    Volentieri, ma dopo che avrai consultato la guida a proposito di cio'
che ho scritto, in modo che tu possa spiegarci, riferendoti a quella, cosa
in particolare non ti e' chiaro. Diversamente, per darti maggiori
delucidazioni, dovrei fare un copia/incolla della guida e capisci bene che
non ha senso.


 in particolare non ti e' chiaro.
Tutto!....la prima cosa che ho fatto, dopo il tuo precedente post, è stata
quella di cercare nella guida di access, 2000-sp1, EventError.
Chiedevo spiegazioni  perchè non vedo cosa c'entra la modifica del messaggio
di errore, almeno è quello che ho capito,  con il mio problema che
riepilogo.
Maschera e sottomaschera fatture; maschera scarico entrambe devono scrivere
record nella tabelle dettaglivendite, tabella fatture e dettagli non hanno
l'integrità referenziale, ci sono riuscito, dopo un'infinità di prove,
mettendo idprodotto a duplicati ammessi, non conosco altre soluzioni. :-)))
Ovviamente nella sottomaschera fattura si possono inserire gli stessi
prodotti ed era quello che volevo evitare.
saluti Daniele
---

 prodotti ed era quello che volevo evitare.
    Per ottenere cio' che richiedi dovrai avere una struttura del tipo:
        Tabella: FattureVendita
            Campi:
                idFatturaVendita: Numerico, Intero lungo, Richiesto.
            Indici:
                pk: idFatturaVendita, Primario, Univoco.
        Tabella: ProdottiVendita
            Campi:
                idProdottoVendita: Numerico, Intero lungo, Richiesto.
            Indici:
                pk: idProdottoVendita, Primario, Univoco.
        Tabella: DettagliVendita
            Campi:
                idFatturaVendita:   Numerico, Intero lungo, Richiesto;
                idProdottoVendita:  Numerico, Intero lungo, Richiesto;
                idDettaglioVendita: Numerico, Intero lungo, Richiesto.
            Indici:
                pk: idDettaglioVendita, Primario, Univoco;
                ukFattProd: idFatturaVendita, idProdottoVendita, Univoco;
                kFatt: idFatturaVendita;
                kProd: idProdotto.
    In questo modo, grazie alla chiave univoca ukFattProd, non ti sara'
possibile avere prodotti duplicati nella stessa fattura.
    Cosa succede in fase di immissione se invece si immette un prodotto gia'
presente nella fattura? Quando si tenta di passare ad un nuovo record di
dettaglio, compare il messaggio:
        L'apporto modifiche non e' riuscito perche' si e' cercato di
        duplicare i valori nell'indice, nella chiave primaria o nella
        relazione. Modificare i dati nel campo o nei campi che
        contengono dati duplicati, rimuovere l'indice per consentire
        l'inserimento di voci duplicate, quindi ritentare l'operazione.
        [ Ok ] [ ? ]
    Chiaramente non va bene spaventare gli utenti della nostra applicazione
con questa pappardella, meglio un messaggio conciso ma chiaro, che indichi
anche come l'utente deve comportarsi per rimediare. Questo lo si ottiene
appunto intercettando l'errore nella procedura evento di cui ti ho parlato.


 ha scritto nel messaggio
news:b1ln4v$14o8fi$1...@ID-52090.news.dfncis.de...

E' stato bello assistere........!
No Maurizio hai afferrato benissimo il senso, purtroppo facciamo fatica
a capirci a vicenda, per colpa di entrambi, mi spiego....!
Quello che vuole fare Cidi, e che sono sicuro tu abbia capito, è una cosa
abbastanza ovvia, ma richiede un minimo di conoscenza di base sia
della Terminologia, che dei contenuti dei Database.
Mi pare, senza che Cidi si ritenga offeso, che debba fare ancora qualche
passettino
per completare queste cose...........!
Di contro da parte nostra, io per primo, diamo per scontato che lui sappia
ciò di cui staimo
parlando, e visto che chiede aiuto, mi pare ovvio non sia così.
Detto questo.........:
La segnalazione che ricevi dopo aver fatto le modifiche di cui sopra si può
evitare, come..?
Inserendo una condizione nell'evento OnError di Maschera.
Per tua conoscenza, sull'evento in questione inserisci MsgBox Err.Number &
"-->" & Err.Description
Ora puoi vedere qual'è l'errore al quale mi riferivo.....!
Quì adesso devi solo  dirottarlo, con una condizione sempre nell'evento
Errore:
If err.Number=NumeroDiPrima then MsgBox"Stai inserendo Valori
Doppi.....!!!":Exit Sub
Ciao.
@Alex.

 Doppi.....!!!":Exit Sub
    Sicuro? Ora non posso verificare ma, dato che stiamo parlando di:
        Event Error(DataErr As Integer, Response As Integer)
            Membro di Access.Form
mi sembra non si possa gestire l'errore come se fosse un errore di run-time
di Visual Basic dato che dovrebbe essere un errore di run-time di Access.
    Ecco, mi pareva. Questo e' l'esempio della guida:
Private Sub Form_Error(DataErr As Integer, Response As Integer)
    Const conChiaveDuplicata = 3022
    Dim strMsg As String
    If DataErr = conChiaveDuplicata Then
        Response = acDataErrContinue
        strMsg = "È necessario che ciascun record per impiegato abbia " _
            & "un numero ID impiegato univoco. Verificare di nuovo i dati."
        MsgBox strMsg
    End If
End Sub


 ha scritto nel messaggio
news:b1mbpv$14cja7$1...@ID-52090.news.dfncis.de...

Beh, quello che hai postato è quello che intendevo, ho provato a leggere
la guida, ma non ho trovato nulla, se non:
dalla guida.......
"DataErr Il codice di errore restituito dall'oggetto Err quando si verifica
un errore.
È possibile utilizzare l'argomento DataErr con la funzione Error per
associare il numero al messaggio di errore corrispondente."
Da quì ho dedotto che si potesse usare Err direttamente, anche se in effetti
non serve.
C'è da dire che non ho mai usato questa tecnica, quindi non ne conosco i
difetti
perchè solitamente uso Form non associate su inserienti e usando le
transazioni sul
metodo Execute mi risolvo molte rogne.......!
Questa però mi pareva, con le opportune correzioni, la strada più semplice
da spiegare..........!!!
@Alex.

 da spiegare..........!!!
    Ecco, appunto. Allora tu non hai bisogno di intercettare tali errori
perche' con le maschere unbound tali eventi di errore non si scatenano
proprio. (Sempre se non sbaglio).


 appunto intercettando l'errore nella procedura evento di cui ti ho
parlato.
Certamente adesso si può intercettare il messaggio e modificare il testo. Ma
prima no perchè non avevo nessun messaggio, settando a si duplicati ammessi
idprodotto, invece mettendolo a no duplicati non ammessi, non riuscivo a
scaricare senza fattura.
saluti Daniele
---


Beh, in realtà gli errori li hai, solo che io imposto SetWarning=False, ma
come opzione del'Execute uso dbFailOnerror, poi controllo quanti Record
ha modificato la QRY, di quì gestisco con le transazioni una corretta
gestione.
Poi dipende tutto da come si struttura la cosa..........!
@Alex.

 ha scritto nel messaggio
Imparata la lezione degli indici multicampo. Nella sottomaschera fattura
intercetto il messaggio d'errore standard, però non risolvo il problema. La
chiave univoca vale anche per la maschera Scarico ed ovviamente mi blocca
appena inserisco lo stesso prodotto due volte. Qualche altra info per
un'altro passettino in avanti? Grazie
saluti Daniele


    Mi sa che non ci sia altro da fare che eliminare quell'indice e gestire
la cosa in altro modo: un indice o va bene in tutte le circostanze o non
merita di esistere.
    Un modo potrebbe essere quello di verificare, nella fase di carico, in
cui non sono ammessi duplicati, prima della registrazione del record, se
c'e' la possibilita' di ottenere un duplicato... Oppure non preoccuparsene
ed intercettare l'errore.


 ed intercettare l'errore.
oddio... la sibilla cumana!  :-))
Maurizio, ti prego, non giudicarmi male. Considerata la tua bravura non
posso e non voglio essere irrispettoso ma la tua risposta mi è oscura.
Una domanda: è possibile leggere la query della sottomaschera ed impedire i
duplicati?
 saluti Daniele

 i duplicati?
    Facciamo un esempio, ok?
        Tabella: x cidi
            Campi:
            id: numerico, intero lungo, richiesto, duplicati non
                    ammessi, valido se >0, primario;
            idTipoOperazione: numerico, intero lungo, richiesto,
                    duplicati ammessi, valido se between 1 and 2,
                    descrizione 1=Carico; 2=Scarico;
            idDocumento: numerico, intero lungo, richiesto,
                    duplicati ammessi, valido se >0;
            idArticolo: numerico, intero lungo, richiesto,
                    duplicati ammessi, valido se >0;
            Quantità: numerico, precisione doppia, richiesto.
        Maschera: x cidi
            Origine record: x cidi
            Su apertura: =docmd.restore
            Casella di testo id:
                Valore predefinito: nz(DMax([id].[Name];"x cidi");0)+1
            Modulo Visual basic:
Option Base 0
Option Compare Database
Option Explicit
Private Sub Form_BeforeUpdate( _
  ByRef Cancel As Integer)
  Const c_lIdTipoOperazioneSenzaDuplicati& = 1
  Dim sWhere    As String
  Dim sTitle    As String
  Dim sPrompt   As String
  Dim lButtons  As VBA.VbMsgBoxStyle
  Dim oDaoRst   As DAO.Recordset
  With Me
    If (.NewRecord = True) Then
      If ( _
        .idTipoOperazione.Value _
        = c_lIdTipoOperazioneSenzaDuplicati _
      ) Then
        lButtons = vbExclamation + vbOKOnly
        sWhere _
          = "[" & .idDocumento.ControlSource & "]" _
          & " = " & .idDocumento.Value _
          & " AND " _
          & "[" & .idArticolo.ControlSource & "]" _
          & " = " & .idArticolo.Value
        Debug.Print sWhere
        sTitle = "Attenzione!"
        sPrompt _
          = "Articolo " & .idArticolo.Value _
          & " già presente" & vbCrLf _
          & "nel Documento " & .idDocumento.Value _
          & "."
        Debug.Print sPrompt
        Set oDaoRst = .RecordsetClone
        With oDaoRst
          .FindFirst sWhere
          If (.NoMatch = False) Then
            Cancel = True
            MsgBox sPrompt, lButtons, sTitle
          End If
        End With
        Set oDaoRst = Nothing
      End If
    End If
  End With
End Sub
    Prova a farlo girare.


                 Valore predefinito: nz(DMax([id].[Name];"x cidi");0)+1
[...]
    Questa e' ancora piu' bellina:
        nz(DMax([id].[Name];[recordset]![id].[sourcetable]);0)+1


     Prova a farlo girare.
Grazie, ci provo.
saluti Daniele
---


Fallo anche con A97..........!!! ;-)
@Alex.

 Fallo anche con A97..........!!! ;-)
    Nun cello'... Che succede? BSOD?



Un se pole................, i vecchietti che hanno come me 97 devono
rimpiangere parecchie migliorie di XP e 2000.....!
Arriveranno tempi migliori....... ne rimarrà solo 1.
@Alex.

 Arriveranno tempi migliori....... ne rimarrà solo 1.
    Seee... Quando mai...


     Seee... Quando mai...
Mai.
@Alex.

 ha scritto nel messaggio
news:YRA0a.142292$0v.40...@news1.tin.it...

Ciao Maurizio, ho provato il tuo codice e funziona tutto perfettamente. Però
non riesco  a capire come adattarlo al mio caso. Certamente tu avresti fatto
tutto con 3-4 tabelle per fare carico dei prodotti da fornitori, e scarico a
dettaglio e tramite le fatture di vendita. Io invece ho per gli acquisti:
fornitori, fattureacquisti e dettagliacquisti. per le vendite: clienti,
fatturevendite e dettaglivendite con la tabella prodotti legata alle due dei
dettagli. Prima o poi troverò una soluzione. grazie
saluti Daniele