|
- Sub test2()
- Dim arr, dic(5), i, j, m, key, t, MaxRow
- ' 循环定义6个字典,编号为0-5
- For i = 0 To UBound(dic)
- Set dic(i) = CreateObject("scripting.dictionary")
- Next
- With ActiveSheet
- ' 清除o-W列现有的数据
- MaxRow = Sheet1.Cells(.Rows.Count, "o").End(xlUp).Row 'o列最后一行
- If MaxRow > 2 Then
- .Range(.Cells(3, "o"), .Cells(MaxRow, "W")).ClearContents
- End If
- MaxRow = .Cells(.Rows.Count, 6).End(xlUp).Row '第6列(F列)最后一行
- If MaxRow <= 2 Then
- '当第6列(F列,条件区域)只有标题行。没有具体的数据时,退出。
- End
- End If
- End With
- ' 条件数据部分导入数组中
- arr = Range("f3:g" & MaxRow).Value
- ' 条件数据写入字典4:Key=母件名称,Item=母件数量
- For i = 1 To UBound(arr, 1)
- If dic(4).Exists(arr(i, 1)) Then
- ' 条件区域的母件名称存在重复
- tsxx = "条件区域的母件名称列存在重复,是否继续?" & Chr(10) & Chr(10)
- tsxx = tsxx & "单击按钮“是”,重复的母件名称数量相加。" & Chr(10) & "单击按钮“否”,退出修改。"
- If MsgBox(tsxx, vbYesNo + vbQuestion + vbDefaultButton2, "条件数据区域母件名称重复提示") = vbNo Then
- ' 单击按钮否,退出修改
- End
- End If
- End If
- dic(4)(arr(i, 1)) = arr(i, 2) + dic(4)(arr(i, 1))
- Next
- ' 基础数据部分导入数组
- arr = Range("a3:a" & Cells(Rows.Count, "a").End(xlUp).Row).Resize(, 5).Value
- ' 重定义数组:10000个成员
- ReDim brr(1 To 10 ^ 4, 1 To 4)
- ' 基础数据写入字典2:key=子件名称,Item=1
- For i = 1 To UBound(arr, 1)
- dic(2)(arr(i, 2)) = 1
- Next
- '根据字典2更改数组arr数组中第5列的值:
- For i = 1 To UBound(arr, 1)
- If dic(2).Exists(arr(i, 1)) Then
- '在字典dic(2)的子件名称中寻找arr数组中的母件名称,并找到
- arr(i, 5) = 1
- Else
- arr(i, 5) = 0
- End If
- Next
- dic(2).RemoveAll '清空字典2
- ' 根据更新后的arr数组第5列
- For i = 1 To UBound(arr, 1)
- If arr(i, 5) = 0 Then
- ' 此时:子件名称 不出现 在母件名称中
- ' 字典0:key=母件名称,Item=母件名称+空格1+子件名称
- dic(0)(arr(i, 1)) = dic(0)(arr(i, 1)) & Space(1) & arr(i, 2)
- ' 字典1:key=母件名称+子件名称,Item=子件数量
- dic(1)(arr(i, 1) & arr(i, 2)) = arr(i, 4)
- Else
- ' 此时:子件名称 出现 在母件名称中
- ' 字典2:key=母件名称,Item=字典2中母件名称对应的键值+空格1+子件名称
- dic(2)(arr(i, 1)) = dic(2)(arr(i, 1)) & Space(1) & arr(i, 2)
- ' 字典2:key=子件名称,Item=子件数量
- dic(3)(arr(i, 2)) = arr(i, 4)
- End If
- dic(5)(arr(i, 2)) = arr(i, 3)
- Next
- ' 经上述处理后:
- ' 字典0:key=母件名称,Item=该母件需要的子件名称表,空格间隔
- ' 字典1:key=母件名称&该母件需要的子件,Item=该母件需要的某个子件的数量
- ' 字典2:key=存在于母件名称中的子件名称(该子件需要子件组成),Item=该子件需要的下级子件名称表,空格间隔
- ' 字典3:key=存在于母件名称中的子件名称(该子件需要子件组成),Item=该子件需要的数量
- ' 字典4:key=条件数据区的母件名称,Item=该母件的数量
- ' 字典5:key=子件名称,Item=该子件的计量单位
- ' 按照字典0的key数量循环
- For Each key In dic(0).keys
- t = Split(dic(0)(key))
- For i = 1 To UBound(t)
- If dic(2).Exists(t(i)) Then
- ' 递归调用 dfs
- Call dfs(dic, key, t(i), brr, m, dic(1)(key & t(i)))
- Else
- m = m + 1
- brr(m, 1) = key
- brr(m, 2) = t(i)
- brr(m, 4) = dic(4)(key) * dic(1)(key & t(i))
- End If
- Next
- m = m + 1
- Next
- For i = 1 To UBound(brr)
- brr(i, 3) = dic(5)(brr(i, 2))
- Next
- ReDim drr(1 To m, 1 To 4)
- For i = 1 To m
- If brr(i, 4) <> 0 Then
- For j = 1 To 4
- drr(i, j) = brr(i, j)
- Next
- End If
- Next
- ' t = "车圈"
- ' If dic(5).Exists(t) Then [g6] = t & ":" & dic(5)(t) Else [g6] = Empty
- [o3].Resize(UBound(drr, 1), UBound(drr, 2)) = drr
- dic(2).RemoveAll '清空字典2
- ' 汇总brr数组中子件名称的数量
- For i = 1 To UBound(brr)
- dic(2)(brr(i, 2)) = dic(2)(brr(i, 2)) + brr(i, 4)
- Next
- ReDim crr(1 To dic(2).Count, 1 To 3)
- i = 1
- For Each key In dic(2).keys
- If key <> "" Then
- crr(i, 1) = key
- crr(i, 2) = dic(5)(crr(i, 1))
- crr(i, 3) = dic(2)(key)
- i = i + 1
- End If
- Next
- [t3].Resize(UBound(crr, 1), UBound(crr, 2)) = crr
- End Sub
复制代码 |
|