在内存中,独立,断开的ADO记录集

时间:2012-05-05 02:53:18

标签: ms-access ms-access-2007 access-vba

当我的表单加载并且我没有收到任何错误消息或代码中断时,我在我的数据表子表单上运行此代码。我的debug.print显示Recordset rs已经填充了2131条记录,但我的表单显示了一行#Name?在每个领域。我的控件上的控件源属性肯定与我上面列出的字段名称匹配。 RS是一个表单级变量,我不会关闭它或将其设置为空,直到表单关闭。

知道我做错了什么吗?

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

记录集必须包含一个或多个唯一索引的字段,例如表的主键。

(注意:在这种情况下,这些信息似乎是错误的。)

3 个答案:

答案 0 :(得分:7)

是否可以在仅作为内存中对象的记录集上设置主键?

是的,使用adFldKeyColumn作为Append MethodAttrib。有关详细信息,请参阅FieldAttributeEnum

如果您的SQL语句中已有合适的唯一字段(或字段组合),请使用该字段。如果没有,请创建一个长整数字段并将其用作伪主键字段...增加您插入的每一行的值。

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

另请参阅Danny Lesandrini撰写的数据库期刊中的这篇文章是否有帮助:Create In-Memory ADO Recordsets

答案 1 :(得分:5)

我发现我能使这项工作的唯一方法是使用LockType adLockPessimistic或adLockOptimisic。 adLockReadOnly由于显而易见的原因不起作用,并且由于某种原因adLockBatchOptimistic不允许记录显示在我的表单中,即使记录集看起来完全正常。

我还发现您不必为这种类型的断开连接的Recordset定义主键以绑定到表单。我确定你无法通过表单对记录集进行任何编辑或更新,但在我的测试中,我发现我无法对这种类型的表单/记录集进行任何编辑,因为我收到了错误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错误消息判断。我还没弄清楚这些属性是什么或如何设置它们。

总之,我认为我会使用Access“temp”表,因为它不那么复杂,也没有我上面列出的问题。

答案 2 :(得分:4)

注意:我能够使所有内容正常工作并插入新记录 通过使用上面显示的示例 Create In-Memory ADO Recordsets 然后将以下内容更改为表单代码... '注意:诀窍是使用rstADO.MoveFirst& rstADO.Update后面的rstADO.MoveLast

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