ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: forrest

[原创]VBA 学习笔记--不断更新(2008.8.3)

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-11 19:07 | 显示全部楼层

二、使用API 函数或过程

    以API 函数Beep 来说明API函数的几种使用方法,Beep 函数的介绍如下:

[VBA声明]

   Public Declare Function Beep Lib "kernel32" Alias "Beep"(ByVal dwFreq As Long, ByVal dwDuration As Long) As Long

[说明]

  用于生成简单的声音

[返回值]

Long,非零表示成功,否则返回零。

[参数表]

  dwFreq------Long,声音频率(从37HZ到 32767Hz)
  dwDuration---Long,声音的持续时间,以毫秒为单位。如为-1,表示一直播放声音,直到再次调用该函数为止。

可采用以下几种方式使用API函数或过程,以BEEP为例:
(1)忽略函数返回值的调用:
       Beep 1000,5000
   注意此时函数的参数是不加括号的。

 (2)Call 方法调用:
     Call Beep(1000,5000)
    注意这里需要加上括号,便我们不取加函数的返回值。
 

  (3)取得函数返回值的调用:
     MyLng=Beep(1000,5000)
    此时需要加上括号,而且我们必须事先定义一个变量(变量的类型与函数返回值类型相同)来存储API函数的返回值。

三、声明的一些说明
(1)声明中的Lib 和 Alias 是怎么回事
   一般情况下WIN32 API 函数总是包含在WINDOWS系统自带的或是其它公司提供的动态链接库DLL中,而Declare 语句中的关键字Lib就是用来指定DLL文件路径的,这样VBA才能找到这个DLL文件,然后才能使用其中的API函数。
   如果我们只是列出DLL文件名而不指出其完整路径的话,VBA会自动到EXCEL文件所在目录、当前工作目录、windows\System目录、Windows目录下搜寻这个DLL文件。所以如果所要使用的DLL文件不在上述几个目录下的话,我们应该指明其完整路径。

   Alias用于指定API函数的别名,如果我们调用的API函数要使用字符串(参数中包含String型)的话,Alias 关键字是必须的。这是因为在ANSI和Unicode 字符集中同一API函数的名称可能不一样,为了保证不出现声明错误,所以我们使用Alias关键字指出API函数的别名。

(2)常见API参数类型的说明
    API函数的参数中最常见的是长整形数据(Long)类型,例如 API 中的句柄、一些特写的常量、函数的返回值都是比类型的值;另外几种常见的参数类型有:整形Integer,Byte型,String型

(3)声明中的ByVal是作什么用的
  这跟VBA的参数传递方式有关,在默认情况下VBA是通过传值方式传递函数的参数、而有些API函数要求必须采用地址传递(ByRef)来传递函数参数(这两种参数传递方式是不同的,前者传递的是参数真实的值,而后者要求是一个地址指针)。声明中的ByVal表明参数是传递一个值。

(4) 怎么轻松得到完整API函数声明
       VB6。0自带API文本查看器API Texi Viewer,我们可以使用它来找到API函数的完整声明,然后把它粘贴到程序就可使用。

 大家使用API有必要对它进行有一定了解,然后再去使用API文本查看器。虽然不必研究第一个API函数(如果真的知道100来个API函数的使用,相信绝对有用),但是需要我们了解一下该函数的作用。
而地API函数功能的介绍,网络也有现丰的软件供大家下载使用。

示例实验成功!!!

[此贴子已经被作者于2008-8-11 19:21:12编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-11 23:17 | 显示全部楼层

(2) API函数ShellExecute 的使用,打开网页和发送邮件。

API函数ShellExecute 的介绍:

[VBA声明]

Private Declare Function ShellExec Lib"shell32.dll" Alias "Sell32.dll" Alias "SellExecuteA" (Byval hwnd As Long,ByVal lpOperation As String,ByVal lpFile As String,ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

[别名]

 ShellExecuteA

[说明]

 查找与指定文件关联在一起的程序的文件名

[返回值]

  Long,非零表示成功,零表示失败

[参数表]

  hwnd--Long,指定一个窗口的句柄,有时候,windows程序有必要在创建自己的主窗口前显示一个消息框
  lpOperation---String,指定字串“open"来打开lpFile文档,或指定"Print"来打印它
  lpFile----String, 想用关联程序打印或打开一个程序名或文件名
  lpParameters---- String, 如 lpszFile 是可执行文件,则这个字串包含传递给执行程序的参数
  lpDirectory---String, 想使用的完整路径
  nShowCmd----Long,定义了如何显示启动程序的常数值。参考ShowWindow 函数的 nCmdShow参数

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
(ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Const SW_SHOWNORMAL As Long = 1
Private Sub CommandButton1_Click()
Unload Me
End Sub
Private Sub Label4_Click()
'启动邮件程序
ShellExecute 0, "Open", "mailto:zhoujibin123@1126.com", "", "", SW_SHOWNORMAL
Unload Me
End Sub
Private Sub Label5_Click()
'启动网络程序, 连接到Excelhome 论坛的帖子上
ShellExecute 0, "Open", _
"http://club.excelhome.net/dispbbs.asp?boardid=2&replyid=462739&id=178278&page=1&skin=0&Star=1",
"", "", SW_SHOWNORMAL
Unload Me
End Sub

虽然理解的不深,暂且先放一下。

[此贴子已经被作者于2008-8-12 18:42:33编辑过]

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-12 19:02 | 显示全部楼层

第二节   EXCEL VBA程序的保密

    Excel VBA程序的保密是个难点,大家对此都感兴趣,原因是想保护核心代码和技术以及商业的EXCEL VBA程序进行安全保障。EXCEL 对VBA 工程加密仅起简单保护作用,稍懂一点的程序员就可手工破解或使用网上的破解软件。目前唯一能保障VBA代码就一个方法,把VBA核心代码封装到动态连接库(DLL)文件中。大家可以放心动态连接库,因为它是很难被反编译的(反编译的代价比开发还大)、非常安全。下面就开始介绍如何制作和使用动态连接库DLL。

一、动态连接库DLL的制作和使用

1)用VB6 企业版下 ActiveX.dll 工具开发,在缺省类代码窗口输入下面代码:

   实用的东西比理论要复杂的多,留空待更新。继续

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-12 19:19 | 显示全部楼层

      第四章   EXCEL VBA优化及结束语

           第一节 EXCEL VBA 优化

VBA是一种宏语言,在运行速度上有很大的限制。因此VBA编程的方法直接关系到VBA程序运行的效率,本节列举了一些提高VBA程序运行效率的方法。

11个方法,11个利器,看你能用几个?

方法1: 尽量使用VBA原有的属性、方法和Worksheet函数
   由于EXCEL对象多达百多个,对象的属性、方法、事件多不胜数,对于初学者来说可能对它们不全部了解,这就产生了编程者经常编写与EXCEL对象的属性、方法相同功能的VBA代码段,而这些代码段的运行效率显然与EXCEL对象的属性、方法完成任务的速度相差甚大。例如用Range的属性 CurrentRegion来返回Range对象,该对象代表当前区。(当前区指以任意空白行及空白列的组合为边界的区域)。同样功能的VBA代码需数十行。因此编程前应尽可能多地了解EXCEL对象的属性、方法。

充分利用Worksheet 函数是提高程序运行速度的极度有效的方法。如求平均工资的例子:

    For Each c In Worksheet(1). Range("A1:A1000")
       TotalValue=TotalValue + c.Value
    Next

    AverageValue=TotalValue/Worksheet(1).Range("A1:A1000").Rows.Count

而下面代码程序比上面例子快得多:

   AverageValue=Application.WorksheetFunction.Average(Worksheets(1).Range("A1:A1000"))

其它函数如Count,Counta,countif,Match,Lookup等等,都能代替相同功能的VBA程序代码,提高程序的运行速度。

方法2:尽量减少使用对象引用,尤其在循环中
   每一个EXCEL 对象的属性、方法的调用都需要通过OLE接口的一个或多个调用,这些OLE调用都是需要时间的,减少使用对象引用能加快VBA代码的运行。例如:
  1) 使用 WITH 语句
    Workbooks(1).Sheets(1).Range("A1:A1000").Font.Name="Pay"
    Workbooks(1).Sheets(1).Range("A1:A1000").Font.FontStyle="Bold"

则以下语句比上面的快:

   With Workbooks(1).Sheets(1).Range("A1:A1000").Font
     .Name="Pay"
     .FontStyle="Bold"
     ...
   End With

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-14 06:50 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

方法2:尽量减少使用对象引用,尤其在循环中
   每一个EXCEL 对象的属性、方法的调用都需要通过OLE接口的一个或多个调用,这些OLE调用都是需要时间的,减少使用对象引用能加快VBA代码的运行。例如:
  1) 使用 WITH 语句
    Workbooks(1).Sheets(1).Range("A1:A1000").Font.Name="Pay"
    Workbooks(1).Sheets(1).Range("A1:A1000").Font.FontStyle="Bold"

则以下语句比上面的快:

   With Workbooks(1).Sheets(1).Range("A1:A1000").Font
     .Name="Pay"
     .FontStyle="Bold"
     ...
   End With

2).使用对象变量。
如果你发现一个对象引用被多次使用,则你可以将此对象用Set 设置为对象变量,以减少对对象
的访问。如:
Workbooks(1).Sheets(1).Range(″A1″).Value = 100
Workbooks(1).Sheets(1).Range(″A2″).Value = 200
则以下代码比上面的要快:
Set MySheet = Workbooks(1).Sheets(1)
MySheet.Range(″A1″).Value = 100
MySheet.Range(″A2″).Value = 200

3).在循环中要尽量减少对象的访问。
For k = 1 To 1000
Sheets(″Sheet1″).Select
Cells(k,1).Value = Cells(1,1).Value
Next k
则以下代码比上面的要快:
Set TheValue = Cells(1,1).Value
Sheets(″Sheet1″).Select
For k = 1 To 1000
Cells(k,1).Value = TheValue
Next k

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-14 06:52 | 显示全部楼层

方法3:减少对象的激活和选择
如果你的通过录制宏来学习VBA 的,则你的VBA 程序里一定充满了对象的激活和选择,例如
Workbooks(XXX).Activate、Sheets(XXX).Select、Range(XXX).Select 等,但事实上大多数情况下这些操作不
是必需的。例如
Sheets(″Sheet3″).Select
Range(″A1″).Value = 100
Range(″A2″).Value = 200
可改为:
With Sheets(″Sheet3″)
.Range(″A1″).Value = 100
.Range(″A2″).Value = 200
End With

方法4:关闭屏幕更新
如果你的VBA程序前面三条做得比较差,则关闭屏幕更新是提高VBA程序运行速度的最有效的方法,
缩短运行时间2/3 左右。关闭屏幕更新的方法:
Application.ScreenUpdate = False
请不要忘记VBA 程序运行结束时再将该值设回来:
Application.ScreenUpdate = True

方法5:变量类型确定,少用变体变量
Option Explicit 语句, 在模块级别中使用,强制显式声明模块中的所有变量。 如果模块中使用了
Option Explicit,则必须使用 Dim、Private、Public、ReDim 或 Static 语句来显式声明所有的变量。如果
使用了未声明的变量名在编译时间会出现错误。如果没有使用 Option Explicit 语句,一般所有未声明的变
量都是 Variant 类型的。
注意 使用 Option Explicit 可以避免在键入已有变量时出错,在变量的范围不是很清楚的代码中使用
该语句可以避免混乱.

方法6:关闭Excel 系统提示
'本示例关闭所有打开的工作簿。如果某个打开的工作簿有改变,Microsoft Excel 将显示询问是否保存
更改的对话框和相应提示。
Workbooks.Close
实际开发程序时,需要关闭提示信息对话框,给用户简洁高效的体验.
Application.DisplayAlerts = False '信息警告关闭
请不要忘记VBA 程序运行结束时再将该值设回来:
Application.DisplayAlerts = True '信息警告开启
关闭信息警告后, 保存文档及关闭需要先保存,在关闭
Workbooks("filename.xls").Save '文件保存
Workbooks("filename.xls").Close SaveChanges:=True
'文件关闭, 不出现是否要保存的窗口,并保存所有对此工作簿的更改。
Workbooks("BOOK1.XLS").Close SaveChanges:=False
'本示例关闭 Book1.xls,并放弃所有对此工作簿的更改。
这样可以提高程序的简洁性,给用户服务.

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-14 06:53 | 显示全部楼层

以下的代码没有测试,贴出来以供日后浏览方便.

方法7: 提高关键代码和循环代码的效率
不同方法执行效率的差异,但千万不要因为追求效率而损失了代码的可读性、清晰性。效率的优化必
须是针对关键代码的优化,对于一些在程序执行过程中,只执行很少次数的代码,没有必要牺牲可读性而
进行优化。对于代码执行效率,千万不要人云亦云,必要时候,自己动手测试一下,结果往往会出 乎
意料。
代码执行时间的测算VBA 和VB 中,没有专门的代码执行事件测算工具和方法,笔者一般是使用Timer
函数,其返回值是一个Single 类型的数值,代表从午夜开始到现在经过的秒数,此数值包括小数部分,但
精确程度在Windows NT,2000 和XP 下大概接近10 毫秒。如果要测试一段代码的执行速度,可以使用如
下方法:
Sub MeasureTime()
Dim Time1 As Single, Time2 As Single
Dim TotalTime As Single
Dim Times As Long
Dim i As Long
Times = 10000
Time1 = Timer
For i = 1 To Times Step 1
Mytest1
Next i
Time2 = Timer
TotalTime = (Time2 - Time1) * 1000
MsgBox "执行时间: " & TotalTime & " 毫秒(次数:" _
& Times & ")"
End Sub
Sub Mytest1()
Dim i As Long
Dim s As String
i = Rnd
s = Format(i, "#.00")
End Sub
过程MeasureTime 可以测试一个过程的执行速度,因为一般一个过程执行会很快,所以使 用循环,
执行n 次(第8 行设置),在第12 行调用测试的过程,通过循环前的时间(第9 行)和 循环后的时
间(第15 行),计算总共执行时间(第17 行)。使用这个方法,就可以做一些测试,看哪些方法执行效率
更高。另外,由于Windows 的多任务特定,测试时最好关闭其他无关程序,以获得较准确的测试结果。

TA的精华主题

TA的得分主题

 楼主| 发表于 2008-8-14 06:53 | 显示全部楼层
方法9 不要直呼其名
a= Worksheets(1).Name >>>>> a=Worksheets("Sheet1").name
方法10 少用RANGE 对象,可用数组取代,速度快5-10 倍,Test2 就比Test1 快。
Sub Test1()
Dim i As Long, j As Long, buf As Long
For i = 1 To 10000
For j = 1 To 100
buf = Cells(i, j)
Next j
Next i
End Sub
Sub Test2()
Dim i As Long, j As Long, buf As Long, C As Variant
C = Range("A1:CV10000")
For i = 1 To 10000
For j = 1 To 100
buf = C(i, j)
Next j
Next i
End Sub
方法11 注意函数的类型, 尽量少用Variant 变量,多用整型变量,如多用整型变量函数。
Chr$ ChrB$ Command$
CurDir$ Date$ Dir$
Error$ Format$ Hex$
Input$ InputB$ LCase$
LeftB$ LTrim$
Mid$ MidB$ Oct$
Right$ RightB$ RTrim$
Space$ Str$ String$
Time$ Trim$ UCase$
这些字符型函数 就比chr date space 等快,因为不加后缀类型指定的函数,其返回值是Variant 类型结

TA的精华主题

TA的得分主题

发表于 2008-9-16 17:29 | 显示全部楼层

非常感谢,总结的很好,辛苦了!

TA的精华主题

TA的得分主题

发表于 2008-10-12 09:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

谢谢楼主的辛苦

资料收集,认真学习中.........

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-21 23:50 , Processed in 0.044427 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表