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

Posted

技术标签:

【中文标题】使用类模块将可编辑的 ADO 记录集返回到 MS Access 表单【英文标题】:Returning editable ADO Recordsets to an MS Access Form using a Class Module 【发布时间】:2016-09-04 16:24:03 【问题描述】:

前言:我在前端使用 SQL Server 2008 R2 后端和 MS Access 2007

我有一个类模块,它可以从 SQL Server 返回我想要的任何 ADO 记录集。然后我可以将其分配给任何形式的 RecordSource 属性。

问题是,当我尝试编辑字段时,状态栏中会显示“此表单是只读的”。我希望表单是可编辑的。

我有两种形式

    表单实体 FormEntities编辑

FormEntitiesEdit 表单不使用类模块。而是所有代码都在表单本身中。

类模块的目的是避免冗余,只是能够使用类模块轻松地从 SQL Server 获取记录集。

首先是我的全局模块

'默认错误信息。 'eh' 代表错误处理程序 公共 eh 作为字符串 '通用的全局变量 公共连接作为 ADODB.Connection 公共 rs 作为 ADODB.Recordset 公共 com 作为 ADODB.Command

第二个是类模块(名称是cADO)。 这个类模块使用上面的conn连接对象

选项显式 私有常量 CONST_LockType = 3 私有常量 CONST_CursorType = 1 私有常量 CONST_CursorLocationServer = 3 私有常量 CONST_CursorLocationClient = 2 私有 m_Recordset 作为 ADODB.Recordset '对于公共记录集函数 私有 cSQL$ '****************************************************** ************************ 公共函数 cGetRecordset(ByRef sql) As ADODB.Recordset 设置 m_Recordset = New ADODB.Recordset cSQL = sql cOpenRecordset 设置 cGetRecordset = m_Recordset 结束功能 '****************************************************** ************************ 公共属性集 Recordset(Value As ADODB.Recordset) '为私有变量赋值 If Not Value is nothing 然后设置 m_Recordset = Value 结束属性 '****************************************************** ************************ 公共属性 Get Recordset() As ADODB.Recordset '从私有变量中读取记录集并赋值给新的对象变量 设置记录集 = m_Recordset 结束属性 '********************************** 私人部门 ************* ************************ 私有子 cOpenRecordset() On Error GoTo eh '确保如果一个记录集是从以前打开的,它会在打开一个新的之前关闭 If m_Recordset.State adStateClosed Then m_Recordset.Close 设置 m_Recordset.ActiveConnection = conn 使用 m_Recordset .LockType = CONST_LockType .CursorType = CONST_CursorType .CursorLocation = CONST_CursorLocationClient .Source = cSQL .Open .Source 结束于 If Not m_Recordset.EOF Then m_Recordset.MoveFirst 退出子 嗯: eh = "Error # " & Str(Err.Number) & " 由 " & _ 生成 Err.Source & Chr(13) & Err.Description MsgBox eh, vbCritical, "打开记录集系统" 结束子 '****************************************************** ************************ 私有子 cCloseRecordset() m_Recordset.Close 设置 m_Recordset = 无 结束子 '****************************************************** ************************ 私有子类_Terminate() If Not (m_Recordset Is Nothing) Then Set m_Recordset = Nothing 结束子

第三个是我的 FormEntities 表单背后的代码(使用 cADO 类模块)

选项显式 Dim db As cADO '****************************************************** ************************ 私有子表单_Current() 加载选项卡 结束子 '****************************************************** ************************ 私有子 Form_Load() 设置 db = 新 cADO FetchRecordSource 结束子 '****************************************************** ************************ 私有子 FetchRecordSource() db.cGetRecordset ("SELECT * FROM dbo.Entities") 设置 Forms("fEntities").Recordset = db.Recordset 结束子

第四个也是最后一个是FormEntitiesEdit表单背后的代码(这个表单不使用类模块,我可以编辑它)

选项比较数据库 选项显式 Dim rsEntity 作为新的 ADODB.Recordset '****************************************************** ************************ 私有子 Form_Load() FetchRecordSource 结束子 '****************************************************** ************************ 私有子 FetchRecordSource() 设置 rsEntity.ActiveConnection = conn '设置主窗体的记录源 使用 rsEntity .LockType = adLockOptimistic .CursorType = adOpenKeyset .CursorLocation = adUseClient .Source = "SELECT * FROM dbo.Entities" .Open .Source 结束于 设置 Forms("fEntitiesEdit").Recordset = rsEntity 结束子 '****************************************************** ************************ 私有子 CloseConn() rsEntity.关闭 结束子

如果 Access Jet SQL 可以执行 SQL,我会改为将此表单绑定到链接表。但是,我正在使用 Jet SQL 无法执行的分层(递归)查询,因此我必须绕过将表单绑定到链接表的想法。

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

我还尝试将 ADO 记录集上的 .LockType 更改为

    adOpenKeyset 和 adOpenDynamic

我的 LockType 是 adLockOptimistic

如您所见,属性设置正确,以便能够编辑我返回的记录集。

我知道这是真的,因为当我使用具有相同属性的 FormEntitiesEdit 表单时,它可以让我编辑该字段。但是当我使用类模块返回时(使用相同的属性)它说它是只读的。

这很重要,因为您可以看到使用类模块要简单得多,只需要它返回一个可编辑的记录集。

有人有想法吗?建议?

【问题讨论】:

【参考方案1】:

问题出在类的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

【讨论】:

谢谢!我一直在与这个问题作斗争 3 个月!然而,您回答的是我遇到的问题的确切解决方案。正如一位编程朋友曾经告诉我的那样“它总是一个语法错误”。嗯,在大多数情况下,这似乎是正确的。

以上是关于使用类模块将可编辑的 ADO 记录集返回到 MS Access 表单的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ADO 记录集字段将图片加载到 MS-Access Image 控件中?

获取从 PHP ADO 连接返回到 MS-Access DB 的 JSON

MS Access - ADO 记录集,使用 SQL 语句检索数据和建表

Javascript ADO 记录集打开方法不起作用。参数化查询

MS Access ADP 断开连接的记录集恢复

MS Access/ADO AddNew 方法不附加记录