设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 4459|回复: 13
打印 上一主题 下一主题

[ADO/DAO] 主子窗体批量保存,发现的问题,(原来是2010的问题,换为07就好了,谢谢T小宝版主提醒

[复制链接]
跳转到指定楼层
1#
发表于 2012-4-16 01:50:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dlack 于 2012-4-21 23:58 编辑

t小宝 版主发布的[ADO/DAO] 主子窗体批量保存(http://www.office-cn.net/thread-72836-1-1.html),非常有用,在使用过程中发现如下问题:,使用ADO方式的时候,在子表中的统计以及好多其他的表功能都没法使用(在DAO模式下Me.frmsub.Form.rsChildClone可以使用,ADO时候也没法使用),使用DAO的时候一切功能正常,但是如果数据多于50行或者项次多于15列左右,在第二次打开的时候就会出现假死状态。现在正在使用这个做一个数据库,感觉T小宝版主做的这个是最适合的,请了解的朋友帮忙改一下,谢谢了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2012-4-16 09:37:00 | 只看该作者
谁能帮忙看一下,谢谢了!
3#
 楼主| 发表于 2012-4-16 09:59:40 | 只看该作者
是不是函数在载入关闭后没有卸载掉,所以多开几次就会导致崩溃。请高手帮忙看看,谢谢!


'--------------------------------------------------------------------------------------------------
'类    名:  ADOTransForm
'功    能:  应用于主子窗体(子可以是数据表或连续窗体),实现主子窗体所有数据修改的同步批量保存或取消,
'           可用于 ACCESS 2000 以上版本.
'
'方    法:  InitForm      加载窗体和数据
'           UndoAll       取消所有数据更改
'           SaveAll       保存所有数据更改,成功返回真
'
'属    性:  FormDataMode  返回窗体的允许添加属性, 添加:true  修改:false
'
'事    件:  BeforeUnload  主窗体卸载前发生,可确定是否保存记录和关闭窗体
'           BeforeSaveAll 保存所有数据之前发生,可确定是否允许保存记录
'           AfterSaveAll  保存所有数据之后发生
'
'使用注意:  指定给主窗体的记录不要超过1条.
'           将窗体的模式属性设为是,因为启动事务之后会影响其它打开的记录集.
'
'相关说明:  这个类使用了DAO事务.
'
'作    者:  t小雨 (tcl013@126.com)
'创建日期:  2009-7-22
'--------------------------------------------------------------------------------------------------
Option Compare Database
Option Explicit

Public Event BeforeUnload(ByVal Dirty As Boolean, Cancel As VbMsgBoxResult)       ' 窗体卸载前
Public Event BeforeSaveAll(Cancel As Boolean, Response As Integer)                ' 保存前
Public Event AfterSaveAll(ByVal DataMode As Boolean)                              ' 保存后

Dim WithEvents frmMain As Form                    ' 主窗体
Dim WithEvents frmChild As Form                   ' 子窗体
Dim mblDataMode As Boolean                        ' 数据模式,添加:true 修改:false
Dim mblBeginTrans As Boolean                      ' 是否已开启事务
Dim mblDataChange As Boolean                      ' 数据是否已更改
Dim mblChildDel As Boolean                        ' 用于判断子窗体取消删除


'===========================================================
' 加载窗体和数据
'===========================================================
Public Sub InitForm(Main As Form, MainRcSource As String, Child As SubForm, ChildRcSource As String)

    Set frmMain = Main
    Set frmChild = Child.Form
   
    With frmMain
        .AllowDeletions = False                ' 强制主窗体不能删除记录
        .AfterInsert = "[Event Procedure]"
        .AfterUpdate = "[Event Procedure]"
        .OnUnload = "[Event Procedure]"
    End With
    With frmChild
        .AfterUpdate = "[Event Procedure]"
        .AfterDelConfirm = "[Event Procedure]"
        .OnDelete = "[Event Procedure]"
    End With

    mblDataMode = (CreateFormRst(frmMain, MainRcSource) = 0)
    frmMain.AllowAdditions = mblDataMode
    CreateFormRst frmChild, ChildRcSource

    DBEngine.BeginTrans    ' 开启事务
    mblBeginTrans = True

End Sub


'===========================================================
' 主窗体 事件
'===========================================================
Private Sub frmMain_AfterInsert()
    frmMain.AllowAdditions = False       ' 一次只能添加一条记录
End Sub

Private Sub frmMain_AfterUpdate()
    If mblDataChange = False Then mblDataChange = True
End Sub

Private Sub frmMain_Unload(Cancel As Integer)
' 卸载前提示
    Dim msg As VbMsgBoxResult
    msg = vbNo                                        ' 默认不保存
    RaiseEvent BeforeUnload(mblDataChange, msg)
    Cancel = (msg = vbCancel)
    If mblDataChange Then
        If msg = vbNo Then
            UndoAll
        ElseIf msg <> vbCancel Then
            SaveAll
        End If
    ElseIf mblBeginTrans Then
        If msg <> vbCancel Then DBEngine.Rollback
    End If
End Sub


'===========================================================
' 子窗体 事件
'===========================================================
Private Sub frmChild_AfterDelConfirm(Status As Integer)
    If Status = acDeleteOK Then
        If mblDataChange = False Then mblDataChange = True
    Else
        If mblChildDel Then
            ' 如删除不成功且是第一次更改窗体数据
            mblDataChange = False
            mblChildDel = False
        End If
    End If
End Sub

Private Sub frmChild_AfterUpdate()
    If mblDataChange = False Then mblDataChange = True
End Sub

Private Sub frmChild_Delete(Cancel As Integer)
    If mblDataChange = False Then
       ' 第一次更改窗体数据
        mblDataChange = True
        mblChildDel = True
    End If
End Sub


'===========================================================
' 取消所有数据更改
'===========================================================
Public Sub UndoAll()
    If mblDataMode Then frmMain.AllowAdditions = True
    If frmMain.Dirty Or frmChild.Dirty Then DoCmd.RunCommand acCmdUndo
    DBEngine.Rollback
    mblBeginTrans = False
    mblDataChange = False
End Sub

'===========================================================
' 保存所有数据更改
'===========================================================
Public Function SaveAll() As Boolean

    Dim b As Boolean, i As Integer
    If frmMain.Dirty Or frmChild.Dirty Then DoCmd.RunCommand acCmdSaveRecord
    If mblDataChange Then
        RaiseEvent BeforeSaveAll(b, i)
        If b Then
            If i = 0 Then MsgBox "无法保存数据!", vbExclamation, "系统提示"
            Exit Function
        End If
        DBEngine.CommitTrans
        RaiseEvent AfterSaveAll(mblDataMode)
        mblDataMode = False
        mblDataChange = False
    Else
        DBEngine.Rollback
    End If
    mblBeginTrans = False
    SaveAll = True
   
End Function


'===========================================================
' 主窗体数据模式 添加或修改
'===========================================================
Public Property Get FormDataMode() As Boolean
    FormDataMode = mblDataMode
End Property


'===========================================================
' 子函数 设置窗体记录集
'===========================================================
Private Function CreateFormRst(frm As Form, RecSource As String) As Integer
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset(RecSource, dbOpenDynaset)
    Set frm.Recordset = rs
    CreateFormRst = rs.RecordCount
    Set rs = Nothing
End Function

4#
 楼主| 发表于 2012-4-16 10:04:43 | 只看该作者
采用DAO时,数据多一点,下面的语句就会出问题!
Set mDAOTransForm = New DAOTransForm
    mDAOTransForm.InitForm Me, "Select * From 订单 Where 订单ID='" & stID & "'", _
        Me.订单明细_子窗体, "Select * From 订单明细 Where 订单ID='" & stID & "'"
5#
 楼主| 发表于 2012-4-16 10:54:42 | 只看该作者
实例改为低版本的了,烦请了解的朋友帮忙看一下,谢谢了

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
6#
发表于 2012-4-16 16:56:24 | 只看该作者
看着挺复杂的,你用些简单的不行吗?
7#
 楼主| 发表于 2012-4-16 19:06:33 | 只看该作者
风中漫步 发表于 2012-4-16 16:56
看着挺复杂的,你用些简单的不行吗?

主要是这个功能挺好的,不用建临时表就可以实现批量保存。能帮忙看看吗?

点击这里给我发消息

8#
发表于 2012-4-21 13:57:37 | 只看该作者
本帖最后由 t小宝 于 2012-4-21 13:58 编辑
dlack 发表于 2012-4-16 10:54
实例改为低版本的了,烦请了解的朋友帮忙看一下,谢谢了


5楼的例子没发现问题呀,你把有问题的传上来
9#
 楼主| 发表于 2012-4-21 16:31:48 | 只看该作者
本帖最后由 dlack 于 2012-4-21 19:05 编辑
t小宝 发表于 2012-4-21 13:57
5楼的例子没发现问题呀,你把有问题的传上来



T小宝版主,我尝试过了很多次,当表 请购单ID 设置为主键的时候,数据一多,多点几次修改请购单,程序马上崩溃
。如果请购单ID不设置为主键,那么请购单ID  s0000中如果有数据,S0000多点几次修改,程序会直接退出。修改s0001,不会出现这个问题。如果删除请购单ID S0000,那么S0001在多次点击修改后也会直接退出。
   一直不知道是啥原因,请版主帮忙修改一下,谢谢了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

点击这里给我发消息

10#
发表于 2012-4-21 16:49:11 | 只看该作者
dlack 发表于 2012-4-21 16:31
T小宝版主,我尝试过了很多次,当表 请购单ID 设置为主键的时候,数据一多,多点几次修改请购单,程序 ...

你把引起出错的操作过程讲清楚,让我按照你说的步骤操作就会出现你所说的错误!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-4 11:46 , Processed in 0.108797 second(s), 34 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表