2012-05-05 4 views
5

Я запускаю этот код в своей подчиненной форме, когда моя форма загружается, и я не получаю никаких сообщений об ошибках или разрывов кода. Мой debug.print показывает, что Recordset rs заполнен 2131 записями, как и должно быть, но моя форма показывает одну строку с #Name? в каждом поле. Свойства источника управления на моих элементах управления, безусловно, соответствуют именам полей, которые я перечислял выше. RS - это переменная уровня формы, и я не закрываю ее или не устанавливаю ее ничего, пока форма не закрывается.В памяти, в автономном режиме, отключен ADO Recordset

Любая идея, что я делаю неправильно?

Set rs = New ADODB.Recordset 
rs.Fields.Append "TimesUsed", adInteger 
rs.Fields.Append "strWorkType", adVarWChar, 150 
rs.Fields.Append "DateLastUsed", adDate 
rs.Fields.Append "SelectedYN", adBoolean 
Set rs.ActiveConnection = Nothing 
rs.CursorLocation = adUseClient 
rs.LockType = adLockBatchOptimistic 
rs.Open 

Dim sSQL As String 
sSQL = "MyComplicated SQL Statement Ommitted from this SO Question" 

Dim r As DAO.Recordset 
Set r = CurrentDb.OpenRecordset(sSQL, dbOpenDynaset, dbSeeChanges) 
If Not (r.EOF And r.BOF) Then 
    r.MoveFirst 
    Dim fld 
    Do Until r.EOF = True 
     rs.AddNew 
     For Each fld In r.Fields 
      rs(fld.Name) = r(fld.Name).value 
     Next 
     rs.Update 
     r.MoveNext 
    Loop 
End If 
r.Close 
Set r = Nothing 
Debug.Print rs.RecordCount '2131 records 
Set Me.Recordset = rs 

ОК, так что я просто прочитал this on the MSDN site:

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

(Примечание: Эта информация, как представляется, ошибочным в этом контексте.)

+2

Это небольшой стол (4 поля). Но я думаю, что мне никогда не приходилось разрабатывать для предприятия, поэтому я привык тянуть большие объемы данных (10 000 записей, а иногда и больше) в представления таблиц. С Gigabit Ethernet и быстрыми жесткими дисками на нашем сервере у меня нет никаких претензий от моих пользователей, хотя мы используем DAO с ODBC Linked Tables. Итак, я не оправдываю свой подход настолько, насколько я просто говорю, что «пока» на самом деле он работает очень хорошо. – HK1

ответ

4

я узнал, что единственный способ, которым я могу сделать эту работу, чтобы использовать LockType adLockPessimistic или adLockOptimisic. adLockReadOnly не работает по понятным причинам, и по какой-то причине adLockBatchOptimistic не позволяет выводить записи в мою форму, даже если набор записей выглядит полностью функциональным.

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

Вот минимальный объем кода, необходимый для создания рабочих в памяти записей:

Dim rs As ADODB.Recordset 'Form Level variable 

Private Sub Form_Load() 
    Set rs = New ADODB.Recordset 
    rs.Fields.Append "ID", adInteger 
    'Set rs.ActiveConnection = Nothing 'Not Required 
    'rs.CursorType = adOpenKeyset 'Not Required 
    'rs.CursorLocation = adUseClient 'Not Required 
    rs.LockType = adLockPessimistic 'May also use adLockOptimistic 
    rs.Open 

    Dim i as Integer 

    For i = 1 To 10 
     rs.AddNew 
     rs("ID").Value = i 
     rs.Update 
    Next i 

    Set Me.Recordset = rs 
End Sub 

Это первый явилось мне, что связывание формы (вид техническое описания в моем случае) к этому типу отключенных записей будут быть хорошим, простым решением для моих конкретных потребностей. Однако я столкнулся с несколькими проблемами. Сортировка по умолчанию не работает, если ваша форма привязана к набору записей ADO. Кроме того, по какой-то причине я никогда не мог заставить этот набор записей быть редактируемым/обновляемым, что было требованием для моих потребностей (я в основном использовал его как список с несколькими проверками). Если вы получите набор записей из таблицы (даже если это пустая таблица), а затем отключите, вы можете обойти эту проблему. По-видимому, таблица предоставляет какую-то структуру или свойства, которые я не смог установить в моем коде выше, судя по сообщению об ошибке 3270, которое я получаю, когда пытаюсь добавить/отредактировать запись. И я не понял, что эти свойства и как их установить.

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

+0

В прошлые дни у меня было аналогичное желание создать простой набор данных в памяти. У меня были такие же разочарования, и я тоже сдался. –

7

возможно установить первичный ключ на набор записей, который является только объектом в памяти?

Да, используйте adFldKeyColumn как Attrib на Append Method. Читайте о FieldAttributeEnum для получения более подробной информации.

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

rs.Fields.Append "pkey", adInteger, , adFldKeyColumn 

см Кроме того, если эта статья из журнала базы данных Дэнни Lesandrini полезно: Create In-Memory ADO Recordsets

+0

ok, поэтому я добавил первичное ключевое поле, как было предложено выше, и я заполнил его, но я все еще вижу #Name? во всех моих полях. Я озадачен. – HK1

4

Примечание: Я был в состоянии получить все, чтобы правильно работать вместе с установкой новых записей , используя пример, приведенный выше в Create In-Memory ADO Recordsets Тогда изменение следующей коды формы ... «Примечания: Хитрость в том, чтобы использовать rstADO.MoveFirst & rstADO.MoveLast после rstADO.Update

Option Compare Database 
Dim rstADO As ADODB.Recordset 
Dim lngRecordID As Long 

Private Sub Form_BeforeInsert(Cancel As Integer) 

    lngRecordID = lngRecordID + 1 
    rstADO.AddNew 
    rstADO("EmployeeID").value = lngRecordID 
    rstADO.Update 
    rstADO.MoveFirst 
    rstADO.MoveLast 

End Sub 

Private Sub Form_Load() 

    Dim fld As ADODB.Field 

    Set rstADO = New ADODB.Recordset 
    With rstADO 
     .Fields.Append "EmployeeID", adInteger, , adFldKeyColumn 
     .Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull 
     .Fields.Append "LastName", adVarChar, 20, adFldMayBeNull 
     .Fields.Append "Email", adVarChar, 64, adFldMayBeNull 
     .Fields.Append "Include", adInteger, , adFldMayBeNull 
     .Fields.Append "Selected", adBoolean, , adFldMayBeNull 

     .CursorType = adOpenKeyset 
     .CursorLocation = adUseClient 
     .LockType = adLockPessimistic 
     .Open 
    End With 
    Set Me.Recordset = rstADO 

End Sub 

Private Sub Form_Unload(Cancel As Integer) 

    Set rstADO = Nothing 

End Sub 
Смежные вопросы