VBA实战技巧精粹015:关于Split函数的一些认识
在前面已经用过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 值。
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, 爱好者, 成就感, 程序设计, 关键字, 循环, 应用程序, 源程序, 源代码