VB学习入门教程

来源:互联网 时间:1970-01-01

字串中文的问题字串中文的问题,起於vb的字串是使用UniCode,而我们一般是使用Ascii Code。这差别在何处呢?UniCode的每个字元长度是2个byte,而Ascii是一个byte,如果说,我将们将VB的字串写入档案,有时会有意想不到的结果。例如: Text1.Text = "这是一个abc" len5 = Len(str5)如果我们的Access资料库有一栏位的长度是10个Byte,所以我们在TextBox中设定MaxLength = 10,但是上面的例子得到的len5是7,而不是我们认为的11,因为不管是中文或英文,vb一律以UniCode来存,所以str5的长度是7个"字元",而text1最大的长度限制是10,7没有超过10,故使用者仍可输入,但存档时,11个byte超过10个byte,所以会有错。可是或许有人发现,使用RS232来传资料时,另一端主机是Ascii编码的机器,在vb中我们若使用String来传,一样可以通啊,其实那是vb在传送与接收data时,会做转换,使我们的程式设计较方便,但如果传的资料是Binary时,就头大啦。例如说,以字串的方式来传送资料,当想传Ascii 大於128时,常有些问题,因为ASC(Chr(129))=0,使我们不能用Chr()的指令来放资料。(事实上,您可以使用ChrW(129)来存资料,和使用AscW()来取得值,加个W代表是Word的运算),这时候,就只有使用Byte Array来做了。1.UniCode转成ByteAry Dim byteAry() As Byte Dim str5 As String Dim i As Long str5 = "这abc" byteAry = str5 For i = LBound(byteAry) To UBound(byteAry) Debug.Print byteAry(i) '得 25 144 97 0 98 0 99 0 Next i Debug.Print Len(str5), LenB(str5) '得4 8 所以了,可看出UniCode 的特性,程式应改一下,使用Strconv()来转换 Dim byteAry() As Byte Dim str5 As String Dim i As Long str5 = "这abc" byteAry = StrConv(str5, vbFromUnicode) For i = LBound(byteAry) To UBound(byteAry) Debug.Print byteAry(i) '得 25 144 97 98 99 Next i Debug.Print LenB(StrConv(str5, vbFromUnicode)) '得52.ByteAry转回UniCode 使用Strconv()转换 Dim byteAry(10) as Byte Dim Str5 as String byteAry(0) = 25 byteAry(1) = 144 byteAry(2) = 97 byteAry(3) = 98 byteAry(4) = 99 Str5 = StrConv(byteAry, vbUniCode)3.一些有用的函式
SubStr() 中文化取子字串,相对Mid()Strlen() 中文化字串长度,相对Len()StrLeft() 中文化取左字串,相对Left()StrRight() 中文化取右字串,相对Right()isChinese() Check某个字是否中文字Public Function SubStr(ByVal tstr As String, start As Integer, Optional leng As Variant) As StringDim tmpstr As StringIf IsMissing(leng) Then tmpstr = StrConv(MidB(StrConv(tstr, vbFromUnicode), start), vbUnicode)Else tmpstr = StrConv(MidB(StrConv(tstr, vbFromUnicode), start, leng), vbUnicode)End IfSubStr = tmpstrEnd FunctionPublic Function Strlen(ByVal tstr As String) As Integer Strlen = LenB(StrConv(tstr, vbFromUnicode))End FunctionPublic Function StrLeft(ByVal str5 As String, ByVal len5 As Long) As StringDim tmpstr As Stringtmpstr = StrConv(str5, vbFromUnicode)tmpstr = LeftB(tmpstr, len5)StrLeft = StrConv(tmpstr, vbUnicode)End FunctionPublic Function StrRight(ByVal str5 As String, ByVal len5 As Long) As StringDim tmpstr As Stringtmpstr = StrConv(str5, vbFromUnicode)tmpstr = RightB(tmpstr, len5)StrLeft = StrConv(tmpstr, vbUnicode)End FunctionPublic Function isChinese(ByVal asciiv As Integer) As Boolean If Len(Hex$(asciiv)) > 2 Then isChinese = True Else isChinese = False End IfEnd Function
 

将阿拉伯数字转成中文字的程式 一个Form 一个TextBox 一个Label 这个修订後的程式是当使用者在TextBox中输入只包含 0~9 的数值後,在Label中就可 看见被转换後的中文字,例如:1560890 转成 "壹佰伍拾陆万零捌佰玖拾"。程式限制 为不可输入超过16个数字。 请建立一个新专案,并在表单中放入上述物件,再把以下程式码复制到表单的程式 码视窗,最後按下F5来执行。 Private Sub Form_Load() Text1.MaxLength = 16 Text1.Text = "" Label1.Caption = "" Label1.AutoSize = True Label1.BorderStyle = 1 End Sub Private Sub Text1_Change() Label1.Caption = CChinese(Text1.Text) End Sub Private Function CChinese(StrEng As String) As String If Not IsNumeric(StrEng) Or StrEng Like "*.*" Or StrEng Like "*-*" Then If Trim(StrEng) <> "" Then MsgBox "无效的数字" CChinese = "": Exit Function End If Dim intLen As Integer, intCounter As Integer Dim strCh As String, strTempCh As String Dim strSeqCh1 As String, strSeqCh2 As String Dim strEng2Ch As String strEng2Ch = "零壹贰叁肆伍陆柒捌玖" strSeqCh1 = " 拾佰仟 拾佰仟 拾佰仟 拾佰仟" strSeqCh2 = " 万亿兆" StrEng = CStr(CDec(StrEng)) intLen = Len(StrEng) For intCounter = 1 To intLen strTempCh = Mid(strEng2Ch, Val(Mid(StrEng, intCounter, 1)) + 1, 1) If strTempCh = "零" And intLen <> 1 Then If Mid(StrEng, intCounter + 1, 1) = "0" Or (intLen - intCounter + 1) Mod 4 = 1 Then strTempCh = "" End If Else strTempCh = strTempCh %26amp; Trim(Mid(strSeqCh1, intLen - intCounter + 1, 1)) End If If (intLen - intCounter + 1) Mod 4 = 1 Then strTempCh = strTempCh %26amp; Mid(strSeqCh2, (intLen - intCounter + 1) 4 + 1, 1) If intCounter > 3 Then If Mid(StrEng, intCounter - 3, 4) = "0000" Then strTempCh = Left(strTempCh, Len(strTempCh) - 1) End If End If strCh = strCh %26amp; Trim(strTempCh) Next CChinese = strCh End Function
 在VB中使用枚举变量VB5 引入枚举变量,使用它,我们可以显著地改变应用程序的易读性:
Public Enum TimeOfDay
Morning = 0
Afternoon = 1
Evening = 2
End Enum
Sub Main()
Dim RightNow As TimeOfDay
If Time >= #12:00:00 AM# And Time <#12:00:00 PM# Then
RightNow = Morning
ElseIf Time >= #12:00:00 PM# And Time <#6:00:00 PM# Then
RightNow = Afternoon
ElseIf Time >= #6:00:00 PM# Then
RightNow = Evening
End If
End Sub
VB编程技巧几例
山东 许振华

1 文本框内容的自动选择。
在软件安装等一些场合需要将文本框中的内容自动选择,比如选择确省安装路径,在VB中可用如下的事件驱动代码:
sub text1_getfocus()
text1.selstart=0 ’选择起始位置
text1.sellength=65000 ’选择长度
end sub
sellength接近文本框允许的最大长度(65535),这样做是为了
强迫VB使用文本的实际长度。

2 防止自身多次运行。
由于WINDOWS的多任务处理功能, 有些程序可能打开后忘记了,下次用时还可能再打开,这样做会占用系统资源降低系统效率。为了防止自身被多次运行,可利用VB应用对象提供的PrevInstance属性来检测内存中是否已有一个自身的副本,若有则给出提示后结束。一般将检测代码放在FORM_LOAD()中,因为程序一运行就要检测。
代码如下:
sub form_load()
if App.PrevInstance then
msg$=App.exename & ”has already run”
msgbox msg$,48 ’给出程序已运行的提示和一惊叹号以示警告
end
endif
end sub
3 格式化输入。
在数据输入过程中,有些数据要求一定的格式,比如限制输入的只能为数字或英文字符,这可用VB的格式输入文本框来实现。它与文本框(TEXT BOX)功能基本相似,但多了一个MASK属性,MASK属性常用的设定如下:
#―限定仅能输入数字0~9;
A― 限定输入为英文字符及数字;
?―限定仅能输入英文字符;
.―限定小数点位置;
:―限定时间分隔号;
/―限定日期分隔号
不需编写代码,只要在设计时将格式化文本框对象(MASKED EDIT)的MASK属性设计好所需格式即可。比如 ## - ## - ## 可输入12-11-96。
4 用MSGBOX函数设计版权信息。
MsgBox函数可用来设计简易的版权信息,它只能显示文本,如果要求不高的话可采用它,优点是非常方便,比如在菜单ABOUT项中显示版权信息。
MsgBox函数的用法如下:MsgBox msg [, [type][, title] ]
msg ―需要显示的文字信息,如版权信息。
type―按钮显示选择项。
如 0 只显示 OK按钮(确省选择),4 显示 Yes 和 No 按钮
title―标题文字信息。
MSGBOX最多能显示1024个字符, 超出的将被截去;它可自动换行,如果你想强制换行的话需要在换行处加入换行符CHR(10)。
例子:
Sub Form_Click ()
Msg1 = ” Copyright (c) 1996” & Chr(10) & ”Ver
1.0 ” ’分两行显示
MsgBox Msg1, 0, ”Copyright demo” ’只显示一个OK按钮
End Sub
使用 IIF 和 SWITCH 以精减代码在很多地方你都可以使用一个更紧凑的 IIf 函数来代替 If...Else...Endif 的结构: 例:返回两个值中较大的一个 maxValue = IIf(first >= second, first, second)
Switch 则是一个很少使用的函数,可是在很多方面它都提供比 If...ElseIf 结构更好的 例:判断 "x" 是正、负还是 null?
Print Switch(x<0,"负",x>0,"正", True, "Null")
变量的地址VB5 内置了一个 VarPtr 函数,可是此函数在 VB4 中没有提供。可是你知道吗?VB4 的运行库中已经包含了此函数。只是在用它之前,我们需要声明一下:
#If Win16 Then
Declare Function VarPtr Lib "VB40016.DLL" (variable As Any) As Long
#Else
Declare Function VarPtr Lib "VB40032.DLL" (variable As Any) As Long
#End If
此函数在传递一个 Type 结构(如果此结构要求其一段是另一个变量或记录的地址)给一个外部的 API 程序时十分有用。
向文件中写入非 ASCII 字符如何向一个文件中写入非ASCII字符(ASCII码在128-255之间)?这在 VB3 中按常规方法就可以很好处理。但是,自 VB4 起,微软引入 Unicode 后,此问题就显得有些麻烦。方法如下:
Dim a As Byte '如果你不用 Unicode,微软推荐使用 Byte 类型替换 String 类型
a=%26amp;HF5 '此处直接给处 ASCII 码即可
Open "test.dat" For Binary As #1
Put #1, , a
Close (1)
VB中感叹号“!”与圆点“.”的用法差异
河北 马昱
在Visual Basic中,惊叹号“!”与圆点“.”都用于给对象命名,但两者语法上却存在很大的区别,这点在编程时尤其需要注意。
圆点操作符“.”用来表示对象的属性和方法,在引用时,需要用到对象的Name、圆点和需要的属性或方法。例如要引用文本框Textl中的文本属性时可用reponse$=Text1.Text,再如要改变Form1窗体返回或读取对象高度的单位时用Form1.ScaleHeigh=2000表示。
感叹号“!”常用于当一个控件作为一个特性访问的情况下,例如引用Fomr2中Text1文本框文本属性时,可采用response$=Form2!text1.text语法格式。
虽然两者的语法应用结构有较大差异,但两条语句的性能是相同的,值得注意的是如果你在感叹号“!”的位置使用“.”可以获得对窗体上Text1特性的直接访问权,为了进一步增加感性认识,你不妨运行下面的例子来试试。
1.建立一个新项目,并在Form1窗体中增加一个命令控件。
2.双击Form1窗体,编辑Form-Load事件并输入:
Form1!Command1.Caption=”Text”
Form1.Command1.Caption=”It Works”
3.运行试项目,这时你就会在Command1命令框中看到字符串It Works。
为了在程序中清楚地界定引用的控件名和该控件的属性或方法,增加程序的可读性,最好使用感叹号“!”,这也是VB的推荐方式。
0、""(空字串)、Null、Empty、与 Nothing 的区别先回答以下问题吧! 经过以下的叙述之后, 变量 A、B、C、D 分别等于 0、""、Null、 Empty、 Nothing 的哪一个?
Dim A
Dim B As String
Dim C As Integer
Dim D As Object
A 等于 Empty, 因为尚未初始化的「不定型变量」都等于 Empty。但如果检测 A = "" 或 A = 0, 也都可以得到 True 值。
B 等于 "", 因为尚未初始化的非固定长度「字串」都等于 "" 。 但请注意 B<> Null。
C 等于 0, 这个还有问题吗?
D 等于 Nothing, 尚未设定有物件的「物件变量」都等于 Nothing, 但请不要使用 D = Nothing , 而要使用 D Is Nothing 来判断 D 是否等于 Nothing, 因为判断 是否相等的符号是 Is 不是 = 。
最令人迷惑的地方是 Null 这个保留字, 请看以下语句:
Print X = Null
Print X <> Null
结果都是输出 Null(不是 True 也不是 False), 这是因为任何一个运算式只要含有 Null , 则该运算式就等于 Null, 实际上想要判断某一数据是否为 Null 绝对不能使用:
If X = Null Then ' 永远都会得到 Null
而要使用:
If IsNull(X) Then
哪一种数据会等于 Null 呢? 除了含有 Null 运算式之外, 就属没有输入任何数据的「数据字段」(在数据库中) 会等于 Null。
巧用Visual Basic的RND()函数
浙江 傅昌盛
Visual Basic的RND()函数有一个重要的特征:当RND()的参数(我们称这里可以称它为种子)为负值时,同一种子(负值)产生同一个随机数序列。同时Visual Basic还具有强大的二进制技术功能,这样我们可以按以下思路实现文件内容加密:
X=RND(-KEY) ’KEY为正数
VAULE=INT(256*RND) ’产生一个随机数(以此为密码)
Open FILENAME$ For Binary As #FILENUM’打开文件
Get #FILENUM,I,A ’取文件内容
B=A XOR VAULE ’得到加密文件
结合
C=B XOR VAULE’得到解密文件(B为加密后文件内容)
注意:这里的A非整个文件内容,可以是极少部分、几个字节甚至单个字节,若为单字节,则文件中的每个字节同不同的数异或,破译难度可见有多么大。具体过程:
Sub ENDECODE(FILENAME$,MA,FILE2$)'参数为:源文件,密码,目标文件
Dim FILENUM As Integer,X As Single,I As Single
Dim CHARNUM As Integer,RANDOMINTEGER As Integer
Dim SINGLECHAR As String *1,filen2 As Integer'取单字节
If MA<0 Them
MA=MA*(-1)
End If
X=Rnd(-MA)'参数为负
FILENUM=FreeFile
Open FILENAME$ For Binary As #FILENUM '二进制方式打开源文件
filen2=FreeFile
Open FILE2$ For Output As #filen2’以顺序文件打开目标文件
For i=1 To LOF(FILENUM)'LOF()文件字节长
Get #FILENUM,i,SINGLECHAR'取单字节内容
CHARNUM=Asc(SINGLECHAR)
RANDOMINTEGER=Int(256*Rnd)'得到字母表
CHARNUM=CHARNUM Xor RANDOMINTEGER'异或
Print #filen2,Chr$(CHARNUM);’写入目标文件
Next I
Close FILENUM
Close filen2
ok ’调用成功对话框
End Sub
调用格式:ENDECODE 源文件名,密码,目标文件名
上面过程可以对任何EXE、COM、文本等文件进行加解密(奇数次加密,偶数次解密),重演性极好,保密性特优,若对上述过程进一步加工,如进行多重随机等手段处理,那么将会更上一层楼,在此不累述。
顺便提一下,上面过程若对目标文件同样以二进制文件打开、写入,那么只能对纯西文文本进行加解密,对于纯中文文本则通过修改取双字节、I的步长为2来实现,其它(中西文结合文本、EXE、COM等文件)则将得不到预期结果,其原因可以能是ASCII大于127的字符,不能正常显示,不能用put语句正常写入文件(得到的只是空格),有兴趣者不妨一试。
利用 lstrlen 计算中英文混合字串的长度在 32-bit 版本的 VB 底下, 将每一个字符都视为两个 Byte, 所以
Len("中英Mixed") 等于 7
LenB("中英Mixed") 等于 14
但是在很多场合底下, 我们希望中文字长度以 2 计算, 英文字母长度以 1 计算, 此时使用的方法如下:
' 欲计算字串 S 的长度
N = 0
For I = 1 To Len(S)
C = Asc(Mid(S, I, 1)) ' 取得第 I 个字符组的字符码
If C >= 0 And C <128 Then ' 英文
N = N + 1
Else ' 中文
N = N + 2
End If
Next
看起来程序有点罗唆, 如果您不喜欢这个方法, 可以使用 Windows API 的 lstrlen 函数, 假设假计算 S 的长度, 则 API 声明式如下:
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
而调用的叙述则是:
n = lstrlen("中英Mixed" + Chr(0))
Print n ' n 将等于 9
请注意调用 lstrlen 时必须加上 Chr(0), 因为此一函数是根据 Chr(0) 来判断字串的结束。
调用 lstrlen 除了程序比较简短之外, 速度也比我们写 VB 程序判断中英文字然后计算长度来的快。
利用 StrConv 计算中英文混合字串的长度上一周说明利用 Windows API 的 lstrlen 计算中英文混合字串的长度之后,台中的 Rose 读者来函, 说还有更简单的计算方法, 如下:
LenB(StrConv("中英Mixed", vbFromUnicode))
说真的, 因为笔者懂得调用 Windows API, 所以竟然忽略了此一 VB 内建的函数,可见闻道有先后, 在此笔者亦希望先闻道的读者能够将您的心得发表出来, 与喜欢 VB 的读者交流。
StrConv 的作用是字串内容的转换, 其中将叁数二设定成 vbFromUnicode,作用是把「双位元」的字串转换成中文字占用 2 Bytes、英文占用 1 Bytes 的字串,所以紧接着调用 LenB, 便可以计算出中英文混合字串的长度。
如何传递不固定个数的叁数?定义副程序时, 我们必须把叁数一一列出来, 例如:
Sub MySub( P1, P2, ┅)
但如果我们将来调用副程序时, 可能会传入不固定个数的叁数, 那么副程序该如何定义呢?答案如下:
Sub MySub( ParamArray P() ) ' 把叁数 P 定义成一个阵列
如此定义副程序之后, 以下都是将来可能出现的调用叙述:
MySub "ABC" ' 只传递一个叁数
MySub 1, 3, 9, 988, 776, 234 ' 传递 6 个整数叁数
MySub 123, "abc", Date() ' 传递 3 个不同型别的叁数
以最后一个调用叙述为例, P(0) 叁数将等于 123, P(1) 叁数等于 "abc", P(2) 叁数则等于 Date() 函数的传回值, 而由于 P() 是一个阵列, 我们可以利用以下方法读取每一个叁数:
For i = 0 To UBound(P)
' P(i) 等于第 i 个叁数
Next
最后, 请注意以 ParamArray 所定义的叁数一定是 Variant(不定型) 型别, 若要判断每一个个别叁数的资料型别, 可以使用 TypeName 函数

相关阅读:
Top