2015-03-05 6 views
1

В MS Access 2013 У меня есть таблица под названием [Сериалы], который состоит только из 3-х колонка: [ID], [Hashed ID] и [Описание продукта].Event Driven Data Macro для расчета поля в Новой записи - MS Access

[ID] - это инкрементный целочисленный автономный номер и первичный ключ. [Hashed ID] содержит результат функции хеширования, примененной к [ID]. Наконец, [Product Description] содержит пользовательский ввод (функция Hash хранится в модуле VBA в качестве публичной функции).

Что я хотел бы сделать, так это иметь поле [Hashed ID], рассчитанное автоматически после того, как строка будет вставлена ​​в таблицу [Serials].

Я полагаю, что трюк заключается в правильном использовании Макросов данных, управляемых событиями для этой таблицы, но мне удалось выполнить эту работу только с помощью события «Перед изменением» в уже вставленных строках (Следовательно, с сохраненное значение в поле [ID]?). Я потерялся!!!

+0

ОБНОВЛЕНИЕ: Я продолжал играть с событием «Перед изменением» и использовал его для копирования всех вставленных значений в записи на разные пустые столбцы в той же строке. Все они были скопированы, ЗА ИСКЛЮЧЕНИЕМ [ID] КОЛОНКА, которая, по-видимому, просто выбрасывает значение NULL. Может ли быть, что АВТОНОМБЕРЫ или ПЕРВЫЕ КЛЮЧИ НЕ ДЕЙСТВИТЕЛЬНО «ВСТАВЛЕНЫ» на столе, пока все события не будут обработаны? –

+1

Да, к сожалению, когда макрос данных «Перед изменением» запускается, когда вставлена ​​строка, он «видит» значение поля AutoNumber как «Null». Это несмотря на то, что Access уже получил следующее значение AutoNumber и может даже отображать его (например, в представлении Datasheet). Поэтому макрос данных, управляемый событиями, может оказаться непригодным по назначению. –

+0

Спасибо за комментарий! Тот факт, что он показан в представлении Datasheet, делает его настолько антиинтуитивным. Пожалуйста, просмотрите мой ответ ниже, это может быть не идеальное решение, но я думаю, что это эффективный обходной путь! –

ответ

0

Ну, мне удалось найти приемлемое решение!

Прежде всего оказывается, что в MS Access, когда один использует Event Driven Data Макросы для таблиц, это НЕВОЗМОЖНО к НАПРЯМУЮ ссылка значение поля счетчика до после того, как он был полностью вставлен и сохранен на БД (это не относится к другим типам полей). При передаче в качестве параметра он всегда будет возвращать NULL VALUE.

Это сказанное, мы можем ссылаться на ТОК SEED НОМЕР для любого поля Autonumber с помощью пользовательского VBA функции (Благодаря HansUp для This Post):

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 в качестве входного параметра. Теперь мы можем создать макрос данных в до изменения события, которое должно выглядеть следующим образом:

If [IsInsert] = True Then 
    Set Field 
     Name Hashed ID 
     Value = HASHFUNCTION (NEXTAUTONUM ("Serials","ID") - 1) 
End If 

Кроме того, мы вычитаем 1 из значения, возвращаемого функцией NEXTAUTONUM, потому что нам нужно значение [ID] Autonumber для в которой мы сейчас работаем, а не тот, который будет создан далее.

Надеюсь, это поможет кому-то!

+0

Решение заключается не в том, чтобы приготовить средство для захвата автоматического номера, а на самом деле переместить любой код в событие после вставки. Вы не должны и не можете действительно использовать идентификатор PK в предыдущем событии обновления, ЕСЛИ вы не нарушаете базовый дизайн базы данных и не считаете, что значение PK имеет значение. Единственная возможная причина ссылаться на значение PK в таких событиях - это когда дочерняя таблица задействована, и, таким образом, снова такой код появляется после вставки, так как ваш код перед изменением может ОТМЕНА вставить, и вы никогда не знаете, будет ли запись быть добавленным. По какой возможной причине вам нужен идентификатор PK перед изменением? –

+0

Я должен добавить, что это правильно, после вставки будет показывать/иметь текущую запись в контексте только как ЧИТАТЬ. Вы можете обойти это ограничение, выполнив запись поиска, чтобы создать новый вариант в контексте, который вы можете изменить. Основная проблема здесь заключается в том, что вы придаете смысл и используете столбец PK ID для чего-то еще в одной записи - это нарушает большинство правил проектирования баз данных, так как вы таким образом используете и придаете значение столбцу идентификатора PK. Что вам нужно сделать, так это построить пользовательскую функцию Hasfunction, которая возвращает ее собственную систему нумерации - не основанную на PK. –

+0

Ничего себе! Большой комментарий и много вопросов =), поэтому я отвечу один за другим: –

1

Это проверено на Access 2016. Я выяснил ситуацию, когда вы получаете значение NULL при чтении поля внутри макроса данных BeforeChange. Это происходит, если это поле является ПЕРВИЧНЫМ КЛЮЧОМ. Это не AutoNumber. Таким образом, проблема возникает, когда у вас есть такое сочетание:

  1. BeforeChange события
  2. ВСТАВИТЬ действие (только)
  3. поля первичного ключа

Простое решение заключается в изменении первичного ключа UNIQUE.