ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

VBA高级教程之字典篇,使用类模块实现字典一对多应用

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-11-4 17:34 来自手机 | 显示全部楼层
本帖已被收录到知识树中,索引项:数组集合和字典
本帖最后由 lee1892 于 2013-11-4 17:36 编辑

不知道什么情况下要这么麻烦,需要用类来存取静态数据,下面这样不行吗?
[code=vb]Private Type INFO
    ID As String * 6
    Name As String * 10
    TelNumber As String * 11
End Type

Sub Test()
    Dim arrGuys() As INFO, dicInd As Object, i As Long, nInd
    Set dicInd = CreateObject(Scripting.Dictionary)
    ReDim arrGuys(2)
    For i = 0 To UBound(arrGuys)
        With arrGuys(i)
            .ID = ...
            .Name = ...
            .TelNumber = ...
            dicInd(.Name) = i
        End With
    Next
    For Each nInd In dicInd.Keys
        With arrGuys(nInd)
            Debug.Print .ID; .Name; .TelNumber
        End
    Next
End Sub[/code]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-4 19:46 | 显示全部楼层
本帖最后由 liucqa 于 2013-11-4 20:11 编辑
lee1892 发表于 2013-11-4 17:34
不知道什么情况下要这么麻烦,需要用类来存取静态数据,下面这样不行吗?

这个就是我在一楼说的字典+数组方式的一种嘛,从完成任务来说,无论采用自定义数据类型+一维数组,还是直接采用二维数组,都可以达成一对多的目的。

但是,从代码的可维护性来看,这样的代码会造成应用层和数据层的耦合度过高,无法复用数据结构,更影响项目升级和后期维护。
想象一下,如果我有40个模块需要用到这个数据结构以及关联的若干功能,如果不用类模块,唯一的办法是写公共自定义数据类型,并在同一个模块写出该数据结构用到的全部函数,然后在其他模块或文件中进行调用,这是典型的面向过程的思路。容易造成代码冗余甚至混乱。而通过一维数组来引用这个数据结构,其结果更是造成数据处理与应用功能耦合到了一起,无法拆分。代码模块之间或者数据结构与代码功能之间耦合度过高,是项目开发不成熟的表现。

面向对象的编程理念,就是解决代码复用、功能耦合之类的问题,给项目维护创造方便。这也是类模块被发明的原因。对面向过程的编程来说,有没有类模块都无所谓的。而面向对象的编程,就完全依赖类模块了。从面向过程到面向对象,我们需要思想上的转变和艰苦的学习过程。一楼代码只不过是一个小例子而已,还很粗糙,仅供参考。


实际上,对初学者来说,采用字典+数组就完全可以达成目的了,没必要搞复杂的类模块来实现目标。
而这也是为什么我在一楼写的短短十几行代码被归属到高级教程的原因。

因为这是编程思路的转变,而不仅仅是编程代码的技巧问题呀。

深刻的理解这句话吧,俺也是最近几年才明白的。






TA的精华主题

TA的得分主题

发表于 2013-11-4 20:17 | 显示全部楼层
liucqa 发表于 2013-11-4 19:46
这个就是我在一楼说的字典+数组方式的一种嘛,从完成任务来说,无论采用自定义数据类型+一维数组,还是直 ...

哦,这对VBA基本没啥太大帮助。没人会拿螺丝刀干冲击钻的活吧~

点评

其实vba和vb没啥本质区别,你看看现在还有好多人在用vb干发射火箭的活呢,无它,唯费用低而...  发表于 2013-11-4 20:24
唉,所以才是高级教程嘛。绝大多数人都是初级的干活...。实际上用VBA干冲击钻的活,在国外是很常见的,总比用C++写要省力气多了,费用低呀!  发表于 2013-11-4 20:22

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-4 20:40 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 liucqa 于 2013-11-4 20:43 编辑
lee1892 发表于 2013-11-4 20:17
哦,这对VBA基本没啥太大帮助。没人会拿螺丝刀干冲击钻的活吧~

其实,我以前也不理解,为啥人类要发明这么复杂的面向对象的理论,什么“类、对象、 继承、属性、方法、静态、抽象、重载、隐藏、重构、声明、定义、初始化、赋值、接口、封装、多态“等等等等,分明是自己给自己找事嘛

后来,写了个2W行的程序,终于理解了

等学了C#之后,更加理解了。

VBA其实提供了简单的面向对象的手段,只是大家水平有限,平时不用而已
但这也是vba的技术呀,不能因为无知而不用,就不去学习和理解,

就好比给你一支枪,有的人上山打鸟下酒喝,一辈子过去了;有的人去奥运会打靶,一辈子也过去了

意义不同,追求不同,能力也不同嘛

点评

赞成!有些东西,随着应用程度越来越高而且不断学习,才会明白  发表于 2014-1-27 11:58
哦,我业余爱好,需求不同~  发表于 2013-12-20 23:16

TA的精华主题

TA的得分主题

发表于 2013-12-20 16:47 | 显示全部楼层
liucqa 发表于 2013-11-4 20:40
其实,我以前也不理解,为啥人类要发明这么复杂的面向对象的理论,什么“类、对象、 继承、属性、方法、静 ...

确实要接触过一段时间的C#,特别是SqlHelper类才能更明白类的思想。

TA的精华主题

TA的得分主题

发表于 2013-12-21 08:26 | 显示全部楼层
一个实用的类模块学习教材
谢谢

TA的精华主题

TA的得分主题

发表于 2013-12-21 11:18 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
方向大于方法,方向大于技巧,这句话在管理学上有效,今天看到楼主的述说,突然意识到这句话在程序界照样适用

最近做查体查询,等返回主界面是,主界面窗体没有激活,需要单击两下鼠标才能输入,正准备查找复杂的API函数,后来看到SendKeys "~"一句简单的代码就可以实现了,就不需要调用API了

TA的精华主题

TA的得分主题

发表于 2014-1-10 19:29 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 yiyiyicz 于 2014-1-10 19:32 编辑

一个应用实例
附件
Book1.rar (9.29 KB, 下载次数: 607)
说明见附件

  1. Sub tt02()
  2. '===================
  3. '====BOM展开实例====
  4. '===================
  5. Dim Arr, Brr
  6. Dim D1 As Object, D2 As Object, Scol As String, Srow As String, i&, j&
  7. Dim Item As CItem
  8.     Arr = Sheet1.Range("a3:e14")     '取源数据
  9.     Set D1 = CreateObject("Scripting.Dictionary")    '后期绑定引用字典对象
  10.     Set D2 = CreateObject("scripting.dictionary")
  11.     For i = 1 To UBound(Arr)  '建立对象
  12.         Set Item = New CItem
  13.         Item.Name = i & "|" & Arr(i, 2)
  14.         Item.Icol = i
  15.         Item.Quantity = Arr(i, 4)
  16.         D1.Add i & "|" & Arr(i, 2), Item
  17.         D2(Arr(i, 2)) = D2(Arr(i, 2))
  18.         Arr(i, 5) = 1
  19.         Set Item = Nothing
  20.     Next i
  21.     '====建立邻接矩阵Brr====
  22.     ReDim Brr(1 To UBound(Arr), 1 To UBound(Arr))
  23.     For i = 1 To UBound(Arr)
  24.         For j = i To UBound(Arr)
  25.             If i = j Or Arr(i, 1) < Arr(j, 1) Then
  26.                 Brr(i, j) = 1
  27.             Else
  28.                 Exit For
  29.             End If
  30.         Next
  31.     Next
  32.     '====利用邻接矩阵Brr,展开BOM====
  33.     '注意,此邻接矩阵是方阵,列标就是行标的转置
  34.     For i = 1 To D1.Count
  35.         Scol = CStr(i & "|" & Arr(i, 2))  '列标
  36.         For j = 1 To D1.Count
  37.             Srow = CStr(j & "|" & Arr(j, 2))   '行标
  38.             'Debug.Print D1(Srow).Icol & "  " & Srow & "  " & Brr(D1(Srow).Icol, i)
  39.             If Not IsEmpty(Brr(D1(Srow).Icol, i)) Then
  40.                 'D2(Arr(i, 2)) = D2(Arr(i, 2)) * D1(Srow).Quantity
  41.                 Arr(i, 5) = Arr(i, 5) * D1(Srow).Quantity
  42.             End If
  43.             If j = i + 1 Then Exit For
  44.         Next j
  45.     Next i
  46.     For i = 1 To UBound(Arr)
  47.         D2(Arr(i, 2)) = D2(Arr(i, 2)) + Arr(i, 5)
  48.     Next i
  49.     '====结果复制到sheet1中====
  50.     Sheet1.Range("b16").Resize(D2.Count, 1) = Application.Transpose(D2.keys)
  51.     Sheet1.Range("d16").Resize(D2.Count, 1) = Application.Transpose(D2.items)
  52.     Sheet1.Range("a24").Resize(UBound(Arr), UBound(Arr, 2)) = Arr
  53. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2014-1-10 19:35 | 显示全部楼层
18楼,仅仅是应用实例
如果简单的展开BOM,在明白了邻接矩阵在其中的作用。只用数组也行

TA的精华主题

TA的得分主题

发表于 2014-1-29 15:55 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-15 21:55 , Processed in 0.036491 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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