set db = currentdb
set tb = db.openrecordset("tabella")
with tb
.addnew
.fields("campo1") = textbox1
.....
.update
end with
Ora poichè devo inserire dei dati anche in un'altra tabella, mi
occorre sapere l' ID dell'ultimo record inserito
poichè lo devo inserire nel campo di un'altra tabella.
Gli esempi che ho letto sfruttano l'SQL select @@IDENTITY as lastID
from tabella
ma questo funziona solo se l'inserimento viene fatto con un'istruzione
INSERT di SQL
come posso risolvere?
grazie
<andr...@gmail.com> ha scritto nel messaggio
news:46a2e645-1ae2-427b...@n21g2000vba.googlegroups.com...
ciao a tutti
utilizzo VBA per inserire il contenuto delle textbox di una maschera
in una tabella
set db = currentdb
set tb = db.openrecordset("tabella")
with tb
.addnew
.fields("campo1") = textbox1
.....
.update
end with
Ora poich� devo inserire dei dati anche in un'altra tabella, mi
occorre sapere l' ID dell'ultimo record inserito
poich� lo devo inserire nel campo di un'altra tabella.
Gli esempi che ho letto sfruttano l'SQL select @@IDENTITY as lastID
from tabella
ma questo funziona solo se l'inserimento viene fatto con un'istruzione
INSERT di SQL
come posso risolvere?
grazie
>>>>>>>>>>>RISPOSTA>>>>>>>>>>>>>>
Ciao Andros976,
@@IDentity pu� essere usato anche con DB Jet e non solo SQL Server
vedi in proosito questo articolo di Giorgio Rancati
http://www.riolab.org/viewrisorsa.asp?id=1
Nel tuo caso per�, dopo l'update puoi leggere il valore assunto dal
campo Identity semplicemente facendo:
id = .fields("CampoID")
--
Cinzia [Office Access MVP]
_______________________
www.riolab.org
http://accessdaziacin.spaces.live.com
----------------------------------------
ciao cinzia grazie della risposta
avevo già provato quello che tu mi dici ma si comporta in maniera
anomala.
With tb_contatti
.AddNew
.Fields("OPERATORE") = ope
.................
.Update
ids = .Fields("ID")
End With
If pulsante_assegna = -1 Then
With tb_trattative
.AddNew
.Fields("ID_CONTATTO") = ids
............
.Update
End With
End If
alla prima esecuzione, nel punto dell'assegnazione
ids = .fields("ID") mi dice nessun record corrente
poi termino l'esecuzione dello script , chiudo la maschera e la riapro
e non mi da errori, l'unico problema è che
ids = .fields("ID") contiene sempre il numero 1
infatti andando a vedere nel db la prima tabella è scritta
regolarmente, la seconda chiaramente no.
perchè si comporta così, ho sbagliato qualcosa
grazie
ciao
>set db = currentdb
>set tb = db.openrecordset("tabella")
>with tb
>.addnew
>.fields("campo1") = textbox1
>.....
>.update
>end with
>Ora poich� devo inserire dei dati anche in un'altra tabella, mi
>occorre sapere l' ID dell'ultimo record inserito
[CUT]
Ciao,
dopo l'update riposiziona il bookmark del recordset sull'ultimo record
modificato/inserito
----
...
...
.update
.Bookmark = .LastModified
'* fatto questo puoi conoscere l'ID inserito
Debug.print .fields("ID")
end with
----
trovi tutti i detagli nel manuale VBA di Access cercando "LastModified"
Ciao
--
Giorgio Rancati
[Office Access MVP]
Ciao Giorgio,
anch'io da sempre uso LastModified per questo scopo, ma quest'anno
in una discussione ho imparato che leggere il nuovo valore del contatore
funziona anche prima dell'Update:
.addnew
.fields("campo1") = textbox1
Debug.print .fields("ID")
.update
Non mi sono mai accorto prima.
--
cu
Karl
*********
Access FAQ: www.donkarl.com/it
Posso essere d'accordo con te che .update posiziona il puntatore del
recordset sull'ultimo record modificato
ma allora perchè la porzione di codice che ho scritto
.Update
ids = .Fields("ID")
mi dice nessun record corrente ?
No, questo non ho scritto e anche non sono d'accordo.
Credo che fra AddNew ed Update ci troviamo in un tipo di cache.
Un Udate dopo AddNew posiziona il cursore al primo record del
recordset o in caso che non ci sono record a EOF.
> ma allora perch� la porzione di codice che ho scritto
>
> .Update
> ids = .Fields("ID")
>
> mi dice nessun record corrente ?
Perch� tenti di leggere l'ID _dopo_ l'Update (invece di prima come
l'ho scritto io) e molto probabile il tuo recordset non ha altri record.
In questo caso il cursore si trova a EOF --> il messaggio di errore.
--
HTH
>Posso essere d'accordo con te che .update posiziona il puntatore del
>recordset sull'ultimo record modificato
no, non intendevo dire questo :-)
lo riscrivo in modo pi� esplicito.
----
dopo l'update (Tu tramite .Bookmark=.LastModified) riposiziona il bookmark
del recordset sull'ultimo record
modificato/inserito
----
>ma allora perch� la porzione di codice che ho scritto
>.Update
>ids = .Fields("ID")
>mi dice nessun record corrente ?
perch� dopo l'update il record non � posizionato sull'ultimo inserito.
:-)
Ciao Karl,
s�, vero perch� con database Mdb, Jet legge il prossimo ID prima dell'Update
come succede nelle maschere.
Per� questo metodo non funziona se si usa tabelle allegate a Database Server
dove l'ID viene recuperato solo dopo aver scritto il record.
:-)
Io mi trovo nella situazione di tabelle collegate tramite ODBC.
Vorrei pertanto sapere quand'è che viene scritto il record ?
con .update oppure già con l'assegnazione .fields() = valore
faccio delle prove e vi faccio sapere
per il momento grazie del supporto a tutti e due
ciao
>Io mi trovo nella situazione di tabelle collegate tramite ODBC.
>Vorrei pertanto sapere quand'� che viene scritto il record ?
>con .update oppure gi� con l'assegnazione .fields() = valore
Ciao,
Il server assegna l'identity quando scrive il record, quindi per forza di
cose dopo l'istruzione update.
Per essere precisi il valore dell'Id viene recuperato da Jet tramite il
comando di resync inviato dopo l'insert fisico del record.
Se stai usando Sql Server e hai l'utilit� Profiler, puoi aprire una traccia
e vedere qualcosa di simile a:
----
exec sp_executesql N'INSERT INTO "dbo"."Tabella2" ("Campo1") VALUES
(@P1)',N'@P1 nvarchar(255)',N'aaaa'
SELECT @@IDENTITY
exec sp_prepexec @p1 output,N'@P1 int',N'SELECT "Id","Campo1" FROM
"dbo"."Tabella2" WHERE "Id" = @P1',1
----
Ciao
Dim temp As Variant
...
With tb_contatti
.AddNew
...........
.Update
.Bookmark = .LastModified
temp = .Bookmark
end with
If pulsante_assegna = -1 Then
tb_contatti.Bookmark = i
With tb_trattative
.AddNew
* .Fields("ID_CONTATTO") = tb_contatti.Fields("ID").Value
.Update
End With
End If
cosa sto sbagliando mi dice record eliminato al'istruzione con *
abbiate pazienza.....
ho trascritto male l'istruzione tb_contatti.Bookmark = i
tb_contatti.Bookmark = temp
il risultato non cambia
...
>ho trascritto male l'istruzione tb_contatti.Bookmark = i
>tb_contatti.Bookmark = temp
Se provi a fare:
----
With tb_contatti
.AddNew
...........
.Update
.Bookmark = .LastModified
MsgBox .Fields("ID").Value
end with
----
ti da errore ?
Se la risposta � s�: La tabella tb_contatti ha un trigger che inserisce
record in qualche altra tabella ?
o anche:
----
ACC2000: Linked SQL Server Table That Uses BigInt Data Type as Primary Key
Displays #Deleted
http://support.microsoft.com/kb/321901
----
Ciao giorgio innanzitutto grazie per la disponibilità.
Ieri ho fatto delle prove ed è emerso questo:
se lavoro con tabelle locali, funziona tutto. se lavoro con tabelle
collegate tramite ODBC mi da il problema.
Il mio db è un db MySQL i campi indice si della tabella contatti che
trattative sono di tipo INT UNSIGNED.
tali campi vengono visti da access di tipo numerico (non contatore) e
dimensione intero
ti dico anche che il mio codice non fa altro che andare a inserire i
dati prima nella tabella contatti e poi rilevando l'id
dell'inserimento ultimo lo inserisce nella tabella trattative.
Non so se ci troviamo di fronte ad un caso di non compatibilità tra
prodotti (non essendo microsoft entrambi) e se magari c'è qualche
altro modo per aggirare il problema. che dici?
grazie
ciao
mi da errore di runtime 3167 record eliminato
ho fatto qualche ricerca
http://support.microsoft.com/?kbid=208799
sono infatti nel caso in cui inserendo il nuovo record, non assegno
l'id
pertanto se dopo lo vado a recuperare e mi da l'errore. ho provato
come dice l'articolo ad inserire
Set tb_contatti = DB.OpenRecordset("CONTATTI", dbOpenDynaset,
dbSeeChanges)
Set tb_trattative = DB.OpenRecordset("TRATTATIVE", dbOpenDynaset,
dbSeeChanges)
ma non cambia nulla.
mi trovo anche nella condizione di gestione dati tramite ODBC
http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B172339
"Indexes on non-standard datatypes or floating point datatypes. Some
server datatypes have no ODBC or Jet engine equivalent datatype. In
most cases, the Recordset is created as read-only, but sometimes it is
not. Rounding or conversion errors on the datatypes can cause the
error as well."
non ho però ben capito la risoluzione
una delle tre dice
"Refresh the recordset after every edit or addnew or execute operation
that affects the data in the recordset. The Jet engine will rebuild
the keyset with the updated information. "
come faccio a fare il refresh?
che dici
ciao
andrea
>Ciao giorgio innanzitutto grazie per la disponibilit�.
>Ieri ho fatto delle prove ed � emerso questo:
>se lavoro con tabelle locali, funziona tutto. se lavoro con tabelle
>collegate tramite ODBC mi da il problema.
>Il mio db � un db MySQL i campi indice si della tabella contatti che
>trattative sono di tipo INT UNSIGNED.
>tali campi vengono visti da access di tipo numerico (non contatore) e
>dimensione intero
[CUT]
bene, cominciano ad arrivare informazioni :-)
La tabella conttti ha un campo di tipo timestamp ?
Se non c'� aggiungilo fai lo stesso per tutte le alre tabelle.
Qui un link che potrebbe esserti utile.
----
20.1.7.2.1. Using Connector/ODBC with Microsoft Applications
http://dev.mysql.com/doc/refman/5.0/en/connector-odbc-usagenotes-apptips.html#connector-odbc-usagenotes-apptips-microsoft-access
l'altra "For Access 2.0, you should additionally enable the Simulate
ODBC 1.0 option."
NON l'ho trovata !
avevo tentato anche quello di fare il refresh del recordset prima di
richiamare il campo di un record
aggiungendo .movelast dopo .update
niente sempre stesso problema..
disperato
umm proseguiamo con le indagini:
Se apri la tabella dall'applicazione Access (in Tabelle doppio click sulla
tabella allegata) e inserisci un record ti viene visualizzato #cancellato#
??
altra cosa:
hai scritto che utilizzi per l'ID un campo di tipo INT UNSIGNED, Access non
ha nessun tipo equivalente a INT UNSIGNED.
Prova a modificare il campo ID in INT SIGNED che equivale a "Intero Lungo"
di Access.
ps. come avrai capito non ho mai lavorato con MySql quindi vado per
associazioni
andrea
dici ?
facendo una ricerca con google ho visto altri post simili al tuo.
----
mySQL/ODBC/Microsft Access problems
http://lists.mysql.com/mysql/1095
----
potrebbe anche essere la configurazione del DSN, vedi parametro "Option =
3" per Microsoft Access, Visual Basic.
----
20.1.4.2. Connector/ODBC Connection Parameters
http://dev.mysql.com/doc/refman/5.0/en/connector-odbc-configuration-connection-parameters.html
----
>nel weekend cercher� di fare altre prove
>ti tengo aggiornato.
Ok :-)
>grazie per l'aiuto che mi stai dando
prego
Per quanto riguarda l'opzione del DSN suggeritami da te
"potrebbe anche essere la configurazione del DSN, vedi parametro
"Option =
3" per Microsoft Access, Visual Basic. "
vorrei andarlo a settare ma non esiste nei parametri del DSN . a te
risulta!
andrea
Access non c'entra nulla, con tabelle allegate a MS Sql Server non si
presenta il problema da te riscontrato.
Credo sia un Bug di MySql.
Prova a vedere Qui.
----
Bug #10910
Access shows #Deleted for records inserted with NULL values
http://bugs.mysql.com/bug.php?id=10910
----
forse devi solo aggiornare il Driver ODBC di MySql.
adesso cerco di andare avanti e di vedere se si verificano altri bug
anomali.
ti ringrazio molto per l'aiuto , ho visto che sei una persona
competente in materia.;-)
avrei altre domande su access ....
andrea