Valor de Autonumérico de la última fila insertada – MS Access / VBA

Tengo una tabla JET con un número automático como clave principal, y me gustaría saber cómo puedo recuperar este número después de insertar una fila. He pensado en usar MAX () para recuperar la fila con el valor más alto, pero no estoy seguro de cuán confiable sería. Algunos ejemplos de código:

Dim query As String Dim newRow As Integer query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");" newRow = CurrentDb.Execute(query) 

Ahora sé que esto no funcionaría, ya que Execute() no devolverá el valor de la clave principal, pero este es básicamente el tipo de código que estoy buscando. Necesitaré usar la clave primaria de la nueva fila para actualizar varias filas en otra tabla.

¿Cuál sería la forma más simple / más legible de hacer esto?

Si DAO usa

 RS.Move 0, RS.LastModified lngID = RS!AutoNumberFieldName 

Si ADO usa

 cn.Execute "INSERT INTO TheTable.....", , adCmdText + adExecuteNoRecords Set rs = cn.Execute("SELECT @@Identity", , adCmdText) Debug.Print rs.Fields(0).Value 

cn es una conexión ADO válida, @@Identity devolverá la última Identity (Autonumérico) insertada en esta conexión.

Tenga en cuenta que @@Identity puede ser problemático porque el último valor generado puede no ser el que le interesa. Para el motor de la base de datos de Access, considere una VIEW que une dos tablas, ambas tienen la propiedad IDENTITY , y INSERT INTO el VIEW . Para SQL Server, considere si hay activadores que a su vez insertan registros en otra tabla que también tiene la propiedad IDENTITY .

BTW DMax no funcionaría como si alguien más insertara un registro justo después de insertar un registro, pero antes de que su función Dmax termine de ejecutarse obtendrá su registro.

En su ejemplo, debido a que usa CurrentDB para ejecutar su INSERT, lo ha hecho más difícil para usted. En cambio, esto funcionará:

  Dim query As String Dim newRow As Long ' note change of data type Dim db As DAO.Database query = "INSERT INTO InvoiceNumbers (date) VALUES (" & NOW() & ");" Set db = CurrentDB db.Execute(query) newRow = db.OpenRecordset("SELECT @@IDENTITY")(0) Set db = Nothing 

Solía ​​hacer agregados abriendo un conjunto de registros AddOnly y recogiendo el ID desde allí, pero esto es mucho más eficiente. Y, tenga en cuenta, Tony, que no requiere ADO.

Esta es una adaptación de mi código para ti. Me inspiré en developpez.com (Busque en la página ” Pour insérer des données, vaut-il mieux passer par un RecordSet ou par une requête de type INSERT? “). Ellos explican (con un poco de francés). De esta manera es mucho más rápido que el superior. En el ejemplo, esta forma fue 37 veces más rápida. Intentalo.

 Const tableName As String = "InvoiceNumbers" Const columnIdName As String = "??" Const columnDateName As String = "date" Dim rsTable As DAO.recordSet Dim recordId as long Set rsTable = CurrentDb.OpenRecordset(tableName) Call rsTable .AddNew recordId = CLng(rsTable (columnIdName)) ' Save your Id in a variable rsTable (columnDateName) = Now() ' Store your data rsTable .Update recordSet.Close 

LeCygne

 Private Function addInsert(Media As String, pagesOut As Integer) As Long Set rst = db.OpenRecordset("tblenccomponent") With rst .AddNew !LeafletCode = LeafletCode !LeafletName = LeafletName !UNCPath = "somePath\" + LeafletCode + ".xml" !Media = Media !CustomerID = cboCustomerID.Column(0) !PagesIn = PagesIn !pagesOut = pagesOut addInsert = CLng(rst!enclosureID) 'ID is passed back to calling routine .Update End With rst.Close End Function