在开发ERP程序和其它一些企业程序的时候,经常需要用到工厂挂历,台历。工厂挂历台历就是描述企业作息时间的一组程序或者数据。企业往往要根据挂历台历来决定任务的性质或作业,而且这个挂历台历是工厂实际使用的挂历台历,不是简单的双休挂历台历,需要能够根据工厂的实际情况进行方便的调整。例如,当我们在下达生产订单的时候,就要注意,不要将订单下达到公司的休息日,如果碰到休息日要能够自动顺延。在计算订单的加工时间的时候,需要系统自动将休息日挖去,只算工作日。如果因为特殊需要,需要将某个休息日确定为工作日时,系统要能够很方便的调整。
在有些ERP中,只有一个工厂挂历台历,即所有的分厂或车间等使用同一个挂历台历。有的时候,可能不同的分厂或车间需要不同的挂历台历,可能是因为有的分厂这段时间比较忙,需要加班,另一些分厂可能这段时间任务比较少,需要多放一些假。还有,我们在进行生产排产的时候,可能一个设备就需要一个挂历台历,可能某些设备需要三班制运作,有些设备需要两班制作业,还有些设备一天上一个班就行了,有时候来了特别急的任务,一些设备需要临时加班。因此我们不仅需要挂历台历,可能还需要多个挂历台历,而且挂历台历的数量可能还比较多,甚至需要能够动态添加,因为企业随时都可能购进新的设备。
挂历台历的设计方法很多,微软的Project软件中挂历台历设计就是一种典型的设计方法,大家将Project用Access另存以后可能看到其挂历台历的设计方法。
但Project挂历台历的设计方法好像并不够好,主要是当数据库数据量比较大以后,系统的运行速度就变慢很多。更主要的是Project的挂历台历设计方法不能通过SQL语句进行高效的查询和计算,比较适宜于流程型的语言的使用,使用SQL语言查询和计算效率不高。
我的设计方法是纯粹使用SQL的表进行挂历台历设计。在SQL数据库中建立一个表,只需要四个字段,第一个是挂历台历日期,datetime类型,将从某个开始日期到某个结束日期的所有日期按次序记录在表中。例如从2008年1月1日到2008年12月31日,那么这个表就有365条记录,如果考虑程序需要使用50年,那么表中应该有约18250条记录。 第二个字段是工作日数量,int类型。从挂历台历的起始日期开始,有一个工作日数字自动加一,休息日数字加零。 第三个字段是表示该记录所表示的日期是休息日还是工作日,bit类型,也可以是int类型或tinyint类型,可以用1表示工作日,用0表示休息日。
第四个字段是对应工作日日期,datetime类型。如果今天是工作日,则该字段的日期等于第一个字段的日期;如果今天是休息日,则该日期就是该日期之前最近的工作日的日期。
这样在下达订单时,凡是碰到日期的数据,一律用数据库中的第四个字段代替,这样计算就变成了查表。碰到计算两个日期之间的工作日个数时,只要用两个日期之间的第二个字段减一下就可以了,碰到跨年度这样的复杂计算和灵活工作日的计算也变得很简单了,一个简单的减法运算就OK了。
这种方法不仅使日期的计算变得简单,同时日期的设置修改也很容易和高效。修改挂历台历首先修改第三个字段,就是将第三个字段的零改成1,1改成0.然后修改第二个字段,将休息日改成工作日时,就是将从修改日起的所有工作日数量自动加1;将工作日改成休息日,就是将从修改日起的所有工作日数量字段自动减1 。最后修改第四个字段,将休息日改成工作日时,令该字段等于第一个字段的日期,否则该字段改成最近的上一个工作日日期。
如果需要多个挂历台历时,例如企业可能需要多个分厂,并且需要设置成不同的挂历台历时,可以再在这个挂历台历表上加一个分厂ID字段就行了,查询的时候在增加一个条件就可以了。