Подключение Excel VBA к MS Access (чтение / запись) к многопользовательским таблицам / запросам

Я дошел до конца, пытаясь выяснить, почему я не могу получить правильные настройки для многопользовательского чтения и обновления таблиц MS Access из Excel (Office 2013). Поэтому я надеюсь, что кто-то здесь может помочь.

Предыстория - у меня есть база данных MS Access, которая содержит все данные в таблицах, которые используются приложением Excel, работающим на каждом компьютере пользователя. Файл.accdb находится на совместно используемом QNAP NAS. Я спроектировал систему так, чтобы в ней была таблица со списком пользователей, доступ к которой при запуске осуществляется через форму, позволяющую пользователям "входить" в систему. Когда пользователь вошел в систему, цель состоит в том, чтобы записать поле Да / Нет в этой таблице, чтобы одно и то же имя пользователя не использовалось на двух разных машинах для доступа к одному и тому же подмножеству данных. Теперь все это хорошо работает на одном компьютере или нескольких экземплярах Excel на одном компьютере. Когда я загружаю приложение Excel на нескольких компьютерах, поле Да / Нет между компьютерами несовместимо, если только я не остановлю приложение Excel на компьютере и не перезапущу. Иногда я получаю ошибки доступа или ошибки повреждения базы данных в этой многопользовательской настройке - так что я явно делаю что-то не так - но не могу понять это. Помогите, пожалуйста!!

Подключение из приложения Excel выполняется следующим образом:

' connect to the Access database
Set cn = New ADODB.Connection
With cn
 .Provider = "Microsoft.ACE.OLEDB.12.0"
 .Mode = adModeShareDenyNone
 .CursorLocation = adUseServer
 .Open ThisWorkbook.Worksheets("Title").Range("B1") & "cms.accdb"
End With

Набор записей открывается в Excel следующим образом (который не отображает пользовательский набор, зарегистрированный на другом компьютере через поле да / нет, если я не запускаю приложение ПОСЛЕ того, как они "вошли")

Set rs = New ADODB.Recordset
sSQL = "SELECT [access list].* FROM [access list] where [access list].[user] = '" &        Me.userlist.Text & "';"
rs.Open sSQL, cn, adOpenDynamic, adLockPessimistic
Application.CalculateUntilAsyncQueriesDone ' not sure I need this????

Тест для этого пользователя, вошедшего в систему:

If rs.Fields("Logged in").Value = -1 Then
    fname = rs.Fields("user").Value
    rs.Close
    cn.Close
    Set rs = Nothing
    Set cn = Nothing
    MsgBox fname & " is already logged in - please select another user or exit"
Else
    userid = rs.Fields("user").Value
    rs.Close
    Set rs = Nothing
    sSQL = "Update [access list] Set [access list].[logged in] = '-1' WHERE [access list].[user] = '" & userid & "'"
    cn.Execute (sSQL)

    MsgBox "Welcome " & userid & "! Starting system for your contracts."
    cn.Close
    Set cn = Nothing
    Unload Me

End If

Так что я делаю не так? Я пробовал все разные способы с небольшой разницей. (Примечание: я не пытаюсь протестировать условия гонки, выполнив оба входа в один и тот же пользователь в одно и то же время - ситуация, которая не вызывает беспокойства - это просто модель блокировки, которую я реализую). Я думал, что держу блокировку на уровне записи, чтобы убедиться, что я вижу, как другие пользователи изменяют записи в каждом приложении на каждом компьютере. Я в тупике! Открытие MS Access и просмотр базы данных показывает несоответствие: на одной машине пользователь вошел в систему, а на другой - нет. Я думаю, это то, как я подключаюсь к базе данных доступа или к какой-либо настройке в базе данных доступа, на которую я не имею права - но это всего лишь мысль.

И последний поворот к этому - мои машины для тестирования - это Apple MacBook с Win 8.1/ Office 2013 на виртуальной машине VMware Fusion. В настоящее время у меня нет среды для тестирования на родных машинах Win 8.1, но это будет конечной целью. Возможно, он будет работать в целевой среде, но пока не может это проверить, и, поскольку это последний шаг, решение любых проблем с кодом в тестовой среде является моим текущим приоритетом.

Russ

1 ответ

Я вижу, что этот пост старый, так что вы, возможно, уже ушли, но я подумал, что отвечу, если кому-то это поможет. Я исследовал похожую проблему, когда расположение курсора и тип блокировки, кажется, указаны правильно, но я все еще иногда получаю противоречивые результаты чтения. Я не эксперт, но это может быть связано с обновлением кэша и задержками записи, связанными с базами данных JET/ACE/Access. Возможно, вы захотите поиграть с параметрами Page Timeout и Flush Transaction Timeout и подумать об использовании инструкции DBEngine.Idle dbRefreshCache перед выполнением чтения - хотя это функция DAO.

Другие вопросы по тегам