【问题标题】:Action on Form Save表单保存操作
【发布时间】:2020-07-13 20:46:09
【问题描述】:

我们有一个 Access 2010 数据库,它充当 MS SQL 数据库的前端。当我们在表单中编辑数据时,需要运行一个过程才能将某些数据正确保存回 SQL。

我们的数据库程序员添加了一个“保存按钮”来执行此操作。但这会导致另一个问题 - Access 中有多种保存表单的方法 -

  • 导航到下一条记录
  • 点击左侧的确认栏
  • 创建新记录
  • 搜索新记录
  • 使用功能区中的命令

有没有办法将程序附加到实际的保存动作中,这样无论人们如何移动到程序运行的下一个表单?

[更新]

这是幕后代码:第一个 sub 附加到“保存”按钮。当然,第二个附在BeforeUpdate的表格上。

Private Sub SaveRecord_Click()
'From NAME form
Form_BeforeUpdate False
End Sub

Private Sub Form_BeforeUpdate(Cancel As Integer)
'used by NAME form
    [Last_Update] = Now
    '*********************
    Save_Record
    '*********************
    MName_ID = Me.Name_ID
    Me.Undo
    Cancel = True
    If Not IsNull(MName_ID) Then
        Jump_to_Name_ID MName_ID, True
    Else
    End If
End Sub

我想我只是不明白这个按钮是干什么用的。

【问题讨论】:

  • 我会调查您关注的表单/控件的“更新前”事件。该事件将在任何记录/数据更新之前触发。它还允许您在必要时取消保存。
  • [Last_Updated] 可以很容易地实现为数据宏,因此无论何时更改表,无论如何(无论是调用 DoCmd.RunSQL 的表单还是默认表视图),[Last_Updated] 都会总是被设置。我的回答为您提供了一些处理插入/更新/删除的高级方法,但在这种情况下,从 vba 执行此操作可能有点过头了。查找有关如何使用数据宏的指南...

标签: ms-access vba ms-access-2010


【解决方案1】:

所以我安装了一个 MS Access 2010 试用版,最终设法找到解决您问题的方法。它包括数据宏和hidden gem,我花了很长时间才找到。

当表发生变化时,您运行 VBA 的方式如下:

  1. 用公共函数创建一个普通模块(没试过类模块):

模块名称:EventHandlers

Public Function InsertEvent(ByVal id As Integer)
    MsgBox "inserted: " + CStr(id)
End Function
  1. 打开修改后应运行 VBA 的表并转到功能区中的“表”。

  2. 点击“插入后”

  3. 在“添加新动作”选择框中,选择SetLocalVar(或从动作目录中选择)。

  4. 在名称字段中,插入模块的名称(在本例中为 EventHandlers,正如我们之前创建的)

  5. 在表达式字段中,写下函数的名称:InsertEvent([id])(其中 [id] 是要为其添加数据宏的表中的实际列)

  6. 保存并关闭

每当向表中插入内容时,都会显示一个带有 id 的消息框。

你可以对更新事件做同样的事情。函数可能是这样的:

Public Function UpdateEvent(ByVal oldValue As String, ByVal newValue As String)
    MsgBox oldValue + " changed to: " + newValue
End Function

数据宏是

操作:SetLocalVar

姓名:EventHandlers

表达式:UpdateEvent([Old].[your_column_name];[your_column_name])

注意:使用更新、插入或删除执行 DoCmd.RunSQL 将执行数据宏,然后询问用户他或她是否真的想要更新/插入/删除行。如果用户单击取消,则不会更改任何内容,但仍会执行您的数据宏。如果您还没有,您可能应该在实现数据宏之前禁用此检查。

【讨论】:

  • 感谢您的想法。你用过这个吗?
  • 不,现在我正在进一步调查,我错了。您不能通过数据宏运行 VBA。我会更新我的答案。
  • 我猜是个棘手的问题。感谢您的回答。
  • 什么???我不敢相信你安装试用版只是为了解决我的问题!我现在就给你 +1(上帝保佑你),但我想在接受之前先尝试一下。
  • 说,你能把你的示例项目发给我吗?您可以通过我的个人资料中链接的表格向我发送电子邮件 - 然后我会回复,您可以将附件发送给我。 (如果你愿意!)
【解决方案2】:

好吧,我无法使用 Sommer 先生的解决方案,因为无法将事件处理程序添加到链接表中,因为它们是只读的。但是,我确实制定了一个简单的程序,似乎效果很好。

所以,我实际上已经在使用BeforeUpdate 事件,所以我在这里捕捉到了正确的事件 - 这是捕获保存的事件,无论是更改导航还是保存记录栏左边。但是,使用Application.Echo False 来阻止Access 在Me.Undo 发生时将旧数据回发到控件会导致一些问题。

因此我们使用cancel=true 来阻止BeforeUpdate 事件进行正常处理,并使用Me.Undo 来阻止Access 尝试将数据保存到链接表中。

Private Sub Form_BeforeUpdate(Cancel As Integer)
    Cancel = True

    [Last_Update] = Now
    '*********************
    Save_Record '-->This will save the data back to SQL
    '*********************
    MName_ID = Me.Name_ID
    Application.Echo False  'don't show the undo in the controls
    Me.Undo

    If Not IsNull(MName_ID) Then    'used for the navigation buttons
        Jump_to_Name_ID MName_ID, True
    Else
    End If

    Application.Echo True   'turn the control refresh back on
    Me.Repaint
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 2011-09-08
    • 1970-01-01
    相关资源
    最近更新 更多