【问题标题】:Adding new records to Access table on an update to a linked table in Access VBA SQL在 Access VBA SQL 中更新链接表时向 Access 表添加新记录
【发布时间】:2021-01-07 17:59:30
【问题描述】:

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

表格:技能矩阵

id employee mediumElement completionDate
autoNumber Dave Walking 10/27/2020

表格:元素树

Id mediumElement
26 Walking
27 Running

我希望技能矩阵表在运行代码后看起来像这样

id employee mediumElement completionDate
autoNumber Dave Walking 10/27/2020
autoNumber Dave Running

我已尝试以下方法来排除故障以构建逻辑。以下打印出 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 还很陌生。

我不希望所有员工都使用关联的新元素进行更新。该代码是由按钮按下控制的子,并且在该表单上选择要更新的员工,并使用控件员工姓名

编辑: 关于插入选择的建议

以下工作用于将 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


【问题讨论】:

  • 问题是什么?您遇到了什么问题 - 错误消息,错误结果,没有任何反应?将skillMatrix中的employee和mediumElement字段设置为复合索引,不允许重复对。有雇员表吗?您是否真的在技能矩阵中保存了员工 ID 和元素 ID?您是否希望所有员工都与新元素相关联?尝试使用INSERT SELECT 操作 SQL,而不是循环记录集。
  • @June7 没有任何事情发生/错误的事情发生,因为 thers.Fields("mediumElement") 没有给出我期望的正确值。不是 rs.[mediumElement] 显示 elementTree 表中元素的查找 ID,而是始终显示 1 到 RS 中 rs.Fields("mediumElement") 的记录数。有一个员工表,ID 保存在技能矩阵中。尽管我在建立连接时使用了查找向导,但这可能是问题所在。我为我糟糕的白话道歉,我对访问和 SQL 还是很陌生。我将研究 INSERT SELECT。谢谢
  • 应该用相关信息编辑问题,这样读者就不必扫描 cmets 并将各个部分拼凑起来。没有回答问题“您希望所有员工都与新元素相关联吗?”。我建议不要在表中建立查找字段。
  • @june7 感谢您的帮助。我对问题添加了编辑并修改了函数以使用插入选择,我不确定的一件事是如何使用插入选择将员工姓名也添加到技能矩阵中。我不希望所有员工都使用关联的新元素进行更新。该代码是由按钮按下控制的子代码,并且在该表单上选择要更新的员工,并使用控件员工姓名
  • 表单后面的代码是否用于输入新元素?如果是这种情况,那么新的元素 ID 应该可供参考,并且代码可以更简单。代码在什么事件中?

标签: sql vba ms-access


【解决方案1】:

如果通过表单上的组合框选择员工,则无需打开记录集即可获取员工 ID。 EmployeeID 应该是组合框的隐藏列,并且组合框应该将其作为其值。

idValue = Me.employeeName

如果员工 ID 在表单上不可用,则仍然不需要记录集。使用 DLookup。
idValue = DLookup("ID", "employeeTable", "[Employee Name]='" &amp; Me.employeeName &amp; "'")

在 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 不会弹出警告。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 2013-03-15
    • 2010-10-27
    相关资源
    最近更新 更多