在子窗体中保存记录
Posted
技术标签:
【中文标题】在子窗体中保存记录【英文标题】:Save record in subform 【发布时间】:2010-04-13 12:35:09 【问题描述】:我有一个包含多个子表单的选项卡控件的主表单。我需要确保在用户切换选项卡时保存子表单中的数据。问题是 DoCmd.RunCommand acCmdSaveRecord 似乎只适用于当前表单,因此它不会将数据保存在子表单中。
我在子表单上尝试了不同的事件,例如停用、OnLostFocus 等,但直到其他地方的另一个字段获得焦点时它们才会触发。
理想的解决方案似乎是在选项卡控件的 OnChange 事件上放置一些东西,以确保保存所有数据。这是我的问题,如何将记录保存在子表单中?
【问题讨论】:
【参考方案1】:在 Access 中,默认是保存,所以除非你做了一些非常复杂的事情来防止这种情况发生,否则将焦点从子窗体移动会自动保存记录。您可以通过添加一条记录、从子表单移动然后检查表格来测试这一点。
【讨论】:
我找到了解决方案。当某些数据发生更改时,我需要运行一些代码来更新其他字段。发生的事情是它没有在它应该触发的时候触发......感谢您的输入! 为此,您可以考虑子窗体控件的 LostFocus 事件。【参考方案2】:您根本不必做任何事情,因为它一旦丢失焦点就会保存子表单(当标签控制更改时)。
但作为一个练习,我已经概述了你需要编写的代码。
您可以通过将其 .Dirty 属性设置为 False 来保存任何表单。对于像这样会运行很多的东西,我想我会写一个子来遍历子表单,检查是否有脏的,并保存脏的。像这样的:
Public Sub SaveSubFormsOnTab()
Dim pge As Control
Dim ctl As Control
For Each pge In Me!ctlTab.Pages
Debug.Print pge.Name
For Each ctl In pge.Controls
If ctl.ControlType = acSubform Then
If ctl.Form.Dirty Then
ctl.Form.Dirty = False
End If
Debug.Print ctl.Name
End If
Next ctl
Next pge
Set ctl = Nothing
Set pge = Nothing
End Sub
现在,如果您的选项卡控件上有很多不是子表单的控件,这实际上是非常低效的。如果您的选项卡只有子表单,它将相当有效。在任何一种情况下,使用填充在表单的 OnLoad 事件中的自定义集合会更有效,然后您将遍历该集合,该集合只包含选项卡控件的子表单,并保存任何脏的。
其中任何一个都比使用选项卡的 OnChange 事件更可取,因为每次添加带有子表单的选项卡页或更改子表单控件的名称时,都必须更改 OnChange 事件。
【讨论】:
【参考方案3】:我遇到了类似的问题,我需要在子表单中运行各种代码,并在主表单中运行基于子表单中的值的值来重新计算。这是最终奏效的方法:
这是一个示例,其中一个名为“frmCustomers”的主表单包含一个子表单“sfmTransaction”,而该子表单又具有一个名为“sfmOrderLine”的子表单。表单有一个“cmdSave”按钮,仅在用户单击“cmdEdit”按钮时可见(其目的是锁定所有控件,直到用户单击编辑按钮,然后在他单击时重新锁定它们保存):
在主窗体 ('frmCustomer') 上转到子窗体的退出事件,并添加'me.recalc' 两次,如下所示:
Private Sub sfmTransaction_Exit(Cancel As Integer)
If (Not Form_sfmTransaction.NewRecord And Form_sfmTransaction.cmdSave.Visible) Or (Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible) Then
'To save subforms
Me.Recalc
Me.Recalc
End If
End Sub
在 subform ('sfmTransaction') 中,进入子窗体的子窗体的退出事件,并添加 'me.recalc' 两次,如下所示:
Private Sub sfmOrderLine_Exit(Cancel As Integer)
If Not Form_sfmOrderLine.NewRecord And Form_sfmOrderLine.cmdSave.Visible Then
'To save subform
Me.Recalc
Me.Recalc
End If
End Sub
希望这会有所帮助。
【讨论】:
【参考方案4】:将dirty 属性设置为false 可能会强制Access 将数据保存到数据库,但它会绕过before_update 事件。这意味着,如果您将此事件用于验证或其他目的,您的数据库中可能会有错误数据。
【讨论】:
这不是真的—— FORM 更新事件全部触发(我刚刚测试过)。但是,单个控件的事件不一定会触发(因为它们不会仅通过保存记录来激活)。以上是关于在子窗体中保存记录的主要内容,如果未能解决你的问题,请参考以下文章
在测试者的设备上部署应用程序无法在 iCloud 中保存记录