如果你只用VBA处理Excel的数据的话,一般都不会碰上编码的问题,但是一旦涉及到读取外部数据,就很有可能会碰上编码问题了。
1、什么是编码:
百度百科:
编码是信息从一种形式或格式转换为另一种形式的过程,也称为计算机编程语言的代码简称编码。用预先规定的方法将文字、数字或其它对象编成数码,或将信息、数据转换成规定的电脉冲信号。编码在电子计算机、电视、遥控和通讯等方面广泛使用。编码是信息从一种形式或格式转换为另一种形式的过程。解码,是编码的逆过程。
看上面的解释可能还是有点晕,我自己是这样理解:
计算机能够存储的只有0和1,每8个bit为1个byte,所以1个byte能代表2的8次方,也就是256种不同的东西。如果人只看0和1不同的排列组合的话,根本无法区分到底代表了什么内容。
所以,为了方便,前辈们设计出了编码,也就是让电脑根据编码的规则,把所代表的内容显示在显示器上,这样我们就能够看懂了,但是,计算机实际存储的内容是没有改变的。
随着计算机不断的发展,为了尽量能够兼容世界上的语言,编码方案也在不停的发展,也就出现了许多的编码方案。
2、VBA的编码:
VBA对字符串的编码是按照Unicode编码方案里的UTF-16,也就是所有字符都是按照2个Byte来代表。如果你想查看,可以这样:
从图中可以看出,6个字符,需要使用12个容量的Byte数组来存储,你可以baidu查看一下字符a的编码,在ASCII中,a的编码是97,Unicode编码为了兼容ASCII编码,所有的ASCII字符,第2个Byte都是用0。另外我们使用的中文都是用2个Byte代表,
3、Windows系统的编码:
我们在文件操作——读取中,自己手动创建了1个txt文本文档,在把数据读取出来之后,还使用了VBA.StrConv(b, vbUnicode)进行了转换,这个的功能就是把ANSI编码转换成了VBA里的Unicode编码,那为什么我们手动创建的是ANSI编码呢?
我们可以这样查看,打开手动创建的那个txt文本文档,点击文件-另存为:
在这个界面,我们就可以看到这个文本文档的编码了。
所以,如果把新建的txt文本文档另存为,选择编码Unicode,那么,你可以再试试读取的操作,这个时候不需要VBA.StrConv(b, vbUnicode)这条代码了,直接使用str = b,在立即窗口里就可以输出你写的东西。
代码语言:javascript复制Sub ReadTxtByOpenBin()
Dim num_file As Integer
Dim str As String
Dim b() As Byte
'获取1个文件号
num_file = VBA.FreeFile()
'打开文件
Open ThisWorkbook.Path & "test.txt" For Binary Access Read As #num_file
'VBA.LOF(num_file)返回num_file这个文件的字节数
ReDim b(VBA.LOF(num_file) - 1) As Byte
'读取数据,读取的字节数就是数组b的大小
Get #num_file, 1, b
'关闭文件
Close #num_file
str = b
Debug.Print str
End Sub
但是细心查看的话,会发现前面会出现1个问号。这个的原因是系统造成的,如果我们存储为编码Unicode,系统会自动在前面加上2个Byte的东西,16进制的FF和FE。
所以,既然系统是通过前面这2个字节来确认文件是Unicode编码的,那么,我们在文件操作——写入中,如果我们自己先写入那2个标志,再写入我们需要的东西,也可以省略掉StrConv了:
代码语言:javascript复制Sub WriteTxtByOpenBin()
Dim num_file As Integer
Dim str As String
str = "测试文件写入"
Dim b() As Byte
'将string转换为byte数组
b = str
'获取1个文件号
num_file = VBA.FreeFile
Open ThisWorkbook.Path & "put.txt" For Binary Access Write As #num_file
'写入Unicode编码文件头
Put #num_file, 1, &HFF
Put #num_file, 2, &HFE
'写入数据
Put #num_file, 3, b
'关闭文件
Close #num_file
End Sub
这个时候再打开put.txt,你可以看到已经不会乱码了,同时你可以用另存为来查看它的编码,会发现已经变成了Unicode,而不是系统默认的ANSI了。