如何在MS Access报告中使用VBA对计算字段求和

时间:2015-09-22 18:47:41

标签: vba ms-access report calculated-field

我希望有人能指出我在这里正确的方向,并希望我能够清楚地解释清楚。我的报告收到了不良后果,因为我需要对计算字段求和。 “员工ID”标题中的“员工姓名”,“周”标题中的标签以及“详细信息”标题中的“日期”和“计算小时数”均正确显示。但是,Access正在以错误的顺序填写信息。

这是它正在做的事情:

计算并填写该期间最后一周的最后一天的小时数 - >

填写该期间最后一周的小时数 - >

填写期间的小时数 - >

计算并填写该期间前一周的最后一天 - >

填写上一周的小时数 - >

重复到第一周。

然后填写剩下的计算时间。

所以我的结果显示如下:(请注意舍入是有意的,我之所以不能在页脚中执行= Sum([Hours])

Employee Name
    Date       Hours    Reg     OT
    9/8/15      8:00
    9/9/15      8:28
    9/10/15     8:00
    9/11/15     7:32 <--Inputs this fourth
    ------------------------------
Week Totals:    7:30   7:30   0:00 <--Inputs this fifth then fills in other dates

    Date       Hours    Reg     OT
    9/14/15     9:43
    9/15/15     8:00
    9/16/15    13:14
    9/17/15    11:39
    9/18/15     5:25 <--Starts here first
    ------------------------------
Week Totals:    5:30   5:30   0:00 <--Inputs this second
    ------------------------------
Period Totals:  5:30   5:30   0:00 <--Inputs this third

以下是我现在的报告设置方式:

Employee Name                                                        (Employee ID Header)
Date       Hours                Regular            Overtime          (Week Header)
=[Date]    =CalcHours([Hours])                                       (Details)    
           =GetWeekTot()        =GetWeekReg()      =GetWeekOT()      (Week Footer)
           =GetPeriodTot()      =GetPeriodReg()    =GetPeriodOT()    (Employee ID Footer)

这是我的模块:

Option Compare Database
Option Explicit

Private WeekTot As Double
Private WeekReg As Double
Private WeekOT As Double

Private PeriodTot As Double
Private PeriodReg As Double
Private PeriodOT As Double

Public Function CalcHours(ByVal Hours As Double) As String
    'Add the Daily Hours to the Total Weekly Hours
    WeekTot = WeekTot + Hours

    'Format and Return the Daily Hours
    CalcHours = Int(Hours) & ":" & Format((Hours * 60) Mod 60, "00")
End Function

Public Function GetWeekTot() As String
    'Round the Total Weekly Hours to the Nearest Quarter Hour
    WeekTot = Round(WeekTot * 4, 0) / 4

    'Calculate the Regular Weekly Hours and the Overtime Weekly Hours
    If WeekTot > 40 Then
        WeekReg = 40
        WeekOT = WeekTot - 40
    Else
        WeekReg = WeekTot
        WeekOT = 0
    End If

    'Add the Total Weekly Hours to the Total Period Hours
    PeriodTot = PeriodTot + WeekTot

    'Format and Return the Total Weekly Hours
    GetWeekTot = Int(WeekTot) & ":" & Format(WeekTot * 60 Mod 60, "00")

    'Reset the Total Weekly Hours
    WeekTot = 0
End Function

Public Function GetWeekReg() As String
    'Add the Regular Weekly Hours to the Regular Period Hours
    PeriodReg = PeriodReg + WeekReg

    'Format and Return the Regular Weekly Hours
    GetWeekReg = Int(WeekReg) & ":" & Format(WeekReg * 60 Mod 60, "00")

    'Reset the Regular Weekly Hours
    WeekReg = 0
End Function

Public Function GetWeekOT() As String
    'Add the Overtime Weekly Hours to the Overtime Period Hours
    PeriodOT = PeriodOT + WeekOT

    'Format and Return the Overtime Weekly Hours
    GetWeekOT = Int(WeekOT) & ":" & Format(WeekOT * 60 Mod 60, "00")

    'Reset the Overtime Weekly Hours
    WeekOT = 0
End Function

Public Function GetPeriodTot() As String
    'Format and Return Total Period Hours
    GetPeriodTot = Int(PeriodTot) & ":" & Format((PeriodTot * 60) Mod 60, "00")

    'Reset the Total Period Hours
    PeriodTot = 0
End Function

Public Function GetPeriodReg() As String
    'Format and Return Total Period Hours
    GetPeriodReg = Int(PeriodReg) & ":" & Format((PeriodReg * 60) Mod 60, "00")

    'Reset the Total Period Hours
    PeriodReg = 0
End Function

Public Function GetPeriodOT() As String
    'Format and Return Total Period Hours
    GetPeriodOT = Int(PeriodOT) & ":" & Format((PeriodOT * 60) Mod 60, "00")

    'Reset the Total Period Hours
    PeriodOT = 0
End Function

如果有人想出办法让它显示出来,我将非常感激:

Employee Name
    Date       Hours    Reg     OT
    9/8/15      8:00
    9/9/15      8:28
    9/10/15     8:00
    9/11/15     7:32
    ------------------------------
Week Totals:   32:00  32:00   0:00 

    Date       Hours    Reg     OT
    9/14/15     9:43
    9/15/15     8:00
    9/16/15    13:14
    9/17/15    11:39
    9/18/15     5:25 
    ------------------------------
Week Totals:   48:00  40:00   8:00 
    ------------------------------
Period Totals: 80:00  72:00   8:00 

2 个答案:

答案 0 :(得分:1)

由于您发现在报告的文本框中调用了这些函数,因此可以说您在初始化报告时无法确定Access以何种顺序调用它们。

我提出了另外两种可能性:

<强> 1。使用带有额外字段的表达式

在报告明细行中设置实际每日小时的字段,例如将其命名为DAILY_CORRECT_FIELD,隐藏它可见设置为false。插入另一个文本字段,将其命名为DAILY_ROUNDED_FIELD,您可以在其中插入round-to-quarter表达式。在本周的sum字段中,请参考sum(DAILY_CORRECT_FIELD),这是不可见字段的未定义值。

<强> 2。基于代码

如果要使用VBA,请不要编写一个汇总所有字段的模块,尤其是当您无法控制调用该函数的顺序时。写一个查询,而不是总结一周,并将其设置为报告中的字段。网上有很多教程,所以我不会进一步解释。

虽然是使用VBA的忠实粉丝,但我强烈推荐建议1,因为它的实现很简单。

答案 1 :(得分:0)

我提出了一个解决方案,@ asdev,你让我考虑再次使用访问表达式,但这次我添加了一种绕过聚合查询到员工和周的分组,然后舍入其中的总和查询给我与我在报告周的页脚中得到的总数相同。然后我使用DSum函数按员工ID过滤旁路查询,并将我的Period页脚中的总数相加,得到正确的总数。