【发布时间】:2017-06-13 16:36:38
【问题描述】:
当表单打开时(通过 Append 查询)添加数据时,我很难让子表单显示最新数据。
与问题相关的表/表单/VBA & SQL 的快速解释:
我有三个表格,其中记录了我部门内的团队、团队中可用的工作角色以及每个角色可用的职位总数。
这些表格是:
- 团队:TeamID (AutoNum, PK)、TeamName (Text)、CostCode (Text)
- 角色:RoleID (AutoNum, PK)、RoleDesc (Text)、Abbrev (Text)
- Team_Composition:TeamID (Num, PK), RoleID (Num, PK), RoleCount (Num)
主窗体的 RecordSource 位于 Teams 表中。
子表单的 RecordSource 是一个查询,允许用户在 RoleCount 字段中为每个团队中的每个角色输入所需的数字:
SELECT Team_Composition.TeamID
, Roles.RoleDesc
, Roles.Abbrev
, Team_Composition.RoleCount
FROM Team_Composition INNER JOIN Roles ON Team_Composition.RoleID = Roles.RoleID
WHERE Team_Composition.TeamID=[Forms]![Edit_Teams]![cmbTeamName]
主窗体上的 Team Name 组合框从 Teams 表中获取数据,并添加 作为列表中的第一项(SingleRecord 表就是这样 - 一个具有 1 个字段和 1 个记录的表,因此 SELECT 将起作用):
SELECT DISTINCT 0 AS TeamID
, '<New Team>' AS TeamName
FROM SingleRecord
UNION ALL SELECT TeamID
, TeamName
FROM Teams
ORDER BY TeamName
当打开表单时一切都已经存在时,这一切都很好。我可以更改组合框中的值并触发 VBA 代码以移动到该记录并在子表单中显示链接的数据。然后我可以添加每个团队的总数。
移动到正确记录的代码如下:
'----------------------------------------------------------------------------------
' Procedure : cmbTeamName_AfterUpdate
' Author : Darren Bartrup-Cook
' Date : 12/06/2017
' Purpose : Keeps the details on the form in sync with the team selected in the combo box.
' Ensures all teams have all roles available to them by updating the team_composition
' table with new roles whenever the team is selected.
'-----------------------------------------------------------------------------------
Private Sub cmbTeamName_AfterUpdate()
'The first item in cmbTeamName is <New Team> which will not exist in the recordset.
'To avoid FindFirst going to the wrong record an attempt is made to create a new record
'allowing the form to filter to a non-existant record.
If cmbTeamName = 0 Then
DoCmd.GoToRecord , , acNewRec
Else
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[TeamID]=" & cmbTeamName
If Not (rs.BOF And rs.EOF) Then
Me.Recordset.Bookmark = rs.Bookmark
End If
rs.Close
Set rs = Nothing
If cmbTeamName <> 0 Then
Update_TeamComposition cmbTeamName.Column(1)
End If
End If
End Sub
Update_TeamComposition 过程执行 SQL 语句以确保团队拥有最新的可用角色列表:
Private Sub Update_TeamComposition(TeamName As String)
With DoCmd
.SetWarnings False
.RunSQL "INSERT INTO Team_Composition(TeamID, RoleID) " & _
"SELECT TeamID, RoleID " & _
"FROM Teams, Roles " & _
"WHERE TeamID = (SELECT TeamID FROM Teams WHERE TeamName='" & TeamName & "')"
.SetWarnings True
End With
End Sub
现在是问题代码(或者至少我认为问题出在哪里):
当一个新团队被添加到组合框时,它被插入到 Teams 表中,并且各种角色也被添加到 Team_Composition 表中。这有效 - 我可以打开表格并查看其中的记录,但子表单拒绝更新和显示新记录。数据库 ID 显示为 1。表单底部的记录计数显示记录 1 of 6,即使这是我添加的第 7 条记录 - Teams 表显示 7 条记录,Team_Composition 表显示角色已添加到 Team ID 7。
添加新团队的 VBA 如下:
Private Sub cmbTeamName_NotInList(NewData As String, Response As Integer)
With DoCmd
.SetWarnings False
If cmbTeamName.OldValue = 0 Then
'A new team needs adding to the Team table.
.RunSQL "INSERT INTO Teams(TeamName) VALUES ('" & NewData & "')"
Response = acDataErrAdded
'The job roles for the team are inserted.
Update_TeamComposition NewData
Else
.RunSQL "UPDATE Teams SET TeamName = '" & NewData & "'" & _
"WHERE TeamID = " & cmbTeamName.Column(0)
Response = acDataErrAdded
End If
.SetWarnings True
End With
End Sub
我尝试在 Else 语句之前添加代码以刷新表单 - Me.Refresh、Me.Requery、Me.Repaint。
Me.Requery和Me.Refresh 导致NotInList 代码运行多次并最终给出run-time 2237 - The text you entered isn't an item in the list(在Me. 行上)。
Me.Repaint 似乎没有做任何事情。
我想我已经包含了所有内容 - 有谁知道在添加新团队时如何让子表单填充角色?对我来说,表索引似乎没有更新,并且表单无法识别已创建新记录。
编辑:
根据@June7 的建议,我将NotInList 代码更新为:
Private Sub cmbTeamName_NotInList(NewData As String, Response As Integer)
With DoCmd
.SetWarnings False
If Me.cmbTeamName.OldValue = 0 Then
'A new team needs adding to the Team table.
.RunSQL "INSERT INTO Teams(TeamName) VALUES ('" & NewData & "')"
Response = acDataErrAdded
'The job roles for the team are inserted.
Update_TeamComposition NewData
'To stop the Requery from making NotInList fire multiple times
'the combo box is moved to a team that does exist before the requery.
'Then it can move to the new record.
Me.cmbTeamName = Me.cmbTeamName.ItemData(0)
Me.Requery
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
rs.FindFirst "[TeamName]='" & NewData & "'"
Me.Recordset.Bookmark = rs.Bookmark
rs.Close
Set rs = Nothing
Me.cmbTeamName.Requery
Me.cmbTeamName = CLng(Me.txtTeamID)
Else
.RunSQL "UPDATE Teams SET TeamName = '" & NewData & "'" & _
"WHERE TeamID = " & Me.cmbTeamName.OldValue
Response = acDataErrAdded
End If
.SetWarnings True
End With
End Sub
我还更新了子表单的 SQL,删除了 WHERE 子句,允许表单使用主/子链接。
【问题讨论】:
标签: vba ms-access ms-access-2010