VBA实战技巧精粹010:如何快速选定工作表及Option Base 1
问题背景:经常性的要对同一工作簿中的多个工作表同时进行格式设置等,那就需要首先先对其进行选定,建立工作表组,然后才能对进行操作.
问题提出:①如何快速选定同一工作簿中所有工作表?②如何选定部分工作表?
解决代码:
①如何快速选定同一工作簿中的所有工作表?
Sub 快速选定所有工作表()
Dim sht As Worksheet
For Each sht In Worksheets
sht.Select Replace:=False
Next sht
Sheets(1).Select ' 如何取消工作表
Sheets.Select
Sheets(1).Select
Worksheets.Select
Sheets(1).Select
End Sub
上面的代码提出了两种解决方法:一是利用For each循环语句,但要注意其中的sht.Select replace:=Fasle语句,表示延伸当前选定对象以包括任何以前选定的对象;若为True,则用指定对象代替当前选定的对象.二是直接利有工作表集合Worksheets的Select方法.同时还解决如何取消工作表群组,非常简单-选定其中任一个工作表即可.
②如何选定部分工作表?
需要用到Array函数,解释如下:
Array 函数
语法
Array(arglist)
所需的 arglist 参数是一个用逗号隔开的值表,这些值用于给 Variant 所包含的数组的各元素赋值。如果不提供参数,则创建一个长度为 0 的数组。
说明
用来表示数组元素的符号由变量名、圆括号以及括号中的所需元素的索引号组成。在下面的示例中,第一条语句创建一个 Variant 的变量 A
。第二条语句将一个数组赋给变量 A
。最后一条语句将该数组的第二个元素的值赋给另一个变量。
Dim A As Variant A = Array(10,20,30) B = A(2)
使用 Array 函数创建的数组的下界受 Option Base 语句指定的下界的决定, 除非 Array 是由类型库(例如 VBA.Array )名称限定。如果是由类型库名称限定,则 Array 不受 Option Base 的影响。
注意 没有作为数组声明的 Variant 也可以表示数组。除了长度固定的字符串以及用户定义类型之外,Variant 变量可以表示任何类型的数组。尽管一个包含数组的 Variant 和一个元素为 Variant 类型的数组在概念上有所不同,但对数组元素的访问方式是相同的。
Sub 测试用()
Dim A As Variant, B As String
A = Array(10, 20, 30)
B = A(2)
Debug.Print B '输出30
Worksheets(Array("sheet1", "sheet2")).Select
End Sub
但用Array函数未成功,因为我想通过循环将获得的需群组工作表名称添加到Array函数的参数列表中,但未成功,但现在已经明白一点:Array返回数组.
重新编写的代码如下:
'群组后 , 选定的工作就成为活动工作表了
Sub 选定部分工作表()
Dim ShtCount As Integer, i As Integer, ShtName() As String, sht As Worksheet
ShtCount = Worksheets.Count
ReDim ShtName(1 To ShtCount)
Sheets(1).Select
For i = 1 To ShtCount Step 2
ShtName(i) = Sheets(i).Name
Set sht = Worksheets(ShtName(i))
sht.Select Replace:=False
Next i
End Sub
感觉上面的代码有点麻烦,改进如下:
Sub 选定部分工作表改进()
Dim ShtCount As Integer, i As Integer
ShtCount = Worksheets.Count
Sheets(1).Select
For i = 1 To ShtCount Step 2
Worksheets(Sheets(i).Name).Select Replace:=False
Next i
End Sub
总想利用数组来一次性全选,改进代码如下:
Sub 选定部分工作表改进2()
Dim ShtCount As Integer, i As Integer, ShtName() As String, arr() As String
ShtCount = Worksheets.Count
ReDim ShtName(1 To ShtCount)
For i = 1 To ShtCount Step 2
ShtName(i) = Sheets(i).Name
Next i
ReDim arr(Int((ShtCount - 1) / 2 + 1))
For i = 1 To Int((ShtCount - 1) / 2 + 1)
arr(i) = Sheets(1 + (i - 1) * 2).Name
Next i
Worksheets(arr).Select
End Sub
'进一步的改进如下:
Sub 选定部分工作表改进3()
Dim ShtCount As Integer, i As Integer, arr() As String
ShtCount = Worksheets.Count
ReDim arr(Int((ShtCount - 1) / 2 + 1)) '计算需要循环几次,即为arr数组需要重定义的元素数.
For k = 1 To Int((ShtCount - 1) / 2 + 1)
arr(k) = Sheets(1 + (k - 1) * 2).Name '需要算出每次循环对应的工作表索引号.(默认从1开始)
Next k
Worksheets(arr).Select
End Sub
这里就要用到数学上的数列知识了:
有一循环语句:for i=m to n step j,现需要计算一共循环了几次:(m代表工作表开始的索引号,n代表结束的索引号)
用k表示循环次数,那么n=m+(k-1)*j,解得:k=(n-m)/j+1,但出来的结果一般情况会有小数部分,则实际k值为取整.即为:
k=int((n-m)/j+1)
那么上面的循环就可以用循环次数来进行代替:for k=1 to int((n-m)/j+1)
可是如何确定每次循环对应的工作表索引号?
m+(k-1)*j就是这k次循环所对应的工作表索引号.
进一步的改进代码如下:
'进一步的改进如下:
Sub 选定部分工作表改进4()
Dim ShtCount As Integer, k As Integer, arr() As String
ShtCount = Worksheets.Count
ReDim arr(Int((ShtCount - 1) / 2 + 1))
For k = 1 To Int((ShtCount - 1) / 2 + 1)
arr(k) = Sheets(1 + (k - 1) * 2).Name
Next k
Worksheets(arr).Select
ActiveCell.ClearContents
ActiveCell.Value = "qufuyizhong"
Cells.Columns.AutoFit
End Sub
③关于Option Base 1
option base:在模块级别中使用,用来声明数组下标的缺省下界
所以需要将此语句放在模块内开始部分,不能放在中间.验证如下.
源代码:
Option Base 0
Sub 测试用()
Dim A As Variant, B As String
A = Array(10, 20, 30)
B = A(2)
Debug.Print "数组A的第2个元素值为:" & A(2) '输出30
ReDim A(5)
Debug.Print LBound(A)
Debug.Print UBound(A)
End Sub
输出:
数组A的第2个元素值为:30
0
5
Option Base 1
Sub 测试用()
Dim A As Variant, B As String
A = Array(10, 20, 30)
B = A(2)
Debug.Print "数组A的第2个元素值为:" & A(2) '输出30
ReDim A(5)
Debug.Print LBound(A)
Debug.Print UBound(A)
End Sub
输出:
数组A的第2个元素值为:20
1
5
两段代码的UBound(A)的值均为5!!这是怎么回事?借用帮助中一句话解释:如果不显式指定 lower,则数组的下界由 Option Base 语句控制。如果没有 Option Base 语句则下界为 0。也就是说如果如果Option Base 1则从1开始到5,而如果Option Base 0则从0开始到5,这样第1种情况元素有5个,而第2咱情况元素有6个.
那谁不会受Option Base 1的限制呢?由字典创建的数组不会受它的限制,仍然是从0开始,这点一定要注意.
BuzzNet: Excel, Excel VBA, 循环
del.icio.us: Excel, Excel VBA, 循环
Flickr: Excel, Excel VBA, 循环
IceRocket: Excel, Excel VBA, 循环
LiveJournal: Excel, Excel VBA, 循环
Technorati: Excel, Excel VBA, 循环