Есть ли способ выполнить код VBA при обновлении определенных таблиц и полей в базе данных Microsoft Access? - PullRequest
4 голосов
/ 04 июня 2009

У меня есть программа, которая использует базу данных Microsoft Access для своей внутренней части. Мне нужно, чтобы некоторый код VBA (который вызывает веб-сервис) выполнялся всякий раз, когда программа обновляет определенные таблицы / поля. Я вижу, что это работает так же, как триггер в SQL Server.

Можно ли отслеживать и действовать в соответствии с такими изменениями в Access?

Обновление Рассматриваемая программа не работает внутри Access (т.е. не является приложением VBA), она просто использует файл MDB в качестве внутреннего хранилища. К сожалению, у меня нет доступа к коду программы, так как это закрытое стороннее приложение.

Ответы [ 6 ]

3 голосов
/ 15 октября 2016

Этот вопрос старый, но ответы больше не верны. Access 2010 добавил макро-события данных, которые можно запускать при вставке, обновлении или удалении данных. Следующие события доступны при использовании представления таблицы данных таблицы или представления дизайна таблицы (события прикрепляются непосредственно к таблице, а не через кнопку макроса формы):

  • После удаления макрокоманды
  • Событие после вставки макроса
  • После обновления макрокоманды
  • Событие до изменения макроса
  • Перед удалением макрокоманды

Более подробная информация находится здесь:

1 голос
/ 04 июня 2009

Когда файл базы данных Access записывается, его отметка даты / времени изменяется. Я полагаю, вы можете попробовать использовать файловый монитор для обнаружения изменений в файле, а затем проверить файл, чтобы увидеть, что изменилось.

Было бы полезно, если в базе данных Access есть столбцы даты / времени LastModified в таблицах.

1 голос
/ 04 июня 2009

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

В противном случае вам потребуется другое приложение / служба, работающая все время, которая проверяет наличие обновлений в таблицах файлов доступа (возможно, у вас есть какой-то тип поля update_date в ваших таблицах?).

1 голос
/ 04 июня 2009

Доступ к среде графического интерфейса против Jet формат базы данных - это разные вещи.

Если вы используете базу данных Access в качестве бэкэнда - это всего лишь функциональность JET, с которой вы можете работать. Доступ к графическому интерфейсу (который включает VBA) выполняется на клиентском компьютере и не имеет функции автоматического запуска.

0 голосов
/ 05 июня 2009

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

Но лично я бы не рекомендовал вам это делать. Доступ печально известен коррупцией. При использовании в качестве простого бэкэнда вы в большинстве случаев достаточно безопасны, но если на нем запущен монитор, это означает, что файл всегда открыт. Это в основном игра в русскую рулетку с вашей базой данных. Как минимум, я бы связался с вашей базой данных из другого файла Access и проследил бы за связанными таблицами, чтобы в случае сбоя монитора вы не брали с собой производственную БД. Наконец, убедитесь, что вы не выполняете запросы слишком часто, так как я не хотел бы видеть, что вы являетесь единственной причиной истечения времени ожидания сайта:)

Option Explicit

Private m_lngLstRcrdCnt_c As Long

Private Sub Form_Open(Cancel As Integer)
    Const lngOneMinute_c As Long = 60000
    Me.TimerInterval = lngOneMinute_c

End Sub

Private Sub Form_Timer()
    Const strTblName_c As String = "Foo"
    Const strKey_c As String = "MyField1"
    Dim rs As DAO.Recordset
    Dim lngRcrdCnt As Long
    If TableExists(strTblName_c) Then
        Set rs = CurrentDb.OpenRecordset("SELECT Count(" & strKey_c & ") FROM " & strTblName_c & ";", dbOpenSnapshot)
        If Not rs.EOF Then lngRcrdCnt = Nz(rs.Fields(0&).Value, 0&)
        rs.Close
        If lngRcrdCnt <> m_lngLstRcrdCnt_c Then
            m_lngLstRcrdCnt_c = lngRcrdCnt
            'Number of records changed, do something.
        End If
    Else
        'Table is deleted, do something.
        m_lngLstRcrdCnt_c = -1
    End If
End Sub

Private Function TableExists(ByVal name As String) As Boolean
    Dim tdf As DAO.TableDef
    On Error Resume Next
    Set tdf = CurrentDb.TableDefs(name)
    If LenB(tdf.name) Then 'Cheap way to catch broken links.
        Set SafeGetTable = tdf
    End If
End Function
0 голосов
/ 04 июня 2009

Если вы используете Jet (то есть данные хранятся в бэкэнде файла MDB), то единственное место, где вы можете выполнить код, будет в событии после обновления в форме. Проблема здесь, конечно, в том, что если данные изменяются без использования формы, событие не сработает.

Если вы используете MS Access 2003, то для запуска веб-службы вы можете загрузить Microsoft Office 2003 Web Services Toolkit Нажмите здесь, чтобы загрузить

...