|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
本帖最后由 laiwatch 于 2020-6-7 16:23 编辑
还没写完, 为什么保存草稿变成发表
在http://club.excelhome.net/thread-886553-1-1.html@liucqa 提了一个非常有意思的问题 在使用split去处理字符串的时候碰到的诡异情况, split, 在选参数的时候, 在选vbTextCompare出现了奇怪的Error(5)错误, 但是vbBinaryCompare却没有任何问题
特别感兴趣, 去试了一下, 果然同样出现这个问题, 就此引出了下面的一些列疑问
'---------------------------------------------------------------------------------------------------------------------------------------------------------
一. 测试, 为什么 @ liucqa这个问题会出现这个错误
1. 首先, 怀疑的对象是"<>"这两个符号(以为是split函数隐藏的保留字符), 很显然, 简单测试就知道和这个符号无关
2. 怀疑的目光指向潜在的隐藏的干扰字符上, 用Notepad++对文本进行了清洗, 重新尝试, split还是出现错误, 而且文本是以ansi编码保存的txt文档, 隐藏的特殊字符的可能性不大
3. 手滑, 删掉了文本的部分内容, 再试, 发现split没有问题, 从而确定地区内容中的某些内容对split造成了干扰导致出错
使用TextStream.ReadLine, 将出错的内容进行逐行输入进行测试, 可疑的目标终于被锁定
- Sub test()
- Dim x
- Dim texts As TextStream
- Dim fso As New FileSystemObject
- Set texts = fso.OpenTextFile("C:\Users\Lian\Desktop\spli\s.txt", ForReading, False, TristateUseDefault)
- Dim s As String, i As Integer
- Do While texts.AtEndOfLine = False
- s = texts.ReadLine
- x = Split(s, ">", 0, vbTextCompare)
- 'Debug.Print s
- i = i + 1
- Loop
- texts.Close
- 'x = Split(s, "工作温度", -1, vbBinaryCompare)
- End Sub
复制代码CSP</td><td>100ピンLFCSP-VQ (12x12)</td><td>管件</td><td align=center>3</td>
没错就是你了, "ピン", 片假名, 正是这两个片假名导致了选择执行文本比对的时候出现错误, 这种错误在instr函数上同样出现此问题
二, 寻找答案
既然知道了是片假名造成的出错, 这个就涉及到字符集的问题, 由于对这方面的最早了解都是 @liucqa 大神的几个重要的帖子才认识到字符编码, 字符集这些神奇的存在
如: http://club.excelhome.net/thread-830448-1-1.html
如: http://club.excelhome.net/thread-906973-1-1.html
如: http://club.excelhome.net/thread-998747-1-1.html
最早碰上这个问题, 是Kill函数, 用于删除文件的时候遭遇的错误, 就此知道了"Unicode", 但是此次的问题相对麻烦, 和这个问题有所区别, 后面会提到
如何知道那些字符是不是unicode的简单方法,就是将字符串复制到VBE编辑器中, 字符串中非"?"字符变成了"????"这个符号, 那么就说明这些是unicode字符
, 更准确一点说这些是非ANSI字符
在 @ Demon's Blog 的<VB6拾遗:字符串与Unicode>一文中提到
VB6是Windows 98那个年代的古董,那时Windows内核还是ANSI的,而VB6字符串却是Unicode的。为了方便人们调用API,当Declare的函数参数为String或者Any时,VB会自作聪明的在调用前将字符串转成ANSI。
在Unicode内核的现在,这样的设定未免太愚蠢了,因为大部分A版API只不过是W版API的简单封装,内部先把ANSI字符串转成Unicode,然后调用对应的W版函数。也就是说,在VB调用ANSI版API之前将Unicode转成ANSI,而ANSI版API内部把ANSI转成Unicode调用对应的函数,然后又把Unicode转成ANSI作为返回值,最后VB再次将ANSI转成Unicode。
|
|