Option Explicit
Dim row3 As Long '転記先行番号
Dim ws1 As Worksheet '在庫一覧シート
Dim ws2 As Worksheet 'まとめシート
Dim ws3 As Worksheet '転記先シート
Dim dicST As Object '連想配列 キー:車種 値:最初に出現する行番号(在庫一覧)
Dim dicEN As Object '連想配列 キー:車種 値:最後に出現する行番号(在庫一覧)
Public Sub 転記2()
Dim maxrow1 As Long '最大行数 在庫一覧
Dim maxrow2 As Long '最大行数 まとめ
Dim row1 As Long '行番号 在庫一覧
Dim row2 As Long '行番号 在庫一覧
Dim key As String '車種
Set ws1 = Sheets("在庫一覧")
Set ws2 = Sheets("まとめ")
Set ws3 = Sheets("転記先")
Set dicST = CreateObject("Scripting.Dictionary") ' 連想配列の定義
Set dicEN = CreateObject("Scripting.Dictionary") ' 連想配列の定義
maxrow1 = ws1.Cells(Rows.Count, 1).End(xlUp).Row 'A列の最大行取得
maxrow2 = ws2.Cells(Rows.Count, 2).End(xlUp).Row 'B列の最大行取得
'最大行数が要件を満たしてないなら処理しない
If maxrow1 < 5 Then Exit Sub
If maxrow2 < 6 Then Exit Sub
'転記先 6行以降をクリア
ws3.Rows("6:" & Rows.Count).ClearContents
row3 = 6
'車種を取り込む
For row1 = 5 To maxrow1
key = ws1.Cells(row1, "A").Value
If dicST.exists(key) = False Then
dicST(key) = row1
dicEN(key) = row1
Else
If dicEN(key) + 1 <> row1 Then
ws1.Activate
ws1.Cells(row1, "A").Select
MsgBox ("車種が連続していません")
Exit Sub
End If
dicEN(key) = row1
End If
Next
'まとめシートを1行毎に処理する
For row2 = 6 To maxrow2
key = ws2.Cells(row2, "B").Value
If dicST.exists(key) = False Then
ws2.Activate
ws2.Cells(row2, "B").Select
MsgBox ("車種が在庫一覧にありません")
Exit Sub
End If
'転記処理(車種、まとめの行番号)
Call tenki(key, row2)
'該当車種の連想配列を削除
dicST.Remove key
dicEN.Remove key
Next
'ソート用キーをクリア
ws3.Range("K6:L" & Rows.Count).ClearContents
MsgBox ("完了")
End Sub
'転記処理 key:車種 row2:まとめの行番号
Private Sub tenki(ByVal key As String, ByVal row2 As Long)
Dim rcnt As Long '該当者車種の行数(在庫一覧)
Dim srow1 As Long '該当車種の開始行(在庫一覧)
Dim i As Long
Dim ratio As Double '比率
Dim m_weight As Variant '必要重量
Dim p_weight As Variant '部品重量
rcnt = dicEN(key) - dicST(key) + 1
srow1 = dicST(key)
'在庫一覧及びまとめから転記先へ転送(行数分繰り返す)
For i = 0 To rcnt - 1
'車種、型式、必要重量
ws3.Cells(row3 + i, "B").Resize(1, 3).Value = ws2.Cells(row2, "B").Resize(1, 3).Value
'製造No、部品重量
ws3.Cells(row3 + i, "E").Resize(1, 2).Value = ws1.Cells(srow1 + i, "C").Resize(1, 2).Value
'部品単量
ws3.Cells(row3 + i, "G").Value = ws2.Cells(row2, "G").Value
'不良品
ws3.Cells(row3 + i, "H").Value = ws1.Cells(srow1 + i, "F").Value
Next
'判定処理(行数分繰り返す)
For i = 0 To rcnt - 1
If ws3.Cells(row3 + i, "H").Value = "不良" Then
ws3.Cells(row3 + i, "A").Value = "他"
ws3.Cells(row3 + i, "i").Value = "なし" '結果
ws3.Cells(row3 + i, "K").Value = 9 'ソート用第1キー
ws3.Cells(row3 + i, "L").Value = 0 'ソート用第2キー
Else
m_weight = ws3.Cells(row3 + i, "D").Value
p_weight = ws3.Cells(row3 + i, "F").Value
If IsNumeric(m_weight) = False Then
ws3.Activate
ws3.Cells(row3 + i, "D").Select
MsgBox ("必要重量が不正です")
End
End If
If m_weight = 0 Then
ws3.Activate
ws3.Cells(row3 + i, "D").Select
MsgBox ("必要重量が0です")
End
End If
If IsNumeric(p_weight) = False Then
ws3.Activate
ws3.Cells(row3 + i, "F").Select
MsgBox ("部品重量が不正です")
End
End If
ratio = (p_weight - m_weight) / m_weight
If Abs(ratio) <= 0.1 Then
ws3.Cells(row3 + i, "A").Value = "○" '状態
ws3.Cells(row3 + i, "K").Value = 1 'ソート用第1キー
Else
ws3.Cells(row3 + i, "A").Value = "他" '状態
ws3.Cells(row3 + i, "i").Value = "なし" '結果
ws3.Cells(row3 + i, "K").Value = 2 'ソート用第1キー
End If
ws3.Cells(row3 + i, "L").Value = Abs(ratio) 'ソート用第2キー
End If
Next
'ソート
ws3.Range("A" & row3 & ":L" & row3 + rcnt - 1).Sort key1:=ws3.Range("K" & row3), key2:=ws3.Range("L" & row3)
'車種、型式、必要重量の重複部、部品単量をクリア
For i = 1 To rcnt - 1
ws3.Cells(row3 + i, "B").Resize(1, 3).Value = ""
ws3.Cells(row3 + i, "G").Value = ""
Next
row3 = row3 + rcnt + 1
End Sub