Newsgroup: it.comp.lang.visual-basic
Titolo: controllo duplicati su database

Salve a tutti!
Sono da poco approdato al VB6 e nella relizzazione della gestione di
un database .mdb con visual basic, e mi trovo in panne su un aspetto.
Premetto che lo schema usato é : mdb a cui collego un datacontrol
(Dynaset) e motore jet. A questo ho collegato sia una dbgrid che una
scheda di visione / inserimento dati.
L'ordinamento lo faccio con istruzioni sql (select....ecc).
Funziona tutto come vorrei, tranne un aspetto :
Quando inserisco un nuovo record, il controllo sui campi
"fondamentali" è ok; quindi proseguo ma se immetto un cognome già
esistente, il programma va in errore. ( il db è ordinato per cognome)
A me servirebbe quanto segue:
sig. Mario Rossi    333444555  (esistente)
sig, Mario Rossi    666777888      e l'inserimento va a buon fine
sig, Mario Rossi    333444555      MsgBox..." Contatto già presente" e
uscire dalla routine di inserimento
C'è qualcuno che sa darmi una mano col codice necessario?
Grazie a tutti in anticipo

 C'è qualcuno che sa darmi una mano col codice necessario?
Mi pare un errore di struttura del DB, probabilmente hai fatto il cognome
chiave, e cognome e nome non può essere certo chiave.
Anche se non mi torna, la chiave potrebbe essere cognome+nome+telefono, ma
ti ripeto, è contro ogni logica di programmazione.
Ti basta prima di fare l'insert/update, controllare se esiste già un record
con quei campi che definisci Primary Key

On 3 Ott, 14:42, "Andrea [Work]" <nos...@invalid.invalid> wrote:

Forse mi sono espresso male.
campo 1            campo2           campo3                  Campo4
 Sig                  Rossi               Mario
333445566                 ecc....
Ordinamento per "campo 2
gestione duplicato:
Se l'immissione  è :  Rossi, Mario, 333445566    deve segnalare il
doppio e con un VbOkOnly per esempio uscire ( il discriminante sarà un
campo qualunque diverso da cognome e nome, quindi nell'esempio il
numero)
Se l'immissione  è   Rossi, Mario, 11226677     l'immisione va a buon
fine e il record viene accodato.
Resta comunque fondamentale che l'ordinamento di sia del tipo Cognome,
nome.

 nome.
L'ordinamento credo sia l'ultimo dei problemi, oltre ad essere proprio una
cosa a parte rispetto alla validazione dell'input.

On 3 Ott, 15:36, "Andrea [Work]" <nos...@invalid.invalid> wrote:

Grazie per il consiglio..(Select..ecc).
Certo, l'ordinamento è cosa diversa...era solo per precisare
Per i possibili errori, per il case sensitive risolvo. Per gli altri
che hai citato, tutti realmente possibili, tempo al tempo! come detto
mi sono cimentato in questa cosa ma non sono programmatore. di
professione sono ingegnere e mi occupo di progettazione meccanica.
Capisco che per uno che mastica molto bene il vb alcune cose possano
sembrare eresie...ma l'importante è cominciare no?
Grazie ancora

 sembrare eresie...ma l'importante è cominciare no?
Devi individuare:
Come mai possono essere inserite due volte le stesse persone? C'è un campo
che mi dice che quella persona è già stata inserita? (es. CodFisc per
persone fisiche, o PIVA per aziende), allora la chiave (definita sul DB)
sarà quella.
(oddio se poi una persona non ricorda il suo CF devi comunque inserirla, e
quindi niente PK)

 quindi niente PK)
Sul problema del Primary K. non ho difficoltà. Per il momento
l'applicazione è stand alone e girerà solo sul mio computer (in futuro
vedrò di espanderla in rete per consentirne l'uso ad al più 2 -3
colleghi). Quindi per il momento se riesco a far funzionare il minimo,
posso avere un piccolo database con le funzioni minime necessarie.
La primary key di default dell' mdb è l'indice incrementale numerico,
ma posso decidere io quale mettere ed imporre nel form di immissione
che tale campo sia riempito per forza (come ho fatto per nome e
cognome)
Il problema è che se nego semplicemente il duplicato su PK il
programma va in errore quando metto il duplicato..e questo vorrei
evitarlo gestendo come si deve da codice. E' ovvio che la condizione
deve prevedere un controllo su tutta la riga...cioè cognome , nome e
campo "PK" perchè tanto per esempio, potrei avere nomi diversi con lo
stresso numero di centralino.
Ho provato la tua strada (che mi sembra la migliore) ma ho il seguente
intoppo:
faccio la select * From con la condizione where Cognome = "testo
digitato nelle finestra cerca*"
ora se ottengo un "vuoto".....vado avanti
se ottengo valore trovato
dovrei confrontare quel record con cognome, nome, PK inseriti nel form
di inserimento e se coincidono tutti , non salvare
Il problema è che non so come fare tale confronto, visto che l'sql mi
restituisce una stringa e non dei valori che singolarmente posso
confrontare in un if.
La visualizzazione è fatta con sstab che visualizza sia la scheda
record selezionato che l'intera tabella. La scheda serve anche per
l'inserimento nuovo record quando viene premuto il pulsante aggiungi
Spero di aver eposto bene il concetto
In ogni caso grazie ancora per l'aiuto dato sino ad ora

 confrontare in un if.
L'SQL ti restituisce un insieme di righe, se non te ne sostituisce alcuna
vuol dire che non esiste un record nel DB che soddisfa le condizioni di
ricerca.


Beh, fai una select prima con gli stessi dati e verifichi se ti
ritorna qualcosa.
In caso positivo, il record è già esistente, altrimenti no.
Non entro nel merito dell'implementazione delle tabelle :)
Ciao
AranBanjo
http://blog.ponchio.it

 ricerca.
Ti posto il codice: Ho due malfunzionamenti : aggiunge comunque una
riga vuota e poi mi da come duplicato anche un contatto nuovo...anche
con tutti i valori diversi
Private Sub cmdsalva_Click()
 'CONTROLLO INSERIMENTO NOME E COGNOME     funziona bene!
If Trim(Text2.Text) = "" Or Trim(Text3.Text) = "" Then
  MsgBox "Inserire Cognome e Nome.", vbOKOnly + vbCritical, "Nessun
Nome inserito"
  Exit Sub
End If
' Controllo duplicati  non va
pathmdb = App.Path & "\Rubrica.mdb"
'definizione Data1
'---------------------
Data1.DatabaseName = pathmdb
Data1.Connect = ""
Data1.RecordsetType = 1
Dim duplsql As String
duplsql = "Select Cognome,Nome,Tel From Foglio1 Where Cognome ='Text2'
AND Nome ='Text3' And Tel ='Text6'"
If duplsql <> "" Then
   MsgBox "Contatto esistente.", vbOKOnly + vbCritical, "Controllo
duplicati"
' svuoto le caselle
       Text1.DataChanged = False
       Text2.DataChanged = False
       Text3.DataChanged = False
       Text4.DataChanged = False
       Text5.DataChanged = False
       Text6.DataChanged = False
       Text7.DataChanged = False
       Text8.DataChanged = False
       Text9.DataChanged = False
       Text10.DataChanged = False
       Text11.DataChanged = False
       Text12.DataChanged = False
       Text13.DataChanged = False
End If
    'Salva le modifiche.
    Data1.Recordset.Update
    cmdsalva.Enabled = False
    cmdadd.Caption = "Aggiungi"
End Sub

 duplicati"
duplsql è una stringa, devi aprire un recordset con tale stringa
Con ADO una cosa del tipo:
Dim Rs As ADODB.Recordset
Set Rs = New ADODB.Recordset
Set Rs.ActiveConnection = AdoCN
Rs.Source = duplsql
Rs.Open
If Not Rs.EOF Then
  'ALLORA CI SONO UNO O PIU' DUPLICATI
End If
Rs.Close
Set Rs.ActiveConnection = Nothing
Set Rs = Nothing

 duplicati"
duplsql è una stringa, devi aprire un recordset con tale stringa
Con ADO una cosa del tipo:
Dim Rs As ADODB.Recordset
Set Rs = New ADODB.Recordset
Set Rs.ActiveConnection = AdoCN
Rs.Source = duplsql
Rs.Open
If Not Rs.EOF Then
  'ALLORA CI SONO UNO O PIU' DUPLICATI
End If
Rs.Close
Set Rs.ActiveConnection = Nothing
Set Rs = Nothing
Però ti consiglio di studiare un minimo l'accesso ai database da VB6,
perchè altrimenti fai solo casino.
Recordset, record, Ado (o DAO), devi sapere che sono, perchè assegnare del
testo ad una stringa, e poi controllare se non è vuota è un po' indecente
:D

 :D
:) Grazie mille. Adesso mi studio un pò ciò che hai scritto e vedo di
trovare qualcosa (libro ) da cui studiarmi meglio ste cose. Comunque
forte la definizione "indecente"...ahahah
Vabbè cercherò di migliorare!!
Grazie ancora

 Vabbè cercherò di migliorare!!
Bhe diciamo che ho scritto molto di fretta nei brevi ritagli, non ho avuto
tempo di cercare sinonimi al mio pensiero :D

Rieccomi! :)
Allora ho sistemato praticamente tutto nel programma per gestire il
database... mi son letto un libro su visual basic e database che ho
trovato.
Il problema del controllo sui duplicati non riesco però ancora a
risolverlo, anche se forse ci sono vicino ma la sub non funziona
correttamente.
Ricapitolando: l'accesso al database è di tipo DAO; connetto al mdb il
data control e poi ho due visualizzazioni : dbgrid e form scheda che
mi visualizza un record alla volta. Tra le altre funzioni, la ricerca
è a posto ed ho messo a punto un subroutine che tiene conto
dell'apostrofo.Inoltre la ricerca non è Case sensitive.
Per semplificare la gestione dei duplicati, ho cercato di
semplificare: vorrei cercare Cognome e nome contemporaneamente; se
esiste, decidere (visto che il puntatore si posiziona su quel record e
lo posso leggere) se continuare ed inserire il record o abbandonare.
Nel codice che allego, alcune istruzioni compaiono come commento
perchè le ho inserite qui solo per chiarezza, ma compaiono in altri
punti del codice.
Ora spiego cosa avviene:
Private Sub cmdsalva_Click()
 'CONTROLLO INSERIMENTO NOME E COGNOME
If Trim(Text2.Text) = "" Or Trim(Text3.Text) = "" Then
  MsgBox "Inserire Cognome e Nome.", vbOKOnly + vbCritical, "Nessun
Nome inserito"
  Exit Sub
End If
                                       Funziona correttamente. Se non
metto entrambi esce e non c'è nuovo record
 'Controllo duplicati
Dim Rispcontr As Integer
                                       'ordsql = "select * from
Foglio1 order by Cognome, Nome"
                                       'Data1.RecordSource = ordsql
                                       'Data1.Refresh
 Set rub1 = Data1.Recordset
 newcogn = Text2.Text              (valori che inserisco nel form di
inserimento)
 newnome = Text3.Text
 criteriodupl = "Cognome = '" & newcogn & "' And Nome = '" & newnome &
"'"     (in questa parte non compare ancora la sub per l'apostrofo)
rub1.FindFirst criteriodupl       ( A questo punto, facendo il debug
passo passo, esce dalla sub, va in "validate", mi chiede se salvare e
poi,
                                               tornando a questa riga,
trova il record e mi chiede, visto che è duplicato, cosa fare...questo
anche se il nominativo non esisteva)
 If Not rub1.NoMatch Then
 Rispcontr = MsgBox("Nominativo esistente. Continuare?", vbYesNo,
"Controllo duplicati")
     If Rispcontr = vbNo Then
     Data1.Recordset.CancelUpdate
     cmdadd.Caption = "Aggiungi"
     Save = False
   Exit Sub
  End If
 If Rispcontr = vbYes Then
    'Salva le modifiche.
    Data1.Recordset.AddNew
    Data1.Recordset.Update
    cmdsalva.Enabled = False
    cmdadd.Caption = "Aggiungi"
    cmdmodif.Caption = "Modifica"
  End If
 End If
End Sub.
Mi spiace rompere le scatole ma è un peccato..risolto sto punto è
tutto apposto, almeno per le esigenze per cui sto cercando di creare
il programma.
Grazie a tutti

 poi,
Allora fai un recordset che ha come Source:
"SELECT * FROM FOGLIO1 WHERE " & criteriodupl
Poi apri il recordset, se non ti ritorna valori allora non esiste alcun
record che non 
Con ado si farebbe:
Dim Rs As ADODB.Recordset
Set Rs = New ADODB.Recordset
Set Rs.ActiveConnection = AdoCN
Rs.Source = "SELECT * FROM FOGLIO1 WHERE " & criteriodupl
Rs.Open
If Not Rs.EOF Then
	'allora esiste già
End If
Rs.Close
Set Rs.ActiveConnection = Nothing
Set Rs = Nothing
Con DAO non ricordo, ma i recordset ci sono. Questo potresti metterlo
direttamente nell'eventuale routine OkInput.
Ovviamente un controllo del genere, su un programma Multi UTENTE potrebbe
dare notevoli problemi (due utenti che inseriscono contemporaneamente lo
stesso nominativo).

Scusate se rispondo solo ora ma mi son potuto dedicare al db solo poco
tempo.
Allora Innanzitutto grazie ad Andrea [work]...la soluzione era proprio
la!
Infatti ho inserito un data2 ad ok per il controllo; il datasource è
una select appunto che richiama il criterio di controllo.
Poi con il recordcount, se è >0 , metto a true una variabile che mi
evidenzia la condizione di record duplicato.
Il tutto in una sub apposita richiamata in fase di esecuzione del
comando salva.
Funziona tutto alla grande.
Grazie ancora e alla prossima