Access 2010: отображение содержимого нескольких записей для несвязанных элементов управления в таблице данных

Я использую динамический сквозной запрос в Access 2010 для извлечения одной или нескольких записей из серверной базы данных. После долгих проб и ошибок я скопировал достаточно правильного кода, чтобы получить соответствующие записи и назначить их несвязанным текстовым полям в моей форме таблицы данных во время события OnLoad. Единственная оставшаяся проблема заключается в отображении нескольких записей. Я проверил, что я получаю несколько записей, но содержимое полей каждой записи перезаписывает предыдущие значения, сохраненные в элементах управления текстовым полем формы, поэтому я всегда получаю только одну запись, отображаемую в моей таблице данных, когда я ожидаю увидеть где-нибудь из один к 10.

Я уверен, что это простое решение. Может ли кто-нибудь указать мне на это?

Private Sub Form_Load()
    Dim sqlString As String
    sqlString = "SELECT Transmitter_ID, Receiver_ID, UTC_Date, Local_Date from Detections"
    If Not IsNull(Me.OpenArgs) Then
        sqlString = sqlString & " where " & OpenArgs
    End If

    Dim cnn As New ADODB.Connection
    Dim cmd As New ADODB.Command
    Dim rst As ADODB.Recordset

    'Define and open connection
    cnn.ConnectionString = "DRIVER={SQLite3 ODBC Driver};Database=z:\EWAMP\EWAMP_be_dev.sqlite"
    cnn.Open

    'Define ADO command
    cmd.ActiveConnection = cnn
    cmd.CommandText = sqlString

    'Populate and enumerate through recordset
    Set rst = cmd.Execute
    If rst.EOF Then
       MsgBox "Nothing found...", vbInformation + vbOKOnly
       Exit Sub
    Else
        Do While Not rst.EOF
            '// I'm guessing the problem is with my control assignments, here.
            Me.cntl_Receiver_ID.Value = rst("Receiver_ID")
            Me.cntl_Transmitter_ID.Value = rst("Transmitter_ID")
            Me.cntl_UTC_Date.Value = rst("UTC_Date")
            Me.cntl_Local_Date.Value = rst("Local_Date")
            Debug.Print {Show me the four control values}
            rst.MoveNext
        Loop
    End If

End Sub

Ваше здоровье!

ДУХдли


person DUHdley d'Urite    schedule 21.05.2012    source источник


Ответы (2)


Я не верю, что форму в режиме таблицы можно использовать как несвязанную форму. Но вы можете использовать набор записей ADO в качестве набора записей форм.

Set Me.Recordset = rst

Тогда просто будьте осторожны, чтобы не закрыть вашу переменную с именем rst, пока форма не закроется.

Другим альтернативным решением является использование созданного в памяти автономного набора записей ADO. По сути, вы в конечном итоге создадите новый набор записей, добавите к нему поля, чтобы они соответствовали существующему набору записей, а затем переместите все данные в новый набор записей. Но я действительно не вижу смысла делать это, если у вас уже есть действительный заполненный набор записей ADO.

Если вам действительно нужно/хотите отображать несколько записей в несвязанной форме, я думаю, вам придется использовать элементы управления ActiveX, такие как GridView, ListView, TreeView или MSFlexGrid. Я заметил, что наиболее опытные, профессиональные разработчики Access стараются как можно меньше использовать элементы управления ActiveX. Если и когда они их используют, они обычно ограничиваются только TreeView и ListView, я думаю, потому что они единственные элементы управления ActiveX, которые добавляют достаточно ценности, чтобы их стоило мириться с любыми проблемами, которые они могут создать.

Я предлагаю вам взглянуть на эту статью о различиях между DAO и ADO. http://www.utteraccess.com/wiki/index.php/Choosing_between_DAO_and_ADO

person HK1    schedule 22.05.2012

Читатель на другом форуме указал мне на решение, подобное предложенному HK1, а именно Set Me.Recordset = rst. Это устранило мою первоначальную проблему, но создало другую.

Сначала я повторно привязал четыре элемента управления текстовыми полями к несвязанной форме, а затем значительно изменил код, используя образец из http://msdn.microsoft.com/en-us/library/ff835419.aspx. Пересмотренный код выглядит так:

Private Sub Form_Load()
   Dim sqlString As String
   sqlString = "SELECT Transmitter_ID, Receiver_ID, UTC_Date, Local_Date from Detections"
   If Not IsNull(Me.OpenArgs) Then
      sqlString = sqlString & " where " & OpenArgs
   End If

   Dim cn As ADODB.Connection
   Dim rs As ADODB.Recordset

   'Define and open connection
   Set cn = New ADODB.Connection
   cn.ConnectionString = "DRIVER={SQLite3 ODBC Driver};Database=z:\EWAMP\EWAMP_be_dev.sqlite;"
   cn.Open

   'Create an instance of the ADO Recordset class,
   'and set its properties
   Set rs = New ADODB.Recordset
   With rs
       Set .ActiveConnection = cn
       .Source = sqlString
       '// .LockType = adLockOptimistic
       .LockType = adLockReadOnly
       .CursorType = adOpenKeyset
       '// .CursorType = adOpenStatic
       .Open
   End With

   'Set the form's Recordset property to the ADO recordset
   Set Me.Recordset = rs

   Set cn = Nothing
   Set rs = Nothing
End Sub

Теперь форма отображает четыре строки для четырех возвращаемых записей, 20 строк для двадцати записей и так далее, по крайней мере, до 256 тыс. строк (как указано в моем наборе параметров). Единственная оставшаяся крошечная проблема заключается в том, что для четырех или более записей, если я нажимаю кнопку навигации «последняя строка» (>|), локальный курсор устанавливает фокус на одну или несколько промежуточных строк, и лист свойств элемента управления энергично обновляется. (несколько раз в секунду). Если у меня больше строк формы, чем может быть отображено на экране, я не могу перейти или курсор к последней строке. Как будто набор рекордов постоянно обновляется.

Как видите, я играл со свойствами RecordSet LockType и CursorType (включая adOpenDynamic и adOpenForwardOnly, оба из которых вызвали ошибку во время выполнения с оператором Set Me.Recordset). Переключение LockType между adLockOptimistic и AdLockReadOnly, а CursorType между adOpenKeyset и adOpenStatic не влияет на производительность поиска (которая сейчас фантастически быстрая!) или кажущуюся частоту обновления (которая, к сожалению, еще выше).

Возможно, стоит упомянуть, что таблица «Обнаружения», из которой «выбирает» sqlString, содержит ~ 4M записей. Я был разочарован в своих предыдущих попытках использовать форму с источником данных, привязанным к сквозному запросу этой таблицы, потому что запрос всегда возвращал клиенту все 4M записей независимо от параметра filter/WhereClause/OpenArgs, который я передал в форму. . Решение, показанное выше, было бы идеальным, если бы я только мог закрыть соединение (я пытался) или иным образом приостановить запись RecordSet после того, как я вызвал его один раз.

person DUHdley d'Urite    schedule 22.05.2012