Newsgroup: it.comp.lang.delphi
Titolo: problema con la rete

ciao a tutti,
ho realizzato un semplice gestionale adoperando delphi 6 e access mediante
ADO.
il programma mi da problemi se funziona con due pc in rete. Soprattutto
quando entrambi gli utenti utilizzano la stessa tabella del database (mi da
un problema di aggiornamento della tabella) . Come posso risolvere
l'inconveniente? Su ogni pc viene utilizzato un eseguibile diverso che
condividono lo stesso database.
ciao
--

ecco l'errore che viene generato:
'impossibile individuare la riga specificata per l'aggiornamento...'

uso tadotable o tadoquery?
A.

un problema di aggiornamento della tabella) . 
Puoi postare l'errore preciso sollevato dal Jet ?
Come hai impostato le proprieta' della Adotable in questione? il LockType?
Ciao!
Morde.
morde [at] programmer [.] net

 ha scritto nel messaggio
news:rSSU9.36961$AA2.1...@news2.tin.it...

Forse ho capito...
Si tratta dei campi "contatore", suppongo... come fai a incrementare i
contatori?


Questo errore puo' significare che il record sul quale il programma sta cercando di scrivere
non esiste piu'. Fai uso di chiavi primarie autoincrementanti?
Che struttura ha la tabella?


 contatori?
bhe i contatori vengono incrementati direttamente da Access....


adotable.

io proverei a vedere cosa succede usando tadoquery...
Bye
A.

 ha scritto nel messaggio
news:rSSU9.36961$AA2.1...@news2.tin.it...


come risolverlo..
Posta il codice....
Ciao


 ha scritto nel messaggio
news:IWUU9.38068$AA2.1...@news2.tin.it...

Quindi il problema e' sicuramente quello:
Utente A: creo nuovo record, l'ultimo era 450, il nuovo sara' 451.
Utente B: creo nuovo record, l'ultimo era 450, il nuovo sara' 451.
Utente A: eseguo Post, il nuovo record e' 451.
Utente B: eseguo Post, il nuovo record e' 451.
A questo punto in Access i 2 record sono 451 e 452, in Delphi sono entrambi
451. Ok?

 451. Ok?
e come posso ovviare a questo problema???

ecco il codice:
procedure TForm10.FormActivate(Sender: TObject);
begin
edit3.setfocus;
edit1.Text:='1,00';
edit2.Text:='';
edit4.Text:='';
CHECKBOX1.checked:=true;
checkbox2.checked:=false;
checkbox3.Checked:=false;
checkbox4.Checked:=false;
form1.ADOTable2.Active:=false;
form1.adotable1.active:=false;
form1.adotable5.active:=false;
form1.adotable2.active:=true;
form1.adotable1.active:=true;
form1.adotable5.active:=true;
button1.enabled:=false;
button3.Enabled:=false;
form1.adotable5.First;
while not form1.adotable5.Eof do
form1.adotable5.Delete;
end;
( quando clicco su button1 ed entrambi gli utenti utilizzano lo stesso form,
si genera l'errore)
procedure TForm10.Button1Click(Sender: TObject);
 var sottrazione:real;
begin
form1.edit6.Text:='';
form1.adotable5.First;
if checkbox3.Checked then begin
(* form di fatturazione *)
form25.adotable1.Append;
form25.ADOTable1.FieldByName('numerofattura').asinteger:=
form25.ADOTable3.Fi
eldByName('numerofattura').asinteger;
form25.ADOTable3.Edit;
form25.ADOTable3.FieldByName('numerofattura').AsInteger:=
form25.ADOTable3.Fi
eldByName('numerofattura').AsInteger+1;
form25.ADOTable3.Post
;
form25.ADOTable1.FieldByName('datafattura').asdatetime:=date;
form25.adotable1.Post
;
end;
if checkbox4.Checked then begin
form1.adotable11.active:=true;
form1.ADOTable11.append;
form1.ADOTable11numero.Value:=form1.adotable13numeropreventivo.Value;
form1.ADOTable11.FieldByName('datapreventivo').asdatetime:=date;
form1.ADOTable11.post
;
form1.adotable13.Edit;
form1.adotable13numeropreventivo.Value:=form1.adotable13numeropreventivo.Val
ue+1;
form1.ADOTable13.Post
;
end;
while not form1.adotable5.eof do
 begin
if
form1.ADOTable2.Locate('barcode',form1.ADOTable5.FieldByName('codicearticolo
').Asstring,[]) then
begin
form1.ADOTable2.edit;
sottrazione:=(form1.adotable2.fieldbyname('qntprodotto').asfloat)-(form1.ado
table5.fieldbyname('qnt').asfloat);
form1.ADOTable2.fieldbyname('qntvendute').Asfloat:=(form1.ADOTable2.fieldbyn
ame('qntvendute').Asfloat)+(form1.adotable5.fieldbyname('qnt').asfloat);
form1.adotable2.fieldbyname('qntprodotto').asstring:=floattostr(sottrazione)
;
form1.adotable2.post
;
end;
if checkbox2.Checked then begin
form1.ADOTable1.Append;
form1.ADOTable1.FieldByName('data').AsDateTime:=date;
form1.ADOTable1.FieldByName('descriz').Asstring:='Vendita '+
form1.ADOTable5.FieldByName('descrizione').Asstring+' -
[Qnt.]:'+form1.adotable5.FieldByName('qnt').asstring+' - [Prezzo iva
comp.]:'+form1.adotable5.FieldByName('prezzounitario').asstring+' ?';
form1.ADOTable1.FieldByName('entrata').Asstring:=form1.adotable5.FieldByName
('totale').asstring;
form1.adotable1.post
;
 end;
if checkbox3.checked then begin
 form25.adotable2.append;
form25.adotable2.FieldByName('id_articolo').AsString:=form25.adotable1.field
byname('id').asstring;
form25.adotable2.fieldbyname('codicearticolo').asstring:=form1.adotable5.fie
ldbyname('codicearticolo').asstring;
form25.adotable2.fieldbyname('descrizione').asstring:=form1.adotable5.fieldb
yname('descrizione').asstring;
form25.adotable2.fieldbyname('qnt').asfloat:=form1.adotable5.fieldbyname('qn
t').asfloat;
form25.adotable2.fieldbyname('prezzounitario').asstring:=form1.adotable5.fie
ldbyname('prezzoalpubblico').asstring;
form25.adotable2.fieldbyname('importototale').asfloat:=(form25.adotable2.fie
ldbyname('prezzounitario').asfloat)*(form25.adotable2.fieldbyname('qnt').asf
loat);
form25.ADOTable2.FieldByName('iva').asinteger:=form1.adotable5.fieldbyname('
iva').AsInteger;
form25.ADOTable2.FieldByName('um').asstring:=form1.adotable5.fieldbyname('um
').Asstring;
 
form25.ADOTable2.post
;
 end;
 if checkbox4.checked then begin
 form1.ADOTable12.Active:=true;
 form1.adotable12.append;
form1.adotable12.FieldByName('id_articolo').AsString:=form1.adotable11.field
byname('id').asstring;
form1.adotable12.fieldbyname('codicearticolo').asstring:=form1.adotable5.fie
ldbyname('codicearticolo').asstring;
form1.adotable12.fieldbyname('descrizione').asstring:=form1.adotable5.fieldb
yname('descrizione').asstring;
form1.adotable12.fieldbyname('qnt').asfloat:=form1.adotable5.fieldbyname('qn
t').asfloat;
form1.adotable12.fieldbyname('prezzounitario').asstring:=form1.adotable5.fie
ldbyname('prezzoalpubblico').asstring;
form1.adotable12.fieldbyname('importototale').asfloat:=(form1.adotable12.fie
ldbyname('prezzounitario').asfloat)*(form1.adotable12.fieldbyname('qnt').asf
loat);
form1.ADOTable12.FieldByName('um').asstring:=form1.adotable5.fieldbyname('um
').Asstring;
 
form1.ADOTable12.post
;
 end;
form1.adotable5.next;
end;
close;
form1.adotable1.Refresh;
if checkbox3.checked then begin
form25.ADOTable1.Refresh;
form25.ADOTable2.Refresh;
form25.ShowModal;
end;
if checkbox4.checked then begin
form1.ADOTable11.Refresh;
form1.ADOTable12.Refresh;
form40.ShowModal;
end;
 end;

 ha scritto nel messaggio
news:kZbV9.44261$AA2.1...@news2.tin.it...

- Cambiando database e utilizzando un server (Interbase, per esempio), e
gestendo i contatori esplicitamente.
- Utilizzando un campo numerico come chiave primaria e incrementandolo da
programma.
- Bloccando le tabelle quando leggi o scrivi. (anche se mi sembra strano che
non lo faccia Access).
E comunque non prendere per buono al 100% quello che ti dico, e' solo una
mia ipotesi... magari qualcuno che ne sa piu' di me sa darti qualche
consiglio migliore.

 e come posso ovviare a questo problema???
Il campo contatore in genere viene valorizzato ad ogni nuovo record.
Dipende da cosa devi fare ed a cosa ti serve il campo, ma in generale ti
conviene calcolartelo e valorizzarlo nell'evento BeforePost della tabella,
solo dopo aver eventualmente eseguito tutte le validazioni.
SELECT MAX(campo_contatore) FROM tabella
e poi assegni al tuo campo il valore trovato incrementato di 1.
Ciao.
Gianluca.

 [...]
Azz.... non è di facile comprensione, comunque:
Aggiungi le transazioni (usi forse access 97?)
Aggiungi i try, nel caso ci sia l'eccezione fai rollback e dai la possibilità di ripetere l'operazione.
Fai uso di Adoquery per il contatore fattura (vedi post di Plevani stesso thread)
Ti chiedo ancora: come hai impostato il locktype delle tabelle?
Se ti va, puoi mandarmi in privato uno zippone col tuo programma con anagrafiche vuote o riempite
al minimo, vedo se riesco a fare qualcosa.... ma non ti garantisco nulla, sono preso da tante cose
pero' prima o dopo un'occhiata la darò...


"schumi83" ha scritto
[...]
Mi era sfuggito si trattasse di fatturazione.
In questo caso conviene (e piu o meno č uno standard) ti gestisci un
contatore separato in un'altra tabella.
Ciao.
Gianluca.

 Ti chiedo ancora: come hai impostato il locktype delle tabelle?
scusa...ma cos'è il locktype?? ;-)) come lo imposto?
ciao

 contatore separato in un'altra tabella.
in effetti già utilizzo una tabella separata...il campo numero fattura è un
campo intero. La tabella è relazionata tramite il campo ID (contatore)...

 campo intero. La tabella è relazionata tramite il campo ID (contatore)...
Non so se può venirti utile la mia esperienza personale.
Utilizzando i controlli DataAware, io in genere impegno immediatamente l'ID
del record salvandolo quando l'Utente usa l'opzione "nuova fattura". Durante
questo salvataggio uso uno specifico contatore che gestisco in genere come
ho scritto in qualche post precedente sempre in questo thread.
Ovviamente immediatamente apro lo stesso record in modifica e l'utente ha
comunque l'impressione di inserire un nuovo record. In questo modo anche
tutte le tabelle di dettaglio hanno già un riferimento al master e non ci
sono problemi di sorta.
Se poi l'Utente salva, sono a posto e salvo il record. Se invece annulla,
invece di annullare le modifiche semplicemente cancello il record corrente e
tutti i correlati. E' poco codice in piu, ma mi è sempre sembrato abbastanza
sicuro.
Visto che poi non ci dovrebbe essere motivo per cui l'ID sia effettivamente
un contatore e segua un progressivo, potresti pure generarlo casualmente: ho
visto un esempio carino di Cantu dove, per risolvere definitivamente (e
sicuramente così è DEFINITIVO) i conflitti, usa come chiave primaria un GUID
generato al volo prima di salvare il record.
Ciao.
Gianluca.

generato al volo prima di salvare il record.
Sono fortemente interessato a questo esempio!!!
Dove si trova?
Ciao!
