2012-05-05 99 views
5

我在我的表單加載時在我的數據表子窗體上運行此代碼,並且沒有收到任何錯誤消息或代碼中斷。我的debug.print顯示Recordset rs充滿了2131條記錄,但是我的表單顯示了單行的#Name?在每一個領域。我的控件上的控件來源屬性絕對與我上面列出的字段名稱匹配。 RS是一個表單級變量,在表單關閉之前我沒有關閉它或將其設置爲空。在內存中,獨立,斷開連接的ADO記錄集

任何想法我做錯了什麼?

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 

OK,所以我剛剛看了this on the MSDN site

記錄集必須包含一個或多個字段是唯一索引,如表的主鍵。

(注意:此信息似乎是在這種情況下錯誤的。)

+2

這是一個小的表(4場)之後。但我想我從來沒有真正爲企業開發過,因此我習慣於將大量數據(10,000條記錄,有時甚至更多)引入數據表視圖。在我們的服務器中使用千兆位以太網和快速硬盤驅動器後,即使我們在ODBC鏈接表中使用DAO,我也沒有收到用戶的投訴。所以,我並沒有真正地重複我的方法,我只是說「迄今爲止」它實際上工作得很好。 – 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作爲AttribAppend Method。閱讀關於FieldAttributeEnum的更多詳情。

如果您已經從SQL語句中獲得了合適的唯一字段(或字段組合),請使用該字段。如果沒有,請創建一個長整型字段並將其用作假主鍵字段...爲您插入的每一行增加值。

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

也看看這篇文章從數據庫日誌由丹尼Lesandrini是有幫助的:Create In-Memory ADO Recordsets

+0

好吧,所以我已經添加了上面建議的主鍵字段,並且已經填充了它,但我仍然看到#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