赞
踩
目录
本文作为专栏《VBA实用编程技巧》专栏其中的一部分,返回专栏总纲,阅读所有文章,点击Link:
在使用VBA编程的时候,我们经常会使用Type函数自定义数据类型。在VBA中,关键字Type用于定义用户自定义的数据类型。这些自定义类型允许你将一组相关的变量组合成一个单独的数据结构,类似于其他编程语言中的结构体或类。使用Type定义的自定义类型可以简化代码并提高可读性。
VBA中,Type 是一种用户定义的数据类型,它允许您创建自定义的数据结构,以更好地组织和处理数据。使用 Type 定义数据类型具有以下好处,如图1-1:
图1-1 Type定义数据类型的好处
需要注意的是,虽然 Type 在某些情况下非常有用,但它并不是VBA中唯一的数据结构工具。VBA还提供了其他数据结构,如类(Class)和集合(Collection),它们提供了更高级的数据组织和管理功能。在选择使用 Type 还是其他数据结构时,应根据具体的应用场景和需求进行权衡。这些类型后续我们都会进行介绍,请大家持续关注。
如下代码所示,Type类型的使用非常简单,形式如下:
- Type 数据类型名
- 成员1 as 数据类型(VBA内基本数据类型)
- 成员2 as 数据类型(VBA内基本数据类型)
- 成员3 as 数据类型(VBA内基本数据类型)
- ...
- end Type
简单举个实例说明一下用法:
- Option Explicit
- Type student
- Name As String
- Age As Integer
- Score As Single
- End Type
- Sub TypeTest()
- Dim stu01 As student
- stu01.Name = "John"
- stu01.Age = 20
- stu01.Score = 88
- Debug.Print "Stu01 Name: " & stu01.Name & vbCrLf & "Age: " & stu01.Age & vbCrLf & "Grade: " & stu01.Score
- End Sub
需要注意,Type定义类型只能在标准模块或类模块中定义,不能在对象模块(比如工作表)中创建。
在VBA中,如果我们直接把一个Type类型存入字典,会发现是无法实现的。如下代码,我们定义一个学生信息的数据类型,然后尝试存入字典:
- Option Explicit
- Option Base 0
- Type student
- Name As String '姓名
- Age As Integer '年龄
- Score As Single '分数
- End Type
- Sub TypeData2Dic()
-
- Dim dict As Object
- Set dict = CreateObject("Scripting.Dictionary") '创建字典
- Dim i As Integer
- Dim student() As student '创建studen类数据
- '定义一个student数组
- ReDim student(1)
-
- student(0).Name = "Jim"
- student(0).Age = 10
- student(0).Score = 98.5
-
- student(1).Name = "Joy"
- student(1).Age = 11
- student(1).Score = 88
-
- '存入字典
- For i = LBound(student) To UBound(student) Step 1
- If Not dict.Exists(student(i).Name) Then
- dict.Add student(i).Name, student(i)
- End If
- Next i
-
- End Sub
-
如果按上述代码运行,会爆出如下图2-1所示的编译错误提示,这是因为在VBA中的字典只能存入VBA定义的基本类型,如string,integer等,无法对用户定义的type结构体类型进行存储。
图2-1.编译错误
那么如何解决这个问题呢,我在日常的使用中通常使用如下这2个方法,如果大家还有更好的方法,可以一起分享一下。
代码修改如下:
- Option Explicit
- Option Base 0
- Type student
- Name As String '姓名
- Age As Integer '年龄
- Score As Single '分数
- End Type
- Sub TypeData2Dic()
-
- Dim dict As Object
- Set dict = CreateObject("Scripting.Dictionary") '创建字典
- Dim i As Integer
- Dim student() As student '创建studen类数据
- '定义一个student数组
- ReDim student(1)
-
- student(0).Name = "Jim"
- student(0).Age = 10
- student(0).Score = 98.5
-
- student(1).Name = "Joy"
- student(1).Age = 11
- student(1).Score = 88
-
- '存入字典
- For i = LBound(student) To UBound(student) Step 1
- If Not dict.Exists(student(i).Name) Then
- dict.Add student(i).Name, i '存储的是数组的序号,不再是Type类型数据
- End If
- Next i
- '下面测试一下
- Debug.Print student(dict("Joy")).Score '查看姓名为Joy同学的得分
- '实测运行结果为:88
- End Sub
如上代码,字典存储的是student数组的序号,字典的键是学生的姓名,这样就可以直接通过student(dic("学生姓名"))查询相关信息了。
VBA里我们可以创建一个类模块,类模块可以看成是一个对象,是可以存入字典的。首先VBA创建一个类模型,命名为student,并在类模块里定义上面程序的学生信息。如下图2。
图2-2.类模块的创建方式示意图
然后在模块1中添加主程序,代码如下:
- Option Explicit
- Option Base 0
-
- Sub TypeData2Dic()
-
- Dim dict As Object
- Set dict = CreateObject("Scripting.Dictionary") '创建字典
- Dim i As Integer
- Dim student() As New student '创建studen类数据
- '定义一个student数组
- ReDim student(1)
-
- student(0).Name = "Jim"
- student(0).Age = 10
- student(0).Score = 98.5
-
- student(1).Name = "Joy"
- student(1).Age = 11
- student(1).Score = 88
-
- '存入字典
- For i = LBound(student) To UBound(student) Step 1
- If Not dict.Exists(student(i).Name) Then
- dict.Add student(i).Name, student(i) '将类模块对象存入字典
- End If
- Next i
- '下面测试一下
- Debug.Print dict("Joy").Score '查看姓名为Joy同学的得分
- '实测运行结果为:88
-
- End Sub
上面就是我经常使用的两种方法,欢迎指正和补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。