【问题标题】:How to Insert a Variable Number of Records into an Access Table Based on a Fields Value如何根据字段值将可变数量的记录插入到访问表中
【发布时间】:2016-09-23 10:32:27
【问题描述】:

我有一个包含以下列的访问表:WeeklyID(PrimaryKey)、CampaignID(Foreignkey)、WeekEnded(Date Field)、Duration(Number Field)。

我想自动向表中添加 X 条记录,其中 X 是存储在 Duration 字段中的数字。我希望添加的记录与原始记录具有相同的 CampaignID。因此,当具有一个特定 CampaignID 的记录数等于 Duration 数时,将满足自动化流程。

如果有人能就如何实现这一点提供帮助,将不胜感激。如果您需要任何进一步的信息,请询问!

【问题讨论】:

  • 为什么需要这些记录?您希望何时添加它们?
  • 您是否也使用目标表作为源?您是否打算多次运行您的代码?
  • 目标表也是源表。但是,持续时间值也与外键相关联,即它也被存储并且可以从另一个表中提取,如果使用目标作为源会产生额外的问题。我计划在每次向表中添加新记录时自动调用代码以附加额外的记录。
  • @BitAccesser 我需要这些记录来为活动添加每周级别的数据,该表的列比我提到的 4 列要多,但这些是唯一对我的问题重要的列。跨度>
  • 我为另一个人做了一些代码来做类似的事情。您期望该表中有多少条记录?如果数以百万计,您需要一种在添加新记录时不会触及每条记录的方法。我建议设置初始表并且可以在将来运行以验证事情仍然正常的代码,然后代码只是为新记录添加所需的记录。你的 VBA 技能有多好?

标签: sql ms-access automation vba sql-insert


【解决方案1】:

这是一种方法。请注意,我计划在添加记录之后有人更改持续时间的场景。

Option Compare Database
Option Explicit

Dim dbs     As DAO.Database
Dim rs      As DAO.recordSet
Dim rsOT    As DAO.recordSet

Function Create_New_Rows()
Dim strSQL          As String
Dim i               As Integer
Dim iAdd            As Integer
Dim iDuration       As Integer
Dim lCampaignID     As Long


    On Error GoTo Error_trap

    Set dbs = CurrentDb

    strSQL = "SELECT Count(Campaign.WeeklyID) AS NbrRecs, First(Campaign.Duration) AS Duration, Campaign.CampaignID " & _
                "FROM Campaign " & _
                "GROUP BY Campaign.CampaignID;"
    Set rs = dbs.OpenRecordset(strSQL)
    Set rsOT = dbs.OpenRecordset("Campaign")
    If rs.EOF Then
        MsgBox "No records found!", vbOKOnly + vbCritical, "No Records"
        GoTo Exit_Code
    Else
        rs.MoveFirst
    End If

    Do While Not rs.EOF
        Debug.Print "Campaign: " & rs!CampaignID & vbTab & "Duration: " & rs!Duration & vbTab & "# Recs: " & rs!NbrRecs
        iDuration = rs!Duration
        lCampaignID = rs!CampaignID


        ' Check if already have correct number of records for this ID
        If iDuration = rs!NbrRecs Then
            ' Do nothing... counts are good
        ElseIf iDuration < rs!NbrRecs Then
            MsgBox "Add code to resolve too many records for Campaign: " & lCampaignID & vbCrLf & _
                "Duration: " & iDuration & vbCrLf & _
                "Records: " & rs!NbrRecs, vbOKOnly + vbCritical, "Too many records already!"
        Else
            ' Finally, Duration is less than existing records... time to add...
            iAdd = iDuration - rs!NbrRecs
            Do
                If iAdd > 0 Then
                    ' Add new record
                    Add_Records lCampaignID
                    iAdd = iAdd - 1
                Else
                    Exit Do
                End If
            Loop
        End If
        rs.MoveNext
    Loop

Exit_Code:
    If Not rs Is Nothing Then
        rs.Close
        Set rs = Nothing
    End If
    If Not rsOT Is Nothing Then
        rsOT.Close
        Set rsOT = Nothing
    End If
    dbs.Close
    Set dbs = Nothing

    MsgBox "Finished"

    Exit Function
Error_trap:
    Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In:   Create_New_Rows"
    MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: Create_New_Rows"
    Resume Exit_Code
    Resume
End Function

Function Add_Records(lCampID As Long)
    With rsOT
        .AddNew
        !CampaignID = lCampID
        ' Add code if you want to populate other fields...
        .Update
        'Debug.Print "Added rec for CampaingID: " & lCampID
    End With

End Function

【讨论】:

  • 谢谢!在接下来的几天里,我将尝试根据我的需要进行调整。我缺乏 VBA 知识可能会使其成为一个缓慢的过程,所以我可能会跟进一些问题。
  • 在这个 sn-p:If iAdd &gt; 0 Then ' Add new record Add_Records lCampaign iAdd = iAdd - 1 获取 ByRef 参数类型不匹配错误并突出显示“lCampaign”。对这里出了什么问题有任何想法吗?
  • 假设 CampaignID 是一个长整数,因此被调用子例程中的变量和参数需要更改为您的数据类型。例如,如果它是一个字符串,将 'lCampID As Long' 更改为 '... String' 并将 'lCampaignID as Long' 更改为 '... String' (加上任何其他必要的数据类型更改。
  • 再次感谢韦恩。当您为第一个函数 Create_New_Rows 声明变量时,我更改了变量类型,但忘记为第二个函数 Add_Records 执行相同的操作。现在我都改变了,它似乎工作了!
【解决方案2】:

您可以修改此函数以将 lngCount 设为固定值:

Public Sub CopyEmptyRecords()

  Dim rstSource   As DAO.Recordset
  Dim rstInsert   As DAO.Recordset
  Dim fld         As DAO.Field
  Dim strSQL      As String
  Dim lngLoop     As Long
  Dim lngCount    As Long
  Dim booCopy     As Boolean

  strSQL = "SELECT * FROM tblStats"
  Set rstSource = CurrentDb.OpenRecordset(strSQL)

  strSQL = "SELECT TOP 1 * FROM tblStatsNull"
  Set rstInsert = CurrentDb.OpenRecordset(strSQL)

  With rstSource
    .MoveLast
    .MoveFirst
    lngCount = .RecordCount            ' Set to fixed value of 7.
    For lngLoop = 1 To lngCount
      With rstInsert
        booCopy = False
        .AddNew
          For Each fld In rstSource.Fields
            With fld
              If .Attributes And dbAutoIncrField Then
                ' Skip Autonumber or GUID field.
              Else
                ' Copy field content.
                rstInsert.Fields(.Name).Value = .Value
                If Len(Trim(Nz(.Value, vbNullString))) = 0 Then
                  booCopy = True
                End If
              End If
            End With
          Next
        If booCopy = True Then
          .Update
        Else
          .CancelUpdate
        End If
      End With
      .MoveNext
    Next
    rstInsert.Close
    .Close
  End With

  Set rstInsert = Nothing
  Set rstSource = Nothing

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2020-01-14
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多