内容


在 IBM Lotus Approach 中计算净工作日

Comments

为了正确规划项目,您需要知道员工或团队成员的确切工作日数吗?或许需要跟踪员工的休息时间。IBM Lotus 1-2-3 中的 @Networkdays 功能可以这样做,但是直到目前为止,在 IBM Lotus Approach 中还无法使用这一相同的功能。为了在 Lotus Approach 中模拟 @Networkdays 功能,我们使用 LotusScript 创建了净工作日功能。这个简单的解决方案可以在任何 Lotus Approach 9.8 数据库中实现,采用 IBM Lotus SmartSuite 9.8 的任何受支持的语言版本。

本文介绍 Lotus Approach 中的净工作日功能的工作原理以及如何在任何新的或者现有的 Lotus Approach 数据库中实现该解决方案。

什么是净工作日及其工作原理

净工作日功能计算从给定开始日期到给定结束日期的总工作日数。它排除了这两个日期之间的周末以及所有假期。此功能要求用户输入开始日期和结束日期。然后通过扣除用户定义的周末和假期列表来计算实际的工作日数。

可以使用此功能来计算一年之中或者具体开始和结束日期(如 6 月 1 日到 12 月 31 日)之间的总工作日数。为此,需要两个数据库。第一个数据库支持净工作日功能,第二个数据库列出一年或者具体时间段之内的假期。

这两个数据库被关联在一起,执行一个循环便可将一个数据库中的日期与另一个数据库中的日期相比较。这可以防止任何一天被多次计算。净工作日功能计算假期和周末的总天数, 然后从总数中将其扣除。所得的结果就是给定开始日期和结束日期之间的总工作日数。

注意: 此解决方案专门用于具有最新修复包的 Lotus SmartSuite 9.8。净工作日功能可以工作在 Lotus SmartSuite 9.8 支持的所有语言版本上。

关于净工作日功能的最杰出的方面是可以非常轻松地将其添加到现有的 Lotus Approach 数据库中。在本文的后面部分中,我们介绍如何在新的和现有 Lotus Approach 数据库中实现该解决方案。

概述:用户所见

要想了解有关净工作日功能的工作原理的详细信息,下面便是从用户角度介绍的概述。要计算总工作日数,用户可以在显示图 1 时单击 NetWorkDays 按钮。Lotus Approach 数据中包含此按钮。

图 1. NetWorkDays 按钮
NetWorkDays 按钮
NetWorkDays 按钮

单击此按钮之后,一个输入框提示用户输入开始日期(参见图 2)。用户输入开始日期和并单击 OK 之后,另一个框提示用户输入结束日期。

图 2. Start date 提示
Start date 提示
Start date 提示

输入结束日期并单击 OK 之后,用户从图 3 中所示的列表框中选择周末。用户可以不止选择一天,但是一周之内不能选择多于两个周末。

图 3. Weekend days
Weekend days

用户完成上面的步骤之后,图 1 中的 TotalDays 字段便显示指定开始日期和结束日期之间的总工作日数,其中扣除了存储在另一个数据库中的周末和假期。在本文的后面部分,我们将介绍如何在 Lotus Approach 数据库中实现此净工作日功能。目前,下面是其工作原理的幕后预览。

图 4 显示在两个引用彼此数据的数据库之间创建的关联。

图 4. 关联
关联
关联

图 5 显示包含假期列表的数据库。

图 5. Holiday 数据库
Holiday 数据库
Holiday 数据库

净工作日代码

单击 NetWorkDays 按钮之后,脚本执行三个任务:

  • 打开用于输入开始日期的输入框。
  • 打开用于输入结束日期的另一个输入框。
  • 显示所有工作日的列表。

脚本将开始日期和结束日期转换为所需的日期格式,然后与包含假期列表的数据库建立连接。

输入所有数据之后,便开始计算。如果开始日期晚于结束日期,则用户会收到一条错误消息。如果这两个日期正确,则执行一个 For 循环。对于每个特别的日期,脚本都要使用函数 Weekday (i) 确定它是哪个工作日。这样便返回此特别工作日的各自的天数。然后脚本再次确认它不是用户选择的周末之一。如果不是,则脚本通过从包含假期列表的数据库中扣除此数据来检查此特别的日期是否是假期。

如果此特别的日期是假期,则脚本不会增加总工作日数的计数。如果此日期既不是周末也不是假期,则脚本会将计数加 1。对于开始日期和结束日期之间的所有日期(包括执行为开始和结束日期的日期)执行此循环。此后,脚本计算这两个日期之间的总工作日数。

Sub Click (Source As Button, X As Long, Y As Long, Flags As Long)
	Dim tableName As table
	Dim resultSet As ResultSet
	Dim count As Integer
	Dim Counter, j As Integer	
	Dim value As String
	Dim nRow As Integer
	CurrentView.Body.TotalDays.Text = " "
	On Error Resume Next	
	StartDate=(Inputbox$("Start Date (MM/DD/YYYY) ?", , ,300,350))	
	EndDate=(Inputbox$("End Date (MM/DD/YYYY) ?", , ,300,350))
	Dialog1.Show(1)
	Print Weekend(0),Weekend(1) 
	StartDate = Cdat(StartDate)
	EndDate = Cdat(EndDate)
	If Isdate(StartDAte) And Isdate(EndDate) Then		
		Dim wd As Integer, networkdays As Integer
		Set tableName = CurrentDocument.GetTableByName("Holidays")
		Set resultSet = tableName.CreateResultSet()
		nRow = resultSet.NumRows()
		count=1
		j = 1
		If StartDate > EndDate Then
			Messagebox ("The End Date should be greater than Start Date.")
			Exit Sub
		End If
		For i = StartDate To EndDate		
			wd% = Weekday(i)
			j =1
			
			If wd%  <> Weekend(0) And wd% <> Weekend(1) Then
				Call resultSet.FirstRow()
				Do While j <=  nRow
					If i  <> resultSet.GetValue(count) Then
						Counter = 0
						Call resultSet.NextRow()
					Else
						Counter = 1
					End If
					j = j  +1
				Loop
				If Counter  = 0 Then
					networkdays = networkdays + 1
				End If
			End If
		Next
		If networkdays = 0 Then
			Messagebox("Please enter the date in mm/dd/yyyy format.")
		End If
		CurrentView.Body.TotalDays.Text = Cstr(networkdays)	
	Else
		Messagebox("Please enter the date in mm/dd/yyyy format.")
	End If
End Sub

Weekend list 框代码

选择周末之后,用户在列表框(参见图 3)中单击 OK,然后脚本确定用户选择作为周末的天数以及日期。不得多于两个周末。然后脚本将此信息存储在名为 Weekend (i) 的数组中,以便以后使用。

Sub Click(Source As Lotuscommandbutton)
	Dim value As Integer
	Dim Total,Counter,Index As Integer
	Weekend(0) = 0
	Weekend(1) = 0
	Total = Dialog1.Weekends.ListCount
	For Counter = 0 To Total-1
		value = Dialog1.Weekends.IsItemSelected(Counter)
		If value = -1 Then
			Weekend(Index) = Counter+1
			Index = Index+1
		End If
	Next
	Dialog1.Close
End Sub

当用户单击包含工作日的列表框上的 Cancel 按钮时,执行以下脚本。

Sub Click(Source As Lotuscommandbutton)
Dialog1.Close
End Sub

实现净工作日功能

要在 Lotus Approach 数据库中使用净工作日功能,请遵循这些步骤。

注意: 本文假设您了解在 Lotus Approach 中创建数据库的方法。

  1. 在 Lotus Approach 数据库中,添加以下四个字段:
    • StartDate
    • EndDate
    • TotalWorkingDays(该字段用于创建与 holiday 数据库的关联。)
    • TotalDays
  2. 如果此数据库是新数据库,则创建一个空白表格,并将 TotalDays 字段拖动到该表格上。在现有数据库中,创建一个字段输入框。
  3. 创建一个名为 NetWorkDays 的按钮。
  4. 复制单击该按钮时要执行的脚本,并将此脚本链接到该按钮。单击此按钮时,将执行该脚本。
  5. 保存 APR 文件和数据库。
  6. 如果需要,创建另一个新的数据库以存储整个一年或者特定时间段内的假期信息。此数据库必须包含 holidays 字段。
  7. 保存此 APR 和 DBF 文件。
  8. 拥有两个数据库之后,关联 TotalWorkingDays 和 holidays 字段。

故障排除

如果用户执行操作时发生以下情况,则净工作日功能返回错误消息:

  • 输入的开始日期晚于指定的结束日期
  • 输入日期的格式不正确
  • 一周之内选择了多于两天的周末

语言版本的信息

目前,所有净工作日功能显示的错误消息都采用英语。如果想采用其他语言显示错误消息,可以翻译这些消息。

同样,列表框中的工作日以及所有输入框中的文本也都采用英语显示。如果需要,可以翻译所有 UI 元素中的文本。还可以更改日期格式以匹配本地设置。

结束语

我们在确定解决方案时面临两个挑战。首先,Lotus Approach 是一个成熟而且稳定的产品。实现新功能(如净工作日功能)所做的任何重要的代码更改都会影响某些现有功能。我们从事了这个具有挑战性的任务,并分析了实现我们的解决方案的方法。经过大量分析之后,我们决定采用 LotusScript 实现这个功能。

我们面临的第二个挑战涉及日期格式和各种语言版本。Lotus SmartSuite 有 11 种语言版本。研究了所有语言版本的日期格式之后,我们能够修改该代码以接受所有日期格式,从而在所有支持的语言版本中正确计算出净工作日。

我们希望所有 Lotus Approach 用户都能发现净工作日功能非常有用,而且易于使用。


相关主题

  • 您可以参阅本文在 developerWorks 全球网站上的 英文原文

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Lotus
ArticleID=327769
ArticleTitle=在 IBM Lotus Approach 中计算净工作日
publish-date=10172006