在更新到 Access VBA SQL

问题描述

我有两个表(skillsMatrix),另一个表是(elementTree),表skillsMatrix中有[mediumElement],[ID]列,mediumElement是表二中mediumElements的查找下拉列表。我想编写一个宏来更新技能矩阵表,以便在向 elementTree 添加新的 mediumElement 时添加新记录“名称”、“新主题”、“”,并且不复制任何其他记录。

表格:技能矩阵

id 员工 mediumElement completionDate
自动编号 戴夫 步行 10/27/2020

表格:元素树

Id mediumElement
26 步行
27 运行

我希望在运行代码后的 SkillsMatrix 表看起来像这样

id 员工 mediumElement completionDate
自动编号 戴夫 步行 10/27/2020
自动编号 戴夫 运行

我尝试了以下方法解决构建逻辑的问题。以下打印出 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 并且不会弹出警告。