20070928 excel vba unicode
http://www.yippeesoft.com

len("大家好") len("abc") 所返回的值都是 3,因为「大」和「a」都是一个字符。 但是这对一些中文字串处理,例如纯文字的数据文件,却是一个大灾难,因为你必须以byte 来定位每个字符,可是 unicode 却把一切的处理全搞砸了。例如: len("good morning") 返回 12,而 len("今天天气很好") 返回 6 对初学者而言,好不容易能使用 vb 来写程序已经是件了不起的事了,却马上在中文处理上挨了一记闷棍,所受到的打击实在不小。但是不要怕,事实上只要再多了解一些指令,就可以把中文处理的问题解决了。 是什么指令呢?最重要的莫过于 strconv 了。strconv 函数的语法为:strconv(待转换字串, 转换格式) 其中转换格式在这里用到的是: vbunicode 将 ansi 字串转换为 unicode vbfromunicode 将 unicode 字串转换为 ansi 将字串转成 ansi 之后,所有的字串处理指令都要加个 b,例如:leftb, rightb, midb, chrb, instrb, lenb, inputb 等。例用这些指令来处理就行了。 当你处理完毕之后,你可以再将它再转回 unicode,这样就可以使用一般的字串处理指令了。这样讲看得懂吗?如果还是不了解,看看下面的实例说明:简易使用范例看看下面的基本范例您应该就会对 vb 的字串处理方式有些概念。 private sub command1_click () dim sunicode as string dim sansi as string \’ unicode 运算 sunicode = "王小明,a123456789,651023,上海市中山路100号,(02)2345678" debug.print len(sunicode) \’ 返回 44 debug.print mid$(sunicode, 5, 10) \’ 返回 a123456789 debug.print instr(sunicode, "上海市") \’ 返回 23 \’ 将 unicode 字串转成 ansi sansi = strconv(sunicode, vbfromunicode) \’ ansi 运算 debug.print lenb(sansi) \’ 返回 54 debug.print midb$(sansi, 8, 10) \’ 返回 ?????,因为忘了转回 unicode debug.print strconv(midb$(sansi, 8, 10), vbunicode) \’ 返回 a123456789,请注意转回 unicode 的动作一定要做 debug.print instrb(sansi, strconv("上海市", vbfromunicode)) \’ 返回 23, 不要忘了要把"上海市"也转成 ansi,否则会找不到 end sub 读入文本文件在 vb 的小技巧中,有一个是快速读文件法: private sub command1_click () dim sfile as string open "c:\\filename.txt" for input as #1 sfile = input$(lof(1), #1) close #1 end sub 但是很不幸地,如果你读取的文件内含中文字,那上面这段程序会出现 input pastend of file 的错误。因为 lof 返回的是文件的 byte 数,而 input 函数读取的是字符数,由于文件内含中文,因此文件中的字符数将会小于 byte 数,于是就发生错误了。要解决这个问题,我们就要用到 strconv 和 inputb 这两个函数了: private sub command1_click () dim sfile as string open "c:\\filename.txt" for input as #1 sfile = strconv(inputb$(lof(1), #1), vbunicode) close #1 end sub 上面修正程序先用 inputb 将文件读进来,不过使用 inputb 所读入的文件是 ansi格式的,所以要再用 strconv 转成 unicode 才行。随机数据文件许多文字数据文件是以固定字节的位置来加以区格,例如下面的数据格式:王小民650110上海市中山路100号 (02)1234567 张大呆660824花莲县大甲镇广东街23号(03)9876543 像这种类型的文件要如何处理呢?这是就必须用到 type 以及 byte array 了。 private type tagrecord username(5) as byte \’ 姓名 6 bytes birthday(5) as byte \’ 生日 6 bytes address(21) as byte \’ 地址 22 bytes tel(11) as byte \’ 电话 12 bytes crlf(1) as byte \’ 换行字符 2 bytes end type private sub command1_click() dim urecord as tagrecord open "c:\\filename.dat" for random as #1 len = lenb(urecord) get #1, 2, urecord \’ 取第二笔数据 with urecord \’ with … end with 应该会用吧 debug.print .username \’ 返回 ??? debug.print strconv(.username, vbunicode) \’ 返回 "张大呆" end with close #1 end sub 在这个例子中,一定要用到 byte array,因为只有 byte array 才能正确地定位到每个 byte 的位置。以前使用字串来定位的方法已经不适用了,千万要记住!但是使用byte array 所读入的数据是 ansi 格式,若要处理或是做运算的话,记得还要转成unicode 格式才行。 [●] 使用 byte array 除了上面必须使用 byte 精确定位的例子之外,纯文字的处理基本上是用不到 bytearray 的。byte array 通常是用在处理 binary 数据。这方面的问题我们将另文讨论。看吧!只要熟悉使用 strconv,你就可以在 unicode 及 ansi 格式之间自由自在地变来变去

 在vb中如何将一个integer 类型的数据转换成两个Byte类型存储?
Dim l As Integer, k As String
    Dim arr(1) As Byte
    l = -30000
    k = Right(Format("000" + Hex(l)), 4)
    arr(0) = Val("&H" + Left(k, 2))
    arr(1) = Val("&H" + Right(k, 2))

 \’VB中的String是Unicode 
          Dim   str1   As   String 
          Dim   str2   As   String 
          Dim   abyte1()   As   Byte 
          Dim   abyte2()   As   Byte 
          str1   =   "字符串abcd1234" 
          abyte1   =   str1 
          abyte2   =   StrConv(str1,   vbFromUnicode) 
          
          str2   =   abyte1 
          Debug.Print   "Unicode的byte数组直接赋值:"   &   str2 
          str2   =   abyte2 
          Debug.Print   "没转转换为Unicode是这样:"   &   str2 
          str2   =   StrConv(abyte2,   vbUnicode) 
          Debug.Print   "转换为Unicode就可以了:"   &   str2

 

 

存放文本的Byte数组可以与String直接转换。 
  
  dim   a()   as   byte,s   as   string 
  
  ————————— 
  在内存中的相互转换 
  
  s="hggjh" 
  a=s   \’直接转为Unicode编码的数组 
  s=a   \’将Unicode编码的数组转为String 
  ———————————- 
  
  ——————————————- 
  对于存在文件中的文本,读入byte数组为ANSI编码 
  
  s=strconv(a,vbunicode)   \’可将文件读入byte数组转为String 
  a=strconv(s,vbfromunicode)   \’可将String转为ANSI编码存入byte数组  

  一个vb递归的程序,打印collection内容
注意声明中by val语句,VB中默认的参数传递方式是by ref
 
Public Function printCol(col As H2000_HELPERLib.Collection, Optional ByVal nIntent As Integer) As String
    If Not IsNullCollection(col) Then
        nIntent = nIntent + 1
        Debug.Print Space(nIntent * 4) & "(TotalSize = " & col.GetTotalSize & _
                                         "; Count = " & col.Count & ")"
      
        Dim i As Long
        For i = 1 To col.Count
            Dim strLine As String
          
            strLine = Space(nIntent * 4)
            strLine = strLine + col.GetKeyByIndex(i)
            strLine = strLine + vbTab + TypeName(col(i))
          
            Debug.Print strLine
          
            If TypeName(col(i)) = "ICollection" Then
                printCol col(i), nIntent
            End If
        Next
    End If
End Function

历史博文

标签:, , ,
六月 23, 2008 at 7:52 下午 by yippee 1,107 次
Category: Info
Tags: , , ,