快速浏览
往期合集:【2023年3月】【2023年4月】【2023年5月】【2023年6月】【2023年7月】【2023年8月】
实际案例
电子发票登记系统(版)|
收费项目
|财务管理体系||工资及年终奖金个人税务筹划|
执行摘要
大家好,我正在用冷水泡茶。 今天我们来学习一下【数组】。 它在内存中运行,比在细胞中运行要快得多。
数组,英文名称为Array。 数组也是VBA的一个函数。
数组可以简单理解为“一组数字”,如(1,2,3,4,5)。 当然,在表达上也是有规定的格式的。 下面让我们逐一了解一下。
1.数组的定义
在使用数组之前,我们首先需要定义一个数组。 定义数组有两种方法:
Dim arr1(5)
Dim arr2()
第一种类型在定义数组时指定数组的元素数量。 arr1(5) 表示具有 6 个元素的一维数组。 这个数组称为静态数组。 其尺寸和元素数量是固定的,无法更改。
第二种类型在定义时不指定数组的维数和元素个数,后面使用时再重新定义。 这种数组称为动态数组。 并且,在下面的讨论中,除非另有说明,否则我们讨论的是动态数组。
当我们定义动态数组时,通常会加括号来表明它是一个数组。如果不加括号,那么定义时它就是一个变体变量。 如果以后给它赋值一个数组,它也可以变成一个数组。
顺便说一句,变体变量类型()表示未指定变量类型。 任何类型都可以,但请避免这样做。 有时它可能会使代码难以理解。 太多这样的变量会影响程序。 效率。
2. 数组的维数和下标
数组的维数可以理解为有几组下标,也就是多维数组。
数组的下标是数组元素的位置。 我们通过指定下标来引用和操作数组的元素。
如果不做特殊处理,数组的下标一般从0开始,arr1(5)包含6个元素。 如果不习惯,可以在模块上方添加一条语句:Base 1,强制下标从1开始,这样arr1(5)包含5个元素。
当我们将整个工作表单元格范围分配给数组时,下标从1开始。
获取数组的下标:
1、(arr,1),获取数组的最小行索引,这里1可以省略,直接写成(arr)
2、(arr,2),获取二维数组的最小列索引。 通常情况下,最小列索引和最小行索引是相等的,即arr(0,0)表示数组的第一个元素。 但是,它们不必相等。
3、(arr,1),获取数组的最大行索引,这里1可以省略,直接写成(arr)
4、(arr,2),获取二维数组的最大列索引。
3. 数组的赋值
1、通过指定下标给数组赋值:
Dim arr1(5)
For i = 0 To 5
arr1(i) = i
Next
或者
arr1(0)=0
arr1(1)=1
arr1(2)=2
arr1(3)=3
......
2.将工作表的整个数据区域赋值给数组
Dim ws As Worksheet
Dim arr()
Set ws = Sheets("Sheet1")
arr = ws.UsedRange
或者
Dim ws As Worksheet
Dim arr()
Set ws = Sheets("Sheet1")
arr = ws.Range("A1").CurrentRegion
或者
Dim ws As Worksheet
Dim arr()
Set ws = Sheets("Sheet1")
arr = ws.Range("A1:O15").value
或者
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
Dim arr()
Set ws = Sheets("Sheet1")
With ws
lastRow = ws.UsedRange.Rows.Count
lastCol = ws.UsedRange.Columns.Count
arr = ws.Range(.Cells(1, 1), .Cells(lastRow, lastCol))
End With
还有其他方法可以将工作表分配给数组,但我们不会一一列出。
最后一种我最常使用的方法,虽然有点麻烦,但是操作起来比较灵活。 例如可以使用变量,可以根据需要调整起始行和列。 它不一定必须从数组的第一行或第一列开始。
3.给数组赋值
Dim arr()
arr = Array(1, 2, 3, 4, 5, 6)
arr = Array("A", "B", "C")
arr = Array(Array(1, 2, 3), Array("A", "B", "C"))
或者
Dim ws As Worksheet
Dim lastRow As Long, lastCol As Long
Dim arr(), arr1()
Set ws = Sheets("Sheet1")
With ws
lastRow = ws.UsedRange.Rows.Count
lastCol = ws.UsedRange.Columns.Count
arr = ws.Range(.Cells(1, 1), .Cells(lastRow, lastCol))
End With
arr1 = arr
4、将数据库查询的记录集赋值给数组
Dim rs As Object
Dim cnn As Object
Dim arr()
Set cnn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
......
Set rs = cnn.Execute(Sql)
arr = rs.getrows
5、将字典的Keys和Items赋值给数组
arr = dic.keys
arr = dic.items
6.通过循环给数组赋值
(1)循环单元格并给数组赋值
Dim ws As Worksheet
Dim arr()
Set ws = Sheets("Sheet1")
ReDim arr(1 To 15, 1 To 15)
For i = 1 To 15
For j = 1 To 15
arr(i, j) = ws.Cells(i, j)
Next
Next
(2) 循环遍历数组并给数组赋值
'相当于把arr1转置
For i = 1 To 10
For j = 1 To 15
arr(i, j) = arr1(j,i)
Next
Next
7.数组动态扩展赋值
当我们想要将一些符合条件的数据写入数组时,我们没有办法确切知道数组中有多少个元素。 我们可以定义一个非常大的数组,比如ReDim arr(1 to 10000),这样我们就可以从容的写入数据了。 ,这样就不会出现“下标越界”的错误。
不过我并不提倡这种做法。有一种方法叫动态扩容,在改变数组大小的同时保留现有的数据:redim arr(...),也就是【物料管理:根据数量的多少】发出的物料和退回的数量,查找未退回的数量/未退回的数量单元格范围自动更新中使用的示例代码]
For Each Key In dic.keys
If dic(Key) <> 0 Then
ReDim Preserve arr(0 To 1, 0 To k)
arr(0, k) = Key
arr(1, k) = dic(Key)
k = k + 1
End If
Next
但要注意的是,数组的扩展只能扩展列,不能扩展行。 如果我们必须扩展行,我们可以进行转置,扩展列,然后在数据处理完成后转置回来。 就像上面的代码一样,在数组中,数据是这样的,沿着箭头的方向展开。 最后我们将其保存到工作表中,这就是转置后的数据:
4.将数组数据写入工作表
Set rng = ws.Range("I3").Resize(UBound(arr, 2) + 1, 2)
rng = Application.WorksheetFunction.Transpose(arr)
数据在数组中处理完后,大部分会写回到工作表中。 我们需要指定一个与数组大小相同的区域。 如果数据区域指定不准确,要么数据会丢失,要么工作表中会出现错误的值。
这里使用工作表函数来转置数组。 这里需要注意的是,该函数转置的数组中不能使用Null值,否则会报错。 这种情况通常发生在从数据库中检索数据并存储在数组中时,并且可能存在 Null 值。
如果我们使用错误报告该怎么办? 如果数据不多,我们可以直接循环数组,将数组每个元素的值直接写入到单元格中。 只需将 Cells 的行和列标签与数组 arr 的行和列交换即可。 当然,我们必须添加一个与实际单元格相对应的数字。
如果数据很多,我们可以重新定义一个数组,与原数组交换行和列,通过循环将数据写入新数组。
For i = 1 To 10
For j = 1 To 15
arr(i, j) = arr1(j,i)
Next
Next
然后将新数组直接写入工作表而不进行转置。
5、数组在用户窗体控件中的应用,在时间关系上不再展开。 之前的文章中也提到过。
1、将数组赋值给复合框的List
2. 将数组分配给
3. 将数组分配给
4. 将数组分配给
其实基本原理还是一样的,就是圆形阵列。
好的,今天就这样。
~~~~~~结束~~~~~~