Excel VBA学习——数据类型

Excel VBA学习——数据类型

前言

与其它的编程语言一样,VBA也有它自己的数据类型。讲到数据类型,就离不开“变量”与“常量”这两个概念,变量与常量,都是用于保存数据的。顾名思义,“变量”是会变的,即它的值是可以改变的;而常量,则它的值通常是固定不变的。

为什么要定义数据类型:

  • 定义合适的数据类型可以节省内存空间,提高程序运行的效率;
  • 便于程序进行计算(数值型)和其它使用(非数值型);

变量和常量

a. 定义变量

basic
1
2
3
4
5
6
' 变量名可以是英文字母、数字、下划线的组合,但必须以字母开头
Dim 变量名 As 数据类型
' -------------------------------------------------
' 变量的赋值则直接使用一个等号进行
Dim i as Integer
i = 3

b. 定义常量

basic
1
2
3
4
Const 常量名 As 数据类型 = 常量值
' ----------------------------
' e.g. 如下定义一个整数常量
Const h As Integer = 18

一、数据类型

数据类型 存储空间
Boolean 2个字节
Byte 1个字节
Collection 未知
Currency 8个字节
Date 8个字节
Decimal 14个字节
Dictionary 未知
Double 8个字节
Integer 2个字节
Long 4个字节
LongLong 8个字节
LongPtr 32位系统:4个字节
64位系统:8个字节
Object 4字节
Single 4个字节
String(可变长度) 10字节+字符串长度
String(定长) 字符串长度
Variant(带数字) 16个字节
Variant(带字符) 22字节+字符串长度
用户定义(使用Type) 元素所需的数字

下面举例一些常用的数据类型:

1.1 字符型(字符串)

字符型:string 字符型是用于保存文本数据的,字符型内容应放置于双引号内 "" ;

字符串符号:$

basic
1
2
3
' 数据声明
Dim str1 as String
Dim str2$

1.2 数值型

1.2.1 整数

整数:integer【整数】、long【长整数】 currency【缩放整数】表示整数

整数符号:%

长整数符号:&

缩放整数符号:@

整数与长整数的区别在于两者所能表示的数值范围不同:

  • 整数数据能表示的数据范围:-32768 ~ 32767
  • 长整数数据能表示的数据范围:-2147483648 ~ 2147483647
  • 缩放整数数据能表示的数据范围:-922,337,203,685,477.5808 到 922,337,203,685,477.5807
basic
1
2
3
4
5
6
7
8
9
' 整数数据声明
Dim a as Interger
Dim b%
' 长整数数据声明
Dim c as Long
Dim d&
' 缩放整数声明
Dim e as Currency
Dim f@

补充:还有byte【字节】、longlong【整数的一种,只在64位平台上生效】


1.2.2浮点数

浮点型:single【单精度浮点型】、double【双精度浮点型】 表示小数

单精度符号:!

双精度符号:#

单精度浮点数与双精度浮点数除了在数值范围不同之外,两者所能表示的数据精度(即小数点后多少位)也是不同的;

  • 单精度浮点型能表示的数据范围:
    • 在表示负数时: -3.402823E38 ~ -1.401298E-45
    • 在表示正数时: 1.401298E-45 ~ 3.402823E38
  • 双精度浮点型能表示的数据范围:
    • 在表示负数时: -1.79769313486231E308 ~ -4.94065645841247E-324
    • 在表示正数时: 4.94065645841247E-324 ~ 1.79769313486231E308
basic
1
2
3
4
5
6
' 单精度数据声明
Dim a as Single
Dim b!
' 双精度数据声明
Dim c as Double
Dim d#

总结:它们可以表示非常大的数据,但要注意的时,单精度浮点型其精度是6,即只能保存小数点后最多6位的数据;双精度浮点型其精度是14,即只能保存小数点后最多14位的数据。如果超出以上长度,则超出部分会被去掉,并且会自动四舍五入


e.g.

basic
1
2
3
4
5
6
7
8
Sub test()
Dim i1 As Single
Dim i2 As Double
i1 = 3.141592672
i2 = 3.12517237237127
Debug.Print i1
Debug.Print i2
End Sub

输出:

运行可以看到作为单精度浮点数的i1在输出时变成了3.141593

TIPS:如果试图在给变量赋值时直接写到小数点后 15 位,VBE是会自动检测到并且直接进行四舍五入只保留14位的。上图i2我本想赋值为3.125172372371268,但写完最后的 8 之后,它自动消失了并且前面的 6 变成了 7 。

因为在数字的表示范围上长整数大于整数,而双精度浮点型大于单精度浮点型,理论上来说,如果把变量定义为表示范围更大的数据类型可以更好地避免掉数据溢出的问题。但在定义变量时,应当遵守的一个原则就是:够用就好。而不是越大越好。所以通常如果整数和单精度浮点型就足以表示数据的话,应当使用它们而不是长整数和双精度浮点型。


1.3. 时间型

日期型数据不仅可以表示日期,还可以表示时间。

可以表示的日期范围是:100年1月1日 ~ 9999年12月31日

可以表示的时间范围是:0:00:00 ~ 23.59.59

任何可识别文字数据值都可以分配给 Date 变量。 日期文字 必须包含在数字符号 # () ,例如 或 #January 1, 1993# #1 Jan 93#

Date 变量根据计算机识别的短日期格式显示日期。

时间显示基于计算机识别的时间格式(12 小时或 24 小时)。当其他数值类型转换为 Date 时,小数左侧的值表示日期信息,小数右边的值表示时间。 午夜用 0 表示,中午用 0.5 表示。

负整数表示 1899 年 12 月 30 日之前的日期。


1.3.1 返回当前日期时间

e.g.

basic
1
2
3
4
5
6
Sub test()
Debug.Print Date ' 查询当前年月日;
Debug.Print Time ' 查询当前时分秒;
Debug.Print Now ' 查询当前时间戳;
Debug.Print Timer ' 查询0点到当前时间的秒数,用来计算时间差;
End Sub

输出:


1.3.2 时间日期设定

e.g.

basic
1
2
3
4
Sub test()
Debug.Print DateSerial(2021, 12, 12) ' 年月日格式化
Debug.Print TimeSerial(15, 12, 12) ' 时分秒格式化
End Sub

输出:


1.3.3 格式化日期

e.g.

basic
1
2
3
4
5
6
7
Sub test()
Debug.Print Format(Now, "aaa")
Debug.Print Format(Now, "aaaa")
Debug.Print Format(Now, "ddd")
Debug.Print Format(Now, "dddd")
Debug.Print Format(Now, "yy-mm-dd")
End Sub

输出:


1.3.4 获取时间的部分

e.g.

basic
1
2
3
4
5
6
7
8
Sub test()
Debug.Print Year(Now) ' 获取日期的年份
Debug.Print Month(Now) ' 获取日期的月份
Debug.Print Day(Now) ' 获取日期所在日
Debug.Print Hour(Now) ' 获取日期的小时
Debug.Print Minute(Now) ' 获取日期的分钟
Debug.Print Second(Now) ' 获取日期的秒数
End Sub

输出:


1.3.5 日期间隔

e.g.

basic
1
2
3
4
5
6
7
8
9
10
11
Sub test()
Dim a, b As Date
a = #12/12/2020#
b = "2020-12-31"
Debug.Print "相隔" & (b - a) & "天"
Debug.Print "相隔" & DateDiff("d", a, b) & "天"
Debug.Print "相隔" & DateDiff("q", a, b) & "季"
Debug.Print "相隔" & DateDiff("w", a, b) & "周"
Debug.Print "相隔" & DateDiff("h", a, b) & "时"
Debug.Print "相隔" & DateDiff("n", a, b) & "分"
End Sub

输出:


1.3.6 日期加减

e.g.

basic
1
2
3
4
5
6
7
8
9
Sub test()
Dim a As Date
a = #12/12/2020#
Debug.Print "加一季:" & DateAdd("q", 1, a)
Debug.Print "加一月:" & DateAdd("m", 1, a)
Debug.Print "加一天:" & DateAdd("d", 1, a)
Debug.Print "加一时:" & DateAdd("h", 1, a)
Debug.Print "加120分:" & DateAdd("n", 120, a)
End Sub

输出:


1.4.布尔型

布尔类型:boolean 布尔型数据用于表示逻辑值:真、假;真为 true,假为 false;常用于条件判断

e.g.

basic
1
2
3
4
5
6
7
8
9
10
11
12
Sub test()
Dim a, b As Integer
Dim c, d As Boolean
a = 0
b = 12
c = True
d = False
Debug.Print CBool(a) & " " & CBool(b) ' 数值a,b转换为布尔型
Debug.Print CInt(c) & " " & CInt(d) ' 布尔c,d转换为数值型
End Sub

' 应当注意的是,当其它数据类型转换为布尔值时,0会转成False,其它值则变成True。当把布尔值转换成其他数据类型时(不包括字符型,转为字符型不变),False会转换为0,True则是-1。

输出:


1.5. 变体型

变体型:variant

  • 变体型数据是一种特殊的数据类型,几乎可以用于保存所有其它数据类型的数据。可以简单地理解为:当不知道变量所要表示的数据是什么类型时,就把它定义为Variant(但这种操作应当尽量避免)。
basic
1
2
3
4
5
6
7
Sub test()
Dim t As Variant
t = "hello"
Debug.Print t
t = 123.45
Debug.Print t
end Sub

1.6. 对象型

对象型:object 【在Excel中指的是:工作簿、工作表、单元格、图表和透视表等】

  • 对象型是VBA中另一种特殊的数据类型。有点类似于其它高级编程语言中的"对象",因为它们都有自己的属性与方法,但也仅限于在这两个方面上类似。

常见代码操作Excel中的对象:

basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
' 1.工作簿(Workbooks)
' Workbooks(N) 第N个工作簿
' Workbooks("工作簿名")
' ActiveWorkbook 活动工作簿
' ThisWorkBook 代码所在工作簿
' ---------------------------------
' 2.工作表(WorkSheets)
' Sheets(N) 第N个工作表
' Sheets("工作表名")
' SheetsN 第N个工作表
' ActiveSheet 活动工作表
' WorkSheets 与 Sheets的区别
' ----------------------------------
' 3.单元格(cells)
' Range("单元格地址")
' Cells(行号,列号)
' [A1] 单元格简写
' ActiveCell活动单元格
' Selection 当前被选取的区域

对象型详见 [Excel VBA学习——Excel对象操作](./Excel VBA学习——入门.md)


1.7. 枚举型

当一个变量只有几种可能的值时,可以定义为枚举类型。枚举就是将变量的值逐一列出,属于该枚举型的变量只能取列举的某一个值。

枚举型数据定义格式如下:

basic
1
2
3
4
5
6
7
8
Public | Private Enum 变量名
成员1 [= 常数表达式1]
成员2 [= 常数表达式2]
……
End Enum
' -----------------------------------------------------------------------------------
' Public和Private用于定义变量的作用域(即变量的有效范围);
' 用中括号[]括起来的部分是可以省略的,如果省略的话,则默认以0表示第一个成员,1表示第2个成员,以此类推;

e.g.

basic
1
2
3
4
5
6
7
8
9
Public Enum WorkDays
星期日
星期一
星期二
星期三
星期四
星期五
星期六
End Enum


二、数据类型转换

2.1 类型转换函数

2.1.1 CStr

CStr:可强制将一个表达式转换成字符串,返回代表一数值的字符串 Variant (String);


语法: CStr(expression)

如果 expression 为 CStr 返回:

  • Boolean 字符串,包含 True 或 False;
  • Date 字符串,包含系统的短日期格式日期;
  • Null 运行时错误;Empty 零长度字符串 (“”);
  • Error 字符串,包含跟随有错误号码的单词 ;
  • Error;其他数值字符串,包含此数字的字符串;

CStr() 和 Str() 的区别:

  • Str() 把数字转换成为字符号,前面会带有数值的符号,因此,会多出一个前导的空格;

e.g. : Len(Str(99999)),返回的结果为6,而Len(CStr(99999))返回的结果只为5。


2.1.2 CBool

CBool:转换为 Boolean(布尔类型)子类型的 Variant(变量);

语法: CBool(expression)

将其他 数值类型]转换为 布尔 值时,0 将变为 False,所有其他值均变为 True

布尔 值转换为其他 数据类型时,False 将变为 0,True 将变为 -1。


2.1.3 CByte

CByte:转换为 Byte(字节类型)子类型的 Variant;

语法:CByte(expression)

CByte 函数用于进行从其他数据类型到 Byte 子类型的的国际公认的格式转换。

如果 expression 在 Byte 子类型可接受的范围之外,则发生错误。


2.1.4 CInt

CInt:转换为 Integer 子类型的 Variant;

语法:CInt(expression)

CInt 函数用于进行从其他数据类型到 Integer 子类型的国际公认的格式转换。

如果 expression 在 Integer 子类型可接受的范围之外,则发生错误。


2.1.5 CLng

CLng:转换为 Long 子类型的 Variant;

语法:CLng(expression)

CLng 函数用于进行从其他数据类型到 Long子类型的国际公认的格式转换。

如果 expression 在 Long子类型可接受的范围之外,则发生错误。


2.1.6 CSng

CSng:转换为 Single 子类型的 Variant;

语法:CSng(expression)

CSng 函数用于进行从其他数据类型到 Single 子类型的国际公认的格式转换。

如果 expression 在 Single 子类型允许的范围之外,则发生错误。


2.1.7 CDbl

CDbl:换为 Double 子类型的 Variant;

语法:CDbl(expression)

CDbl 函数用于进行从其他数据类型到 Double 子类型的国际公认的格式转换。


2.1.8 CCur

CCur:转换为 Currency 子类型的 Variant;

语法:CCur(expression)

CCur 函数用于进行从其他数据类型到 Currency 子类型的国际公认的格式转换。


2.1.9 CDate

CDate:转换为 Date 子类型的 Variant;
语法:CDate(date) [date 参数是任意有效的日期表达式]

CDate 识别日期文字和时间文字,以及一些在可接受的日期范围内的数字。在将数字转换为日期时,数字的整数部分被转换为日期,分数部分被转换为从午夜开始计算的时间。

CDate 根据系统的区域设置识别日期格式。如果数据的格式不能被日期设置识别,则不能判断年、月、日的正确顺序。另外,如果长日期格式包含表示星期几的字符串,则不能被识别。


2.2 Format函数

Format:格式化数字和文本的,基本和excel里面的format是一样的作用;

e.g.

basic
1
2
3
4
5
6
7
8
9
Sub test()
Dim a As Integer
a = 123
Dim b
b = 12304
Debug.Print Format(a, "0000.00")
Debug.Print Format(a, "\价格\ 0000.00")
Debug.Print Format(b, "yyyy-mm-dd") ' 这里计算是从1900-01-01加上b的得到的日期
End Sub

参考资源:
Excel VBA入门(一)数据类型
Excel VBA 类型转换函数
Excel VBA(07)数据类型和转换
Microsoft Office VBA参考
-------------本文结束感谢您的阅读-------------