问题描述
我有两个表(skillsMatrix),另一个表是(elementTree),表skillsMatrix中有[mediumElement],[ID]列,mediumElement是表二中mediumElements的查找下拉列表。我想编写一个宏来更新技能矩阵表,以便在向 elementTree 添加新的 mediumElement 时添加新记录“名称”、“新主题”、“”,并且不复制任何其他记录。
表格:技能矩阵
id | 员工 | mediumElement | completionDate |
---|---|---|---|
自动编号 | 戴夫 | 步行 | 10/27/2020 |
表格:元素树
Id | mediumElement |
---|---|
26 | 步行 |
27 | 运行 |
我希望在运行代码后的 SkillsMatrix 表看起来像这样
我尝试了以下方法来解决构建逻辑的问题。以下打印出 RS 始终以 1 开头,ME 以元素树中 mediumElement 的正确 ID 开头。
rs
1
我
26
rs
2
我
27
rs
3
我
28
rs
4
我
29
rs
5
我
30
rs
6
我
31
rs
7
我
32
rs
8
我
33
rs
9
我
34
rs
10
我
35
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim mediumElements As DAO.Recordset
Dim employeeTable As DAO.Recordset
Dim strsql As String
Dim strsqlName As String
Dim strsqlintegrityCheck As String
Dim idValue As Long
Dim recordExists As Boolean
If Me.Dirty = True Then Me.Dirty = False 'Save any unsaved data
Set db = CurrentDb
strsqlName = "SELECT employeeTable.ID,employeeTable.[Employee Name] FROM employeeTable WHERE (((employeeTable.[Employee Name])=""" & Me.employeeName & """));"
Set employeeTable = db.OpenRecordset(strsqlName)
idValue = employeeTable.Fields("ID")
Debug.Print (idValue)
strsqlintegrityCheck = "Select skillsMatrix.employee,skillsMatrix.mediumElement From skillsMatrix Where skillsMatrix.employee = " & idValue & ""
Set rs = db.OpenRecordset("skillsMatrix")
strsql = "Select elementTree.[ID],elementTree.[mediumElement] From elementTree Where ( elementTree.plantPosition = " & Me.jobPosition & ")"
'Debug.Print strsql
Set mediumElements = db.OpenRecordset(strsql)
Debug.Print employeeTable.Fields("ID")
If Not mediumElements.BOF And Not mediumElements.EOF Then
mediumElements.MoveFirst
rs.MoveFirst
While (Not mediumElements.EOF)
Debug.Print ("rs")
Debug.Print rs.Fields("mediumElement").Value
Debug.Print ("ME")
Debug.Print mediumElements.Fields("id")
If (rs![employee] <> employeeTable.Fields("ID") And rs![mediumElement] <> mediumElements.Fields("ID")) Then
With rs
.AddNew
![employee] = employeeTable.Fields("ID")
![mediumElement] = mediumElements.Fields("ID")
.Update
End With
End If
rs.MoveNext
mediumElements.MoveNext
Wend
End If
rs.Close
Set rs = nothing
Set mediumElements = nothing
Set employeeTable = nothing
没有任何事情发生/错误发生,因为 rs.Fields("mediumElement") 没有给出我期望的正确值。而不是 rs.[mediumElement] 显示 elementTree 表中元素的查找 ID,它始终显示 1 到 RS 中 rs.Fields("mediumElement") 的记录数。有一个员工表,ID 保存在技能矩阵中。虽然我在建立连接时使用了查找向导,所以这可能是问题所在。我为我糟糕的白话道歉,我对访问和 sql 还很陌生。
我不希望所有员工都使用关联的新元素进行更新。该代码是由按下按钮控制的子,并在该表单上选择要更新的员工,并使用控件 employeeName
编辑: 关于调查插入选择的建议
以下用于将 mediumElements 添加到技能矩阵表中的工作, 基于用户是否存在它们。有没有办法把员工姓名也加到技能矩阵表中,同一个Insert Into?
Dim sqlString As String
Dim name As String
Dim strsqlName As String
Dim db As DAO.Database
Set db = CurrentDb
Dim employeeTable As DAO.Recordset
strsqlName = "SELECT employeeTable.ID,employeeTable.[Employee Name] FROM employeeTable WHERE (((employeeTable.[Employee Name])=""" & Me.employeeName & """));"
Set employeeTable = db.OpenRecordset(strsqlName)
idValue = employeeTable.Fields("ID")
Debug.Print (name)
sqlString = "INSERT INTO skillsMatrix (mediumElement)" _
& "SELECT elementTree.ID FROM elementTree " _
& "WHERE NOT EXISTS(SELECT * FROM skillsMatrix Where skillsMatrix.mediumElement = elementTree.ID AND skillsMatrix.employee = " & idValue & " ) "
DoCmd.Runsql sqlString
End Sub
解决方法
如果通过表单上的组合框选择员工,则无需打开记录集即可获取员工 ID。 EmployeeID 应该是组合框的隐藏列,组合框应该将其作为其值。
idValue = Me.employeeName
如果表单上没有员工 ID,则仍然不需要记录集。使用 DLookup。idValue = DLookup("ID","employeeTable","[Employee Name]='" & Me.employeeName & "'")
在 INSERT 子句中包含员工字段并连接 idValue 以在 SELECT from elementTree 子句中生成计算字段。
sqlString = "INSERT INTO skillsMatrix (employee,mediumElement) " _
& "SELECT " & idValue & " AS Emp,elementTree.ID FROM elementTree " _
& "WHERE NOT EXISTS(SELECT * FROM skillsMatrix WHERE skillsMatrix.mediumElement = elementTree.ID AND skillsMatrix.employee = " & idValue & " ) "
如果将employee 和mediumElement 定义为表中的复合索引,则不需要WHERE 条件,因为不允许重复对。我不知道这个 WHERE 标准是否会降低或提高性能。
如果可以从表单中捕获新的元素 ID,请简化代码:
sqlString = "INSERT INTO skillsMatrix (employee,mediumElement) " _
& "VALUES(" & idValue & "," & idElement & ")"
使用 CurrentDb.Execute
而不是 DoCmd.RunSQL
并且不会弹出警告。