【VBA研究】奇怪的“?”----Unicode格式的字符处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iamlaosong/article/details/83620872

iamlaosong

1、从网站导出的Excel文件单元格内容后面多了一个不可见字符,怎么造成的不知道,但不是每一列都有。想要用VBA代码去掉,就要先判断出是什么字符,将内容复制到文本环境中(比如编程环境或者UltraEdit中),发现最后面那个是个“?”,Asc()函数取其码值也是63,但奇怪的是截取这个字符和“?”或者Chr(63)相比,发现并不相等。

2、实际情况这个字符应该不是“?”,复制到记事本中,字符依然不可见,保存文件,提示包含Unicode字符(如下图),如果继续按ANSI编码格式保存,再打开这个文件发现最后面的那个字符就被转换成了“?”。但如果按Unicode格式保存,再打开这个文件则发现这个字符依然不可见,可见是原样保存的,用UltraEdit打开查看码值,发现是0x00A0,即160。

3、想要去掉这个字符不是很难,因为我们导出内容最后不会有“?”存在,所以用Asc()函数取值,只要是63,就去掉最后一个字符。如下:

If Asc(Right(MyRecord(j), 1)) = 63 Then MyRecord(j) = Left(MyRecord(j), Len(MyRecord(j)) - 1)

4、那么这个字符到底是什么呢?通过下面代码可以判断其内码值是160:

    For kk = 1 To 65535
        If Right(MyRecord(j), 1) = ChrW(kk) Then
            MsgBox kk
        End If
    Next kk

注意:因为是不可见的Unicode字符,上面代码中ChrW(kk)如果写成Chr(kk),那个条件则永远不会成立,因为Chr(kk)返回的是ASCII字符,单字节的。不过,如果左边截取的那个字符是ASCII字符,用Chr(kk)也是可以成立的。

上面的去掉不可见字符的语句写成下面的就完美了:

If Right(MyRecord(j), 1) = ChrW(160) Then MyRecord(j) = Left(MyRecord(j), Len(MyRecord(j)) - 1)

5、为什么这个码值160的字符会被转换成码值63的“?”,研究了一下,发现在记事本中输入码值129以上的字符(Alt+小键盘数字)都会被认为是包含Unicode格式字符,按ANSI格式保存后会转换成“?”。在Windows记事本程序中,Unicode实际指的就是UTF-16。

6、上面内容涉及到文件内容在内存中的编码和保存在硬盘中的编码,实际上当我们打开文件时,系统会对文件内容的编码方式进行转换,变成内存中的编码格式。VBA对字符串的编码是Unicode方式,任何字符都是2字节,但在做判断时,又会根据情况确定是否转换成ANSI方式。当说到一个字符的码值时,首先要确定这个字符的编码方式,上述码值160只是这个字符的Unicode码值。

==============================

附:Chr 函数
  语法:Chr(charcode)
  说明:返回 String,其中包含有与指定的字符代码相关的字符 。
  必要的 charcode 参数是一个用来识别某字符的 Long。
  0 到 31 之间的数字与标准的非打印 ASCII 代码相同。例如,Chr(10) 可以返回换行字符。charcode 的正常范围为 0 – 255。然而,在 DBCS 系统,charcode 的实际范围为 -32768 到 65535。

  注意 ChrB 函数作用于包含在 String 中的字节数据。ChrB 总是返回一个单字节,而不是返回一个字符,一个字符可能是一个或两个字节。ChrW 函数返回包含 Unicode 的 String,若在不支持 Unicode 的平台上,则其功能与 Chr 函数相同。
  注意 Visual Basic for the Macintosh 不支持Unicode 字符串。因此,当n 值在128 – 65,535 范围内时, ChrW(n) 不能像在Windows环境中那样返回所有的 Unicode 字符。相反地,当Unicode 的n 值大于127 时,ChrW(n) 会试图做一个“最好的猜测”。因此,在Macintosh 环境中,不能使用ChrW 。
  示例:
Dim MyChar
MyChar = Chr(65)    ' 返回 A。
MyChar = Chr(97)    ' 返回 a。
MyChar = Chr(62)    ' 返回 >。
MyChar = Chr(37)    ' 返回 %。

  补充知识点:
  要实现回车换行,我目前所知道的3种方法
VbNewline
VbCrLf
Chr(10)

  补充:在Excel中,Char函数具有类似功能。

猜你喜欢

转载自blog.csdn.net/iamlaosong/article/details/83620872