fork download
  1. Option Explicit
  2.  
  3. Public Sub 項目組み合わせ検査()
  4. Dim dict As Object '連想配列 キー:項目名+マシン名 値:件数
  5. Dim ws1 As Worksheet 'シート1
  6. Dim ws2 As Worksheet 'シート2
  7. Dim lastrow As Long '項目名の最終行
  8. Dim lastrowm As Long 'マシン名の最終行
  9. Dim row1 As Long '行番号
  10. Dim item As String '項目名
  11. Dim machines() As String 'マシン名(配列)
  12. Dim org_names() As String '本来のマシン名(配列)
  13. Dim machine As String 'マシン名
  14. Dim cols As Variant '列番号の配列
  15. Dim i As Long
  16. Dim key As String 'dictのキー
  17. cols = Array(1, 4, 7)
  18. Set dict = CreateObject("Scripting.Dictionary") ' 連想配列の定義
  19. Set ws1 = Worksheets("シート1")
  20. Set ws2 = Worksheets("シート2")
  21. lastrow = ws1.Cells(Rows.Count, "A").End(xlUp).Row 'A列最終行取得
  22. lastrowm = ws1.Cells(Rows.Count, "D").End(xlUp).Row 'D列最終行取得
  23. '大きいほうを最終行として採用する
  24. If lastrowm > lastrow Then lastrow = lastrowm
  25. '3~最終行まで繰り返す
  26. For row1 = 3 To lastrow
  27. '項目名取得
  28. item = getItem(ws1.Cells(row1, "A").Value)
  29. 'マシン名取得
  30. machines() = getMachine(ws1.Cells(row1, "D").Value, org_names)
  31. '共に空白なら処理しない
  32. If item = "" And UBound(machines) < 0 Then GoTo NEXT99
  33. 'どちらかが空白なら処理中止
  34. If item = "" Then Call error_proc(ws1.Cells(row1, "A"), "項目名未設定")
  35. If UBound(machines) < 0 Then Call error_proc(ws1.Cells(row1, "D"), "マシン名未設定")
  36. 'マシンの数分、連想配列に登録
  37. For i = 0 To UBound(machines)
  38. 'キーを作成し登録する
  39. key = item & "|" & machines(i)
  40. If dict.exists(key) = False Then
  41. dict(key) = 1
  42. Else
  43. dict(key) = dict(key) + 1
  44. End If
  45. Next
  46. NEXT99:
  47. Next
  48. '組み合わせチェック
  49. For i = 0 To UBound(cols)
  50. Call check_comb(ws2, dict, cols(i))
  51. Next
  52. MsgBox ("完了")
  53. End Sub
  54. '組み合わせチェック
  55. Private Sub check_comb(ws2 As Worksheet, dict As Object, ByVal col As Long)
  56. Dim row2 As Long '行番号
  57. Dim lastrow As Long '項目名の最終行)
  58. Dim lastrowm As Long 'マシン名の最終行
  59. Dim item As String '項目名
  60. Dim machines() As String 'マシン名(配列)
  61. Dim org_names() As String '本来のマシン名(配列)
  62. Dim key As String 'dictのキー
  63. Dim i As Long
  64. lastrow = ws2.Cells(Rows.Count, col).End(xlUp).Row
  65. lastrowm = ws2.Cells(Rows.Count, col + 1).End(xlUp).Row
  66. If lastrowm > lastrow Then lastrow = lastrowm
  67. For row2 = 3 To lastrow
  68. '項目名取得
  69. item = getItem(ws2.Cells(row2, col).Value)
  70. 'マシン名取得
  71. machines = getMachine(ws2.Cells(row2, col + 1).Value, org_names)
  72. '見出しの場合は、スキップする
  73. If UBound(machines) = 0 Then
  74. If item = "項目名" And machines(0) = "実施マシン" Then GoTo NEXT99
  75. End If
  76. 'エラー情報のクリア
  77. ws2.Cells(row2, col).Interior.Pattern = xlNone
  78. ws2.Cells(row2, col + 1).Interior.Pattern = xlNone
  79. ws2.Cells(row2, col + 2).Value = ""
  80. '共に空白なら処理しない
  81. If item = "" And UBound(machines) < 0 Then GoTo NEXT99
  82. 'どちらかが空白なら処理中止
  83. If item = "" Then Call error_proc(ws2.Cells(row2, col), "項目名未設定")
  84. If UBound(machines) < 0 Then Call error_proc(ws2.Cells(row2, col + 1), "マシン名未設定")
  85. '項目の組み合わせチェック
  86. For i = 0 To UBound(machines)
  87. 'キーを作成、連想配列に未登録なら、エラー処理を行う
  88. key = item & "|" & machines(i)
  89. If dict.exists(key) = False Then
  90. '背景色を黄色にする
  91. ws2.Cells(row2, col).Interior.Color = vbYellow
  92. ws2.Cells(row2, col + 1).Interior.Color = vbYellow
  93. 'シート1に未登録のマシンを出力する
  94. If ws2.Cells(row2, col + 2).Value <> "" Then
  95. ws2.Cells(row2, col + 2).Value = ws2.Cells(row2, col + 2).Value & vbLf
  96. End If
  97. ws2.Cells(row2, col + 2).Value = ws2.Cells(row2, col + 2).Value & org_names(i)
  98. End If
  99. Next
  100. NEXT99:
  101. Next
  102. End Sub
  103. '項目名取得
  104. Private Function getItem(ByVal val As String) As String
  105. Dim temp As String
  106. '両端の空白を削除する
  107. temp = Trim(val)
  108. '全角の大文字に変換する
  109. getItem = StrConv(temp, vbUpperCase + vbWide)
  110. End Function
  111. 'マシン名取得
  112. Private Function getMachine(ByVal val As String, org_names() As String) As String()
  113. Dim temp As String
  114. Dim elm() As String
  115. Dim i As Long
  116. '両端の空白を削除する
  117. temp = Trim(val)
  118. '改行で分割する(全角、大文字に変換しない)
  119. org_names = Split(temp, vbLf)
  120. '空の配列を削除
  121. Call seikei(org_names)
  122. '全角の大文字に変換する
  123. temp = StrConv(temp, vbUpperCase + vbWide)
  124. '改行で分割する
  125. getMachine = Split(temp, vbLf)
  126. '空の配列を削除
  127. Call seikei(getMachine)
  128. End Function
  129. 'マシン名の配列から空の配列を削除
  130. Private Sub seikei(arr() As String)
  131. Dim i As Long
  132. Dim j As Long: j = -1
  133. Dim warr() As String
  134. warr = Split("", vbLf)
  135. If UBound(arr) < 0 Then Exit Sub
  136. For i = 0 To UBound(arr)
  137. If arr(i) <> "" Then
  138. j = j + 1
  139. ReDim Preserve warr(j)
  140. warr(j) = arr(i)
  141. End If
  142. Next
  143. arr = warr
  144. End Sub
  145. 'エラー処理
  146. Private Sub error_proc(rng As Range, msg As String)
  147. '該当シートをアクティブにして、該当セルを選択する
  148. rng.Parent.Activate
  149. rng.Select
  150. 'エラーメッセージ表示
  151. MsgBox (rng.Parent.Name & vbLf & msg)
  152. End
  153. End Sub
  154.  
  155.  
  156.  
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty