5

当我的表单加载并且我没有收到任何错误消息或代码中断时,我正在我的数据表子表单上运行此代码。我的 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

好的,所以我刚刚在 MSDN 网站上阅读了这篇文章

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

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

4

3 回答 3

7

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

是的,用作adFldKeyColumnAppend Method。阅读有关FieldAttributeEnum的更多详细信息。Attrib

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

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

另请参阅 Danny Lesandrini 的 Database Journal 中的这篇文章是否有帮助:Create In-Memory ADO Recordsets

于 2012-05-05T03:14:11.827 回答
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“临时”表,因为它不会那么复杂,并且不会出现我刚刚在上面列出的问题。

于 2012-05-05T15:00:16.140 回答
4

注意:通过使用上面在创建内存中 ADO 记录集中显示的示例,我能够使一切正常工作以及插入新记录, 然后将以下内容更改为表单代码...'注意:诀窍是使用 rstADO。 rstADO.Update 之后的 MoveFirst & 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
于 2012-07-26T06:37:31.130 回答