实例10 先字典求得行后显示整行数据
9、[e2].Resize(d.Count, 1) = Application.Transpose(d.items) :把字典所有的项转置以后赋给E2单元格开始的区域。
10、For Each rng In [e2].Resize(d.Count, 1) :For- Each-Next控制结构是VBA中功能最强的循环控制结构,利用这个结构可对集合中的所有对象或者数组中的所有元素进行同一操作。它的一个优点在于你不必操心循环应该执行多少次,它循环的次数恰好就是数组中元素的个数(或者集合中对象的个数),因此对于处理多维数组特别是处理对象时最有效率。本句意思是在E2单元格开始的单元格区域中逐一循环。
11、rng.Resize(1, 3) = Cells(rng, 1).Resize(1, 3).Value :把关键字所在行的3个单元格的值赋给rng开始的3个单元格。在Cells(rng, 1)中作为参数的rng=rng.Valur,而rng.Resize(1, 3)处的rng是一个单元格对象。
代码执行后如图实例10-2所示。
图 实例10-2示例
41
常见字典用法集锦及代码详解
实例11 关键字赋给两列后用Replace方法
一、问题的提出:
有如图实例11-1所示的工资表,要求编写一段代码,运用VBA自动生成1季度的工资表。
解题思路:先把性别和姓名连起来作为关键字求得人员的不重复值,然后通过循环查找关键字获得其各月的工资,最后用Replace方法替换两列关键字区域得到各自的数据。
代码执行前如图实例11-1所示。
图 实例11-1示例
42
实例11 关键字赋给两列后用Replace方法
二、代码: Sub yy()
Dim d, k, t, i&, j&, Arr, x, r1
Set d = CreateObject(\Arr = [a1].CurrentRegion
For i = 1 To UBound(Arr, 2) Step 3 For j = 2 To UBound(Arr) If Arr(j, i) <> \Then
x = Arr(j, i) & \& Arr(j, i + 1) d(x) = \ End If Next Next k = d.keys
[a12:i1000].ClearContents
[a13].Resize(d.Count, 2) = Application.Transpose(k) [a12:b12] = Array(\性别\\姓名\For i = 3 To UBound(Arr, 2) Step 3 Cells(12, 2 + i / 3) = Cells(1, i) Next
For i = 3 To UBound(Arr, 2) Step 3 For j = 2 To UBound(Arr) If Arr(j, i) <> \Then
x = Arr(j, i - 2) & \& Arr(j, i - 1) Set r1 = [a13].Resize(d.Count, 1).Find(x, , , 1) Cells(r1.Row, 2 + i / 3) = Arr(j, i) End If Next Next
[a13].Resize(d.Count, 1).Replace \\xlPart [b13].Resize(d.Count, 1).Replace \\xlPart End Sub
43
常见字典用法集锦及代码详解
三、代码详解
1、Arr = [a1].CurrentRegion :把含有A1单元格的当前单元格区域的值赋给变量Arr。CurrentRegion是Range对象的属性,当前区域指以任意空白行及空白列的组合为边界的区域。如本题A11单元格有数据,但是因为第10行是空白行,所以没有包含在A1的当前区域里面。
2、For i = 1 To UBound(Arr, 2) Step 3 :For-Next控制结构,从1 到数组第2维的最大上界每隔3进行一次循环,Step 3是循环的步长,第一次循环时i=1;第2次循环时i=1+3=4,第3次时i=4+3=7。
3、For j = 2 To UBound(Arr) :从第2行开始循环。没有Step时默认Step为1。 4、If Arr(j, i) <> \ :If-Then-Else控制结构可根据测试条件的结果改变程序执行的流程。本句测试条件是Arr(j, i) <> \,判断性别是否为空白,如果不为空白则执行下面的语句,否则,执行Else下面的语句。
5、x = Arr(j, i) & \:把性别和姓名中间加“|”连起来赋给变量x。 6、d(x) = \ :把x的值作为关键字加入字典d。比如把”男|赵” 加入字典d。这两个循环把每个月的所有的人员都加入了字典d,字典中的人员是没有重复的。 7、k = d.keys :把字典d所有的关键字赋给变量k。
8、[a12:i1000].ClearContents :清空A12:I1000单元格区域。
9、[a13].Resize(d.Count, 2) = Application.Transpose(k) :把变量k转置之后赋给A13开始的单元格区域。Resize是Range对象的属性,调整指定区域的大小,其第1个参数是行的大小,d.Count表示字典关键字的数量,如果有10个关键字,那么就是10行;其第2个参数是列的大小,一般是赋给1列的,本例关键字由两个数据合并而成,所以先赋给2列,后面再处理。
10、[a12:b12] = Array(\性别\\姓名\ :Array是一个VBA函数,返回一个下界为0的一维数组。一维数组可以看作是水平排列的,这里作为表头一次性输入。 11、For i = 3 To UBound(Arr, 2) Step 3 :从第3列开始循环,步长为3。 12、Cells(12, 2 + i / 3) = Cells(1, i) :把“1月工资“、“2月工资“等输入到相应表头的位置。
13、Set r1 = [a13].Resize(d.Count, 1).Find(x, , , 1) :在A13单元格开始的区域中查找字符串变量x,Find方法是Range对象的一个方法,其中第4个参数值为1,其常量为xlWhole,表示精确查找,另一个常量为xlPart,它的值=2。Find方法返回的是Range对象,所以前面要用Set语句来引用对象。
14、Cells(r1.Row, 2 + i / 3) = Arr(j, i) :把关键字对应的工资赋给相应的单元格里。 15、[a13].Resize(d.Count, 1).Replace \\xlPart :Replace方法是Range对象的一个方法,其第1个参数是要查找的字符串,这里\是竖线及后面所有的字符串;其第2个参数是替换字符串,这里替换为空;其第3个参数是精确查找还是模糊查找,xlPart常量的值=2,可以用2代替它。本句是把姓名替换掉,只留下性别;下一句把B列中的性别替换掉,只留下姓名。 代码执行后如图实例11-2所示。
44