【问题标题】:Using a query in Form On-Open event -- MS Access在 Form On-​​Open 事件中使用查询 -- MS Access
【发布时间】:2020-03-14 16:26:57
【问题描述】:

所以我有几个表格。在父表单中,我收集有关用户的信息并包含一个用户 ID 字段。此外,在父表单中,数据输入者可以单击几个按钮来指示几个不同的类别。

当数据输入者单击类别按钮时,引擎会打开一个子 UserCategory 表单。我在按钮的 On-Click 事件(以及子表单的 On-Open 事件)中包含了逻辑,这样 UserID 值是从父表单记录传递的,CategoryID 值由按钮确定单击并传递给子窗体。 UserID 和 CategoryID 的组合对于所讨论的底层 UserCategory 表来说是唯一的,并且表示该表的一个键,但是,主键是另一个字段——UserCategoryID(在 UserID 和 CategoryID 的组合之间具有 1:1 的关系) .

因此,一个要求是,如果表单接收到表中已经存在的 UserID 和 CategoryID 的组合,那么表单应该引用该记录。但是,当它的给定值已经被表示时,表单将继续并创建一个新记录。我之前在创建相关表格的时候也遇到过这个问题,这个问题是因为表格没有尊重相关表格的FK和PK之间的1:1关系。在所有情况下,我都能够通过使用关系数据库工具执行 1:1 关系来解决问题。但是,在这种情况下,一个用户可以属于多个类别,一个类别可以有多个用户——换句话说,UserID 字段是 1:M,CategoryID 字段是 1:M,但它们的组合是 1:1。我不知道是否有办法强制这种关系。

我想到的一个潜在解决方案是在表单的 On-Open 事件中构建查询。它将使用 UserID 和 CategoryID 从表中选择 UserCategoryID,然后将其输入到表单上的字段中。我已经包含了我对查询设计的初步想法。请原谅语法 - VBA初学者。

感谢任何帮助

编辑——路人方的逻辑:

Private Sub FLower_Click()
    Dim catType As Integer
    catType = 2

    DoCmd.OpenForm "frm_RespondentUseCat", OpenArgs:=2


End Sub

Passee 方面的逻辑

Private Sub Form_Open(Cancel As Integer)
    Dim catType As Integer
    catType = Forms.frm_RespondentUseCat!OpenArgs

    Dim userID As Integer
    userID = Forms!Respondent.RespondentID.Value

    Dim strSQL As String
    strSQL = "SELECT * From RespondentUseCategories WHERE RespondentID = " & userID & " AND UseCategoryID = " & catType & ";"

    Dim results As DAO.Recordset
    Set results = CurrentDb.OpenRecordset(strSQL)

    If results.RecordCount > 0 Then
        Set Forms("frm_RespondentUseCat").Recordset = results

    Else
        Me.UseCategoryID.Value = catType
        Me.RespondentID.Value = userID

    End If

End Sub

本质上,传递者(即带有按钮的父表单)将简单地传递反映点击了什么按钮的类别类型。在被接受者方面,表单将在它打开的事件上执行一些代码。首先它会收集类别类型,然后它会尝试从父表单 (Respondent) 中读取用户 ID (RespondentID) 值。然后它将使用这两个值从 UserCategory 表 (RespondentUseCategories) 中获取相关记录。如果这里有任何数据,那么我们将其用作表单的记录集,如果没有,我们使用收集的值填充 userID 和 categoryID,并让 UserCateogryID 自动填充。这似乎是正确的方法,但是,当我尝试存在记录的测试用例(例如,已经遇到的用户和类别 IDS 的组合)时,子表单仍然未填充。我猜VBA中有一个错误。

【问题讨论】:

  • 设置复合索引将防止重复对。这意味着在多条记录中不允许使用 null。此外,使用代码来验证条目。您没有提供任何分析代码,因此这个问题并不适合 SO。
  • 您的代码需要在设置字段值之前进行验证。 VBA 可以使用 SELECT sql 语句打开根据给定条件过滤的数据记录集。如果记录集为空,则数据不存在。还可以使用 DLookup 和 DCount 域聚合函数来查询数据以查找匹配项。数据验证是许多论坛中的常见主题。在表单之间传递数据也是如此。

标签: vba forms ms-access


【解决方案1】:

使用 UserID 和 CategoryID 在 UserCategory 表上创建一个双键,如下所示: https://www.access-programmers.co.uk/forums/threads/how-to-put-two-primary-keys-in-one-table.225908/

现在,如果有人找到尝试添加 UserID 和 CategoryID 的非唯一组合的方法,Access 将引发错误。接下来使用设计器,我希望你会得到类似的东西:

注意文本框已被组合框替换,并且用户表单是所有标题,因为子表单显示了详细信息。用户表单记录源是用户,子表单记录源是用户类别。表单和子表单仅由 UserID 链接。此时,如果有人尝试输入用户和类别的非唯一组合,则访问会引发错误,但我不想输入不正确的数据,所以我想出了以下内容: 在 UserCategorysForm 的数据属性下设置允许数据输入和允许添加到否,因此数据输入者必须使用按钮添加记录,然后设置按钮以添加用户/类别组合(如果它不存在)并删除该组合如果它会的。

    Private Sub cmbUserName_AfterUpdate()
Me.Filter = "UserID = " & Me.cmbUserName.Value
Me.FilterOn = True
End Sub

'TODO ADD CODE TO CHANGE BUTTON CAPTION BASED ON WHETHER BUTTON WILL ADD OR REMOVE CATEGORY
Private Sub cmdCommand_Click()
AddRemoveRecordFromUserCategoryTable 1
End Sub
Private Sub cmdScience_Click()
AddRemoveRecordFromUserCategoryTable 2
End Sub
Private Sub AddRemoveRecordFromUserCategoryTable(ID As Integer)
DoCmd.SetWarnings False
If IsNull(DLookup("UserCategoryID", "UserCategory", "UserID = " & Me.cmbUserName.Value & " AND CategoryID = " & ID)) Then
DoCmd.RunSQL ("INSERT INTO UserCategory (UserID, CategoryID) VALUES(" & Me.cmbUserName.Value & ", " & ID & ")")
Else
DoCmd.RunSQL ("DELETE * FROM UserCategory WHERE UserID = " & Me.cmbUserName.Value & " AND CategoryID = " & ID)
End If
DoCmd.SetWarnings True
Me.Refresh
End Sub

现在表单会在添加之前检查用户/类别组合是否已经在表中,而是删除记录以防止添加重复的组合。 hit 命令删除记录(未显示)。击中科学增加了记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多