ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 881|回复: 0

[讨论] @liucqa你的问题暂时解决了_VBA字符串/字符编码/字符集谜题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2020-6-7 14:54 | 显示全部楼层 |阅读模式
本帖最后由 laiwatch 于 2020-6-7 16:23 编辑

还没写完, 为什么保存草稿变成发表
http://club.excelhome.net/thread-886553-1-1.html@liucqa 提了一个非常有意思的问题 在使用split去处理字符串的时候碰到的诡异情况, split, 在选参数的时候, 在选vbTextCompare出现了奇怪的Error(5)错误, 但是vbBinaryCompare却没有任何问题
Image 008.jpg
Image 009.jpg

特别感兴趣, 去试了一下, 果然同样出现这个问题, 就此引出了下面的一些列疑问
'---------------------------------------------------------------------------------------------------------------------------------------------------------
一. 测试, 为什么 @ liucqa这个问题会出现这个错误
1. 首先, 怀疑的对象是"<>"这两个符号(以为是split函数隐藏的保留字符), 很显然, 简单测试就知道和这个符号无关
2. 怀疑的目光指向潜在的隐藏的干扰字符上, 用Notepad++对文本进行了清洗, 重新尝试, split还是出现错误, 而且文本是以ansi编码保存的txt文档, 隐藏的特殊字符的可能性不大
3. 手滑, 删掉了文本的部分内容, 再试, 发现split没有问题, 从而确定地区内容中的某些内容对split造成了干扰导致出错
使用TextStream.ReadLine, 将出错的内容进行逐行输入进行测试, 可疑的目标终于被锁定
  1. Sub test()
  2. Dim x
  3. Dim texts As TextStream
  4. Dim fso As New FileSystemObject
  5. Set texts = fso.OpenTextFile("C:\Users\Lian\Desktop\spli\s.txt", ForReading, False, TristateUseDefault)
  6. Dim s As String, i As Integer
  7. Do While texts.AtEndOfLine = False
  8. s = texts.ReadLine
  9. x = Split(s, ">", 0, vbTextCompare)
  10. 'Debug.Print s
  11. i = i + 1
  12. Loop
  13. texts.Close
  14. 'x = Split(s, "工作温度", -1, vbBinaryCompare)
  15. 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。




您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-10-24 08:25 , Processed in 0.038255 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表