Подтвердить что ты не робот

Значение Autonumber последней вставленной строки - MS Access/VBA

У меня есть таблица JET с автоматическим номером в качестве первичного ключа, и я хотел бы знать, как я могу получить это число после вставки строки. Я думал о том, чтобы использовать MAX() для извлечения строки с наивысшим значением, но я не уверен, насколько это было бы достоверно. Пример кода:

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

Теперь я знаю, что это не сработает, поскольку Execute() не вернет значение первичного ключа, но это в основном тот тип кода, который я ищу. Мне нужно будет использовать первичный ключ новой строки для обновления ряда строк в другой таблице.

Каким будет самый простой/наиболее читаемый способ сделать это?

4b9b3361

Ответ 1

Если 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 (Autonumber), вставленный в это соединение.

Обратите внимание, что @@Identity может быть проблематичным, потому что последнее сгенерированное значение может не быть тем, которое вас интересует. Для механизма базы данных Access рассмотрите VIEW, который объединяет две таблицы, каждая из которых имеет Identity свойство, а вы INSERT INTO VIEW. Для SQL Server рассмотрите, есть ли триггеры, которые в свою очередь вставляют записи в другую таблицу, которая также имеет свойство Identity.

BTW DMax не будет работать так, как если бы кто-то еще вставлял запись сразу после того, как вы вставили запись, но прежде чем ваша функция Dmax закончит excecuting, вы получите свою запись.

Ответ 2

В вашем примере, поскольку вы используете 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 и собирая идентификатор оттуда, но это намного эффективнее. И, обратите внимание, Тони, что он не требует ADO.

Ответ 3

Это адаптация моего кода для вас. Я был вдохновлен developpez.com (Смотрите на странице для: "Pour insérer des données, vaut-il mieux passer par un RecordSet ou par une requête типа 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

Ответ 4

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