Как получить идентификатор недавно вставленной записи с помощью Excel VBA?

Нет, это не имеет ничего общего с кодированием. Это потому, что у вас есть ссылка на сущность í, которая нигде не определена. Если бы это был HTML, это имя сущности было бы встроено, но это не относится к XML. Помимо нескольких сущностей, таких как amp и lt, ссылки на сущности в XML не распознаются, если они не определены в DTD.

8
задан Renaud Bompuis 30 May 2009 в 12:05
поделиться

4 ответа

О Вашем вопросе:

Я теперь пытаюсь обновить таблицу, которая не имеет большого объема для уникальности, кроме в искусственном первичном ключе. Это означает, что существует риск, что новая запись не может быть уникальной, и я, ненавидят для добавления поля только для принуждения уникальности.

Если Вы используете AutoIncrement для своего первичного ключа, то у Вас есть уникальность, и Вы могли использовать SELECT @@Identity; получить значение последнего автоматически сгенерированного идентификатора (см. протесты ниже).

Если Вы не используете автоинкремент, и Вы вставляете записи от Доступа, но Вы хотите получить последний от Excel:

  • удостоверьтесь, что Ваш первичный ключ является поддающимся сортировке, таким образом, можно получить последний с помощью запроса как любой из них:

    SELECT MAX(MyPrimaryField) FROM MyTable;
    SELECT TOP 1 MyPrimaryField FROM MyTable ORDER BY MyPrimaryField DESC;
    
  • или, если сортировка Вашего основного поля не дала бы Вам последнее, необходимо будет добавить, поле DateTime (сказать InsertedDate) и сохраните текущую дату и время каждый раз, когда Вы создаете новую запись в той таблице, таким образом, Вы могли получить последний как это:

    SELECT TOP 1 MyPrimaryField FROM MyTable ORDER BY InsertedDate DESC;
    

В любом из этих случаев я думаю, что Вы нашли бы добавление первичного ключа AutoIncrement, как являющегося намного легче иметь дело с:

  • Это не собирается стоить Вам очень

  • Это собирается гарантировать Вам уникальность Ваших записей, не имея необходимость думать об этом

  • Это собирается помочь Вам выбрать новую запись, любое использование @@Identity или посредством сортировки по первичному ключу или получения Max().

От Excel

Для получения данных в Excel у Вас есть несколько вариантов:

  • создайте канал передачи данных с помощью запроса, таким образом, можно использовать результат непосредственно в Ячейке или диапазоне.

  • запрос от VBA:

    Sub GetLastPrimaryKey(PrimaryField as string, Table as string) as variant
        Dim con As String
        Dim rs As ADODB.Recordset
        Dim sql As String
        con = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
              "Data Source= ; C:\myDatabase.accdb"
        sql = "SELECT MAX([" & PrimaryField & "]) FROM [" & MyTable & "];"
        Set rs = New ADODB.Recordset
        rs.Open sql, con, adOpenStatic, adLockReadOnly
        GetLastPrimaryKey = rs.Fields(0).Value
        rs.Close
        Set rs = Nothing
    End Sub
    

Отметьте о @@Identity

Необходимо остерегаться протестов при использовании @@Identity в стандартных базах данных Access (*):

  • Это только работает с полями AutoIncrement Identity.

  • Это только доступно, если Вы используете ADO и работаете SELECT @@IDENTITY;

  • Это возвращает последний используемый счетчик, но это для всех таблиц. Вы не можете использовать его для возврата счетчика для определенной таблицы в Доступе MS (насколько я знаю, если Вы указываете использование таблицы FROM mytable, это просто проигнорировано).
    Короче говоря, возвращенное значение не может быть во всем том, которое Вы ожидаете.

  • Необходимо запросить его прямо после INSERT минимизировать риск получения неправильного ответа.
    Это означает, что, если Вы вставляете свои данные когда-то и должны получить последний идентификатор в другое время (или другое место), это не будет работать.

  • Наконец, что не менее важно, переменная установлена только, когда записи вставляются через код программы.
    Это означает, что это - запись, был добавлен через пользовательский интерфейс, @@IDENTITY не будет установлен.

(*): только быть ясным, @@IDENTITY ведет себя по-другому, и более прогнозирующим способом, если Вы используете режим ANSI 92 SQL для своей базы данных.
Проблема, хотя тот ANSI 92, имеет немного отличающийся синтаксис, чем аромат ANSI 89, поддерживаемый Доступом, и предназначена для увеличения совместимости с SQL Server, когда Доступ используется в качестве фронтэнда.

13
ответ дан 5 December 2019 в 07:13
поделиться

Попробуйте после макро-кода. Сначала добавьте кнопку к листу от блока управления и вставки после кодов в окне кода

Private Sub CommandButton1_Click()
    MsgBox GetLastPrimaryKey
End Sub

Private Function GetLastPrimaryKey() As String
Dim con As String
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql As String
con = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\myaccess.mdb;Persist Security Info=False"
sql = "SELECT MAX(id) FROM  tblMyTable"

Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
cn.Open con
rs.Open sql, cn, 3, 3, 1
If rs.RecordCount <> 0 Then
   GetLastPrimaryKey = rs.Fields(0).Value
End If
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Function
0
ответ дан 5 December 2019 в 07:13
поделиться

Если искусственный ключ является автонумерацией, можно использовать @@ идентификационные данные.

Обратите внимание, что с обоими этими примерами, транзакция изолируется от других событий, таким образом, возвращенные идентификационные данные являются тем, просто вставленным. Можно протестировать это путем приостановки кода при Отладке. Дб печати. RecordsAffected или Отладка. Распечатайте lngRecs и вставку записи вручную в Table1, продолжите код и обратите внимание, что возвращенные идентификационные данные не являются идентификационными данными записи, вставленной вручную, но предыдущей записи, вставленной кодом.

Пример ДАО

'Reference: Microsoft DAO 3.6 Object Library '
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb

db.Execute ("INSERT INTO table1 (field1, Crdate ) " _
            & "VALUES ( 46, #" & Format(Date, "yyyy/mm/dd") & "#)")
Debug.Print db.RecordsAffected
Set rs = db.OpenRecordset("SELECT @@identity AS NewID FROM table1")
Debug.Print rs.Fields("NewID")

Пример ADO

Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset

Set cn = CurrentProject.Connection

cn.Execute ("INSERT INTO table1 (field1, Crdate ) " _
            & "VALUES ( 46, #" & Format(Date, "yyyy/mm/dd") & "#)"), lngRecs
Debug.Print lngRecs
rs.Open "SELECT @@identity AS NewID FROM table1", cn
Debug.Print rs.Fields("NewID")
7
ответ дан 5 December 2019 в 07:13
поделиться

Ре: "Я попытался добраться @@ работа ИДЕНТИФИКАЦИОННЫХ ДАННЫХ, но это всегда возвращает 0 использующих кода ниже".

Ваш код отправляет SQL и SQL2 через различные объекты соединения. Я не думаю @@identity возвратит что-либо кроме нуля, если Вы не спрашиваете от того же соединения, где Вы выполнили Ваш INSERT оператор.

Попытайтесь изменить это:

myRecordset.Open SQL2, dbConnectionString, adOpenStatic, adLockReadOnly

кому:

myRecordset.Open SQL2, databaseConnection, adOpenStatic, adLockReadOnly
3
ответ дан 5 December 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: