论坛登陆 用户名:  密 码:
设为首页  加入收藏
08年北京名校秋季招生
名牌院校免试入学宽进严出,突破考分限制,名校与你零距离,以下院校按报名先后顺序录取,24小时网上报名覆盖全国
  您现在的位置: 中国教育招生在线 >> IT >> 应试技巧 >> IT正文
关于排班问题的代码
 作者:佚名     2007-3-14 15:59:32        来源:不详  浏览次数:

  *-- 广州分公司司机/送货员排班系统
  *-- 程序员:红虎 于 2001年7月5日
  
  *-- 前提条件:
  * 建立临时表:排班表和员工表
  * 每个司机只能送2条车线
  * 车线名称:R1,R2,R3,... Rn
  * 驾 驶 员:D1,D2,D3,... Dn
  * 搬 运 工:L1,L2,L3,... Ln
  
  
  #define nRouteNum 9 && 最多车线数
  #define nDriverNum 14 && 最多驾驶员
  #define nLiftNum 13 && 最多搬运工
  
  #define cDriverType "D" && 表示驾驶员
  #define cLiftType "L" && 表示搬运工
  
  #define nWeekDays 5 && 一周上班数
  lnFreeDays = 7 - nWeekDays && 每周休息日
  
  ldDateFrom = {^2001.07.01} && 排班开始日
  ldDateto = {^2001.07.31} && 排班结束日
  lnTotalDays = ldDateTo - ldDateFrom + 1 && 共有的上班天数
  lnMaxWorkDays = 21 && 一段时间(月)最大上班数
  
  
  *-- 程序思路:
  * 在每一个车线中,有驾驶员和搬运工2个工种,
  * 字段名称以此规律:R1_D,R1_L, R2_D,R2_L....
  
  
  ShowProcessBar("创建排班数据表...",nRouteNum)
  *-- 创建排班表:
  Create cursor cursor_works (date d) && 日期字段
  For n= 1 to nRouteNum
  showbar(n)
  *-- 加入车线字段
  cn = allt(str(n))
  lcFieldName = "R" + cn + "_D"
  alter table cursor_works add column &lcFieldName c (6) && 6位字段宽度可用来填写驾驶员姓名
  lcFieldName = "R" + cn + "_L"
  alter table cursor_works add column &lcFieldName c (6) && 6位字段宽度可用来填写搬运工姓名
  Endfor
  
  ShowProcessBar("创建员工数据表...",nDriverNum+nLiftNum)
  *-- 创建员工表:
  Create cursor cursor_personal ( ;
  姓名 c (6) ,;
  类型 c (2) ,;
  天数 n (3) ,;
  车线1 n (3) ,;
  车线2 n (3) ,;
  连续 n (3) ,;
  休息 n (3) ,;
  已排 l )
  
  For n=1 to nDriverNum
  showbar(n)
  *-- 加入驾驶员记录
  lcName = cDriverType + allt(str(n))
  appe blank
  repl 姓名 with lcName ,;
  类型 with cDriverType && D = Driver = 司机
  Endfor
  For n=1 to nLiftNum
  showbar(nDriverNum+n)
  *-- 加入搬运工记录
  lcName = cLiftType + allt(str(n))
  appe blank
  repl 姓名 with lcName ,;
  类型 with cLiftType && L = Lift = 搬运工
  Endfor
  
  *-- 注意:每一个司机最多送2条车线,
  * 如果共有司机 14 个,那么可以送 14*2 = 28 条车线人
  * 假设现在有 9 条车线,那么 28/9 = 3.1111
  * 每天车线在14个人中需要出现 3.11 次才够
  
  *-- 将车线根据 1、2、3、4...N、1、2、3...N、1、2、....的规律排列
  ShowProcessBar("计算每位司机所送货的2条车线...",nDriverNum*2)
  dime laRouteList(nDriverNum*2)
  For n=1 to nDriverNum*2
  showbar(n)
  laRouteList(n) = mod(n,nRouteNum)
  if laRouteList(n) = 0
  laRouteList(n) = nRouteNum
  endif
  Endfor
  
  *-- 将排列出来的车线在员工表中根据:
  * 记录1的车线1、车线2,记录2的车线1、车线2...记录N的车线1、车线2 依次填充
  sele cursor_personal
  ShowProcessBar("计算每位司机所送货的2条车线...",nDriverNum)
  scan for 类型 = cDriverType
  showbar(recn())
  repl 车线1 with laRouteList( recn() * 2 - 1 )
  repl 车线2 with laRouteList( recn() * 2 )
  endscan
  
  *!* acti scre
  *!* brow for 类型 = cDriverType ;
  *!* field 姓名,车线1,车线2 ;
  *!* title "请修改司机姓名以及他们所送的2条车线,保证每条车线被排至少3次 按 Ctrl+W 存盘!"
  
  *-- 开始进行排班
  *-- 从日期范围 ldDateFrom 到 ldDateTo 进行循环处理
  ShowProcessBar("正在处理排班...",lnTotalDays)
  For d=1 to lnTotalDays
  showbar(d,"排 "+dtoc(ldDateFrom+d-1) +" 这天的班...")
  *-- 重新刷新员工表
  sele cursor_personal
  repl 已排 with .F. all
  go top
  
  *-- 在工作表中添加一天的记录
  sele cursor_works
  appe blank
  repl date with ldDateFrom + d - 1
  
  *-- 先排司机的班次 =======================================================
  For r=1 to nRouteNum
  lcFieldName = "R" + allt(str(r)) + "_D"
  sele cursor_personal
  sele recn() as rec_no,* from cursor_personal ;
  where 类型 = cDriverType ;
  and 天数 < lnMaxWorkDays ;
  and !已排 ;
  and inlist(r,车线1,车线2) ;
  order by 天数 ;
  into cursor temp
  llFound = iif(_tally>0,.T.,.F.)
  
  If llFound
  sele cursor_personal
  goto temp.rec_no
  
  repl 已排 with .T.
  
  if inlist(r,车线1,车线2) && 满足车线服务
  repl 天数 with 天数 + 1
  repl 连续 with 连续 + 1
  lcCurName = allt(姓名)
  sele cursor_works
  repl &lcFieldName with lcCurName
  sele cursor_personal
  else
  repl 休息 with 休息 + 1
  r = r - 1
  endif
  
  sele cursor_personal
  if 连续 >= nWeekDays or 休息 >= lnFreeDays
  repl 连续 with 0
  repl 休息 with 0
  endif
  Endif
  
  Endfor
  *-- 司机的班次排结束 =====================================================
  
  
  *-- 接着排送货员的班次 ====================================================
  For r=1 to nRouteNum
  lcFieldName = "R" + allt(str(r)) + "_L"
  sele cursor_personal
  sele recn() as rec_no,* from cursor_personal ;
  where 天数 < lnMaxWorkDays ;
  and !已排 ;
  order by 天数 ;
  into cursor temp
  llFound = iif(_tally>0,.T.,.F.)
  
  If llFound
  sele cursor_personal
  goto temp.rec_no
  
  repl 已排 with .T.
  
  repl 天数 with 天数 + 1
  repl 连续 with 连续 + 1
  lcCurName = allt(姓名)
  sele cursor_works
  repl &lcFieldName with lcCurName
  sele cursor_personal
  
  sele cursor_personal
  if 连续 >= nWeekDays or 休息 >= lnFreeDays
  repl 连续 with 0
  repl 休息 with 0
  endif
  Endif
  
  Endfor
  *-- 送货员排班结束 =====================================================
  
  Endfor
  
  sele cursor_works
  go top
  brow nowait
  
  说明:程序中的ShowProcessBar()和Showbar()是用来显示进度条的,如果没有,可以注释掉!
责任编辑:lss
  相关新闻
关于等级考试三级网络的一些情况介绍
关于MCSE的考试顺序的一些看法
EasyJWeb 关于中文件上传的处理实例
关于Java模板引擎Velocity的简单实践
关于Oracle数据库中密码安全管理总结
关于思科认证中四种ID的区别
自己积累的一些关于Velocity的经验
一个关于UML使用现状的调查报告
预测--2006年关于Google的15条新闻
关于JAVA的自问自答(长期更新)
关于等级考试三级网络的一些情况介绍
关于MCSE的考试顺序的一些看法
关于Oracle数据库中密码安全管理总结
关于思科认证中四种ID的区别
EasyJWeb 关于中文件上传的处理实例
关于Java模板引擎Velocity的简单实践
自己积累的一些关于Velocity的经验
关于在ORACLE下开发JAVA的几个问题
新手推荐:关于Oracle索引的一点认识
关于oracle中大对象处理的一些方法和实例
  评论
现在有100人对本文发表评论
查看所有评论
 
推  荐
 
100本成功必读热销书
热门招生
  北京文理研修学院   前进大学
  北京明园大学   北京建设大学
  北京邮电大学世纪学院   北方工商管理学院
  联想软件定向委培班   香港数码动画学院
  青年企业管理研修学院   北京华夏管理学院
热门培训
网络化办公专家培训认证 电子科技大学软件学院
软件测试工程师培训认证 北大青鸟十大授权培训
IT硬件工程师培训认证班 北京环球雅思荷兰预科
JAVA开发工程师培训 潜能时代IT服务管理培训
网络信息化工程师培训 清华大学继续教育学院
论坛精选
 
有些细节是男人也该注意的风度!最容易读错的字
某强人手机里保存的30条短信 中国十大高薪职业
最感人的十大韩剧经典台词 嫁给工程师的N个理由
爆强!只有一句话的鬼故事 转贴教你如何做妖精
 女人一定要記住的話 女人最好别嫁给最爱的男人
城市联盟
 大连 上海 天津 广州 西安 深圳  天津  青岛  大连  福州  沈阳  青海  连云港  南京  吉林  厦门  威海  辽宁  呼和浩特
Copyright © 2006   www.edu999.com   All rights reserved. 中国教育招生在线  版权所有
北京市通信管理局[2004]字第552号函    京ICP证040442号