MS Access以编程方式提升表单事件

时间:2010-05-10 17:09:40

标签: ms-access events forms

是否可以通过编程方式引发内置MS Access表单事件?我有一个 感觉不是,但我想我会检查。 (我正在使用Access 2003)。

例如,我想在私人潜台上做这样的事情 形式:

RaiseEvent Delete(Cancel)

并让它触发Access.Form删除事件 - 即实际上没有 删除绑定记录。

请注意,我的删除事件不是由表单本身处理,而是由外部处理 class,所以我不能简单地调用Form_Delete(取消)。

2 个答案:

答案 0 :(得分:0)

我能理解你的困惑 - 我没有解释任何更大的背景。抱歉。

基本上,情况是我有一个'索引',即'连续形式'形式,它被绑定到只读查询。必须只读取查询,因为它涉及外部联接。但是,我希望能够从此表单中删除基础记录。

所以我的第一个想法是在表单记录集之外进行删除,例如。使用删除查询。我希望通过自己提升这些事件来挂钩围绕此手动删除例程的标准Delete / BeforeDelConfirm / AfterDelConfirm事件。但是,唉,这是不可能的。

如果表单本身处理这些事件,我可以简单地调用处理程序(Form_Delete等),但我的项目有自定义类,处理所有表单的表单删除和更新事件(验证,确认,日志记录等) 。 ( @Smandoli ,它没有详细记录,几个月前我刚刚发现并现在广泛使用它 - 也许你已经知道了 - 你可以设置外部类来处理你的表单例如,参见 here

长话短说,我找到了一个令我满意的解决方法。它涉及使'index'形成另一个表单的子表单,该表单绑定到可以删除的记录集。因此,可以使用标准的Access表单事件在外部表单中完成删除,具体取决于内部表单中的选择。

@Knox ,我原则上不同意能够自己筹集“内置”活动很难记录和维护。许多其他框架依赖于它。 在实践中,我同意你的看法,因为我们都必须在我们的工具和围绕这些限制发展的“最佳实践”的限制范围内工作。 Access的祝福和诅咒是它在记录集和表单之间的紧密结合......

答案 1 :(得分:0)

通常,根本不需要自己激活标准表单事件,通常这表示对表单事件的错误理解(如果一般情况下甚至不是事件)。

表单事件的存在是为了对用户与表单的交互作出反应,或者通知后面的代码通常会发生的事情(如Form_Load事件)。事件潜艇可以对这些事件作出反应 - 仅此而已。

人们常常想直接执行事件,但这也是一种错误的方法。事件潜艇一般被宣称为"私人"而不是" Public",它应该阻止直接从代码模块外部调用它们,但实际上你也不应该在同一个代码模块中执行它们中的任何一个。事件潜艇总是必须由他们的事件专门调用,尽管可以直接调用它们。

如果一个事件子有任何代码也应该在其他地方执行,那么在同一个模块中创建一个私有或公共子(取决于你是否想从外部执行它们)然后从事件子中调用这个子。如果您认为必须从其他地方执行相同的子程序,您现在也可以调用相同的子程序。这不是"可以直接调用事件子",它主要是一个设计问题。您应始终确保事件子仅由事件本身调用,而不是由任何代码调用。通过代码调用事件时的问题是,如果执行代码并且真实事件执行它,您可能会非常快地遇到麻烦。最后,你会得到很大的代码混乱,这很难调试。

顺便说一句,顺便说一句,可以从类模块中调用事件subs,该类模块具有对表单的引用(如果使用类模块来处理常规事件则需要它)。您只需将事件sub声明为Public,然后您可以使用表单引用调用它们,但如上所述:不要这样做。

  1. 如果使用类模块处理事件,那么您可以在此处执行任何操作,而不需要表单代码。
  2. 如果查询是只读的,并且您要删除基表的记录,则没有事件子可以帮助您。当用户想要删除他不能做的事情时,他们会被解雇,因为它只读,所以DoCmd也对你没有帮助。
  3. 就像David在上面的评论中所说,只需在任意位置创建一个删除按钮,然后可以读取连续形式中当前行的ID并启动" DELETE" SQL命令,然后只需重新查询连续的表单即可完成。您也可以在标准类模块中处理此问题,因为您不仅可以转发表单事件,还可以以相同的方式转发控制事件。在您的类模块中创建一个Init过程,它接受您想要处理的表单中的所有控件,或者在每个连续表单中添加基表的名称,然后类模块可以将其分配给标准" WITHEVENTS"定义的控制变量,例如类型CommandButton,并将基表名称保存为字符串变量。 (不要忘记在初始化过程中将OnClick事件设置为" [事件过程]") 在您可能初始化类模块的连续表单的Load事件中,您可以将基表名称和删除按钮控件转发到类模块的Init过程,然后可以通过启动一个非常通用的方式来处理删除。删除基表上的查询并重新查询表单,因为它已经具有表单引用。无需调用任何事件过程。
  4. 最后但并非最不重要:也许有一些框架可以让你直接提出事件但是我会说这些框架的创建者也不了解事件过程的目的。如果您曾在自己的类模块中创建自己的事件,您将看到它们也无法在类模块之外引发。当然,你可以创建一个" RaiseEvent" sub自己来外部调用它们 - 实际上,在自己的事件中它可以在某些情况下有意义。在表格(控制......)事件的情况下,他们应该告知代码发生的事情,现在应该有反应。如果您在自己的类模块中使用事件,通常也会创建一个" WithEvents"外部模块中的变量,以便在其他类模块中发生事件时获得通知。事件应该可以使模块对象彼此独立。带有事件的模块只会引发事件,并且它不知道是否有人正在收听它或对此事件作出反应。它通知世界"在类模块中发生了一些事情,没有别的。就像一个向世界发送每日新闻的广播电台"但它并不知道是否有人听过它。通常,无线电台的听众不会去广播电台并为其他听众读取他自己的新闻。只有广播电台的人才决定发送什么以及何时发送。同样的故事。

相关问题