在前面已经用过Split函数了,可以方便的获取指定单元格的行标或列标,具体的用法可以参见以下代码:
Sub 获取指定列的字母()
Debug.Print Cells(1, 27).Address
Debug.Print Split(Cells(1, 27).Address, "$")(1)
End Sub
下面是关于Split函数的一些认识,肯定不全,但也得记下来,不然以后怎么再复习呢。切记:好记性不如烂笔头,更不如臭博客。
先抄一段官方解释:
描述
返回一个下标从零开始的一维数组,它包含指定数目的子字符串。
语法
Split(
expression
[
,
delimiter
[
,
limit
[
,
compare
]]]
)
Split
函数语法有如下命名参数:
部分
|
描述
|
expression
|
必需的。包含子字符串和分隔符的字符串表达式 。如果
expression
是一个长度为零的字符串(""),
Split
则返回一个空数组,即没有元素和数据的数组。
|
delimiter
|
可选的。用于标识子字符串边界的字符串字符。如果忽略,则使用空格字符(" ")作为分隔符。如果
delimiter
是一个长度为零的字符串,则返回的数组仅包含一个元素,即完整的
expression
字符串。
|
limit
|
可选的。要返回的子字符串数,–1表示返回所有的子字符串。
|
compare
|
可选的。数字值,表示判别子字符串时使用的比较方式。关于其值,请参阅“设置值”部分。
|
设置值
compare
参数的设置值如下:
常数
|
值
|
描述
|
vbUseCompareOption
|
–1
|
用
Option Compare
语句中的设置值执行比较。
|
vbBinaryCompare
|
0
|
执行二进制比较。
|
vbTextCompare
|
1
|
执行文字比较。
|
vbDatabaseCompare
|
2
|
仅用于Microsoft Access。基于您的数据库的信息执行比较。
|
连段示例代码都没有,看来对这个函数应该是比较好掌握,也是,语法比较简单,但问题的焦点不在这儿,而是它最终返回的数值问题:①到底是不是从0开始?②受不受Option Base 1的约束?③到底如何理解数组的上标和下标,是表示数组长度吗?
关于①与②的问题其实是一个问题:如果受Opiton Base 1的约束,那就从1开始,如果不受,那就从0开始了。帮助里说的很清楚了,返回一个下标从0开始的一维数组(顺便解决一个,水平方向的一维数组!!),言外之意就是不受Option Base 1的约束。
关于③:利用Lbound函数及Ubound函数可以分别得到指定数组的下标及上标,但要注意,这仅是说明了该数组的第1个元素及最后1个元素所对应的索引号,而上标并不一定是该数组的长度,如果数组从0开始计数,例如Split函数返回的数组,那上标只是最后1个元素对应的索引号,并不是数组的长度了。那不管是下标是不是从0开始,应该如何计算数组的长度呢?或者说有没有一个通用的方法来计算数组的长度?当然有啊,就是Ubound(arr)-Lbound(arr)+1,这就是标准的计算数组长度的公式,而不用考虑下标是否从0开始了。
下面是关于以上方法的一个验证:
Sub split函数赋值给单元格()
Dim i As Integer, s As String
For i = 1 To 2
Cells(i, 1).Value = Split(Cells(i, 1).Address, "$")(1)
s = s & Cells(i, 1).Address
Next i
Debug.Print UBound(Split(s, "$")) - LBound(Split(s, "$")) + 1
Range("C1").Resize(UBound(Split(s, "$")) + 1, 1).Value = Application.WorksheetFunction.Transpose(Split(s, "$"))
For i = 0 To UBound(Split(s, "$"))
Cells(i + 1, 4).Value = Split(s, "$")(i)
Next i
End Sub
需要注意一点,在模块开始部分务必加上Option Base 1
在上一句的基础上,再验证以下代码:
Sub 验证()
Dim arr() As Variant
arr = Array("11", "22", "3")
Debug.Print UBound(arr)
Debug.Print arr(0)
End Sub
运行后会提示:下标超界,什么原因呢?原来是由于你在模块开始部分加上了Option Base 1了,导致array函数返回的数组下标(索引号)变成从1开始,你非要输出arr(0)当然要错了,那如果不加Opiton Base 1呢?再输出arr(0)当然没问题了。
从以下两段代码现在可以看出:Split函数生成的数组不受Option Base 1的约束,而Array函数生成的数组受Option Base 1的约束,那么到底哪些返回的结果是数组,哪些不是,在返回数组的基础上,又有哪些受Option Base 1的约束,哪些又不受呢?
慢慢总结吧。
再补充:
Sub split函数赋值给单元格()
Dim i As Integer, s As String, y As Variant
For i = 1 To 2
Cells(i, 1).Value = Split(Cells(i, 1).Address, "$")(1)
s = s & Cells(i, 1).Address
Next i
s = "$A$1$A$2"
Debug.Print UBound(Split(s, "$")) - LBound(SplitVariant(s, "$")) + 1
Range("C1").Resize(UBound(Split(s, "$")) + 1, 1).Value = Application.WorksheetFunction.Transpose(Split(s, "$"))
For Each y In Split(s, "$")
Debug.Print y
Next y
End Sub
注意到红体字了吗?这是利用遍历的一样可以输出每个元素,但要注意是所有元素,包括前为空的那个,而实际上我需要的是后4个,所以方法可以借鉴,但不如利用for循环来的更精确。
关于Variant的解释:(来自官方解释,抄袭,严重的抄袭!)
Variant
数据类型是所有没被显式声明(用如
Dim
、
Private、Public
或
Static
等语句)为其他类型变量的数据类型。
Variant
数据类型并没有类型声明字符。
Variant
是一种特殊的数据类型,除了定长 String 数据及用户定义类型外,可以包含任何种类的数据。
Variant
也可以包含 Empty、
Error
、
Nothing
及 Null等特殊值。可以用
VarType
函数或
TypeName
函数来决定如何处理
Variant
中的数据。
数值数据可以是任何整型或实型数,负数时范围从
-1.797693134862315E308 到 -4.94066E-324,正数时则从 4.94066E-324 到 1.797693134862315E308。通常,数值
Variant
数据保持为其
Variant
中原来的数据类型。例如,如果把一个 Integer赋值给
Variant
,则接下来的运算会把此
Variant
当成
Integer
来处理。然而,如果算术运数针对含 Byte、
Integer
、Long 或 Single 之一的
Variant
执行,并当结果超过原来数据类型的正常范围时,则在
Variant
中的结果会提升到较大的数据类型。如
Byte
则提升到
Integer
,
Integer
则提升到
Long
,而
Long
和
Single
则提升为 Double。当
Variant
变量中有 Currency、Decimal 及
Double
值超过它们各自的范围时,会发生错误。
可以用
Variant
数据类型来替换任何数据类型,这样会更有适应性。如果
Variant
变量的内容是数字,它可以用字符串来表示数字或是用它实际的值来表示,这将由上下文来决定,例如:
Dim MyVar As Variant MyVar = 98052
在前面的例子中,
MyVar
内有一实际值为
98052
的数值。像期望的那样,算术运算子可以对
Variant
变量运算,其中包含数值或能被解释为数值的字符串数据。如果用
+
运算子来将
MyVar
与其他含有数字的
Variant
或数值类型的变量相加,结果便是一算术和。
Empty 值用来标记尚未初始化(给定初始值)的
Variant
变量。内含
Empty
的
Variant
在数值的上下文中表示 0,如果是用在字符串的上下文中则表示零长度的字符串 ("")。
不应将
Empty
与 Null 弄混。
Null
是表示
Variant
变量确实含有一个无效数据。
在
Variant
中,
Error
是用来指示在过程中出现错误时的特殊值。然而,不像对其他种类的错误那样,程序并不产生普通的应用程序级的错误处理。这可以让程序员,或应用程序本身,根据此错误值采取另外的行动。可以用
CVErr
函数将实数转换为错误值来产生
Error
值。
43 Things:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
BuzzNet:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
del.icio.us:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
Flickr:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
IceRocket:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
LiveJournal:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
Technorati:
Excel VBA
,
Range
,
VBA
,
爱好者
,
成就感
,
程序设计
,
关键字
,
循环
,
应用程序
,
源程序
,
源代码
这就是
菊子曰
啦!