前一段收的网易期刊里有一篇《加速VB》,我以为切实说到了大多数VB程序员的缺点,所以不嫌罗嗦,在这里先复述一遍。
在此篇里,主要的一段程序的三种写法,因为原文被我给误删掉了,我只是凭记忆写出,和原文程序有出入,但大体不错,首先是作者的朋友的:
If Form1.WindowState = vbNormal Then
MsgBox "此窗口在正常状态"
Else
If Form1.WindowState = vbMinimized Then
MsgBox "此窗口在最小化状态"
Else
If Form1.WindowState = vbMaximized Then
MsgBox "此窗口在最大化状态"
End If
End If
End If
然后是作者的朋友修改后的:
With Form1
If .WindowState = vbNormal Then
MsgBox "此窗口在正常状态"
ElseIf .WindowState = vbMinimized Then
MsgBox "此窗口在最小化状态"
ElseIf .WindowState = vbMaximized Then
MsgBox "此窗口在最大化状态"
End If
End With
然后是作者修改后的:
Select Case Form1.WindowState
Case vbNormal
MsgBox "此窗口在正常状态"
Case vbMinimized
MsgBox "此窗口在最小化状态"
Case vbMaximized
MsgBox "此窗口在最大化状态"
End If
至此,作者修改的是当然的最好的程序,以下我来简单分析一下这三段程序。
其实第一段程序和第二段程序没有本质区别,其中的 With 语句也没有起到应有的作用——比如有一属性“Form1.Picture1.Picture.Height”使用“With Form1.Picture1.Picture”有用,但是在这里没有用,VB帮助里说VB为每一个“.”付出一些分析的时间,第二段程序里使用 With 并没有减少“.”的用量,所以速度并不会加快,只是看上去比较整齐罢了。
第三段程序当然是标准的用法,事实上,遇到这种问题的首选自然是“Select Case”,这应该说是一个习惯问题,不过养成好的编程习惯至关重要。但是从很多人不使用“Select Case”来看,很有些仓促上阵的感觉,我并不是想强调编程一定要科班出身,但是对编程来说,对语言有一种整体的了解很重要,对于类或控件的用法我们大可以慢慢的查,但对于类似“Select Case”这样的语句一定在编程序前就要有充分的了解。
现在我想改写以上程序,不记得原作者是不是用的“Form1”,不过我用“Me”,简单而且移植性强,这个习惯也很好,推荐使用,好了,再说一下以上程序可以这样写:
Dim S: S = Array("正常", "最小化", "最大化")
MsgBox "此窗口在" & S(Me.WindowState) & "状态"
可能大多数人对这种写法比较陌生,甚至会有抵制思想,但是这却是一种最小的写法,速度上也不会比“Select Case”慢,因为“Select Case”可以判断字符串,还有许多同级的复杂格式(可参见“Select Case”的VB帮助),势必速度更慢,不信各位大可进行测试,如果我错了,我将会对有个VB重新认识了。
其实,不规则的写法不止一个,下面我再写一个:
Dim S As Integer: S = Me.WindowState
MsgBox "此窗口在" & Switch(S=0,"正常",S=1,"最小化",S=2,"最大化") & "状态"
为了使行短一些,我用数字而不是系统定义的变量进行测试,我在这里举例并没有什么大碍,但这不是一个好习惯,很可能在你回头升级程序时才会发现有太多的类似的地方需要修改,不过到那时就悔之晚矣!
在这里我用变量 S 取得“Me.WindowState”的值进行判断,不只是程序变短,而且速度更快,为什么是这样呢?如果大家编过“类模块”,编过“属性”的话,就会知道“属性”其实是由两个函数组成的,一个变量之于一个函数,自然“变量”的速度快了,其实我在这里是有过教训的,这就是为“VBAPI”写的搜索程序,以前我是这样写的:
sub B2_onClick()
dim i,v,n:v=trim(T2.value):n=len(v)
if n>0 then
answer.innerhtml=""
for i=0 to ubound(index)
if instr(1,index(i),v,1) then
answer.innerhtml=answer.innerhtml & _
"<a href='" & index(i) & ".htm'>" & index(i) & "</a><br>"
end if
next
else
MsgBox "请输入有效的搜索关键字"
end if
end sub
在使用中,如果所查到的项数不多,这个程序运行的也非常好,但是项数多时简直要死掉了,我让它查所有的 API 名时,不得不小睡了一觉。
然后我考虑要优化,遍查程序,我认为最吃时间的就是“answer.innerhtml”了,于是将程序改为以下:
sub B2_onClick()
answer.innerhtml="正在搜索,请稍候……"
setTimeout "B2onClick()",100
end sub
sub B2onClick()
dim i,v,n,t:t="":v=trim(T2.value):n=len(v)
if n>0 then
for i=0 to ubound(index)
if instr(1,index(i),v,1) then
t=t & "<a href='" & index(i) & ".htm'>" & index(i) & "</a><br>"
end if
next
answer.innerhtml=t
else
MsgBox "请输入有效的搜索关键字"
end if
end sub
现在大家看到了,程序最主要的变化只在于定义了一个“t”,但是却使此程序增速不止十倍!如果想体验一下这种速度差异,我的主页上有“VBAPI”,其中包括我以前写的搜索程序和修改后的。
这两天,我加入了网易社区,而后在网易的讨论版上我见到一个问题说“怎么提取完整路径名里的文件名”,如从完整路径名“c:/tools/winrar/winrar.exe”中提取“winrar.exe”,有一人回答查找最后一个“/”,这种回答是对的,不过我有更好的办法,所以也回答了一下:
Dim F As String, x
F = "c:/tools/winrar/winrar.exe"
x = split(F, "/") 'VB6 格式,和我写的“Perl2”模块参数不同
F = x(UBound(x))
而后提问题的人给我留言说我是他的救星,虽然肉麻,我也满接受的。只不过我想说一下,Split 确实很好用,但即使没有我以上的那一段程序,没有 Split 函数,也不至于一筹莫展的:
Dim F As String, t As Integer, t1 As Integer
F = "c:/tools/winrar/winrar.exe"
Do
t = t1 + 1
t1 = InStr(t, F, "/")
Loop Until t1 <= 0
F = Mid(F, t)
这一段程序也不见得比上一段复杂多少,我愿意相信各位都能编出来,也衷心希望如此,若非,则其他人笑骂 VB 程序员没水平也就不值得奇怪了!