早期的计算机主要面向科学计算,因此文字处理能力比较弱。随着计算机应用的逐步深入,对文字处理的要求越来越高。可以说,现代计算机所处理的数据中,文字类型的数据应该说占到了半壁江山甚至更多。文字类型的数据相比数值类型的数据,有一个非常大的麻烦。数值类型的数据,全世界都统一用10、2、8、16等进制来表示。任何一个十进制数,譬如 42,放到任何国家,都是 42。所以,对数值数据的表示,全世界都是统一的,除极个别的场合,所有十进制的数值数据都是用 0 - 9 这 10 个符号表示的。文字类型的数据则不同,英文有英文的表示,中文有中文的表示,阿拉伯文有阿拉伯文的表示,等等。文字处理遇到的第一个困难就是如何在机器中表示各种文字,即文字的编码。关于这个问题,请参看文末相关阅读的《谈谈 Encoding》,此处不赘。Hex(number) / Hex$(number)其中,number 是一个数值表达式或字符串表达式,表达式的求值结果必须是一个 Long 型(32位)整数,浮点数将四舍五入为最接近的整数。函数返回将 number 转换为十六进制的结果。Hex 返回 Variant(String) 类型,Hex$ 返回 String 类型。如果 number 求值结果为 Null,则 Hex 返回 Null。如果求值结果为 Empty,则 Hex 返回 0。Debug.Print Hex(5) ' 5Debug.Print Hex(15) ' FDebug.Print Hex(123) ' 7BDebug.Print Hex(Null) ' NullDebug.Print Hex(Empty) ' 0
Debug.Print &H0F ' 15Debug.Print &H7B ' 123Debug.Print &H80 ' 128
Asc(strexpr) / AscW(strexpr)其中,strexpr 为任何合法的字符串表达式,Asc 返回该表示中第一个字符的 ANSI 编码,AscW 返回该表示中第一个字符的 Unicode 编码。因为大写字母 Z 的 ANSI(ASCII)编码是十六进制的 5A,所以 Asc(s) 输出的结果就是 5A。又因为 26 个英文字母的 ASCII 编码和 Unicode 编码是一样的,因此 AscW(s) 的输出结果也是 5A。汉字"中"的 ANSI 编码(GB18030)是十六进制的 D6D0,因此 Asc(s) 的输出结果是 D6D0。又因为“中”的 Unicode 编码(UTF-16 LE)是 4E2D,因此 AscW(s) 的输出结果是 4E2D。VBA 还有一个 AscB,这只是一个遗留函数(继承自 2000 年左右的 VB/VBA),现在的 VBA 中已不需要。与 Asc / AscW 将字符转换为编码相反,Chr / ChrW 是将编码转换为字符。一般格式为:Chr(charcode) / ChrW(charcode)其中,charcode 是一个 Long 型的数值表达式,表示字符编码。从示例的输出可以看出,汉字的 GB18030 和 Unicode 编码中,字的编排顺序是不一样的:GB18030 似乎是按照拼音排序,而 Unicode 似乎是按笔画排序的。Str 是将数值转换为字符串的转换函数。其一般格式为:其中,number 是一个 Long 型的数值表达式。Str 返回 Variant(String) 类型的表示。从输出结果可以看出,Str 返回的第一个字符表示符号,如果是正数,则显示为空格,隐含这里是正号(+),如果是负数,则显示负号(-)。与 Str 类似,CStr 也是将数值表达式转换为字符串表示。其一般格式为:expression 与 CStr 的返回值之间的关系列于下表:图4 CStr 的参数类型与 CStr 的返回值之间的关系本示例演示了图4 列表上所表示的关系。由图可以看出,图4上关于 expression 为 Error 时的说法不对,事实是:如果 expression 为 Error,则 CStr 仅返回错误号,因为 Number 是 Err 的默认属性,因此,CStr(Err) 在对 Err 求值时,相当于是 CStr(Err.Number),因此仅返回对 Err.Number 求值的结果。另外,从最后两行可以看出,与 Str 不同,CStr 不再对正数前置一个空格。String 返回一定数量的重复字符。其一般格式如下:String(number, character)其中,number 为 Long 型数值,表示返回的字符串长度。character 为 Variant 型数值或字符串,数值表示字符编码,字符串表示第一个字符作为 String 的返回值。如果 number 或 character 为 Null,则 String 返回 Null。注:如果 character 是一个数值型的字符编码,并且大于 255,则取 character 与 256 的模,即 character Mod 256。如果操作的目的是保证 character 所表示的字符为单字节字符。由图可以看出,character 参数如果是字符串的话,则只取第一个字符。如果是数值型的字符编码,则取第一个字节。这个结论可以用下面的示例证明。根据 VBA 文档中的说明,如果 character 参数是大于 255 的数值型字符编码,则取 character Mod 256 作为字符的编码输出该字符。但由图7 可以看出,并非如此,因为 String(20, 32487) 和 String(20, 32487 Mod 256) 的输出结果并不一致。32487 的十六进制表示是 7EE7,经过 Mod 256 运算后,结果为 E7。但 String(20, 32487) 输出结果却是 String(20, &H7E), 而非 String(20, &HE7)。同样,String(10, &H4E2D) 是按照 String(10, &H4E) 来输出的,而非 String(10, &H2D),其中 &H2D 是 &H4E2D Mod 256 的结果。经过多方测试,character Mod 256 实际上应该是 character \ 256。见例3。由图可见,将 Mod 操作符改成整数除法 \ 之后,\ 256 操作后的结果与 String 自己内部处理的结果一致。- /:a / b 得到一个浮点数结果,15 / 2 = 7.5
- \:a \ b 得到一个整数结果,15 \ 2 = 7