【问题标题】:Looping through multiple date records to find the number of days循环遍历多个日期记录以查找天数
【发布时间】:2014-04-29 15:36:45
【问题描述】:

需要遍历日期记录以计算工作天数。日期的数量因人而异,可能少至 1 个,也可多至 11 个,以从序列中的最后一个日期到当前日期的计算结束。

数据示例:

Employee No     Date     
4522            08/11/2011
4522            09/06/2011
4522            05/04/2013
4522            07/15/2013
4522            01/31/2014

所以今天是 2014 年 4 月 29 日,所以从 01/31/2014 到 04/29/2014 是 88 天,从 05/04/2013 到 07/15/2013 是 72 天,从 08/11/2011 到2011 年 9 月 6 日是 26 天。将这些加在一起,您总共工作了 186 天。

同样,日期的数量在每种情况下都会有所不同。

这是我目前所拥有的......

Sub getActualEmployment(empID As Variant)
  Dim strconnection, strSQL As String
  Dim conn As ADODB.Connection
  Dim tbl As ADODB.Recordset
  Dim OptimumCode As String
  Dim orghrdt As Date
  Dim intNumDays As Integer

  strSQL = "SELECT EmployeeID,EffectiveDate, OriginalHireDate FROM "
  strSQL = strSQL & "EmploymentStatusChanges WHERE EmployeeID= '" & empID & "'"
  strSQL = strSQL & " Order by EffectiveDate ASC"

  Set tbl = New ADODB.Recordset

  With tbl
    Set .ActiveConnection = conn
    .Source = strSQL
    .LockType = adLockOptimistic
    .CursorType = adOpenKeyset
    .CursorLocation = adUseClient
    .Open
  End With

  With tbl
    On Error Resume Next
    .MoveFirst
      Do Until tbl.EOF
        If tbl!OriginalHireDate = tbl!EffectiveDate Then
          orghrdt = tbl!EffectiveDate
        Else
          intNumDays = CInt(DateValue(tbl!EffectiveDate) - orghrdt)

        End If
        .MoveNext
      Loop
  End With

End Sub

这是整个函数代码,希望这更有意义。

【问题讨论】:

    标签: sql function loops ms-access vba


    【解决方案1】:
    SELECT Employees.[Employee No], Employees.Action, Employees.DDate AS Start, Min(IIf([employees_1].[DDate]>=[employees].[ddate],[employees_1].[ddate])) AS [End], IIf([end] Is Not Null,[end],Now())-[start] AS Days
    FROM Employees LEFT JOIN Employees AS Employees_1 ON Employees.[Employee No] = Employees_1.[Employee No]
    WHERE (((Employees_1.Action)="term"))
    GROUP BY Employees.[Employee No], Employees.Action, Employees.DDate
    HAVING (((Employees.Action)="hire" Or (Employees.Action)="rehire"));
    

    此查询提供了所有招聘事件和相应条款的列表,并为每个事件计算了天数。在查看第一个查询的结果后,您可以使用第二个查询按员工汇总天数。

    注意 - 这假设您有一组交替的雇用/终止事件。如果没有,您可能需要为此添加一些验证。另外,我认为 Date 是保留的,所以我使用 DDate 作为字段名。

    【讨论】:

    • 我需要能够在 VBA 中以编程方式执行此操作,而不是使用查询,因为原始数据未保存在我的 access 数据库中,而是一个单独的 SQL 数据库。
    • 您不能将 SQL 表作为表附加到您的数据库中,然后使用查询吗?或者将上面的逻辑转换为 VBA 脚本中的 SQL 语句?
    【解决方案2】:

    在调用 MoveFirst 方法和迭代记录集之前,请始终确保检查记录数以确保至少有一条记录。这比依赖错误处理程序更好。

    当您说想要前两个日期之间的天数时,您是指第 0 行和第 1 行中“日期”列中的日期,还是指我们在其他列中的同一行中的日期?图片中看不到?我假设还有其他日期列“OriginalHireDate”和“EffectiveDate”。

    使用 VB6 中的 DateDiff 函数计算日期之间的差异。此处概述:

    http://www.chennaiiq.com/developers/reference/visual_basic/functions/datediff.asp

    intNumDays = DateDiff("d", CDate(tbl!EffectiveDate), orghrdt)
    

    这将返回 tbl!EffectiveDate 和 orghrdt 之间的天数。如果后者在前者之后,它将返回一个正数,如果前者在后者之后,它将返回一个负数。

    如果你能澄清你的表结构和我以前的查询,我会看看我是否能进一步帮助你。您应该能够实现您的目标,而无需遍历整个记录集。

    【讨论】:

    • 感谢@GuruJosh 的回复,在这种情况下,总会有至少一条记录。图片中的日期只是一个例子。我们可以雇佣和任命一个特定的人 11 次。给我们总共 23 条记录(每次的雇用日期和任期日期,以及最新的雇用日期)。我没有提到所有这些员工目前都在工作。名称 originalhiredate 和 effectivedate 列的名称。 OriginalHireDate 始终是 EffectiveDate 列中的第一个日期,因此它位于两个位置。
    • 我很困惑。上面的记录集没有任何在查询的 SELECT 部分中引用的 3 列。正如唐乔治所说,我不相信“日期”这个词是合法的列名。
    • 关于记录的数量,即使您认为记录总是存在的,检查记录仍然是一个好习惯。在这种情况下,使用“On Error Resume Next”是不好的编程习惯。如果发生任何类型的错误,那么您的函数将错误地捕获数据。更好地通过程序逻辑预测任何潜在错误并使用错误处理程序捕获任何其他错误,提醒用户(以及测试期间的您自己)发生错误并且不允许应用程序继续并返回不正确的数据。
    猜你喜欢
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多