|
本帖最后由 wlianke 于 2024-4-8 17:27 编辑
结合各位大师的算法,自己胡乱编了一个代码,21个人以内随便排,间隔合理,值勤均匀。在此非常感谢所有提供帮助的大师!代码非常乱,算法也不科学,但已经够用了!有心的大师能否帮助修整代码,成分感激!!!
求助老师们,能否实现以下功能:
一、共14个人参与值班,每天1个人值班。
二、每个周mod周日都进行人员调整,目的是不能让某人老是周六或周日值班,所以,需要每个人都能轮到周六或周日值班
三、每个人的值班的频次要均等,不能有的人值的多,有的人值的少。例如,王聪聪两个月值了四天班,而邢金两个月只值了两三或者三天班。
四、排班周期可以一个月,也可以两个月,也可以三个月,只要大家都能轮一遍。
五、排好班后值完这一轮,最好下一轮可以继续用这个,或者可以重排,但原则还是每个人的值班频次均等。
- 模块1:
- Sub test() '统计排班情况
- Dim arr, brr(1 To 10000, 1 To 8)
- Dim dic
- Set dic = CreateObject("scripting.dictionary")
- arr = Sheets("排班表").Range("B2:D" & Sheets("排班表").Cells(Rows.Count, "B").End(xlUp).Row)
- For x = 1 To UBound(arr)
- If Not dic.exists(arr(x, 2)) Then Set dic(arr(x, 2)) = CreateObject("scripting.dictionary")
- dic(arr(x, 2))(arr(x, 1)) = dic(arr(x, 2))(arr(x, 1)) + 1
- Next
- brr(1, 1) = "姓名"
- brr(1, 2) = "周一"
- brr(1, 3) = "周二"
- brr(1, 4) = "周三"
- brr(1, 5) = "周四"
- brr(1, 6) = "周五"
- brr(1, 7) = "周六"
- brr(1, 8) = "周日"
- c = 2
- For Each aa In dic.keys
- brr(c, 1) = aa
- For Each bb In dic(aa).keys
- For n = 2 To 8
- If brr(1, n) = bb Then
- brr(c, n) = dic(aa)(bb)
- End If
- Next
- Next
- c = c + 1
- Next
- Sheets("排班情况").[A2].Resize(UBound(brr), UBound(brr, 2)) = brr
- With Sheets("排班情况")
- With .Range("A1").CurrentRegion
- .Borders.LineStyle = xlContinuous '加边框
- .HorizontalAlignment = xlCenter '居中
- End With
- .Cells.EntireColumn.AutoFit '列自适应
- End With
- Sheets("排班情况").Activate
- End Sub
- 模块2
- Option Explicit
- Public pbname '排班人员数组
- Public rs As Integer '参与排班的人数
- Public zqarray '排班周期数组
- Public ksrq As Date '开始日期
- Public arr '人数大于等于21人时的数组
- Sub pbsub()
- Dim i As Integer, ts As Integer, x As Integer, y As Integer
- pbname = Sheets("基础数据").Range("B2:D" & Sheets("基础数据").Range("B10000").End(xlUp).Row)
- ReDim Preserve pbname(1 To UBound(pbname), 1 To 4)
- For i = 1 To UBound(pbname)
- pbname(i, 4) = i - 1
- Next
- ksrq = Sheets("基础数据").Range("A2")
- rs = UBound(pbname)
- If rs > 21 Then MsgBox "抱歉,暂不支持21人以上的排班!": End
- If rs Mod 4 = 0 Then
- ts = UBound(pbname) * 7
- Else
- ts = UBound(pbname) * 2 * 7
- End If
- ReDim crr(1 To ts)
- ReDim zqarray(0 To ts, 1 To 5)
- zqarray(0, 1) = "日期": zqarray(0, 2) = "星期": zqarray(0, 3) = "姓名": zqarray(0, 4) = "部门": zqarray(0, 5) = "电话"
- If rs Mod 4 = 0 Then
- For i = 1 To UBound(zqarray)
- zqarray(i, 1) = ksrq + (i - 1)
- zqarray(i, 2) = Format(Weekday(zqarray(i, 1), 1), "aaa")
- crr(i) = y
- For x = 1 To rs
- If pbname(x, 4) = crr(i) Then zqarray(i, 3) = pbname(x, 1): zqarray(i, 4) = pbname(x, 2): zqarray(i, 5) = pbname(x, 3)
- Next x
- If y < rs - 1 Then y = y + 1 Else y = 0
- Next
- ElseIf rs = 21 Then
- Call shiyan
- For i = 1 To UBound(zqarray)
- zqarray(i, 1) = ksrq + (i - 1)
- zqarray(i, 2) = Format(Weekday(zqarray(i, 1), 1), "aaa")
- For y = 1 To rs
- If pbname(y, 4) = arr(i - 1) Then zqarray(i, 3) = pbname(y, 1): zqarray(i, 4) = pbname(y, 2): zqarray(i, 5) = pbname(y, 3)
- Next
- Next i
- Else
- For i = 1 To UBound(zqarray)
- zqarray(i, 1) = ksrq + (i - 1): crr(i) = (i - 1 + Int((WorksheetFunction.WeekNum(zqarray(i, 1), 2) + 1) / 2) * 2) Mod rs
- zqarray(i, 2) = Format(Weekday(zqarray(i, 1), 1), "aaa")
- For x = 1 To rs
- If pbname(x, 4) = crr(i) Then zqarray(i, 3) = pbname(x, 1): zqarray(i, 4) = pbname(x, 2): zqarray(i, 5) = pbname(x, 3)
- Next
- Next
- End If
- Sheets("排班表").UsedRange.Clear 'Contents
- Sheets("排班表").Range("A1").Resize(UBound(zqarray) + 1, UBound(zqarray, 2)) = zqarray
- With Sheets("排班表")
- With .Range("A1").CurrentRegion
- .Borders.LineStyle = xlContinuous '加边框
- .HorizontalAlignment = xlCenter '居中
- End With
- .Cells.EntireColumn.AutoFit '列自适应
- End With
- Sheets("排班表").Activate
- End Sub
- Public Sub shiyan()
- Dim cs As Integer, x As Integer, y As Integer, z As Integer, u As Integer, v As Integer, w As Integer, brr
- ReDim brr(0 To rs - 1)
- For x = 0 To UBound(brr)
- brr(x) = x
- Next x
- ReDim arr(0 To (UBound(brr) + 1) * 2 * 7 - 1)
- x = 0
- y = 0
- For z = v To (UBound(arr) + 1)
- For x = w To UBound(brr)
- arr(v) = brr(x)
- v = v + 1
- Next x
- If UBound(brr) - w < UBound(brr) Then
- w = (UBound(brr) + 1) - (UBound(brr) + 1 - w) - 1
- For y = 0 To w
- arr(v) = brr(y)
- v = v + 1
- Next
- w = w + 1
- End If
- w = w + 1
- If v >= (UBound(arr) + 1) Then GoTo 100
- Next z
- 100:
- End Sub
复制代码
|
|