fork download
  1. Option Explicit
  2.  
  3. Public Sub 番号転記()
  4. Dim sh1 As Worksheet 'Sheet1
  5. Dim sh2 As Worksheet 'Sheet2
  6. Dim st_day As Variant '月初日
  7. Dim en_day As Variant '月末日
  8. Dim flag As Boolean
  9. Dim maxrow1 As Long 'Sheet1の最大行数
  10. Dim maxrow2 As Long 'Sheet2の最大行数
  11. Dim row1 As Long
  12. Dim row2 As Long
  13. Dim col2 As Long
  14. Dim i As Long
  15. Dim pcount As Long '登録人数
  16. Dim dicT As Object 'dictionary キー:担当者 値:Sheet2の行番号
  17. Dim arr As Variant 'dictionaryの値(arr(0)=行番号,arr(1)=日付,arr(2)=番号,arr(3)=段数)
  18. Dim key As Variant 'キー(担当者)
  19. Dim wdate As Variant
  20. Dim wno As Long
  21. Dim dd As Long
  22. Set dicT = CreateObject("Scripting.Dictionary")
  23. Set sh1 = Worksheets("Sheet1")
  24. Set sh2 = Worksheets("Sheet2")
  25. '開始日取得
  26. st_day = sh2.Cells(1, "B").Value
  27. If IsDate(st_day) = True Then
  28. If day(st_day) = 1 Then
  29. flag = True
  30. End If
  31. End If
  32. If flag = False Then
  33. MsgBox ("Sheet2 B2日付不正")
  34. Exit Sub
  35. End If
  36. '月末日取得
  37. en_day = GetLastDay(st_day)
  38. maxrow2 = sh2.Cells(Rows.count, "A").End(xlUp).Row '最終行を求める
  39. If maxrow2 < 5 Then Exit Sub
  40. If (maxrow2 - 5) Mod 4 <> 0 Then
  41. MsgBox ("Sheet2 A列最大行数エラー")
  42. Exit Sub
  43. End If
  44. pcount = ((maxrow2 - 5) \ 4) + 1
  45. 'Sheet2の担当者を記憶
  46. For i = 1 To pcount
  47. row2 = 5 + (i - 1) * 4
  48. key = sh2.Cells(row2, "A").Value
  49. If dicT.exists(key) = True Then
  50. MsgBox ("Sheet2 重複担当者:" & key)
  51. Exit Sub
  52. End If
  53. arr = Array(row2, 0, 0, 0)
  54. dicT(key) = arr
  55. Next
  56. 'Sheet2の初期化
  57. For i = 1 To pcount
  58. row2 = 5 + (i - 1) * 4
  59. For dd = 1 To day(en_day)
  60. col2 = 2 + (dd - 1) * 4
  61. sh2.Cells(row2, col2 + 1).ClearContents '1段目開始番号
  62. sh2.Cells(row2, col2 + 3).ClearContents '1段目終了番号
  63. sh2.Cells(row2 + 1, col2 + 1).ClearContents '2段目開始番号
  64. sh2.Cells(row2 + 1, col2 + 3).ClearContents '2段目終了番号
  65. sh2.Cells(row2 + 2, col2 + 1).ClearContents '3段目開始番号
  66. sh2.Cells(row2 + 2, col2 + 3).ClearContents '3段目終了番号
  67. sh2.Cells(row2 + 3, col2 + 3).ClearContents '小計
  68. Next
  69. Next
  70. 'Sheet1を最終行まで処理する
  71. maxrow1 = sh1.Cells(Rows.count, "A").End(xlUp).Row '最終行を求める
  72. For row1 = 2 To maxrow1
  73. wno = sh1.Cells(row1, "A").Value '番号
  74. wdate = sh1.Cells(row1, "C").Value '日付
  75. key = sh1.Cells(row1, "D").Value '担当者
  76. If dicT.exists(key) = False Then
  77. Call ErrorMsg(sh1, row1, "担当者未登録:" & key)
  78. End If
  79. flag = False
  80. If IsDate(wdate) = True And wdate >= st_day And wdate <= en_day Then flag = True
  81. If flag = False Then
  82. Call ErrorMsg(sh1, row1, "日付不正:" & wdate)
  83. End If
  84. arr = dicT(key)
  85. '行番号、列番号決定
  86. row2 = arr(0)
  87. col2 = 2 + (wdate - st_day) * 4
  88. '日付戻りチェック
  89. If arr(1) > 0 And wdate < arr(1) Then
  90. Call ErrorMsg(sh1, row1, "日付戻り発生:" & wdate)
  91. End If
  92. '番号戻りチェック
  93. If arr(2) > 0 And wno <= arr(2) Then
  94. Call ErrorMsg(sh1, row1, "番号戻り発生:" & wno)
  95. End If
  96. '日付変更発生時
  97. If wdate > arr(1) Then
  98. arr(1) = wdate '日付更新
  99. arr(2) = wno '番号更新
  100. arr(3) = 1 '段数設定
  101. sh2.Cells(row2 + arr(3) - 1, col2 + 1).Value = wno '開始番号
  102. sh2.Cells(row2 + arr(3) - 1, col2 + 3).Value = wno '終了番号
  103. Else
  104. '日付が前回と同じ場合、
  105. '番号に飛びがないなら、終了番号のみ更新
  106. If arr(2) + 1 = wno Then
  107. sh2.Cells(row2 + arr(3) - 1, col2 + 3).Value = wno '終了番号
  108. Else
  109. '番号が飛んでいるなら、次の段へ移動
  110. arr(3) = arr(3) + 1
  111. If arr(3) > 3 Then
  112. Call ErrorMsg(sh1, row1, "段数オーバー")
  113. End If
  114. sh2.Cells(row2 + arr(3) - 1, col2 + 1).Value = wno '開始番号
  115. sh2.Cells(row2 + arr(3) - 1, col2 + 3).Value = wno '終了番号
  116. End If
  117. arr(2) = wno '番号更新(日付は更新不要、段数は設定済み)
  118. End If
  119. dicT(key) = arr '値を戻す
  120. '計更新
  121. sh2.Cells(row2 + 3, col2 + 3).Value = sh2.Cells(row2 + 3, col2 + 3).Value + 1
  122. Next
  123. MsgBox ("完了")
  124. End Sub
  125.  
  126. 'エラーメッセージ出力&停止
  127. Private Sub ErrorMsg(ByVal ws As Worksheet, ByVal wrow As Long, ByVal msg As String)
  128. MsgBox ("Sheet1 " & wrow & "行 " & msg)
  129. ws.Activate
  130. ws.Cells(wrow, 1).Select
  131. End
  132. End Sub
  133.  
  134. '月末日取得
  135. Private Function GetLastDay(ByVal st_day As Variant) As Variant
  136. Dim yyyy As Long
  137. Dim mm As Long
  138. Dim wday As Date
  139. yyyy = Year(st_day)
  140. mm = Month(st_day)
  141. mm = mm + 1
  142. If mm > 12 Then
  143. yyyy = yyyy + 1
  144. mm = 1
  145. End If
  146. wday = DateSerial(yyyy, mm, 1)
  147. GetLastDay = wday - 1
  148. End Function
  149.  
  150.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty