基于查询的子表单中的字段的 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 False
和DoCmd.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 字段