使用VBA快速梳理多层级族谱(组织架构)

news2024/11/17 1:40:45

实例需求:族谱(或者公司组织架构等)都是典型的带有层级关系数据,例如下图中左侧表格所示。

  • A列为层级(准确的讲是B列成员的层级),从一开始递增
  • B列和C列为成员直接的父(/母)子(/女)关系
  • D列为辅助标记

现需要整理为右侧表格的形式,按照每个家族链依次排列,如标记颜色部分所示。

在这里插入图片描述

由于每个层级的成员梳理,层级深度不确定,因此需要使用递归过程实现。

实例代码如下。

Dim arrRes(), iR As Long
Sub Demo()
    Dim i As Long, j As Long, objDic As Object
    Dim arrData, rngData As Range, aRow(1 To 4)
    Dim sParent As String, sChild As String, sFirst As String
    Set rngData = ActiveSheet.Range("A1").CurrentRegion
    arrData = rngData.Value
    ReDim arrRes(1 To UBound(arrData), 1 To 4)
    iR = 1
    For j = 1 To 4
        arrRes(iR, j) = arrData(1, j)
    Next
    Set objDic = CreateObject("scripting.dictionary")
    For i = LBound(arrData) To UBound(arrData)
        If arrData(i, 1) = 1 Then 
            If Len(sFirst) > 0 Then
                Call GetChild(objDic, "", sFirst)
                objDic.RemoveAll
            End If
            sFirst = arrData(i, 3)
        End If
        sParent = arrData(i, 2): sChild = arrData(i, 3)
        If Not objDic.exists(sParent) Then
            Set objDic(sParent) = CreateObject("scripting.dictionary")
        End If
        For j = 1 To 4
            aRow(j) = arrData(i, j)
        Next
        objDic(sParent)(sChild) = aRow()
    Next i
    Call GetChild(objDic, "", sFirst)
    With ActiveSheet.Range("F1").Resize(iR, 4)
        .EntireColumn.Clear
        .Value = arrRes
    End With
End Sub
Sub GetChild(oDic As Object, sParent As String, sChild As String)
    Dim vKey, aRow, j As Long
    aRow = oDic(sParent)(sChild)
    iR = iR + 1
    For j = 1 To 4
        arrRes(iR, j) = aRow(j)
    Next
    If oDic.exists(sChild) Then
        For Each vKey In oDic(sChild).keys
            Call GetChild(oDic, sChild, vKey)
        Next
    End If
End Sub

【代码解析】
第1行代码声明模块基本变量,用于保存结果数据。
第2~36行代码为主过程。
第6行代码获取A1开始的当前数据区域。
第7行代码将数据加载到数组中。
第8行代码为结果数组分配存储空间。
第10~12行代码将表头复制到结果数组中。
第13行代码创建字典对象。
第14~30行代码循环处理每行数据。
第15行代码判断当前数据是否为第一级。
如果是的话,第16~20行代码进行相应处理。
第16行代码判断sFirst变量是否为空,如果不为空,说明从该行开始一个新的族系。
第17行代码调用递归过程GetChild(),将objDic对象中保存的族谱整理到结果数组中。
第18行代码清空字典对象。
第20行代码将当前行的C列成员保存到sFirst变量中。
第22行代码分别读取B列和C列数据。
第23行代码判断父成员是否已经存在于字典对象中,如果不存在,第24行代码创建一个嵌套的字典对象。
第26~28行代码将该行4个数据保存到临时数组变量aRow中。
第29行代码将行数据保存到嵌套字典对象中,父成员为外层字典的键,子成员为内层字典的键。
第31行代码作用与第17行相同,用于处理最后一个家族。
第32行代码为结果输出区域Range对象。
第33行代码清空输出区域。
第34行代码将结果写入工作表。
第37~49行代码为递归过程用于查找下一级子成员。
第39行代码读取嵌套字典对象中保存的行数据。
第40行行指针标记递增,由于iR是模块级别变量,因此每次在GetChild中调用此变量时,仍保留原值,不会被初始化。
第41~43行代码将行数据写入结果数组中。
第44行代码判断字典中是否存在子成员的键,如果存在的话,说明该成员具备下一级子成员(即孙成员)。
第46行代码再次调用递归过程,注意此处的参数值,sChild作为第二个参数,即作为下一次调用的父成员。


递归过程代码并不复杂,其难点在于如何提炼递归逻辑,确保递归过程返回相应的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1507049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搭建一款实用的个人IT工具箱——it-tools

一、it-tools介绍 IT-Tools是一款开源的个人工具箱,专为IT从业人员打造,支持Docker私有化部署,包含众多实用的IT工具。其功能丰富多样,涵盖二维码生成、数据格式转换、MAC地址生成等,可满足用户多样化的需求。 二、本…

armv8/armv9 MMU深度学习

目录 1、MMU概念介绍2、虚拟地址空间和物理地址空间2.1、(虚拟/物理)地址空间的范围2.2、物理地址空间有效位(范围)2.2.1、页表翻译相关寄存器的配置 3、Translation regimes4、地址翻译/几级页表?4.1、思考:页表到底有几级?4.2、以4KB granu…

《日期类》的模拟实现

目录 前言: 头文件类与函数的定义Date.h 实现函数的Date.cpp 测试Test.cpp 运行结果: 前言: 我们在前面的两章初步学习认识了《类与对象》的概念,接下来我们将实现一个日期类,是我们的知识储备更加牢固。 头文件…

Android Gradle 开发与应用 (五) : 基于Gradle 8.2,创建Gradle插件

1. 前言 本文介绍在Android中,如何基于Gradle 8.2,创建Gradle插件。 1.1 本文环境 Android Studio 版本 : Android Studio Hedgehog | 2023.1.1Gralde版本 : gradle 8.2 使用 Android Gradle 插件升级助理 Android Gradle 插件版本说明 1.2 为什么要写…

【C语言】——详解操作符(下)

【C语言】——详解操作符(下) 前言七、关系操作符八、逻辑操作符8.1、& 与运算符8.2、 | 或运算符 九、条件操作符十、逗号表达式十一、下标引用与函数调用操作符11.1、[ ] 下标引用操作符11.2、( ) 函数调用操作符 十二、 结构成员操作符12.1、…

转移表回调函数实现

回调函数实现 计算器的模拟(函数指针数组的使用)(回调函数) 简化 冗余 老的代码的问题就是 冗余 写死 不能完成不同的任务 函数调用的时候只需要知道地址就可以 calc计算器 这里也称之为转移表 #define _CRT_SECURE_NO_WAR…

朴素贝叶斯 | 多分类问题

目录 一. 贝叶斯公式的推导二. 朴素贝叶斯1. 离散的朴素贝叶斯朴素贝叶斯导入示例 离散的朴素贝叶斯训练 2. 连续的朴素贝叶斯3. 伯努利朴素贝叶斯4. 多项式朴素贝叶斯4.1 Laplace平滑4.2 Lidstone平滑 三. 概率图模型1. 贝叶斯网络(Bayesian Network)1.1 全连接贝叶斯网络1.2 …

【Redis系列】深入了解 Redis:一种高性能的内存数据库

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

分布式搜索elasticsearch

1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 例如: 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案…

25 使用块的网络 VGG【李沐动手学深度学习v2课程笔记】

目录 1. VGG块 2. VGG网络 3. 训练模型 4. 小结 虽然AlexNet证明深层神经网络卓有成效,但它没有提供一个通用的模板来指导后续的研究人员设计新的网络。 与芯片设计中工程师从放置晶体管到逻辑元件再到逻辑块的过程类似,神经网络架构的设计也逐渐变得…

【Linux】文件系统扩展——软硬链接

目录 对文件建立软硬链接 软链接 硬链接 对文件建立软硬链接 对 log 文件建立软链接: ln -s log log.soft.link 对 test 文件建立硬链接: ln test test.hard.link log.soft.link 和 test.hard.link 在 Linux 中都只是文件名,为了方便…

Math类 --Java学习笔记

Math 代表数学,是一个工具类,里面提供的都是对数据进行操作的一些静态方法 Math提供的常用方法

springBoot--静态资源映射

静态资源映射 前言1、通过继承 WebMvcConfigurerAdapter 来实现2、在 application.properties 配置 前言 在 web 开发中,静态资源的访问是必不可少的,如图片、js、css等资源的访问 1、通过继承 WebMvcConfigurerAdapter 来实现 即如果使用了 EnableWe…

web前端框架

目前比较火热的几门框架: React React是由Facebook(脸书)开发和创建的开源框架。React 用于开发丰富的用户界面,特别是当您需要构建单页应用程序时。它是最强大的前端框架。 弊端: 您不具备 JavaScript 的实践知识,则建议不要使用 React。同样&#x…

后端八股笔记------框架篇

👆是单例,不是线程安全 上上图中的count变量在单例bean中就是不安全的。 有fetchType"lazy"的情况就是懒加载,不调用就不加载。 没有"lazy"的情况就不是懒加载。

小迪安全36WEB 攻防-通用漏洞XSS 跨站MXSSUXSSFlashXSSPDFXSS

#XSS跨站系列内容:1. XSS跨站-原理&分类&手法 XSS跨站-探针&利用&审计XSS跨站另类攻击手法利用 XSS跨站-防御修复&绕过策略 #知识点: 1、XSS 跨站-原理&攻击&分类等 2、XSS 跨站-MXSS&UXSS&FlashXss&PDFXSS 等 1、原…

【数据结构与算法】绪论

目录 一、数据结构研究 二、基本概念和术语 2.1 基本概念 2.2 什么是数据结构? 2.3 数据结构内容 2.4 逻辑结构种类 2.5 存储结构种类 2.6 数据类型和抽象数据类型 三、算法和算法分析 3.1 算法的定义 3.2 算法的特性 3.3 算法设计要求 3.4 算法好坏评…

mediapipe 实现姿态分析——举手检测

目录 人体姿态检测 效果展示 举手检测 行业应用 代码实现 代码分析 效果展示 代码修改,一只手举起即可 总结 啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦^_^啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦啦♪(^∇^*)啦啦啦…

计算机网络 —— 运输层

运输层 5.1 运输层概述 运输层的主要任务是,如何为运行在不同主机上的应用进程提供直接的通信服务。运输层协议又称为端到端协议。 根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输协议,即面向连接的TCP和无连接的UDP 5.2…

VBA(学习笔记)

1. 数据类型 变量定义:Dim 变量名 As 数据类型 变量赋值:变量名 值 1.1 数值型 1.1.1 整数 (1) Byte:1字节(0~255) (2) Integer:2字节(-32768~32767) (3) Long:4…