Excel-VBA提高(1): 数组/日期处理

(一)定义数组 

dim arr(1 to 100) as byte : 定义一个byte 类型的数组,名字为arr, 可以存放100个数据

引用 arr(10)    ,, 赋值 arr(5)=10

dim arr(99) as byte  : 初始索引是0 ,这也是长度100的数组

VBA默认初始索引是0 ,option base 1 可以更换为1, 此时dim arr(99) as byte  变为长度99了

声明多维数组: 

dim  arr(1 to 3, 1 to 5) as integer  : 3*5的数组 类型是integer

等价于dim  arr(2,4) as integer    由于默认初始索引是0 

声明动态数组

有时候不确定数组的长度, 想把某一列的数据存到数组中, 求A列的数据个数

Option Explicit
Sub test()
    Dim a As Integer
    a = Application.WorksheetFunction.CountA(Range("A:A"))
    Dim arr(1 To a) As Integer ' 错误,不能用变量来定义数组的长度
End Sub

事先定义数组 留一个空括号 , 之后再改变其长度即可

Sub test()
    Dim a As Integer
    a = Application.WorksheetFunction.CountA(Range("A:A"))
    Dim arr() As Integer ' 空括号
    ReDim arr(1 To a) '重新定义数组的大小, 但是redim 不能改变数据类型
    MsgBox a
End Sub

下面介绍另一种更简单的创建数组的方法:   

1.利用array 函数

使用array创建数组时, 应声明为一个variant类型的变量 

2. 利用split函数创建数组

使用split创建数组时, 应声明为一个variant类型的变量 

split 第一个参数是包含分隔符的字符串, 第二个参数是 分隔符

3. 直接用单元格区域创建数组

Sub test()
    Dim arr As Variant
    arr = Range("A1:C3").Value '
    Range("E1:G3") = arr '
End Sub

 得到: 

由此可见 , 数组可以存放不同类型的数据

注意:  从单元格中 取数据存到数组中, 索引都是从1开始的!! 

 引用需要用到数对(m,n)   ,arr(1,3)=奖金

4.有关数组的一些运算

(1) ubound 得到数组的最大索引号

Sub test()
    Dim arr As Variant
    arr = Array(1, 2, 3, 4, 5)
    MsgBox "数组的最大索引号是:" & UBound(arr)
End Sub

得到 最大索引是4 

类似的, lbound(arr)=0  最小索引

至于多维数组, 

Sub test()
    Dim arr(1 To 10, 1 To 15) As Integer
    Dim a, b
    a = UBound(arr, 1)
    b = UBound(arr, 2)
    
    MsgBox "第一维数组的最大索引号是:" & a & Chr(13) & _
        " 第二维数组的最大索引号是:" & b
    
End Sub

上述 chr(13)表示换行 , & _ 表示下一行的连接

第一维度表示几行, 第二维度表示几列

ubound(arr)-lbound(arr)+1 表示数组的元素个数

对于二维数组arr, 则有

a1=lbound(arr,1); a2=ubound(arr,1); 

b1=lbound(arr,2); b2=ubound(arr,2);

元素个数为(a2-a1+1)*(b2-b1+1)

(2) join 将一维数组变成字符串

Sub test()
    Dim arr As Variant
    Dim s As String
    arr = Array(1, 2, 3, 4)
    s = Join(arr, "*")
    MsgBox s
End Sub

得到1*2*3*4

(3) 将数组中的数据写入到单元格中, 

Sub test()
    Dim arr As Variant
    arr = Array(1, 2, 3, 4, 5)
    Range("A1:A5") = Application.WorksheetFunction.Transpose(arr)
    
End Sub

transpose 表示转置

(二)日期处理

现在想统计名人的生日月份, 已知每个人的出生年月日,1894年3月2日, 要提取 3

excel 有自带的函数month(1693/06/27) , 但是出错了!!

这是因为excel 表示的日期是1900年1月1日之后的, 之前的日期没法做计算!

VBA中最小日期是公元100年1月1日0:0:0,  最大的日期是9999年12月31日23:59:59

 如果还是超出了这个范围怎么办? 那只能用字符串定位的方式了

Sub a()
    Dim s As String
    Dim y As Long, m As Integer, d As Integer
    s = "10000年12月30日"
    y = Left(s, InStr(s, "") - 1)
    m = Mid(s, InStr(s, "") + 1, InStr(s, "") - InStr(s, "") - 1)
    m = Mid(s, InStr(s, "") + 1, InStr(s, "") - InStr(s, "") - 1)
End Sub

但是一般情况下VBA给的时间范围是可以!

Sub demo()
    Dim d As Date ' 定义d 是一个日期型变量
    d = #1/19/2016 12:20:25 PM#  ' 精度是秒 连个#表示里面是日期时间 月 日 年
    MsgBox d
End Sub

1. 获取系统时间 date函数获取当下日期

time 函数获取当下时间

now 函数则返回现在的日期与时间

 实例: 如何知道今天过生日的同事? 已知每个人的出生年月日, 与date 函数返回值进行比较, 当然不能直接比, 要剔除年份.

 2. 时间数据解析函数

Sub demo()
    Dim d As Date, a As Long ' 定义d 是一个日期型变量
    d = #1/19/2016 12:20:25 PM#
    a = Year(d)
    MsgBox a
End Sub

3. 时间运算函数 ,两个时间的间隔

datediff(单位,begin, end)

 

 例子: 

 

 若定义 输出a 是long 就不一样了!!

 时间也可以往前

补充: 

VBA内部日期就是一个double 类型的数字

0 表示 1899年12月30日0:0:0

整数加减1 就是1天, 小数0.1 表示0.1天, 2.4小时表示2小时24分钟, 但是小数部分加减比较复杂, 不要轻易使用

上述也可以往前数 d1=d1-10

猜你喜欢

转载自www.cnblogs.com/xuying-fall/p/9301556.html