使用类模块将可编辑的ADO记录集返回到MS Access表单

5
前言:我正在使用 SQL Server 2008 R2 后端和 MS Access 2007 前端。
我有一个类模块,可以从 SQL Server 返回任何我想要的 ADO 记录集。然后我可以将其分配给任何表单的 RecordSource 属性。
问题是,当我尝试编辑字段时,状态栏中会显示 "此表单为只读"。我希望该表单可编辑。
我有两个表单:
1. FormEntities 2. FormEntitiesEdit
FormEntitiesEdit 表单不使用类模块。而是所有代码都在表单本身中。
类模块的目的是避免冗余,并且只需使用类模块轻松地从 SQL Server 获取记录集。
首先是我的全局模块:
'Default error message. 'eh' stands for error handler Public eh As String
'Global variables for universal use Public conn As ADODB.Connection Public rs As ADODB.Recordset Public com As ADODB.Command
其次是类模块(名称为 cADO)。此类模块使用上面的 conn 连接对象。
    Option Explicit
Dim db As DAO.Database Dim rs As DAO.Recordset '********************************************************************** Private Sub Form_Load()
'Open database and recordset Set db = CurrentDb() Set rs = db.OpenRecordset("SELECT * FROM dbo.Entities WHERE EntityID = " & Me.EntityID) 'Populate form fields with recordset values If Not rs.EOF Then Me.txtEntityName.Value = rs!EntityName Me.txtEntityType.Value = rs!EntityType Me.txtEntityAddress.Value = rs!EntityAddress End If 'Close recordset and database rs.Close db.Close End Sub '********************************************************************** Private Sub btnUpdate_Click() 'Open the database and recordset Set db = CurrentDb() Set rs = db.OpenRecordset("SELECT * FROM dbo.Entities WHERE EntityID = " & Me.EntityID, dbOpenDynaset, dbSeeChanges) 'Update recordset with form field values If Not rs.EOF Then rs.Edit rs!EntityName = Me.txtEntityName.Value rs!EntityType = Me.txtEntityType.Value rs!EntityAddress = Me.txtEntityAddress.Value rs.Update End If 'Close recordset and database rs.Close db.Close 'Close form DoCmd.Close acForm, Me.Name End Sub
Option Compare Database '启用数据库比较
Option Explicit '强制声明变量
Dim rsEntity As New ADODB.Recordset '声明ADODB记录集
'********************************************************************** Private Sub Form_Load() '窗体加载事件 FetchRecordSource '调用FetchRecordSource方法 End Sub
'********************************************************************** Private Sub FetchRecordSource() '获取记录来源方法
Set rsEntity.ActiveConnection = conn '设置记录集的活动连接为conn
'为主表单设置记录来源 With rsEntity .LockType = adLockOptimistic '锁定类型为乐观锁定 .CursorType = adOpenKeyset '光标类型为键集 .CursorLocation = adUseClient '使用客户端光标位置 .Source = "SELECT * FROM dbo.Entities" '查询语句 .Open .Source '打开记录集 End With Set Forms("fEntitiesEdit").Recordset = rsEntity '将记录集设置为表单的记录集
End Sub '********************************************************************** Private Sub CloseConn() '关闭连接方法 rsEntity.Close '关闭记录集 End Sub

如果Access Jet SQL可以执行SQL,我会将此表单绑定到Linked Table上。但是我使用了分层(递归)查询,Jet SQL无法执行,因此我必须放弃将表单绑定到Linked Table的想法。

我将表单上的.Allow Edits 和.AllowAdditions属性都设置为true。

我还尝试更改ADO Recordset上的.LockType为adOpenKeyset和adOpenDynamic。

  1. adOpenKeyset
  2. adOpenDynamic

我的LockType是adLockOptimistic。

正如您所看到的,属性已正确设置以能够编辑返回的记录集。

我知道这是正确的,因为当我使用具有相同属性的FormEntitiesEdit表单时,它允许我编辑字段。但是当我使用Class Module返回(使用相同的属性)时,它却说是只读的。

这很重要,因为正如您所看到的,使用Class Module要简单得多,只需要它返回一个可编辑的记录集。

有人有想法吗?建议?

1个回答

6
问题出现在类的 cOpenRecordset() 方法中:
.CursorLocation = CONST_CursorLocationClient

这里是您分配常量值的地方...

Private Const CONST_CursorLocationServer = 3
Private Const CONST_CursorLocationClient = 2

很遗憾,您交换了这两个值。以下是ADODB.CursorLocationEnum常量...

adUseClient = 3
adUseServer = 2

所以你的类实际上正在执行这个操作...
.CursorLocation = adUseServer

但是如果您想要记录集可编辑,您需要一个客户端游标。我认为您的类方法可能会起作用,如果您只需重新定义常量,或者您将暴露不同的问题...

Private Const CONST_CursorLocationClient = 3

FormEntitiesEdit是可编辑的,因为您在那里使用了正确的常量...

.CursorLocation = adUseClient

2
谢谢!我已经为这个问题奋斗了整整三个月!然而,你所回答的正是我遇到的问题的确切解决方案。正如一个编程朋友曾经告诉我“它总是一个语法错误”。嗯,在大多数情况下似乎是真的。 - Mati Diaz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接