在 MS Access 中插入具有日期范围的多条记录

Posted

技术标签:

【中文标题】在 MS Access 中插入具有日期范围的多条记录【英文标题】:Insert multiple records with a date range in MS Access 【发布时间】:2017-01-23 23:25:45 【问题描述】:

希望有人能提供帮助?我是 Access 2016 的新手,我的任务是为我们学校的早餐和课后俱乐部建立一个非常简单的预订系统。 我有一个包含儿童列表的表(主键是 ChildID),另一个表(CLUBS)列出了 5 个可用的俱乐部,第三个表(BOOKINGS)将孩子连接到俱乐部(ChildID、ClubID、DateRequested)

我有一个简单的表格,可以让我从下拉框中选择一个孩子的名字,然后从列表中选择一个俱乐部,然后输入所需的日期。这会将记录保存到 Bookings 表中。

这很好用,但是为了使其更易于使用...我在表单中添加了未绑定的开始和结束日期字段,以便能够在一个学期内快速预订孩子...即我不必单独添加每一天,而是输入孩子的名字,选择一个俱乐部,然后输入开始和结束日期。在预订表中创建了多条记录,其中 Child ID、Club ID 相同,但 DateRequested 字段有所不同。

我们确实需要在每个日期为孩子在 Bookings 表中存储一条记录,这样我们就可以为每一天打印一个登记册……以及开具发票/报告。

从查看 VBA...我想我需要使用 INSERT INTO 命令?是最好的方法吗?我还需要确保忽略周六/周日范围内的日期。

我非常感谢任何关于此的指导以及哪些命令最有效的指针......

【问题讨论】:

使用Insert,您将需要编写一个大的SQL 字符串并立即执行它。 Recordset.Addnew 是另一种选择,但前者更可取。在这两种情况下,您都需要一个 VBA 循环。考虑创建一个存储过程(MS-Access 中的查询),您只需向它提供ChildIdTermId,它就会在服务器上完成这项工作。 IMO 这将是最好的选择。 【参考方案1】:

这是 DAO 的亮点。运行循环添加记录比多次调用 Insert Into 快得多。

方法如下:

Public Function PopulateBokings()

    Dim rsBookings  As DAO.Recordset
    Dim NextDate    As Date

    Set rsBookings = CurrentDb.OpenRecordset("Select Top 1 * From Bookings")

    NextDate = Me!StartDate.Value
    While DateDiff("d", NextDate, Me!EndDate.Value) >= 0
        If Weekday(NextDate, vbMonday) > 5 Then
            ' Skip Weekend.
        Else
            rsBookings.AddNew
                rsBookings!ChildrenId.Value = Me!ChildrenId.Value
                rsBookings!ClubsId.Value = Me!ClubId.Value
                rsBookings!DateRequested.Value = NextDate
            rsBookings.Update
        End If
        NextDate = DateAdd("d", 1, NextDate)
    Wend
    rsBookings.Close

    Set rsBookings = Nothing

End Function

将代码粘贴到表单的代码模块中,将字段和控件名称调整为您的名称,然后从按钮的Click事件中调用该函数。

【讨论】:

非常感谢古斯塔夫....它第一次工作!剩下的唯一一个问题是如何阻止非工作日的到来(周六/周日)......所以如果日期范围是 14 天 - 应该只添加 10 条记录......【参考方案2】:

考虑填充一个单独的 DateRange 表,该表包含所有可能的日期,例如 2017 年的所有日期。您可以使用 VBA 中的动态 SQL 查询调用迭代地构建这样的表。并且只运行一次。

然后,创建一个存储查询,将 ChildrenClubDateRange 与所有表单参数的过滤器进行交叉连接。这将返回所有可能的日期范围,重复相同的 Child 和 Club 以进行表追加。

VBA

Public Sub PopulateTime()
    Dim i As Integer, StartDate As Date

    CurrentDb.Execute "CREATE TABLE DateRange (" _
                             & " [ID] AUTOINCREMENT PRIMARY KEY," _
                             & " [BookDate] DATETIME)", dbFailOnError

    StartDate = DateSerial(2017, 1, 1)
    For i = 0 To 364
          CurrentDb.Execute "INSERT INTO DateRange ([BookDate])" _
                 & " VALUES (#" & DateAdd("d", i, StartDate) & "#);", dbFailOnError
    Next i

End Sub

SQL

INSERT INTO Bookings (ChildID, ClubID, DateRequested)
SELECT c.ChildID, b.ClubID, d.BookDate
FROM Children c, Clubs b, DateRange d
WHERE c.ChildID = Forms!myformname!ChildID
  AND b.ClubID = Forms!myformname!ClubID
  AND d.BookDate BETWEEN Forms!myformname!StartDate 
                     AND Forms!myformname!EndDate

【讨论】:

【参考方案3】:

您可以使用序列生成器查询在两个参数之间重复向表中插入行。

对于此示例,插入的最大天数为 999,但可以轻松增加到 9999 甚至更多。

灵感来自 Gustav 的 this answer:

PARAMETERS [StartDate] DateTime, [EndDate] DateTime;
INSERT INTO MyTable(MyDateField)
SELECT DISTINCT [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1
FROM MSysObjects As Ones, MSysObjects As Tens, MSysObjects As Hundreds
WHERE [StartDate] - 1+ 100*Abs([Hundreds].[id] Mod 10) + 10*Abs([Tens].[id] Mod 10)+Abs([Ones].[id] Mod 10)+1 Between [StartDate]-1 And [EndDate]

性能不会很好,但使用非 VBA 解决方案有多种优势。

【讨论】:

以上是关于在 MS Access 中插入具有日期范围的多条记录的主要内容,如果未能解决你的问题,请参考以下文章

MS Access:从日期时间值返回特定日期的查询

MS Access 日期范围函数减慢查询速度

MS-Access 中的多个日期范围

在 Ms Access 中的特定时间范围内的特定日期运行宏

MS Access:使用 VBA 进行 SQL 插入的日期格式

经典 ASP 和 ms-access:插入数据的问题