ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
123
返回列表 发新帖
楼主: mrgood88

[求助] 根据上级关系生成由高到低层级关系

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-9-6 19:04 | 显示全部楼层
Dim d, aa, x%, str$
Sub zz()
Dim i&, arr, j%, z1, r0%, j1%, y%
i = [b65536].End(xlUp).Row
arr = Range("b2:d" & i)
Set d = CreateObject("Scripting.Dictionary")
Range("g2:h100").ClearContents
For i = 1 To UBound(arr)
If Not d.exists(arr(i, 3)) Then
Set d(arr(i, 3)) = CreateObject("Scripting.Dictionary")
End If
d(arr(i, 3))(arr(i, 1)) = "(" & arr(i, 2) & ")"
Next
For Each aa In d("无").keys
x = 0: str = ""
If Not d.exists(aa) Then
r0 = [g65536].End(xlUp).Row
Cells(r0 + 1, "g") = aa & d("无")(aa)
Cells(r0 + 1, "h") = 1
Else
Call digui(aa, 0, "", d("无")(aa))
r0 = [g65536].End(xlUp).Row
z1 = Split(str, ",")
For j = 0 To UBound(z1)
Cells(r0 + 1 + j, "g").IndentLevel = Val(Split(z1(j), "|")(1))
Cells(r0 + 1 + j, "g") = Split(z1(j), "|")(0)
Next
For j = 0 To UBound(z1) - 1
For j1 = j + 1 To UBound(z1)
If Val(Split(z1(j1), "|")(1)) > Val(Split(z1(j), "|")(1)) Then
y = y + 1
Else
Exit For
End If
Next
Cells(r0 + 1 + j, "h") = y + 1: y = 0
Next
Cells(r0 + 1 + j, "h") = y + 1: y = 0
End If
Next
End Sub
Sub digui(Pid, n, s, w)
Dim i&, key, temp2, sr%, sar
If d.exists(Pid) Then
temp2 = s & Pid & w & "|" & n & ","
key = d(Pid).keys
For i = 0 To UBound(key)
Call digui(key(i), n + 1, temp2, d(Pid)(key(i)))
Next
Else
If str = "" Then
str = s & Pid & w & "|" & n
Else
sar = Split(s & Pid & w & "|" & n & ",", ",")
For sr = 0 To UBound(sar)
If InStr(str, sar(sr)) = 0 Then str = str & "," & sar(sr)
Next
End If
End If
End Sub

TA的精华主题

TA的得分主题

发表于 2018-9-6 21:26 | 显示全部楼层
本帖最后由 一把小刀闯天下 于 2018-9-6 21:51 编辑

'C列可以为空,因为关系确定后层级也就确定了

Option Explicit

Sub Test()
  Dim arr, i, j, k, n, brr(), t, cnt, m, tt
  arr = [b2:d8]
  For i = 1 To UBound(arr, 1)
    If arr(i, 3) = "无" Then
      n = n + 1
      ReDim Preserve brr(1 To n)
      brr(n) = arr(i, 1)
    End If
  Next
  ReDim crr(1 To Rows.Count, 1 To 2): n = 0
  For i = 1 To UBound(brr)
    n = n + 1: cnt = 1
    crr(n, 1) = brr(i) & "-1"
    For j = 1 To UBound(arr, 1)
      cnt = 2
      If arr(j, 3) = brr(i) Then
        crr(n, 1) = crr(n, 1) & "|" & arr(j, 1) & "-" & cnt
        Call rec(arr, arr(j, 1), crr, n, cnt + 1)
      End If
  Next j, i
  cnt = 0: ReDim arr(1 To Rows.Count, 1 To 2)
  For i = 1 To n
    If InStr(crr(i, 1), "|") Then
      t = Split(crr(i, 1), "|")
      For j = 0 To UBound(t)
        m = m + 1
        For k = j + 1 To UBound(t)
          If Split(t(j), "-")(1) = Split(t(k), "-")(1) Then Exit For
        Next
        tt = Split(t(j), "-")
        arr(m, 1) = Space(4 * (tt(1) - 1)) & tt(0) & "(" & tt(1) & "级)"
        If j <> 0 And k = UBound(t) + 1 Then arr(m, 2) = 1 Else arr(m, 2) = k - j
      Next
    Else
      m = m + 1
      tt = Split(crr(i, 1), "-")
      arr(m, 1) = tt(0) & "(1级)": arr(m, 2) = 1
    End If
  Next
  [j:k].ClearContents
  [j2].Resize(m, 2) = arr
End Sub

Function rec(arr, s, crr, n, cnt)
  Dim i
  For i = 1 To UBound(arr, 1)
    If arr(i, 3) = s Then
      crr(n, 1) = crr(n, 1) & "|" & arr(i, 1) & "-" & cnt
      Call rec(arr, arr(i, 1), crr, n, cnt)
    End If
  Next
End Function

TA的精华主题

TA的得分主题

发表于 2018-9-6 22:33 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2025-1-13 15:53 , Processed in 0.016733 second(s), 5 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表