最后插入行的自动编号值 - MS Access / VBA

时间:2009-10-27 01:18:28

标签: ms-access vba jet

我有一个JET表,其中有一个自动编号作为主键,我想知道如何在插入行后检索此编号。我曾想过使用MAX()来检索具有最高值的行,但我不确定这将是多么可靠。一些示例代码:

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

现在我知道这不起作用,因为Execute()不会返回主键的值,但这基本上就是我要寻找的那种代码。我将需要使用新行的主键来更新另一个表中的多个行。

这样做最简单/最易读的方法是什么?

5 个答案:

答案 0 :(得分:45)

在您的示例中,因为您使用CurrentDB来执行INSERT,所以您自己更难。相反,这将起作用:

  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

我曾经通过打开AddOnly记录集并从那里获取ID来进行INSERT,但这里的效率要高得多。请注意,它不需要ADO

答案 1 :(得分:37)

如果DAO使用

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

如果ADO使用

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

cn是有效的ADO连接,@@Identity将返回最后一个 Identity(自动编号)已插入此连接。

请注意,@@Identity可能很麻烦,因为上一个生成的值可能不是您感兴趣的值。对于Access数据库引擎,请考虑连接两个表的VIEW,这两个表都有IDENTITY属性,INSERT INTO VIEW。对于SQL Server,请考虑是否有触发器将记录插入另一个也具有IDENTITY属性的表中。

BTW DMax无法像其他人在您插入记录之后插入记录一样,但在Dmax功能完成优惠之前,您将获得他们的记录。

答案 2 :(得分:4)

这是我的代码改编。我受到了developpez.com的启发(在页面中查找:“Pourinsérerdesdonnées,vaut-il mieux passer par un RecordSet ou parrequuequêtedetype INSERT?”)。他们解释说(用一点法语)。这种方式比一个鞋面快得多。在这个例子中,这种方式快了37倍。试试吧。

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

答案 3 :(得分:2)

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

答案 4 :(得分:0)

以上两个示例都不适合我。在表上打开记录集并添加记录确实可以添加记录,除了:

myLong = CLng(rs!AutoNumberField)
如果

放在rs.AddNew和rs.Update之间,则返回Null。如果放在rs.Update之后,它确实会返回某些内容,但这总是错误的,并且始终具有相同的错误值。添加新记录后直接查看该表将显示一个自动编号字段值,该值不同于上述语句返回的值。

myLong = DLookup("AutoNumberField","TableName","SomeCriteria")

只要在rs.Update之后完成,它就可以正常工作,并且还有任何其他字段可以唯一地标识记录。