ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2019函数公式学习大典 不用妈妈陪默写神器 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
你的Excel 2016实战技巧学习锦囊 WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 97019|回复: 158

[原创] 管中窥豹 VBA学习的扩展方法--新人进阶必读

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2009-6-30 16:45 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:开发帮助和教程
观此文者必是先能熟练使用互联网搜索引擎,对象浏览器,本地窗口,注册表等基本技能者。
就像吃饭必须认得什么是碗,哪个是锅,什么时候用筷子,什么时候该用汤勺。

  管中窥豹有两种截然不同的理解:一种是褒义的,意谓人们可以从观察到的事物的一部分来推测该事物的全貌。从字面上理解“管中窥豹”,那就是从“竹管”中透过视线来看到豹子,由于视线受到“竹管”圆孔面积的限制,而无法看到“全豹”,只能看到豹子身上极具豹子特征的斑点花纹,于是就此推论这就是一只豹子。这种思路是极具智慧的。
“由一斑而见全豹”,“由一粒沙子看到世界”,“由一滴水了解大海”,这些话常常被用来赞颂那些以小见大,通过小事情了解大道理的聪明人。

一种是贬义的:从竹管的小孔中看豹,只看到豹身上的一块斑纹。比喻只看到事物的一部分。有时可以和略见一斑连用,比喻比喻只看到事物的一部分,指所见不全面或略有所得。
这里指的是前者。

观察到论坛上很多人是从VBA开始学编程的,大致步骤是这样的,了解一些VBA(VB)的语法、对象,深层次一点的就研究API。
相对于VBA来说API近乎天书,学起来就一个字 “真TMD苦”,往往为了实现一个小目标,要写几乎一篇作文一样的代码。
对于快速实现目的来说,在VBA 到 API之间还有一个中间过程被大家忽略了,就是对于Windows提供的一些对象的使用。
有非常多的API实现的方法,可以通过引用对象的方式来简单的实现。

windows中有很多dll、ocx等系统文件,相当多的部分是可以被VBA借用的,但目前还没发现哪一本书是介绍这些文件及对象的使用方法的。
想要通过这些文件去了解用法,不现实,因为有些用不上,有些VBA根本无法引用。

但是碰到了就不能错过,学习过程中经常能看到
Set obj = CreateObject("aaa.bbb")
obj.xxxx
obj.yyyy = zzzz
类似这样的代码,大部分人都是直接复制使用,所知者仅限于xxxx方法和yyyy属性,下次看到 obj.cccc 于是惊呼 “太感谢了,原来obj还有cccc这个方法。”
但善于学习者从看到Set obj = CreateObject("aaa.bbb") 时就会想方设法去了解这个obj对象的所有内容,
于是他不仅知道有cccc方法,还知道obj的所有方法和属性。
他还会把这个后期绑定的代码改写为前期绑定的代码,以提高效率,并扩展出其他VBA自身不能实现的方法。

来吧,成为一个善于学习的人吧,自己端碗拿筷子吃饭。

看个实例,如何做到 “窥一斑而知全豹”
sub 设置默认打印机()
Set obj = CreateObject("WScript.Network")
obj.SetDefaultPrinter "Epson Stylus COLOR 680" '这个打印机名称请根据自己控制面板中打印机名称修改
end sub
1.JPG

按F8单步运行在本地窗口可以看到 obj 对象的类型是 Variant/Object/IWshNetwork2
现在知道obj.SetDefaultPrinter 方法,如果还想了解其他方法,在obj后面打个“.”,并不会出现代码提示框,
因为这是后期绑定,编译器不能告诉你还有什么东西可用。
要想前期绑定这个对象,就必须知道它存在于哪个文件中,这样才能进行引用,这要通过注册表进行搜索实现。
(也可以编写代码用API函数 从 WScript.Network 字符串得到,这不是本文所要讲的,略过)

开始--》运行 输入 regedit 后确认,在注册表编辑器中选中 我的电脑,按ctrl+F 打开搜索框 输入 WScript.Network勾选数据后查找,
2.JPG
3.JPG

十几秒后,找到了在 HKEY_CLASSES_ROOT\CLSID\{093FF999-1EA0-4079-9525-9614C3504B74}\ProgID 看到默认值为 WScript.Network.1
看看 HKEY_CLASSES_ROOT\CLSID\{093FF999-1EA0-4079-9525-9614C3504B74} 项下的两个值

主项默认值:Windows Script Host Network Object 这个是引用窗口中将看到的名称。

InProcServer32 下的默认值 :C:\WINDOWS\system32\wshom.ocx 这是所在的系统文件


有这两个内容就可以进行引用了。VBE菜单栏 工具 --》引用 打开引用窗口,但却找不到 Windows Script Host Network Object
4.JPG
这是因为VBE只默认加载dll文件,对于ocx需要通过浏览方式来指定。点击浏览按钮,默认打开C:\WINDOWS\system32\  文件夹
找到wshom.ocx 文件 点击打开,这下引用窗口中多了一个 Windows Script Host Object Model 选择,勾上它确定,这个名称与在注册表中看到的有些不同,
个人理解:
这是VBA的VBE干的,很多一样的引用在不同的编程工具中所反映出来的名称都会有差异,
最典型的就是IE浏览器对象(WebBrowser控件)在VBA中 显示 Microsoft Web 浏览器
而在VB 6.0 中显示 Microsoft Internet Controls,但这仅仅是显示的文字而已,里面的东西还是一致的。

现在引用成功了,再来编写一个前期绑定的代码,用New关键字来创建对象,但具体使用那个具体的类名称还不确定,需要通过对象浏览器来查找。
找什么?就找SetDefaultPrinter方法,按F2 在所有库 下面输入 SetDefaultPrinter 回车
5.JPG


看图,  “ IWshRuntimeLibrary.WshNetwork 的成员”  
刚才所引用的是IWshRuntimeLibrary类型库
而 obj是 IWshRuntimeLibrary库中的WshNetwork类
SetDefaultPrinter则是WshNetwork类的一个方法。
在对象浏览器中可以看到多个关于打印机的方法,如果认的几个英文,这些方法就相当于大白话。
EnumPrinterConnections 枚举打印机连接
SetDefaultPrinter 设置默认打印机
RemovePrinterConnection 删除打印机
.........
不认的也不要紧,复制了上网找Google翻译去。
输入 Dim obj As New  后会自动弹出代码提示框(New后面有个空格),这下知道该如何“选”代码了
Sub 设置默认打印机前期绑定()
    Dim obj As New WshNetwork
    Dim ptrs As WshCollection
    Set prts = obj.EnumPrinterConnections
    For Each n In prts
Debug.Print n
    Next
    obj.SetDefaultPrinter "Epson Stylus COLOR 680"
End Sub

当你研究完WshNetwork类的各种方法属性后,先别急,既然IWshRuntimeLibrary叫做类型库,那就不止一个类
接着输入 Dim tmp As New IWshRuntimeLibrary.  代码提示框又来了,你会看到7个类供你选择,有些你可能觉得熟悉,因为其他的库也有这些类。

6.JPG
还有些陌生的类,搜索吧,尽可能多的了解它们是干什么的........

你很快就会成为“牛人”的。

点评

很好的进阶入门指引  发表于 2013-9-25 09:57

评分

4

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-6-30 17:02 | 显示全部楼层
ldy版这个贴的作用可以直追山版发的数组入门贴了

搜索注册表,学会了,哈哈,以后找起来就方便多了

TA的精华主题

TA的得分主题

发表于 2009-6-30 17:10 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-6-30 18:02 | 显示全部楼层
好久不见LDY版主的作品了,一出来就是一鸣惊人!
狠狠的学习!

顺便将老朽在引用外部对象时,觉察到的 前期绑定与后期套用之间的差别 一并贴上,希望对大家有所帮助。
记得在使用字典对象时,由于是后期套用,直接使用Set Dic = CreateObject("scripting.dictionary"),而没有在工程引用中相应的对象,以致于在使用 Dic.CompareMode = TextCompare 时失去作用,而Dic.CompareMode = 1 就能达到要求,原来是后期套用对象并没有将对象的保留字TextCompare 一并带出来,TextCompare 自然就为空,如果是前期引用,TextCompare 就是1。
所以,老朽愚见,如果你希望引用其它对象时,请尽量使用前期绑定,这对我们调试代码特别有帮助!

TA的精华主题

TA的得分主题

发表于 2009-6-30 18:40 | 显示全部楼层

举例说明:
先不进行前期绑定,运行前面两段代码,记录结果,然后再进行前期绑定,运行最后一段代码,与前面两段代码运行的结果对照,就明白了。
Option Explicit


      '撰写:老朽
      '网址:http://Club.ExcelHome.net
      '日期:2009-6-30 下午 06:35:12

Sub Test0()    '后期套用,引用对象保留字
'不经绑定,后期套用,不需要前述引用,照样可以使用这个对象
    Dim Dic,I&
    Set
Dic = CreateObject("scripting.dictionary")
    Dic.CompareMode = TextCompare    '如果使用了Option Explicit语句,这时系统会提示TextCompare为未定义变量
    For
I = 65 To 122
        Dic(Chr(I)) = ""
    Next

    MsgBox Dic.Count    '如果没有Option Explicit语句,强制要求声明变量,则返回58
End Sub


      '撰写:老朽
      '网址:http://Club.ExcelHome.net
      '日期:2009-6-30 下午 06:35:13

Sub Test1()    '后期套用,用常数代替对象保留字
'不经绑定,后期套用,不需要前述引用,照样可以使用这个对象
    Dim Dic,I&
    Set
Dic = CreateObject("scripting.dictionary")
    Dic.CompareMode = 1    '这时候,我们只有通过使用常数1来代替TextCompare,即Dic.CompareMode = 1
    For
I = 65 To 122
        Dic(Chr(I)) = ""
    Next

    MsgBox Dic.Count    '返回32
End Sub


      '撰写:老朽
      '网址:http://Club.ExcelHome.net
      '日期:2009-6-30 下午 06:35:13

Sub Test2()    '前期绑定
'VBE窗口,工具->引用->勾选 Microsoft Scripring Runtime
    Dim Dic As New Dictionary,I&
    Set
Dic = New Dictionary
    '我们希望在进行字典比较时,采用文本方式比较,不区分大小写,即a,A是当相同字符处理

    Dic.CompareMode = TextCompare    '这时TextCompare=1
   
For I = 65 To 122
        Dic(Chr(I)) = ""
    Next

    MsgBox Dic.Count    '返回32
End Sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2009-6-30 19:32 | 显示全部楼层
原帖由 zldccmx 于 2009-6-30 18:02 发表
好久不见LDY版主的作品了,一出来就是一鸣惊人!
狠狠的学习!

顺便将老朽在引用外部对象时,觉察到的 前期绑定与后期套用之间的差别 一并贴上,希望对大家有所帮助。
记得在使用字典对象时,由于是后期套用,直接 ...


确实如此
我也喜欢前期引用,一则方便输入,二则方便调试
假如给别人用就再改后期引用

TA的精华主题

TA的得分主题

发表于 2009-6-30 20:41 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-6-30 21:07 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-6-30 22:17 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2009-7-24 23:06 | 显示全部楼层
非常不错的学习方法,谢谢分享
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-3-19 17:25 , Processed in 0.053891 second(s), 11 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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