除了其终端用户特性外,Notes日程表对于应用程序开发人员也非常有用。在本文中,我们提供了构建一个示例日程表应用程序的逐步说明。我们假设您是一名有经验的LotusNotes/Domino开发人员,并且熟悉基本的Notes日程表特性。
约会表单必须有一个起始日期字段。该字段决定了在日程表的什么地方显示事件。起始日期是日程表应用程序的锚。约会表单必须包含一个持续时间(duration)。这个字段必须是一个数字,表示时间持续的天数。(约会表单还可以包含一个起始时间和一个终止时间。不过,这是一个可选值,当实际在日程表上显示事件时这不是必需的。)日程表视图的第一列必须包含一个日期/时间值,并且按升序排序。这一列对用户应该是隐藏的。(为了正确地显示,必须将第一列按升序排序。)日程表视图的第二列必须包含日程表事件的持续时间。这个值决定了应该连续多少天显示这个约会。持续时间值可以是正数,也可以是负数。如果是正数,则将日程表事件显示到起始日期的右边(或将来)。如果是负数,则将日程表事件显示到起始日期的左边(或之前)。视图的风格必须设置为Calendar。这种设置将视图的外观从传统外观变成实际的日程表。现在让我们更深入地研究用于管理重复日程表事件的架构和实现选择。应用程序的复杂性是围绕着管理重复事件的过程而形成的。同任何软件语言一样,设计、开发和实现一个解决方案的方法有很多种。接下来的几个小节将讨论两种可能的架构。
使用单个文档管理重复事件
我们已经讨论了日程表应用程序的主要组成部分,即一个表单和一个视图。接下来要谈到的是管理重复事件的不同选择。第一种方法是管理连续日程表事件的一种简单而有效的方法。
连续事件是指从起始日期起往后延续的约会。换句话说,您可以创建一个约会,这个约会将在多个日程表日期上显示。然而,所有日程表日期必须是连续的,例如从4月4日到4月7日。“单文档”方法只创建一个文档,并在日程表日期范围内显示约会(见图1)。这种方法实现起来比较简单。如果您想快速地构建一个日程表应用程序,或者将一个日程表添加到一个已有的应用程序中,那么这种方法可以作为很好的起点。
图1.单文档重复事件

这种方法的主要优点是易于实现。您可以很轻松地生成一个新的应用程序(或者通过添加两个字段并创建一个日程表视图来增强一个已有的应用程序)。而且,由于所有日程表日期都引用相同的(单个)文档,用户只需更新一个文档。文档的更新可以反映到每一个日程表日期。例如,假设作者想在约会的主体中包括一个会议电话号码。那么作者只需进行一次更新,更改就会立即在所有日程表日期上生效。其他小组成员可以右键单击任何一个文档,然后看到一致的信息。
这种方法的缺点是不能管理复杂的重复事件。如果您需要将事件安排在每个月的第二个星期五或每个月的3号,那么单文档方法就要求用户手动地在每个日期上创建条目。
下面这一节将讨论一种更健壮的、全面的用于重复事件的架构。
使用多个文档管理重复事件
“多文档”方法根据在初次约会中指定的重复事件参数创建一个单独的文档。例如,您可以创建一个约会,这个约会为每个日程表日期生成一个单独的文档(见图2)。这种架构在排日程表时可以提供更大的灵活性,但是实现起来也要复杂许多。
图2.多文档重复事件

为了实现第二种方法,需要在初次约会表单中捕捉附加的信息。这是通过一个单独的对话框窗口管理的,该窗口提示用户指定重复事件参数:weekly(每周)、daily(每天)、dayoftheweek(星期几)、skipweekends(跳过周末)、monthly(每月)、customdates(定制日期),等等。当保存初次约会时,该方法计算出所有重复事件日期,并为每个日程表日期生成一个单独的文档。
通过使用第二种方法可以获得更大的灵活性,并且有更多的选择来管理重复事件。实现这种架构时可以创建各种不同的事件:
事件类型 | 例子 |
ByDate | 4月4日(单天事件) |
Dailybydate | 4月4日到4月7日(连续) |
Weeklybyday | 星期一、星期三和星期五 |
Monthlybydate | 每个月的第一天 |
Monthlybyday | 每个月的第三个星期五 |
Customdates | 定制的一组不连续的日期 |
SkipWeekends | 如果事件落在星期六或星期天上,则不创建 |
NextBusinessDay | 如果碰到周末,则将事件移到星期一 |
另一个优点是可以移动和删除事件。由于每个事件都是作为惟一的文档存放的,因此用户可以在不影响其他相关事件的情况下移动、删除或更新一个日程表事件。
这种方法的缺点是计算事件日期时需要复杂的算法。而且,这种方法要为每个事件创建一个单独的文档。如果作者想要更新所有相关事件的主题或主体,那么需要独立地更新每个文档。
在删除或移除一个已经安排好的约会时也会遇到挑战。为了删除所有相关的约会,作者需要逐个地删除每个约会,或者添加一个子例程来自动删除相关的事件。
构建一个简单的事件日程表
现在让我们将注意力转移到构建一个简单的单文档日程表应用程序上来。首先要启动LotusDominoDesigner客户机,并创建一个空白数据库(见图3)。为此,打开DominoDesigner客户机,并选择File-Database-New。指定一个应用程序标题和文件名。确保选择了"-Blank-"作为模板类型。
图3.NewDatabase屏幕

删除“Filename”字段中的所有空格是有益的。在使用Web应用程序时,空格可能导致一些问题。例如,将“MeetingCalendar.nsf”替换为“MeetingCalendar.nsf”。
创建Appointment表单
约会表单捕捉事件起始日期和终止日期、持续时间、作者、主题和一些细节。持续时间是自动计算的。大多数与日程表应用程序相关的工作都处在约会表单中,包括重复事件的管理。
为创建一个表单,单击NewForm按钮,或者选择Create-Design-Form菜单选项。
定义字段接下来,添加下面表中指定的字段。为创建一个字段,选择Create-Field菜单选项。确保为表单上每个字段设置了数据类型、公式和其他属性。
字段名称 | 类型 | 公式 | 备注 |
StartDate | Date/Time,Editable | DEFAULTStartDate:=@If(@IsNewDoc;@Today;@Return(StartDateTime));StartDate | 在字段属性对话框中将风格设置为Calendar/TimeControl |
EndDate | Date/Time,Editable | n/a | 在字段属性对话框中将风格设置为Calendar/TimeControl |
Duration | Number,Computed | @If(StartDate="";0;EndDate="";0;@BusinessDays(StartDate;EndDate)) | 该公式将根据起始日期和终止日期自动计算持续时间 |
Person | Text,ComputedwhenComposed | @Name([CN];@UserName) | 该公式将自动得出作者的名称 |
Subject | Text,Editable | n/a | n/a |
Body | RichText,Editable | n/a | n/a |
字段名称、类型和风格将在属性对话框中定义。字段公式被放在Programmer’sPane窗格的ValueorDefaultValue部分,这个窗格位于Designer客户机较下面的一个区域。如果没有看到这个窗格,那么可以选择View-Programmer’sPane。(请参阅DominoDesignerproductdocumentation以了解关于如何使用DominoDesigner客户机的细节。)
定义全局对象接下来的步骤是定义与“(Globals)”部分中的表单相关的全局对象。您可以只定义一次对象,然后在整个表单中引用这个对象。这样便简化了代码,并使得应用程序的代码更高效。
在“(Global)”标题下的“Declarations”部分中作如下设置:
DimdocAsNotesDocument"ReferstothecurrentcalendardocumentDimwsAsNotesUIWorkspace"ReferstothecurrentapplicationworkspaceDimsAsNotesSession"ReferstothecurrentnotessessionDimdbAsNotesDatabase"ReferstothecurrentNotesdatabaseDimsDateAsNotesDateTime"TemporaryvariableforStartDatecalculationsDimeDateAsNotesDateTime"TemporaryvariableforEndDatecalculations
|
我们建议在“(Options)”部分添加“OptionExplicit”。这样将迫使您声明(例如DIM)所有变量,从而有助于调试。如果变量没有定义,则语句被标为有语法错误。这样就可以更容易地发现代码中的问题(例如输错的变量名)。
现在您的日程表约会表单看上去应该如图4所示:
图4.日程表约会表单

将窗口标题设置为Appointment。每当在LotusNotes客户机中打开这个表单时,该标题都将显示在窗口的顶端。这个标题有助于使应用程序更加用户友好。应用程序的其他地方不会用到窗口标题,您可以将窗口标题改为自己喜欢的任何值(例如Appointment、Meeting或“Meetingby” 人名)。
打开文档后,在约会表单中设置一个默认的起始日期:
SubQueryopen(SourceAsNotesuidocument,ModeAsInteger,IsnewdocAsVariant,ContinueAsVariant)Setws=NewNotesUIWorkspaceSets=NewNotesSessionApptDate=ws.CurrentCalendarDateTimeEndSub
|
显示了约会之后,获得文档的一个句柄。doc对象将在多个LotusScript事件中用于设置和获取约会记录中的信息:
SubPostopen(SourceAsNotesuidocument)Setdoc=source.DocumentEndSub
|
计算日程表视图中要用到的两个变量:StartDateTime和CalendarDateTime。这两个变量将包括连续日程表日期数组。下面这段代码格式化数据,并设置约会表单上的值。
SubPostrecalc(SourceAsNotesuidocument)DimmydateAsNotesItemSetdoc=source.DocumentSetmydate=doc.GetFirstItem("StartDate")SetsDate=NewNotesDateTime(mydate.DateTimeValue.DateOnly)Setdoc.StartDateTime=sDateSeteDate=NewNotesDateTime("")SeteDate=sDateeDate.AdjustDay(doc.Duration(0)-1)Setdoc.EndDateTime=eDatedoc.CalendarDateTime=doc.StartDateTimeEndSub
|
每当保存文档时刷新当前文档。这样可以确保每当保存表单时(例如,当用户选择File-Save时),将最近的数据显示给用户。
SubQuerysave(SourceAsNotesuidocument,ContinueAsVariant)Source.RefreshEndSub
|
设置表单属性最后,在表单属性对话框中,选中第一个选项卡中Options部分的“Automaticallyrefreshfields”选项(见图5)。该选项在您更改约会表单上的数据时将刷新计算字段。例如,当起始日期和终止日期被更改时,持续时间值将自动更新。
图5.Form属性

为完成这个表单,在Properties对话框中指定Appointment|Appt作为表单名。其中的竖线表明后面是该表单的别名。然后,保存并关闭该表单。(总是提供一个表单名和一个别名是一种很好的作法,这使得后面所有代码都可以引用别名。这样一来,便可以在不影响已有代码和/或视图公式的情况下更改表单名,从而拥有更大的灵活性。)
创建Calendar视图
至此,应用程序的大部分都已经完成了。剩下的惟一一步是用于显示约会事件的日程表视图。每当创建一个数据库时,都会自动生成一个名为“(Untitled)”的默认视图。双击这个视图,从而以Edit模式打开它。将Properties对话框从Column转换为View。将名称设置为Calendar,别名设置为Cal。
定义列接下来的步骤是定义列。通过单击一个已有的列标题,并选择Create-InsertNewColumn菜单选项,就可以添加一个列。接下来添加以下几列。
Column1是一个隐藏列,它必须包含按升序排序的起始日期/时间值。对于本项目,需要选择“showmultiplevaluesasseparateentries”选项。这个选项用于在多个日程表日期之间显示一个文档(见图1)。在programmer’spane上,将显示类型更改为Formula,并将列公式设置为:
REM"Column1containsthelistofstartdatesasdefinedintheappointmentform";StartTime:=@Time(CalendarDateTime);DateList:=@Explode(@TextToTime(@Text(CalendarDateTime) "-" @Text(EndDateTime)));@TextToTime(@Text(DateList) "" @Text(StartTime))
|
为设置排序类型,选择Columnproperties对话框的第二个选项卡,并单击Ascending单选按钮选项。同时也选择“Showmultiplevaluesasseparateentries”。为隐藏该列,选择Columnproperties对话框中的最后一个选项卡。双击column1标题弹出Properties对话框。然后选择最后一个选项卡上的HideColumn复选框:
图6.Columnproperties

Column2是一个隐藏列,它必须包含事件持续时间,以使日程表视图能够正确显示事件。如果第二列没有包含一个有效的数值,那么您将收到一条错误消息。将列公式设置为:
REM"Column2containsthedurationforeachappointmentform";Duration;
使用与设置column1时一样的步骤隐藏column2。
Column3只是显示日程表事件的文本值。这个值将被显示在实际的日程表视图上。将列公式设置为:
REM"Column3representsthevaluedisplayedonthecalendar";Person;
或者,这个列也可以包含人名和主题,或其他某种数据元素和文本的组合。您可能还想设置这个列的背景颜色,以增强应用程序的易用性。这样可以突出条目,帮助用户在视图中找到日程表事件。为设置背景颜色,选择Viewproperties对话框中的第三个选项卡。Background设置位于Entry部分。
注意:列标题在日程表视图中是不显示的。然而,通过提供一个列标题名称可以帮助您和其他开发人员理解视图的设计和列中的内容。
设置视图对象和属性RegionDoubleClick事件允许用户双击一个日程表日期,自动打开新的约会表单。表单显示之后,起始日期上显示日程表上选择的日期。该事件还包含一个数据合法性检查,以判断所选日期是否在当前日期之前。如果所选日期处在过去,那么用户会收到提示:"Dateinpast…Doyouwanttocontinue?"如果用户选择Yes,那么变量“answer”被设置为6(这是由LotusNotes应用程序自动设置的默认值)。
如果所选日期处在将来,或者用户对上述问题回答Yes以创建处在过去的记录,那么将出现一个新的约会表单。下面的例程只有在用户双击一个日程表日期时才会执行。(或者,用户可以选择本节后面描述的NewAppointment按钮,或选择Create-Appointment菜单选项。)
SubRegiondoubleclick(SourceAsNotesuiview)DimdocAsNotesDocumentDimworkspaceAsNewNotesUIWorkspaceDimuidocAsNotesUIDocumentDimviewAsNotesViewDimdateTimeAsNewNotesDateTime("")CalldateTime.SetNow''Displaywarningifselecteddateisinthepast.IfSource.CalendarDateTime<Cdat(dateTime.DateOnly)Thenanswer=Messagebox("Dateinpast...Doyouwanttocontinue?",292,"Continue?")EndIf''CreatetheappointmentifdateisinthepastanduserclickedYES,or''createtheappointmentifdateisinthefuture.If(answer=6)Or(Source.CalendarDateTime>=Cdat(dateTime.DateOnly))ThenSetview=Source.ViewSetuidoc=workspace.ComposeDocument("","","Appt")Setdoc=uidoc.Documentdoc.StartDate=Source.CalendarDateTimeEndIfEndSub
|
您可能想考虑将这段代码添加到任何包含一个日程表视图的应用程序中。为此只需将Appt改为适当的表单名。这样可以使应用程序更具用户友好性,并增加易用性。
为视图创建动作按钮为创建允许用户建立新约会的按钮,选择Create-Action-Actions。将按钮标题设为NewAppointment,并在programmer’spane中输入以下公式:
REM"Createnewcalendarevents";@PostedCommand([Compose];"":"Appt")
为创建允许用户跳到当前日程表日期的按钮,选择Create-Action-Actions。将按钮标题设为Today,并在programmer’spane中输入以下公式:
REM"Jumptotoday’scalendardate";@Command([CalendarGoTo];@Date(@Now));
保存并关闭视图。
恭喜,您已经完成了这个日程表应用程序!
结束语
在本文中,我们讨论了一个简单的单文档日程表的组成部分,以及重复事件的组成部分。我们还提供了关于如何创建一个简单的日程表应用程序的说明。希望本文对您有所帮助。请告诉我们您的想法,并为将来关于LotusNotes和Domino的文章建议其他的话题。
来源:互连网