ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] excelhome中有关BOM的部分内容

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2015-1-11 09:27 | 显示全部楼层
  1. Sub t02()
  2. '** 添加引用 microsoft xml v6.0 **
  3. Dim Arr, nrr
  4. Dim Dic, K, T
  5. Dim Tt As New MSXML2.DOMDocument, Rt As IXMLDOMElement, Ndt As IXMLDOMElement, Nlt As IXMLDOMNode
  6. Dim Nlist As MSXML2.IXMLDOMNodeList
  7. Dim Routelist As String, Routemax As Integer, Tempmax As Integer
  8.     Set Tt = CreateObject("msxml2.domdocument")
  9.     Tt.setProperty "SelectionLanguage", "XPath"
  10.     lastrow = Sheet1.Range("a65536").End(xlUp).Row
  11.     Arr = Sheet1.Range("a2:c" & lastrow)
  12.     Set Tt = New MSXML2.DOMDocument
  13.     Set Rt = Tt.createElement("xmltree")
  14.     Set Tt.documentElement = Rt '//xml树之根节点
  15.    
  16.     '=== 建立xml树 ===
  17.     Set Ndt = Tt.createElement("s" & Arr(1, 1)) '//添加树形图根节点“1”。由于xml的原因,自然数前要加字母变为“s1”
  18.     Call Ndt.setAttribute("edge", "10") '//设定相邻两结点之间的边长(属性)
  19.     Call Ndt.setAttribute("route", "s1") '//设定路径属性,记录路径上的所有结点
  20.     Call Ndt.setAttribute("tleaf", "tt") '//设定叶结点属性,初始标注为叶结点
  21.     Call Ndt.setAttribute("branchedge", "0") '存叶结点之间的最大路径长度
  22.     Call Ndt.setAttribute("branchroute", "") '存叶结点之间的最大路径长度的结点编号集合
  23.     Rt.appendChild Ndt
  24.     For i = 1 To UBound(Arr) '添加所有的子节点
  25.         tempt = "s" & Arr(i, 1)
  26.         Set Nlist = Tt.getElementsByTagName(tempt)
  27.         If Nlist.Length > 1 Then MsgBox "结点重复": Exit Sub
  28.         Set Rt = Nlist.Item(0)
  29.         Rt.removeAttribute ("tleaf") '//删除标注为叶节点属性
  30.         Call Rt.setAttribute("fleaf", "ff") '//新增非叶结点的属性,是为非叶结点的标识
  31.         Set Ndt = Tt.createElement("s" & Arr(i, 2))
  32.         Rt.appendChild Ndt
  33.         Call Ndt.setAttribute("edge", Arr(i, 3)) '由根节点到叶结点的累加路径长度
  34.         Call Ndt.setAttribute("route", "s" & Arr(i, 2)) '结点编号(存结点编号集合)
  35.         Call Ndt.setAttribute("tleaf", "tt") '标识叶结点
  36.     Next i
  37.     'Tt.Save "F:\creatxml.xml"'##调试用
  38.    
  39.     '=== 处理xml树,找最长路径 ===
  40.     Set Nlist = Tt.selectNodes("//*[@tleaf]") '列出叶叶结点集合,属性为tleaf的元素结点。此处为Xpath语句
  41.     '====== 逐层、逐个处理叶结点 ======
  42.     Do Until Nlist.Length = 1 '当只剩一个tleaf属性时,逐层、逐个处理叶结点过程结束
  43.         Set Dic = CreateObject("Scripting.Dictionary")
  44.         For Each Nlt In Nlist '该循环后,得到叶结点的父结点的子结点数量。如果叶结点的父结点的子结点数量多于叶结点的数量,暂不处理
  45.             Dic(Nlt.parentNode.nodeName) = Dic(Nlt.parentNode.nodeName) + 1 '叶结点的父结点出现的次数,即叶结点的父结点的子结点数量
  46.         Next
  47.         For Each Nlt In Nlist '该循环后,保留符合处理条件的叶结点的父结点
  48.             Set Nlist = Nlt.parentNode.childNodes '叶结点的兄弟结点集合
  49.             If Dic.Exists(Nlt.parentNode.nodeName) Then
  50.                 If Not Dic(Nlt.parentNode.nodeName) = Nlist.Length Then '叶结点的父结点的子结点的数量不等于叶结点的父结点出现的次数
  51.                     Dic.Remove (Nlt.parentNode.nodeName) '删除该父结点,因为它的子节点数量不等于叶结点数量
  52.                 End If
  53.             End If
  54.         Next
  55.         K = Dic.keys
  56.         For Each k1 In K
  57.             Set Rt = Tt.getElementsByTagName(k1).Item(0) '找叶结点的父结点
  58.             If Not Rt Is Nothing Then
  59.                 Set Nlist = Rt.childNodes
  60.                 Routemax = 0
  61.                 Tempmax = 0
  62.                 '==== 累加结点间的路径长度,添加路径结点集合 ====
  63.                 For i = 1 To Nlist.Length - 1 '两层循环为找最长路径
  64.                     For j = i + 1 To Nlist.Length
  65.                         Tempmax = CInt(Rt.childNodes(i - 1).Attributes(0).nodeValue) _
  66.                             + CInt(Rt.childNodes(j - 1).Attributes(0).nodeValue)
  67.                         If Tempmax > Routemax Then
  68.                             Routemax = Tempmax '最长路径值记入中间变量
  69.                             Routelist = ""
  70.                             Routelist = Rt.childNodes(i - 1).Attributes(1).nodeValue & Rt.childNodes(j - 1).Attributes(1).nodeValue   '最长路径路过的结点
  71.                         End If
  72.                     Next j
  73.                 Next i
  74.                 If CInt(Tt.getElementsByTagName("s1").Item(0).Attributes(2).nodeValue) < Routemax Then  '比较已有的
  75.                     Tt.getElementsByTagName("s1").Item(0).Attributes(2).nodeValue = Routemax '最长路径值存入根结点属性中
  76.                     Tt.getElementsByTagName("s1").Item(0).Attributes(3).nodeValue = Routelist '最长路径路过的结点存入根结点属性中
  77.                 End If
  78.                 Routemax = 0
  79.                 Routelist = ""
  80.                 '==== 累加根结点到叶结点间的路径长度,添加路径结点集合 ====
  81.                 For i = 0 To Nlist.Length - 1
  82.                     'MsgBox Rt.childNodes(i).Attributes(0).nodeValue & "," & Rt.childNodes(i).Attributes(0).nodeName & "," & Rt.childNodes(i).nodeName
  83.                     If CInt(Rt.childNodes(i).Attributes(0).nodeValue) > Routemax Then
  84.                         Routemax = Rt.childNodes(i).Attributes(0).nodeValue
  85.                         Routelist = ""
  86.                         Routelist = Rt.childNodes(i).Attributes(1).nodeValue
  87.                     End If
  88.                 Next i
  89.                 Rt.Attributes(0).nodeValue = Rt.Attributes(0).nodeValue + Routemax
  90.                 Rt.Attributes(1).nodeValue = Routelist & Rt.Attributes(1).nodeValue
  91.                 '==== 删除处理过的叶节点并修改其父结点的非叶结点的标识为叶结点 ====
  92.                 Rt.removeAttribute ("fleaf")
  93.                 Call Rt.setAttribute("tleaf", "tt")
  94.                 For i = 0 To Nlist.Length - 1
  95.                     Set Ndt = Rt.childNodes(0) '注意:childNodes的Index只能设置为0
  96.                     Call Ndt.parentNode.removeChild(Ndt)
  97.                     Set Ndt = Nothing
  98.                 Next i
  99.             End If
  100.         Next
  101.         Tt.Save "F:\creatxml.xml"
  102.         Set Nlist = Tt.selectNodes("//*[@tleaf]")
  103.         Set Dic = Nothing
  104.     Loop
  105.     'Tt.Save "F:\creatxml.xml"'##调试用
  106.     '比较"根节点到叶结点的累加路径长度"(edge)与"叶结点之间的最大路径长度"(branchedge),谁大
  107.     If CInt(Rt.Attributes(0).nodeValue) > CInt(Rt.Attributes(2).nodeValue) Then
  108.         MsgBox Space(4) & "最大路径长度" & Chr(10) & Space(10) & Rt.Attributes(0).nodeValue _
  109.             & Chr(10) & Space(4) & "最大路径结点集合列表" & Chr(10) & Space(10) & Rt.Attributes(1).nodeValue
  110.     Else
  111.         MsgBox Space(4) & "最大路径长度" & Chr(10) & Space(10) & Rt.Attributes(2).nodeValue _
  112.             & Chr(10) & Space(4) & "最大路径结点集合列表" & Chr(10) & Space(10) & Rt.Attributes(3).nodeValue
  113.     End If
  114. End Sub
复制代码
原帖链接
http://club.excelhome.net/thread-1163712-7-1.html

一种对树形图的分析

TA的精华主题

TA的得分主题

发表于 2015-2-4 22:42 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
真的是太好了,好好学习。争取早日做出自己的作品与大家共享。

TA的精华主题

TA的得分主题

发表于 2016-9-5 09:31 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2016-9-27 13:57 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
非常好,慢慢学习,谢谢

TA的精华主题

TA的得分主题

发表于 2016-11-18 14:35 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
真的是太好了,好好学习。

TA的精华主题

TA的得分主题

发表于 2017-2-25 00:58 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
学习中。。。。

TA的精华主题

TA的得分主题

发表于 2017-6-8 15:17 | 显示全部楼层
还常好的资源贴子,留个记号学习。

TA的精华主题

TA的得分主题

发表于 2017-10-14 10:33 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
谢谢分享      学习

TA的精华主题

TA的得分主题

发表于 2018-6-15 16:45 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-10-15 09:54 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
感谢分享,好好学习!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-19 07:47 , Processed in 0.033813 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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