MS ACCESS 中的 VBA 调度算法

Posted

技术标签:

【中文标题】MS ACCESS 中的 VBA 调度算法【英文标题】:VBA Scheduling Algorithm in MS ACCESS 【发布时间】:2018-07-05 06:28:09 【问题描述】:

我想根据给定日期计算一些时间表。像我一样

    开始日期 结束日期 工作日,例如,星期一、星期三作为频率

我需要计算 weekly biweekly triweekly monthly quarterly 日期从开始日期和结束日期开始,也通过匹配给定的工作日。

举个例子

Date start = 05/07/2018
Date End = 15/07/2018
Frequency days = Saturday

我需要每周星期六的日期,然后是每两周的星期六日期,直到它到达结束日期。

我在 MS ACCESS VBA 中尝试了 DAYOFWEEK,这有点帮助,但我需要知道完整的解决方案,以便计算时间表。

感谢您的帮助。

谢谢

【问题讨论】:

您正在寻找DateAdd 函数。 @Andre 你知道的越多...DateAdd 似乎相当强大,实际上。另外,这不是一个完整的答案吗? 我猜你是对的。 :) @Inarion 【参考方案1】:

DateAdd Function 可以做到所有这些。

航空代码:

d = StartDate
Do While d <= EndDate
    Debug.Print d   ' <-- Output date
    Select Case Interval
        Case "biweekly": d = DateAdd("ww", 2, d)
        Case "monthly" : d = DateAdd("m", 1, d)
        ' etc.
    End Select
Loop

【讨论】:

谢谢。 DateAdd 看起来很有希望。但是我如何才能在 2 周后获得特定日期的日期,例如星期五。例如。 2 周、3 周、4 周等后的星期五日期是什么 @Aziz,我附加了一个查找工作日日期的函数。【参考方案2】:

对于月份,您应始终添加到原始开始日期,因为这可能是一个月的最后几天之一,因此会抵消月份较少天数之后的月份的日期。所以:

Dim StartDate   As Date
Dim EndDate     As Date
Dim NextDate    As Date
Dim Interval    As Long

StartDate = #1/31/2018#
EndDate = #6/30/2018#

Do
    NextDate = DateAdd("m", Interval, StartDate)
    Interval = Interval + 1
    Debug.Print NextDate
Loop Until NextDate >= EndDate

将返回:

2018-01-31
2018-02-28
2018-03-31
2018-04-30
2018-05-31
2018-06-30

对于从特定工作日开始,找到第一个,然后按上述添加间隔:

Public Function DateNextWeekday( _
  ByVal datDate As Date, _
  Optional ByVal bytWeekday As Byte = vbMonday) _
  As Date

' Returns the date of the next weekday, as spelled in vbXxxxday, following datDate.
' 2000-09-06. Cactus Data ApS.

  ' No special error handling.
  On Error Resume Next

  DateNextWeekday = DateAdd("d", 7 - (Weekday(datDate, bytWeekday) - 1), datDate)

End Function

【讨论】:

【参考方案3】:

这也应该可以 - 我已经包含输入框,因此您可以输入开始日期、完成日期、星期几和频率,因为我不知道您希望如何输入;这也会将值存储在 Table2 中,它有一个名为 Dates 的字段/列,然后你可以检索它们(我不知道你想如何检索日期,如果你想存储它们等).. .我希望这会有所帮助!:

Sub test()

'clear the table2:
CurrentDb.Execute "DELETE * FROM Table2"

Dim DBTest As String
Dim RSTest As DAO.Recordset
Dim i As Long
Dim selectorInitDate, selectorEndDate, DBDate As Date

'Enter Start Date
selectorInitDate = Format(InputBox("Initial Date"), "mm/dd/yyyy")
'Enter Finish Date
selectorEndDate = Format(InputBox("End Date"), "mm/dd/yyyy")
'Enter Day of the Week (example: Saturday)
selectorWeekDay = InputBox("Week Day")
'Enter Frecuency (example: weekly, biweekly, etc)
selectorFreqDays = InputBox("Frecuency Days")

If selectorWeekDay = "Sunday" Then WeekDaySelected = 1
If selectorWeekDay = "Monday" Then WeekDaySelected = 2
If selectorWeekDay = "Tuesday" Then WeekDaySelected = 3
If selectorWeekDay = "Wednesday" Then WeekDaySelected = 4
If selectorWeekDay = "Thursday" Then WeekDaySelected = 5
If selectorWeekDay = "Friday" Then WeekDaySelected = 6
If selectorWeekDay = "Saturday" Then WeekDaySelected = 7

If selectorFreqDays = "weekly" Then Freq = 7
If selectorFreqDays = "biweekly" Then Freq = 14
If selectorFreqDays = "triweekly" Then Freq = 21
If selectorFreqDays = "monthly" Then Freq = 30
If selectorFreqDays = "quarterly" Then Freq = 90


DBDate = Format(selectorInitDate, "mm/dd/yyyy")
Count = 0

Do While DBDate <= selectorEndDate

    If Weekday(DBDate) = WeekDaySelected Then

        DBTest = "INSERT INTO Table2 ([Dates]) " & _
                    " VALUES (" & _
                    "'" & DBDate & "');"

        CurrentDb.Execute DBTest

        DBDate = DBDate + Freq - 1

        Count = Count + 1

    End If

DBDate = DBDate + 1

Loop

'this retrieves in a msgbox the saturdays found between the two dates you specify:

DBTest = "SELECT * FROM Table2"

Set RSTest = CurrentDb.OpenRecordset(DBTest)

If Not RSTest.BOF And Not RSTest.EOF Then

    RSTest.MoveFirst

    Do While (Not RSTest.EOF)

        If Format(RSTest.Fields("Dates").Value, "mm/dd/yyyy") >= selectorInitDate And _
        Format(RSTest.Fields("Dates").Value, "mm/dd/yyyy") <= selectorEndDate Then

            mthString = mthString & RSTest.Fields("Dates") & ", "

        End If

      RSTest.MoveNext

     Loop

   End If

' (remove last comma)
mthString = Left(mthString, Len(mthString) - 2)

MsgBox Count & " " & selectorWeekDay & "(s) Added" & Chr(43) & mthString

'clear the table2:
CurrentDb.Execute "DELETE * FROM Table2"

End Sub

按照您的示例,这应该会告诉您每周两个日期之间有多少个星期六,以及这些日期。

注意:您需要在参考中选择“Microsoft DAO 3.6 对象库”

【讨论】:

太棒了。非常感谢。仅 2 cmets 1. 如果我们有多个工作日,例如星期五|星期六,用管道符号分隔 2. 如何选择引用我正在使用 MS Access 2016 的“Microsoft DAO 3.6 对象库”。 1.您可以使用管道符号从字符串中提取“星期五”和“星期六”,然后运行宏; 2. 在 Visual Basic 编辑器中,您必须选择 Tools > References... > Microsoft DAO 3.6 Object Library - :) 非常感谢。您的解决方案效果很好。有一个问题。假设我选择了本周的星期六,并希望获得下周星期一的日期。你知道下周将在一天后开始。但是在您的解决方案中,您要添加 7、14、21 等等。它将日期带到未来,我们无法获得过去的那一周特定日期。我希望你明白我想说什么。 在第一次查找后添加7,14等,所以如果输入7/7/2018是星期六,然后选择星期一,它应该检索下星期一是7/9/ 2018. 是的,这是错误的。它应该检索当前的星期一。【参考方案4】:

如果您只想将双周日期以 14 天为增量分组,从某个开始日期(例如一年中的第一周)开始,indate 可以是当前日期或您选择的某个日期,或者您可以只是今天() .

Function biweeklyDate(indate as date) as Date
biweeklyDate = (DateSerial(2021,1,4)-indate) Mod 14 + inDate
End function

【讨论】:

以上是关于MS ACCESS 中的 VBA 调度算法的主要内容,如果未能解决你的问题,请参考以下文章

《操作系统_时间片轮转RR进程调度算法》

处理机调度算法

可抢占的优先级调度算法算例:CPU利用率

LVS调度算法

操作系统中的几种调度算法(JAVA版)

操作系统进程调度算法