基于查询的子表单中的字段的 Access 2007 验证帮助

Posted

技术标签:

【中文标题】基于查询的子表单中的字段的 Access 2007 验证帮助【英文标题】:Help with Access 2007 validation for a field in a subform based on a query 【发布时间】:2011-07-12 22:57:21 【问题描述】:

我有一个子表单,它是较大表单的一部分,其中两者都包含 PROJECT_ID 字段。在主窗体中,PROJECT_ID 字段是一个键。在子表单中,用户可以选择为项目分配新代表或更改子表单中的当前项目代表。一个项目可以有多个代表,但是只有一个可以是活动的主要代表。我的问题是我在编写主要标志字段 (ADV_FLAG) 的验证时遇到问题,因为它本质上是基于查询的。谈到 VBA,我有点新手,但我认为这可能是解决我的问题的最佳解决方案。有关如何解决此问题的任何建议或类似代码示例。以下是我目前在 sub_form 的 BeforeUpdate 事件过程中拥有的内容。

Private Sub Form_BeforeUpdate(取消为整数)

'验证项目中的多个活动主节点

‘追加到表 T_Error_Catch 的 project_ID 和一个错误标志为 YES '其中一个项目有多个活动的主节点。

DoCmd.SetWarnings False
DoCmd.OpenQuery "Q_Append_Errors_MultiplePrimaries", acViewNormal, acEdit

'向用户抛出一个对话框错误,表明该项目已经有一个活动的主节点

If ERR_FLAG = "Yes" And ADV_FLAG.Value <> "Secondary" Then

   MsgBox "Project already has an Active Primary.", vbExclamation
   ADV_FLAG.SetFocus
   Cancel = True

End If

‘一旦记录被更正,就截断 T_Error_Catch 表,并且再次只有一个活动的主表

If ERR_FLAG = "Yes" And ADV_FLAG.Value = "Secondary" Then

   DoCmd.SetWarnings False
   DoCmd.OpenQuery "Clear T_Error_Catch", acViewNormal, acEdit

End If

结束子

【问题讨论】:

【参考方案1】:

您正在使用更新前的表单来验证现有记录中的 ADV_FLAG 值。我认为您还需要处理新记录...以防止用户添加新代表作为已分配主要代表的 PROJECT_ID 的主要代表。您可以在插入之前为表单添加一个过程来处理它。

但是,与其等到用户完成所有字段后再验证 ADV_FLAG,不如在 ADV_FLAG 控件的更新后事件中进行验证。更新后过程将同时处理记录更新和插入。

但也许更容易实现的是子窗体上的命令按钮,它使当前代表成为当前 PROJECT_ID 的唯一主要对象。按钮的点击事件可以使用如下代码:

    Dim strSql As String
    Dim db As DAO.Database

On Error GoTo ErrorHandler

    strSql = "UPDATE YourTable SET ADV_FLAG = 'Secondary' WHERE PROJECT_ID = " & _
        Me.txtPROJECT_ID & ";"
    Debug.Print strSql
    Set db = CurrentDb
    db.Execute strSql, dbFailOnError
    Me.txtADV_FLAG = "Primary"

ExitHere:
    On Error GoTo 0
    Debug.Print "RecordsAffected: " & db.RecordsAffected
    Set db = Nothing
    Exit Sub

ErrorHandler:
    'your error handler code here '

我假设您的子表单有一个名为 txtPROJECT_ID 的文本框控件绑定到 PROJECT_ID 字段,另一个名为 txtADV_FLG 绑定到 ADV_FLAG 字段。根据需要更改这些名称以匹配您的数据控件。

使用这种方法,用户实际上不需要直接编辑 txtADV_FLG 中的值(因为命令按钮会进行所需的任何更改)。因此,在 txtADV_FLG 的属性表中,您可以设置 Enabled = No,也可以设置 Locked = Yes。

Debug.Print 行用于帮助您解决问题。他们会将信息打印到即时窗口。 (您可以使用 Ctrl+g 键盘快捷键转到即时窗口。)在您正确运行代码后,您可以禁用或删除 Debug.Print 语句。或者让它们保持原样......您不会受到任何重大的性能影响。

请注意,我使用了db.Execute strSql, dbFailOnError 而不是DoCmd.SetWarnings FalseDoCmd.OpenQuery。我从不设置警告关闭。如果你这样做了,你必须记得之后再次打开 SetWarnings。您的代码不包含DoCmd.SetWarnings True。因此,如果不启用 SetWarnings,您可能会隐藏重要信息。不要那样做!

【讨论】:

非常感谢!!这非常有效,感谢您对 SetWarnings 的建议。以后绝对不会这样做了。非常感谢!【参考方案2】:

试图遵循@HansUp 的解决方案,我的眼睛呆滞,我确信这是正确的。相反,我将提供一个使用模式设计来避免以代码方式编写大量代码的答案。

我不得不多次这样做——您有一个 N:1 表,但您希望将其中一条记录指定为 PRIMARY。

首先,您设置 N:1 表。

然后,您将一个字段添加到主表(1 侧),并将记录的 PK 值存储在您想要作为主记录的 N 表中。

例如,假设您有 tblInventory 和 tblImage,它们有一个 ImageID PK 和一个 InventoryID FK。

要将其中一个设置为主图像,您需要将 MainImageID 字段添加到 tblInventory,并使用组合框对其进行编辑,该组合框列出了 tblImage 中与 tblImage 中的该 InventoryID 连接的图像。当然,您必须重新查询 Inventory 表单的 OnCurrent 事件中的组合框。

这里有一个示例 UI:

在该实现中,图像列表有一个用于 TOP 的复选框,但它不可编辑(这是一个糟糕的 UI,因为从外观上看不清楚它不能在那里更改),但用户认为它相当迅速地。当然没有必要在那里显示检查,或者使用相同的控件来指示 TOP 项目。

【讨论】:

以上是关于基于查询的子表单中的字段的 Access 2007 验证帮助的主要内容,如果未能解决你的问题,请参考以下文章

使用来自单独表单 Access 2007 的用户输入自动填充表单中的字段

Access 2007:查询两个短日期值之间的 DateTime 字段

Access 2007 中的选项卡控件之外的选项卡

使用 ODBC 查询 Access 2007 多值字段

仅重新查询数据表视图表单中的一条记录 (MS Access)

Access 2007 中的报告和图形 - 计算查询值