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

Mat*_*iaz 5 ms-access vba ado class ms-access-2007

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

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

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

我有两种形式

  1. 表单实体
  2. 表单实体编辑

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) 作为 ADODB.Recordset

        设置 m_Recordset = 新 ADODB.Recordset

        cSQL = sql
        cOpenRecordset

        设置cGetRecordset = m_Recordset

    结束功能
    '******************************************************** **********************
    公共属性集记录集(值为 ADODB.Recordset)
        '为私有变量分配一个属性
        如果不是值什么都不是,则设置 m_Recordset = Value

    结束财产
    '******************************************************** **********************
    公共属性 Get Recordset() As ADODB.Recordset
        '从私有变量中读取记录集并分配给新的对象变量
        设置记录集 = m_Recordset

    结束财产


    '************************************ 私人部分 ************* **********************

    私有子 cOpenRecordset()

    出错时转到 eh

        '确保如果记录集是从之前打开的,则它会在打开新记录集之前关闭
        如果 m_Recordset.State adStateClosed 那么 m_Recordset.Close

        设置 m_Recordset.ActiveConnection = conn

        使用 m_Recordset
            .LockType = CONST_LockType
            .CursorType = CONST_CursorType
            .CursorLocation = CONST_CursorLocationClient
            .源=cSQL
            .开放.源代码
        结束于

        如果不是 m_Recordset.EOF 那么 m_Recordset.MoveFirst

    退出子程序
    呃:
        eh = "Error # " & Str(Err.Number) & " 由 " & _ 生成
        错误来源 & Chr(13) & 错误描述
        MsgBox eh,vbCritical,“开放记录集系统”
    结束子
    '******************************************************** **********************
    私有子 cCloseRecordset()
        m_Recordset.关闭
        设置 m_Recordset = 无
    结束子
    '******************************************************** **********************
    私有子类_Terminate()

        如果不是(m_Recordset 没什么)则设置 m_Recordset = Nothing

    结束子

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

    选项显式

    调暗 db 作为 cADO
    '******************************************************** **********************
    私有子表单_Current()
        加载选项卡
    结束子
    '******************************************************** **********************
    私有子表单_Load()

        设置 db = 新 cADO
        获取记录源
    结束子
    '******************************************************** **********************
    私有子 FetchRecordSource()

        db.cGetRecordset("SELECT * FROM dbo.Entities")
        设置表单(“fEntities”).Recordset = db.Recordset

    结束子

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

    选项比较数据库
    选项显式

    Dim rsEntity 作为新的 ADODB.Recordset

    '******************************************************** **********************
    私有子表单_Load()
        获取记录源
    结束子

    '******************************************************** **********************
    私有子 FetchRecordSource()

        设置 rsEntity.ActiveConnection = conn

        '设置主窗体的记录源
        使用 rsEntity
            .LockType = adLockOptimistic
            .CursorType = adOpenKeyset
            .CursorLocation = adUseClient
            .Source =“从 dbo.Entities 选择*”
            .开放.源代码
        结束于
        设置表单(“fEntitiesEdit”).Recordset = rsEntity

    结束子
    '******************************************************** **********************
    私有子 CloseConn()
        rsEntity.关闭
    结束子

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

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

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

  1. adOpenKeyset 和
  2. adOpenDynamic

我的 LockType 是 adLockOptimistic

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

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

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

有人有想法吗?建议?

Han*_*sUp 6

问题出在类的cOpenRecordset()方法中:

.CursorLocation = CONST_CursorLocationClient
Run Code Online (Sandbox Code Playgroud)

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

Private Const CONST_CursorLocationServer = 3
Private Const CONST_CursorLocationClient = 2
Run Code Online (Sandbox Code Playgroud)

不幸的是,您交换了这两个值。这是ADODB.CursorLocationEnum常数...

adUseClient = 3
adUseServer = 2
Run Code Online (Sandbox Code Playgroud)

所以你的班级正在有效地这样做......

.CursorLocation = adUseServer
Run Code Online (Sandbox Code Playgroud)

但是如果您希望记录集可编辑,则需要客户端光标。我认为如果您只是重新定义常量,您的类方法可能会起作用,否则您将暴露出不同的问题......

Private Const CONST_CursorLocationClient = 3
Run Code Online (Sandbox Code Playgroud)

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

.CursorLocation = adUseClient
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我已经和这个问题斗争了三个月了!然而你的回答正是我所遇到的问题的解决方案。正如一位编程朋友曾经告诉我的那样“这总是一个语法错误”。嗯,在大多数情况下似乎都是如此。 (2认同)