Access 2016 - ошибка RecordsetClone в форме, созданной с использованием виртуального набора записей, открывает диалоговое окно «Выбор источника данных» - PullRequest
0 голосов
/ 10 марта 2019

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

Ошибка возникает, когда набор записей формы установлен на виртуальный набор записей, а затем на него ссылается оператор DAO recordsetclone. Вместо набора записей, установленного на набор записей формы (посредством клонирования), отображается диалоговое окно «Выбор источника данных».

Чаще всего мы используем это для добавления элемента управления флажка в форму сведений, чтобы пользователь мог выбрать одну или несколько записей для дальнейшей обработки. Я использовал эту технику много раз во многих приложениях, но теперь она не работает.

Примечание. Я подтвердил, что этот код работает правильно в Access 2010.

Я использую Windows 10 Pro с 32-битной установкой Office

Чтобы настроить это и воспроизвести ошибку:

Создать новую базу данных ACCDB Добавьте следующие ссылки к ссылкам по умолчанию: Библиотека объектов данных Microsoft ActiveX 6.1 Microsoft ADO Ext. 2.8 для DDL и безопасности

Создать таблицу тестирования: TestId, AutoNumber, PK TestText, краткий текст

Добавить около 10 строк в таблицу.

Создать несвязанную форму с 3 элементами управления: Флажок, Имя: Выбрано, Источник управления: Выбрано Текстовое поле, Имя: TestId, Источник управления: TestId Текстовое поле, Имя: TestText, Источник управления: TextText

В заголовке формы добавьте командную кнопку: Имя: cmdTest, Заголовок: Test Установить форму Вид по умолчанию: Непрерывный

В Form_Open вызывается подчиненный SetRecordsource, который создает набор записей и добавляет столбец «Выбранные», чтобы пользователь мог проверить нужные записи.

Командная кнопка cmdTest попытается обратиться к источнику записей формы. При попытке сослаться на записи формы возникает ошибка. Вместо ссылки появляется диалоговое окно «Выбор источника данных».

Полный код VBA формы:

Option Compare Database
Option Explicit

Private Sub cmdTest_Click()
On Error GoTo errHandler
  Dim rs As DAO.Recordset
  Set rs = Me.RecordsetClone
' Using an ADODB recordset works but is an ugly solution
' To test comment out the Dim DAO and Set rs statements above and uncomment the next 2 lines.
'  Dim rs As ADODB.Recordset
'  Set rs = Me.Recordset
  rs.MoveFirst
  With rs
    Do While Not .EOF
      Debug.Print .Fields("Selected"), .Fields("TestId"), .Fields("TestText")
    .MoveNext
    Loop
  End With
  Set rs = Nothing
ExitSub:
  Exit Sub
errHandler:
  MsgBox "Error in " & Me.Name & ".SetRecordsource " & Err.Number & " - " & Err.Description
  Resume ExitSub
End Sub

Private Sub SetRecordsource()
  Dim rs As ADODB.Recordset   'the virtual recordset to hold the source data plus the boolean Selected field
  Dim rsSource As DAO.Recordset  'dim the source recordset

  Set rs = New ADODB.Recordset
  With rs
    .Fields.Append "Selected", adboolean
    .Fields.Append "TestId", adInteger, , adFldKeyColumn
    .Fields.Append "TestText", adVarChar, 80
    .CursorLocation = adUseClient
    .LockType = adLockOptimistic
    .CursorType = adOpenKeyset
    .Open

    Set rsSource = CurrentDb.OpenRecordset("Select TestId, TestText from Test", dbOpenDynaset)
    rsSource.MoveFirst
    Do Until rsSource.EOF
      .AddNew
      .Fields("Selected") = 0 'set the checkboxes to unchecked
      .Fields("TestId") = rsSource.Fields(0)
      .Fields("TestText") = rsSource.Fields(1)
      .Update
      rsSource.MoveNext
    Loop
  End With
  Set Me.Recordset = rs 'Set the form's recordset = to our virtual recordset
  Set rsSource = Nothing
  Set rs = Nothing
ExitSub:
  Exit Sub
err_handler:
  MsgBox "Error in " & Me.Name & ".SetRecordsource " & Err.Number & " - " & Err.Description
  Resume ExitSub
End Sub 'SetRecordsource

Откройте форму и нажмите кнопку «Проверить команду», чтобы воспроизвести ошибку.

Одно из предложенных решений - использовать набор записей ADODB и установить для него Me.Recordset вместо Me.Recordsetclone. Хотя это работает, это уродливое решение, поскольку вы теперь работаете с источником записей формы и просматриваете записи, чтобы найти строки, в которых Selected = True перемещает текущую запись в форме. Указатель текущей записи не только перемещается, но и если строк больше, чем может показать, пользователь видит прокрутку записей формы.

Любая помощь, подтверждение или рекомендации будут с благодарностью.

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Из другого форума решение этой проблемы заключается в использовании набора записей ADODB, а затем клонировании формы для него через Recordset.Clone. В приведенном выше коде он ссылается на «некрасивое» решение:

'Использование набора записей ADODB работает, но это уродливое решение Для проверки закомментируйте приведенные выше операторы Dim DAO и Set rs и раскомментируйте следующие 2 строки.

'Dim rs As ADODB.Recordset

'Set rs = Me.Recordset

Настройка rs = Me.Recordset будет работать с формой (не желательно).

Но используя набор записей ADODB, а затем настройка rs = Me.Recordset.Clone работает, не работает с формой и не вызывает диалог источника данных.

Что-то изменилось в 2016 году, но это работает и может помочь кому-то еще. Вы также можете прочитать: Создание наборов записей ADO в памяти в журнале базы данных

0 голосов
/ 10 марта 2019

Ваш код не может работать, так как вы пытаетесь присвоить ADODB.Recordset (тот, что в Form.Recordset) DAO.Recordset, `как он объявлен.

Если тип набора записейможет варьироваться, вы можете затемнить rs as Object, тогда он получит тип Form.Recordset (по свойству Form RecordsetClone, что удивительно работает и для ADODB: Recordsets).Вы можете запросить тип с помощью:

If TypeOf Me.RecordSet Is ADODB.Recordset Then
   'ADODB
 Else
   'DAO
 End If

Если вам нужен несвязанный CheckBox, вы можете использовать clsCCRecordSelect -Class из SelectRecordsV2 .

clsCCRecordSelect используется мной годами, и я не хочу жить без!

...