浅谈VBA中使⽤数组处理⼯作表数据
前⾔
在VBA中最经常涉及的就是读写⼯作表中的单元格,如果读写操作次数较多,或者涉及到的单元格数量较多,往往会导致程序运⾏效率较低。这时经常⽤到的解决⽅法就是使⽤数组保存数据,在内存中进⾏数据处理和加⼯,最后⼀次⾏更新⼯作表,这样的操作⽅式往往会极⼤提升程序的运⾏效率。
读取数据
声明变量
⾸先如何声明⽤于保存单元格内容的变量呢?虽然在VBA可以直接使⽤未声明的变量,但是声明变量⼀个良好的编程习惯。需要注意的是在加载单元格内容到数组的代码中,变量必须声明为Variant类型;如果将变量声明为数组,那么将产⽣类型不匹配的错误。
语法格式
变量 = ⼯作表区域.Value
数据区域
连续规则区域
最简单的情况是⼯作表中数据区域是⼀个连续区域,那么可以直接使⽤CurrentRegion属性。
aData = Activesheet.[A1].CurrentRegion.Value
⾮规则区域
很多时候,数据区域并不⼀定是完美的连续区域,此时就需要先确定最后数据⾏的位置,在VBA中有很多种定位最后数据单元格的⽅法,本⽂不再详细讨论。这⾥只使⽤其中的⼀种,即End属性。假设第⼀列为⾮空数据列,那么就要以此列做为判断的基准,最后数据单元格的⾏号保存在lstRow变量中。
假设数据区域有5列,那么可以⽤最常见的 Range("A1:E" & lstRow) 表⽰⽅法,其实更简单的⽅式是使⽤Resize。
With ActiveSheet
lstRow = .Cells(Rows.Count, 1).End(xlUp).Row
aData = .Range("A1:E" & lstRow).Value
aData = .[a1].Resize(lstRow, 5).Value
End With
数组维度
显⽽易见,多⾏多列的数据区域读⼊数组,将形成⼀个⼆维数组,例如:aDataRect为 8 x 5的⼆维数组。很容易想到,对于单⾏或者单列单元格区域,将产⽣⼀维数组。实际上VBA处理逻辑不是这样的,aDataCol是⼀个 5 x 1的⼆维数组,aDataRow是⼀个 1 x 5的⼆维数组。
简单总结⼀句话,多个单元格区域加载⾄数组时,产⽣的数组肯定是 ⼆维数组。
aDataRect = ActiveSheet.Range("A1:E8").Value
aDataCol = ActiveSheet.Range("A1:A5").Value
aDataRow = ActiveSheet.Range("A1:E1").Value
回写数据
确定结果数组的尺⼨
如果代码只是处理数组中数据,全部数据都需要回写到单元格中,那么只需要将加载数据到数组的代码⾏中等号左右的元素互换就可以了。ActiveSheet.Range("A1:E8").Value = aDataRect
很多情况下,结果数组需要写⼊不同的单元格位置,那么就需要⽤UBound函数来获取结果数组的维度上限。UBound(aRes, 1)获取数组的第⼀维的上限,也就是结果数据集的⾏数,与此类似,UBound(aRes, 2) 获取数据集的列数。
ActiveSheet.[K2].Resize(UBound(aRes, 1), UBound(aRes, 2)).Value = aRes
单⾏或者单列
只要确保接收数据的单元格与读取时是同样规格,并且单元格数量与数组元素数量相同,直接赋值就可以了。
ActiveSheet.Range("B11:B15").Value = aDataCol
ActiveSheet.Range("A6:E6").Value = aDataRow
⼀维数组写⼊单元格
虽然单⾏或者单列单元格区域读⼊数组时,产⽣的是⼀个⼆维数组,但是⼀维数组却是可以回写到单元格中的,貌似似乎有些不合乎逻辑。aMyData是包含5个元素的⼀维数组,可以理解为在⼀⾏中横向排列的5个元素aMyData(0), aMyData(1), ... aMyData(5)。这个数组是可以直接写⼊单⾏单元格区域A6:E6中的;如果想写⼊单列的单元格区域,就需要借助⼯作表函数Transpose完成⾏列转置。请注意。
aMyData = Array(6, 7, 8, 9, 0)
ActiveSheet.Range("A6:E6").Value = aMyData
ActiveSheet.Range("B11:B15").Value = Application.Transpose(aMyData)
看完之后,是不是觉得——使⽤数组处理单元格数据其实很简单!resize函数vba
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论