更新查询以在MS Access表中的指定范围内插入缺少的日期

时间:2015-10-23 16:54:25

标签: sql excel vba ms-access access-vba

我有一个Access数据库,它跟踪作业数据的滚动35周窗口。我有自动化,所以每月一次我运行一个脚本,生成一个电子邮件,并为相应的项目经理附上一个Excel工作表,以便他们可以更新未来35周的船员数量预测。该程序保存Excel工作表的副本,以便我可以在返回工作表后运行比较。

我想要做的是在构建通过电子邮件发送的Excel表格之前,在数据集中添加缺少的日期。这样,我存储日期的表格会有一个自动生成的行项目编号,稍后当我从Excel文件重新导入数据时,我可以参考该编号。

我想我可以运行一个更新查询,将数据库中的所有作业记录扩展到相同的结束日期,然后在滚动窗口消失的情况下清除任何人员数量为零的内容,但是有一个更好的接近这个方法?

1 个答案:

答案 0 :(得分:1)

以下代码将: 1.添加缺失日期(但仅限于运行日期后4周内) 2.在当前日期之后添加35个新的“周”记录

此代码要求您的表格设计具有Job_ID + WeekDate的唯一键

Option Compare Database
Option Explicit

Dim dbs     As DAO.Database
Dim rsJobs  As DAO.recordSet
Dim rsWeek  As DAO.recordSet

Function Create_New_Weeks()
Dim strSQL  As String
Dim i       As Integer
Dim dStartDate      As Date
Dim dEndDate        As Date
Dim dPriorMonday    As Date
Dim dTempDate       As Date
Dim strJobID        As String

Const iWksToAdd = 35            ' Change as desired

    On Error GoTo Error_Trap

    Set dbs = CurrentDb

    ' Get Job_ID and Week records for all OPEN Jobs.
    ' Expect this to possibly be the first date, possibly a gap in dates, then
    ' one or more weekly dates.
    strSQL = "SELECT tblProjects.Job_ID, tblProjects.DateEnded, tblJobWeeks.WorkWeek " & _
                "FROM tblProjects INNER JOIN tblJobWeeks ON tblProjects.Job_ID = tblJobWeeks.Job_ID " & _
                "WHERE (((tblProjects.DateEnded) Is Null)) " & _
                "ORDER BY tblProjects.Job_ID, tblJobWeeks.WorkWeek;"
    Set rsJobs = dbs.OpenRecordset(strSQL)

    If rsJobs.EOF Then
        MsgBox "No Jobs found!", vbOKOnly + vbCritical, "No Jobs"
        GoTo Exit_Code
    Else
        rsJobs.MoveFirst
    End If

    ' First, find prior Monday's date as a baseline
    dPriorMonday = DateAdd("ww", -1, Date - (Weekday(Date, vbMonday) - 1))

    ' Calculate +35 weeks -- and make sure the date will be a monday.
    If Weekday(Date, 1) = 2 Then
        dEndDate = DateAdd("ww", iWksToAdd, Date)
    Else
        dEndDate = DateAdd("ww", iWksToAdd, dPriorMonday)
    End If

    ' Open the 'Weekly' table for inserting 35 new records, plus missing dates
    strSQL = "select * from tblJobWeeks order by Job_ID, WorkWeek"
    Set rsWeek = dbs.OpenRecordset(strSQL)

    ' FYI: It doesn't make sense to add records between the 'start' date and + 35 weeks, then
    ' have your monthly process delete empty ones from prior months.
    ' This code will only add missing records going back 4 weeks.

    ' Your notes indicated there would be at least two records for any given Job. If that is
    ' not correct, this code may not work!

    ' Save the starting point
    strJobID = rsJobs!Job_ID
    dTempDate = rsJobs!WorkWeek
    Do While Not rsJobs.EOF
        Debug.Print "Job: " & rsJobs!Job_ID & vbTab & "First Date: " & rsJobs!WorkWeek & vbTab & "W/E: " & rsJobs!WorkWeek
        If strJobID <> rsJobs!Job_ID Then   ' We have changed to a NEW Job_ID
            ' Fill the +35 weeks
            ' Only add prior 4 wks , then +35
            If dTempDate < dEndDate Then dTempDate = DateAdd("ww", -3, dPriorMonday)    ' Get date from 3 or 4 weeks back.
            Do
                If dTempDate < dEndDate Then
                    ' Don't add dates over 4 weeks old - Remove this if necessary
                    If dTempDate >= DateAdd("ww", -4, Date) Then
                        Debug.Print "Insert ID: " & strJobID & vbTab & dTempDate
                        Add_Week strJobID, dTempDate
                    Else
                        Debug.Print "Skip - Older than 4 weeks: " & vbTab & dTempDate
                    End If
                    dTempDate = DateAdd("ww", 1, dTempDate)
                Else
                    Exit Do
                End If
            Loop
            strJobID = rsJobs!Job_ID
            dTempDate = DateAdd("ww", 1, rsJobs!WorkWeek)       ' Should be the FIRST date for this Job
        Else
            If rsJobs!WorkWeek = dTempDate Then
                dTempDate = DateAdd("ww", 1, dTempDate)
            Else
                ' Don't add dates over 4 weeks old - Remove this if necessary
                If dTempDate > DateAdd("ww", -4, Date) Then
                    Debug.Print "Insert ID: " & strJobID & vbTab & dTempDate
                    Add_Week strJobID, dTempDate
                Else
                    Debug.Print "Skip - Older than 4 weeks: " & vbTab & dTempDate
                End If
                dTempDate = DateAdd("ww", 1, dTempDate)
            End If
        End If
        rsJobs.MoveNext
    Loop

    'Check if last ID has +35 dates
    If dTempDate < dEndDate Then
        Do Until dEndDate = dTempDate
            ' Don't add dates over 4 weeks old - Remove this if necessary
            If dTempDate > DateAdd("ww", -4, Date) Then
                Debug.Print "Insert ID: " & strJobID & vbTab & dTempDate
                Add_Week strJobID, dTempDate
            Else
                Debug.Print "Skip - Older than 4 weeks: " & vbTab & dTempDate
            End If
            dTempDate = DateAdd("ww", 1, dTempDate)
        Loop
    End If

Exit_Code:
    If Not rsJobs Is Nothing Then
        rsJobs.Close
        Set rsJobs = Nothing
    End If
    If Not rsWeek Is Nothing Then
        rsWeek.Close
        Set rsWeek = Nothing
    End If
    dbs.Close
    Set dbs = Nothing
    Exit Function
Error_Trap:
    Debug.Print Err.Number & vbTab & Err.Description & vbCrLf & "In:       Create_New_Weeks"
    ' If duplicate record, ignore
    If Err.Number = 3022 Then
        Resume Next
    End If
    MsgBox Err.Number & vbTab & Err.Description & vbCrLf & "In: Create_New_Weeks"
    Create_New_Weeks = "Error: " & Err.Number & vbTab & Err.Description & vbCrLf & "In: Create_New_Weeks"
    Resume Exit_Code
    Resume
End Function

Function Add_Week(strID As String, dDate As Date)
    With rsWeek
        .AddNew
        !Job_ID = strID
        !WorkWeek = dDate
        !Crew_Num = 0
        .Update
    End With

End Function