かなり修正しました。
<追加の注意点>
職員名を数字で連番にしてテストする場合は、
1,2,3,4,5,6,7,8,9,10,11,12,13
とせずに
社員01,社員02,社員03,社員04,社員05・・・・として下さい。
(オートフィルで簡単に複製できます)
理由は検索の都合です。
1で検索すると11や12がヒットしてしまうからなんです。
'<マクロ修正版>
Sub test2()
On Error GoTo Err
Dim r As Long, c As Long
Dim StaffNum As Long, WorkNum As Long, RndNum As Long
Dim MaxWorkStaffNum As Integer
Dim MyLastCol As Integer, TmpLastCol As Integer
Dim TryStaff As String
Dim Work, Staff
Dim St As Worksheet
Dim MySht As Worksheet, TmpSht As Worksheet
Dim MyRng As Range, TmpRng As Range
Dim FindStaff As Range, FindWork As Range
Dim flg As Boolean
Dim MyRngNotFindFlg As Boolean, TmpRngNotFindFlg As Boolean
Dim MyRowNotFindFlg As Boolean, TmpRowNotFindFlg As Boolean
Dim CaseNum As Integer
Dim ct0 As Integer, ct1 As Integer, ct2 As Integer
Dim ct3 As Integer, ct4 As Integer, ct5 As Integer
Dim WorkStaffSum As Long
Set MySht = Worksheets("sheet1") '当番表のシート名
'前回の当番記録の保存
For Each St In Worksheets
If St.Name = "Tmp" Then
Application.DisplayAlerts = False
St.Delete
Application.DisplayAlerts = True
Exit For
End If
Next
MySht.Copy After:=MySht
ActiveSheet.Name = "Tmp"
Set TmpSht = Worksheets("Tmp")
MySht.Activate
Application.ScreenUpdating = False
'定数セット
Work = MySht.Range("B1:C100")
Staff = MySht.Range("A1:A1000")
StaffNum = MySht.Range("A65536").End(xlUp).Row - 1
WorkNum = MySht.Range("B65536").End(xlUp).Row - 1
MaxWorkStaffNum = WorksheetFunction.Max(MySht.Range("C2:C" & WorkNum + 1))
WorkStaffSum = WorksheetFunction.Sum(MySht.Range("C2:C" & WorkNum + 1))
MyLastCol = MaxWorkStaffNum + 4
With TmpSht.UsedRange
TmpLastCol = .Cells(.Cells.Count).Column
End With
If MaxWorkStaffNum > StaffNum Then GoTo Err
Set MyRng = MySht.Range(MySht.Cells(2, "E"), _
MySht.Cells(WorkNum + 1, MyLastCol))
Set TmpRng = TmpSht.Range(TmpSht.Cells(2, "E"), _
TmpSht.Cells(WorkNum + 1, TmpLastCol))
MySht.Range("E:IV").ClearContents
Range("E1").Value = "計算中"
'当番の試行
For r = 2 To WorkNum + 1
For c = 5 To 4 + Work(r, 2)
flg = False
MyRngNotFindFlg = False
TmpRngNotFindFlg = False
MyRowNotFindFlg = False
TmpRowNotFindFlg = False
ct0 = 0: ct1 = 0: ct2 = 0: ct3 = 0: ct4 = 0: ct5 = 0
If WorkStaffSum > StaffNum Then
CaseNum = 3
ElseIf WorkStaffSum * 2 > StaffNum Then
CaseNum = 2
Else
CaseNum = 0
End If
Do
RndNum = Int(Rnd() * StaffNum + 1) 'ランダム試行
TryStaff = Cells(RndNum + 1, "A").Value
'今回の同一仕事チェック
Set FindStaff = MySht.Range(MySht.Cells(r, "E"), _
MySht.Cells(r, MyLastCol)).Find(TryStaff)
If Not FindStaff Is Nothing Then
Set FindStaff = Nothing
MyRowNotFindFlg = False
Else
MyRowNotFindFlg = True
End If
'今回の当番チェック
Set FindStaff = MySht.Range(MySht.Cells(2, "E"), _
MySht.Cells(r, MyLastCol)).Find(TryStaff)
If Not FindStaff Is Nothing Then
Set FindStaff = Nothing
MyRngNotFindFlg = False
Else
MyRngNotFindFlg = True
End If
'前回の同一仕事チェック
Set FindWork = TmpSht.Range("B:B").Find(MySht.Cells(r, "B").Value)
Set FindStaff = TmpSht.Range(TmpSht.Cells(FindWork.Row, "E"), _
TmpSht.Cells(FindWork.Row, TmpLastCol)).Find(TryStaff)
If Not FindStaff Is Nothing Then
Set FindStaff = Nothing
TmpRowNotFindFlg = False
Else
TmpRowNotFindFlg = True
End If
'前回の当番チェック
Set FindStaff = TmpRng.Find(TryStaff)
If Not FindStaff Is Nothing Then
Set FindStaff = Nothing
TmpRngNotFindFlg = False
Else
TmpRngNotFindFlg = True
End If
Select Case CaseNum
Case 0 '前回当番をしていない人から選び、今回掛け持ちなし。
If MyRngNotFindFlg = False Or _
TmpRngNotFindFlg = False Then
ct0 = ct0 + 1
If ct0 > StaffNum * 5 Then CaseNum = 1
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 1 '前回当番をしていない人から選び、今回掛け持ちあり。
If MyRowNotFindFlg = False Or _
TmpRngNotFindFlg = False Then
ct1 = ct1 + 1
If ct1 > StaffNum * 5 Then CaseNum = 2
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 2 '前回同じ仕事をしていない人から選び、今回掛け持ちなし。
If MyRngNotFindFlg = False Or _
TmpRowNotFindFlg = False Then
ct2 = ct2 + 1
If ct2 > StaffNum * 5 Then CaseNum = 3
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 3 '前回の当番についてはチェックせず、今回掛け持ちなし。
If MyRngNotFindFlg = False Then
ct3 = ct3 + 1
If ct3 > StaffNum * 5 Then CaseNum = 4
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 4 '今回掛け持ちとなるが、前回の当番と重ならないようにする。
If TmpRowNotFindFlg = False Or MyRowNotFindFlg = False Then
ct4 = ct4 + 1
If ct4 > StaffNum * 5 Then CaseNum = 5
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 5 '今回の同一仕事の掛け持ちのみ不許可
If MyRowNotFindFlg = False Then
ct5 = ct5 + 1
If ct5 > StaffNum * 5 Then CaseNum = 6
Else
MySht.Cells(r, c) = TryStaff: flg = True
End If
Case 6 '無条件許可
MySht.Cells(r, c) = TryStaff: flg = True
Case Else
MySht.Cells(r, c) = TryStaff: flg = True
End Select
Loop Until flg = True
Next c
Next r
Range("E1").Value = "当番表"
ActiveSheet.UsedRange.EntireColumn.AutoFit
Columns("D").EntireColumn.Hidden = True
Application.ScreenUpdating = False
Exit Sub
Err:
MsgBox "error"
End Sub
お礼
何度もすみません。助かります。また、よろしくお願いします。