У меня есть разочаровывающая проблема в MS Access 2010, которую я бы на этом этапе квалифицировал как ошибку. И, пробовав все возможные обходные пути, я выхожу из идей и полагаюсь на вас.
Контекст
Приложение Huge Ms Access 2010 с 25-килограммовыми линиями VBA и > 50 форм. Он имеет архитектуру клиентского сервера с объединенным интерфейсом и бэкендом доступа в сети. Он подключается к двум различным базам данных (Oracle/SQL Server/Sybase IQ).
Проблема
Иногда, когда я назначаю набор записей ADODB для подформы, его данные не отображаются в связанных полях.20 >
Данные есть. Я могу debug.print
его, я вижу его в браузере Watches, я могу читать или манипулировать им, когда вы зацикливаете на объекте recordset с кодом. Он просто не отображается в подчиненной форме.
Он может работать безупречно в течение нескольких месяцев, и вдруг одна форма начнет иметь эту проблему без какой-либо видимой причины (это может произойти даже в тех формах, которые я не изменил). Когда это происходит, это делается для всех пользователей, так что это действительно что-то не так в интерфейсе accdb/accde.
Проблема не связана с конкретной СУБД/драйвером. Это может произойти с данными Oracle или Sybase.
Я создал свой собственный класс, абстрагирующий все, что связано с соединениями и запросами ADO, и везде использую ту же технику. У меня есть несколько десятых форм, основанных на нем, и большинство из них отлично работает.
У меня есть эта проблема в нескольких частях моего приложения, и особенно в очень сложной форме с большим количеством подформ и кода. В этой Основной форме проблема имеет несколько подформ, а другие нет. И у них одинаковые параметры.
Код
Вот как я заполняю набор записей формы:
Set RST = Nothing
Set RST = New ADODB.Recordset
Set RST = Oracle_CON.QueryRS(SQL)
If Not RST Is Nothing Then
Set RST.ActiveConnection = Nothing
Set Form_the_form_name.Recordset = RST
End If
Код с Oracle_CON.QueryRS(SQL)
- это
Public Function QueryRS(ByVal SQL As String, Optional strTitle As String) As ADODB.Recordset
Dim dbQuery As ADODB.Command
Dim Output As ADODB.Recordset
Dim dtTemp As Date
Dim strErrNumber As Long
Dim strErrDesc As String
Dim intSeconds As Long
Dim Param As Variant
If DBcon.state <> adStateOpen Then
Set QueryRS = Nothing
Else
DoCmd.Hourglass True
pLastRows = 0
pLastSQL = SQL
pLastError = ""
pLastSeconds = 0
Set dbQuery = New ADODB.Command
dbQuery.ActiveConnection = DBcon
dbQuery.CommandText = SQL
dbQuery.CommandTimeout = pTimeOut
Set Output = New ADODB.Recordset
LogIt SQL, strTitle
dtTemp = Now
On Error GoTo Query_Error
With Output
.LockType = adLockPessimistic
.CursorType = adUseClient
.CursorLocation = adUseClient
.Open dbQuery
End With
intSeconds = DateDiff("s", dtTemp, Now)
If Output.EOF Then
LogIt "-- " & Format(Now, "hh:nn:ss") & " | Executed in " & intSeconds & " second" & IIf(intSeconds = 1, "", "s") & " | Now rows returned."
Set QueryRS = Nothing
Else
Output.MoveLast
pLastRows = Output.RecordCount
LogIt "-- " & Format(Now, "hh:nn:ss") & " | Executed in " & intSeconds & " second" & IIf(intSeconds = 1, "", "s") & " | " & Output.RecordCount & " row" & IIf(Output.RecordCount = 1, "", "s") & " returned."
Output.MoveFirst
Set QueryRS = Output
End If
End If
Exit_Sub:
pLastSeconds = intSeconds
Set Output = Nothing
Set Parameter = Nothing
Set dbQuery = Nothing
DoCmd.Hourglass False
Exit Function
Query_Error:
intSeconds = DateDiff("s", dtTemp, Now)
strErrNumber = Err.Number
strErrDesc = Err.DESCRIPTION
pLastError = strErrDesc
MsgBox strErrDesc, vbCritical, "Error " & pDSN
LogIt strErrDesc, , "ERROR"
Set QueryRS = Nothing
Resume Exit_Sub
Resume
End Function
Вещи, которые я пробовал до сих пор
Для наборов записей я пробовал все возможные варианты
.LockType = adLockPessimistic
.CursorType = adUseClient
.CursorLocation = adUseClient
Подформы, обрабатывающие наборы записей, имеют все Snapshot
recordsettype, проблема остается, если я пытаюсь dynaset
.
Dataentry, дополнение, удаление, изменения отключены. Это чистое чтение.
У меня есть привычка отключать записи с помощью RST.ActiveConnection = Nothing
, поэтому я могу манипулировать ими впоследствии, но это также не влияет на проблему.
Это может происходить с очень простыми запросами только с одним полем в предложении SELECT
и только с одним полем, привязанным к нему на подформе.
Реимпорт всех объектов в свежем accdb также не решает проблему.
Решение, предложенное random_answer_guy, с первого взгляда работало, что подтвердило гипотезу об ошибке. К сожалению, мои проблемы возникли после некоторых (тотально несвязанных) изменений в основной форме. Я вернулся с 4 или 5 подформами, не отображающими данные, и добавление/удаление события загрузки на всех или части из них больше не имеет никакого значения
Если вам нужна дополнительная информация о том, насколько странно эта проблема, я советую вам прочитать мой комментарий к отвечу random_answer_guy.
В заключение
Чрезвычайно разочаровывает то, что у меня могут быть две разные формы с точно такими же свойствами и одинаковыми полями, одна и та же инструкция SQL над одним и тем же БД, один и тот же код управления наборами записей: один показывает данные, а другой нет!
Когда проблема возникает, у меня нет другого выбора, кроме как удалить все объекты, которые будут обрабатываться и реимпортироваться из старой версии, или воссоздать их с нуля.
Если это не ошибка, я все еще ищу подходящее слово, чтобы квалифицировать ее.
Кто-нибудь когда-либо сталкивался с этой проблемой и объяснил и/или обходное решение, чтобы предложить?