Access VBA教程:字符串函数运算的差异

对用于 Microsoft Access 的 Visual Basic 和早期版本 Microsoft Access 的 Access Basic 来说,文本在内存中的存放格式是不同的。Access Basic 代码中的文本以 ANSI 格式存储,而 Visual Basic 代码中的文本以 Unicode 格式存储。

Visual Basic 中使用的 Unicode 格式可以与 OLE 中文本的格式相匹配。OLE 间接地与 Visual Basic 相关。

例如,文本字符串“ABC”在内存中的存储如下所示:

存储格式 存储方式 说明
Unicode 41 00 42 00 43 00 42 30 44 30 46 30 每个字符存为两个字节。
ANSI 41 42 43 82 A0 82 A2 82 A4 ASCII 字符存为 1 个字节;双字节字符存为 2 个字节。

由于在内部格式上这些不同之处,在 Access Basic 和 Visual Basic 中字符串处理函数的运算也是有差异的。下面列出了这些运算有差异的函数及其语句。

Asc函数、Chr函数、InputB函数、InStrB函数、LeftB函数、LenB函数、RightB函数、MidB函数和相应的语句。

另外,Visual Basic 中又新增了 ChrB函数和 AscB函数。

由于这些函数和语句处理文本时均以字节为单位,所以它们在 Access Basic 和 Visual Basic 中是一样的。但因文本的存储格式不同,它们的运算是有差异的。例如,在 Access Basic 中 LenB("A") 为 1,而在 Visual Basic 中为 2。

早期版本的 Microsoft Access 中创建的程序若使用以字节为单位的字符串处理函数,在 Visual Basic 中必须变换成识别 Unicode 格式的源代码。但如果用到的仅是处理字符单位的字符串处理函数,如 Len函数、Left函数和 Right函数等,则无需识别它们。

如果早期版本的 Microsoft Access 中创建的程序移植到当前版本的 Microsoft Access 中,则应考虑下列有关字符串处理的要点。

Asc函数和 AscB函数

该程序在早期版本的 Access 中能正常运行,但在 Microsoft Access 中当前版本的 Visual Basic 中会产生运行时错误。


Print Asc(MidB("", 2,1))

这是因为 Asc函数中的参数 MidB("", 2,1) 不能返回正确的 Unicode 格式文本数据。

用下面的 AscB函数可以使该程序在当前版本的 Microsoft Access 中运行:


Print AscB(MidB("", 2,1))

在该程序中,返回了第二个 Unicode 格式字节的值 (&H30)。

Chr函数和 ChrB函数

Microsoft Access 中的 Chr函数总是返回双字节字符。在早期版本的 Microsoft Access 中 Chr(&H41) 和 ChrB(&H41) 是相等的,而在当前版本的 Microsoft Access 中。Chr(&H41) 和 ChrB(&H41) + ChrB(0) 才是相等的。

同样,在早期版本的 Microsoft Access 中,“”表示为 ChrB(&H82) + ChrB(&HA0),但当前版本的 Microsoft Access 中却表示为 ChrB(&H42) + ChrB(&H30)。

调用 Windows 应用程序编程接口 (API)

在某些 Windows API 中,字符串的字节长度有特殊的含义。例如,下列程序返回一个在 Windows 中建立的文件夹。在 Microsoft Access 中,LeftB(Buffer, ret) 不能返回正确的字符串。这是因为尽管该函数显示了一个 ANSI 字符串的字节长度,但 LeftB函数处理的却是 Unicode 字符串。在这种情况下可使用 InStr函数只返回没有空值的字符串。


Private Declare Function GetWindowsDirectory Lib "kernel32" _
    Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, _
    ByVal nSize As Long) As Long
Private Sub Command1_Click()
    Buffer$ = Space(255)
    ret = GetWindowsDirectory(Buffer$, 255)
    ' WinDir = LeftB(Buffer, ret)   '<--- Incorrect code"
    WinDir = Left(Buffer$, InStr(Buffer$, Chr(0)) - 1)
                                        '<--Correct code"
    Print WinDir
End Sub

Input函数和 InputB函数

在 Microsoft Access 中,Input函数在将文本从文件读到一个 Unicode 格式字符串中时会转换指定数量的字符,并将其作为变量读取。而 InputB函数却不然,它假定数据已是二进制,对其不加转换即存为变量。如果读取一个以固定长度字段存储的文件时使用 InputB函数,那么该固定字节长度的数据一经读取便需转换。


Open "Data.Dat" For Input As 1
dat1 = StrConv(InputB(10, 1), vbUnicode)
dat2 = StrConv(InputB(10, 1), vbUnicode)
dat3 = StrConv(InputB(10, 1), vbUnicode)
===DATA.DAT
123456789012345678901234567
Name      Address      Telephone

在 Microsoft Access 7.0 中处理 ANSI 格式字符串字节

如果必须在 Microsoft Access 中处理 ANSI 格式字符串字节,可以使用 StrConv函数。通过设置 vbUnicode 或 vbFromUnicode 常量可在 ANSI 和 Unicode 格式之间转换文本。如果在临时将一个 Unicode 格式字符串转换为 ANSI 格式字符串之后处理字节,处理完毕后又将其转换回 Unicode 格式,那么使用早期版本的 Access 中的代码要相对容易一些。


' ANSI
dat = StrConv(dat, vbFromUnicode)
.
.
.    '
.    '
.
.
' Unicode
dat = StrConv(dat, vbUnicode)

执行与 16 位字节处理函数相兼容的操作的示例函数

在 Microsoft Access Visual Basic for Applications 中,字符串的内部处理使用 Unicode 格式。因此不同于早期版本 Microsoft Access 中所用的 Access Basic 的二进制处理函数。

ANSI函数是为保持 Access Basic 和 Visual Basic 运算的兼容性而创建的。

注意   用这些 ANSI 处理函数输入和删除的字符串总是 Unicode 的。在函数中会临时转换为 ANSI 格式字符串,但处理过程一结束便将恢复 Unicode 格式。

下列代码不能将一个 DBCS 字符的第一和第二个字节合并而生成一个 DBCS 字符。


AnsiMidB("",1,1) + AnsiMidB("",2,1)

创建的这些函数以字节为单位处理字符串。但是通过这种以字节为单位的处理过程并不能生成不同的字符。在这种情况下,它将表达如下:


StrArg = ""
StrArg = StrConv(StrArg, vbFromUnicode)    ' ANSI
RetArg = MidB(StrArg,1,1) + MidB(StrArg,2,1)    '
    '
StrArg = StrConv(StrArg, vbUnicode)    ' Unicode
RetArg = StrConv(RetArg, vbUnicode)    '

一般来说,如果在处理字符串之前将其转换成了 ANSI 字符,那么处理完毕后应将其恢复成 Unicode 字符。

字节字符串处理函数总是一个用于处理字符串的函数。若要处理二进制数据,可使用字节数组,而不要用字符串变量或字节字符串处理函数。

以字节“数组”形式存储的字符串如下所示:


 Array
Dim Var() As Byte
Var = ""             ' Unicode
Var = StrConv("", vbFromUnicode)    ' ANSI
Function AnsiStrConv(StrArg, flag)
    nsiStrConv = StrConv(StrArg, flag)
End Function
' LenBANSI Unicode
Function AnsiLenB(ByVal StrArg As String) As Long
    AnsiLenB = LenB(AnsiStrConv(StrArg, vbFromUnicode))
End Function
' MidBANSI Unicode
'
Function AnsiMidB(ByVal StrArg As String, ByVal arg1 As Long, _
            Optional arg2) As String
    If IsMissing(arg2) Then
    AnsiMidB = AnsiStrConv(MidB(AnsiStrConv(StrArg, vbFromUnicode) _
            , arg1),vbUnicode)
    Else
    AnsiMidB = AnsiStrConv(MidB(AnsiStrConv(StrArg, vbFromUnicode) _
            , arg1, arg2), vbUnicode)
    End If
End Function
' LeftB ANSI Unicode
Function AnsiLeftB(ByVal StrArg As String, ByVal arg1 As Long) As String
    AnsiLeftB = AnsiStrConv(LeftB(AnsiStrConv(StrArg, _
            vbFromUnicode), arg1), vbUnicode)
End Function
' RightBANSI Unicode
Function AnsiRightB(ByVal StrArg As String, ByVal arg1 As Long) As String
    AnsiRightB = AnsiStrConv(RightB(AnsiStrConv(StrArg, _
            vbFromUnicode), arg1), vbUnicode)
End Function
' InStrB 2 AnsiAnsi
Function AnsiInStrB(arg1, arg2, Optional arg3) As Integer
    If IsNumeric(arg1) Then
    pos = LenB(AnsiLeftB(arg2, arg1))
    AnsiInStrB = InStrB(arg1, AnsiStrConv(arg2, vbFromUnicode) _
            , AnsiStrConv(arg3, vbFromUnicode))
    Else
    AnsiInStrB = InStrB(AnsiStrConv(arg1, vbFromUnicode) _
            , AnsiStrConv(arg2, vbFromUnicode))
    End If
End Function

使用 Byte 数据类型

在 Microsoft Access 中,Byte 数据类型是一种新增的数据类型。如果在处理二进制数据时使用了字符串变量类型,则文本将在 ANSI 和 Unicode 之间进行转换,并且将改变二进制数据。因此,处理二进制数据时应使用 Byte 数据类型的变量。


Dim ByteData() As Byte
ByteData = ""        ' Unicode
ByteData = StrConv("", vbFromUnicode)     'ANSI
ByteData = InputB(10, #1)    '
Debug.Print ByteData(5)        '

上页:Access VBA教程:“排序与分组”框 下页:Access VBA教程:表

Access VBA教程:字符串函数运算的差异

Access VBA教程:表 Access VBA教程:表字段
Access VBA教程:在 Microsoft Access 2002 中使用枚举常量 Access VBA教程:Microsoft Access 常量概述
Access VBA教程:操作查询 Access VBA教程:ActiveX 控件(窗体)
Access VBA教程:了解 ActiveX 控件(数据访问页) Access VBA教程:绑定控件
Access VBA教程:绑定范围控件 Access VBA教程:绑定超链接控件
Access VBA教程:绑定对象框控件 Access VBA教程:图表控件(窗体和报表)
Access VBA教程:复选框控件(窗体和报表) Access VBA教程:复选框控件(数据访问页)
Access VBA教程:组合框控件(窗体) Access VBA教程:命令按钮控件(窗体)
Access VBA教程:命令按钮控件(数据访问页) Access VBA教程:交叉表查询
Access VBA教程:下拉式列表框控件(数据访问页) Access VBA教程:子窗体/子报表控件
版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号