Управляемый событиями макрос данных для вычисления поля в новой записи - MS Access
В MS Access 2013 у меня есть таблица с именем [Serials], которая состоит только из 3 столбцов: [ID], [Hashed ID] и [Product Description].
[ID] является инкрементным целочисленным Autonumber и первичным ключом. [Hashed ID] содержит результат хеш-функции, примененной к [ID]. Наконец, [Product Description] содержит вводимые пользователем данные (функция хеширования сохраняется в модуле VBA как общедоступная функция).
Я хотел бы, чтобы поле [Hashed ID] вычислялось автоматически после вставки строки в таблицу [Serials].
Я предполагаю, что хитрость заключается в правильном использовании макросов данных, управляемых событиями, для этой таблицы, но мне удалось выполнить эту работу только с помощью события "До изменения" в уже вставленных строках (следовательно, с сохраненным значением на их поле [ID]?) . Я потерялся!!!
2 ответа
Что ж, мне удалось найти приемлемое решение!
Прежде всего, похоже, что в MS Access, когда для таблиц используются управляемые событиями макросы данных, НЕВОЗМОЖНО НЕПОСРЕДСТВЕННО ссылаться на значение поля Autonumber до тех пор, пока оно не будет полностью вставлено и сохранено в БД (это не случай других типов полей). При передаче в качестве параметра он всегда будет возвращать значение NULL.
При этом мы можем ссылаться на CURRENT SEED NUMBER для любого поля Autonumber с помощью пользовательской функции VBA (спасибо HansUp за это сообщение):
Public Function NEXTAUTONUM(ByVal pTable As String, ByVal pColumn as String) As Long
Dim CAT As Object
Set CAT = CreateObject("ADOX.Catalog")
Set CAT.ActiveConnection = CurrentProject.Connection
NEXTAUTONUM = CAT.Tables(pTable).Columns(pColumn).Properties("Seed")
Set CAT = Nothing
End Function
NEXTAUTONUM вернет значение Autonumber, которое Access установит следующим в поле [ID], если будет вставлена новая строка, что и требуется HASH FUNCTION в качестве входного параметра. Теперь мы можем создать наш макрос данных в событии Before Change, которое должно выглядеть следующим образом:
If [IsInsert] = True Then
Set Field
Name Hashed ID
Value = HASHFUNCTION ( NEXTAUTONUM ( "Serials","ID" ) - 1 )
End If
Кроме того, мы вычитаем 1 из значения, возвращаемого функцией NEXTAUTONUM, потому что нам нужно значение [ID] Autonumber для строки, над которой мы сейчас работаем, а не то, которое будет создано следующим.
Надеюсь, это поможет кому-то!
Это проверено на Access 2016. Я обнаружил ситуацию, когда вы получаете значение NULL при чтении поля внутри макроса данных BeforeChange. Это происходит, если это поле является ПЕРВИЧНЫМ КЛЮЧОМ. Это не AutoNumber. Таким образом, проблема возникает, когда у вас есть эта комбинация:
- Событие BeforeChange
- ВСТАВИТЬ действие (только)
- ПЕРВИЧНЫЙ КЛЮЧ
Простое решение состоит в том, чтобы изменить ПЕРВИЧНЫЙ КЛЮЧ на УНИКАЛЬНЫЙ.