12月19/20日 财务会计玩转Excel 300集Office 2010微视频教程
12月22/23日 7天Excel脱白 高效办公必会的Office实战技巧
11月28日 Excel图表之美 网易云课堂-Excel数据透视表应用大全
Excel数据处理与分析实战技巧第1季
查看: 14388|回复: 64

【日积月累】上11118班所学到的基础知识点

  [复制链接]
发表于 2012-5-8 18:42:36 | 显示全部楼层 |阅读模式
本帖最后由 hustnzj 于 2012-5-31 23:06 编辑

为了让大家能够更好的学习VBA基础知识,我决定每天只要一有时间就与大家分享一些知识点,主要是针对大家有疑问的,难理解的,容易忽略的,比较重要和实用的知识点,所以看起来不会很系统,大家需要跟视频和论坛上一些比较好的精华帖串起来看,效果才会更好。呵呵。


1、2012-5-8:  【几个对象的层次关系】

2、2012-5-9:  【VBE中代码存放的几个位置】、【什么叫对象,什么叫方法,什么叫属性】

3、2012-5-10:  【如何看懂属性窗口中的属性所代表的含义】、【工作表的引用】

4、2012-5-11:  【如何计算一段程序运行的时间】、【立即窗口的作用】

5、2012-5-12:  【录制宏的作用】、【哪些操作不能被录制宏?】、【哪些操作一般被认为是不能被录制为宏但又会被录制到?】

6、2012-5-13:  【工作表的常见操作】

7、2012-5-14:  【参数的位置,省略】、【IF End if】、【良好的代码输入习惯:配对语句一次性录入】

8、2012-5-15:  【用好With语句】、【设置对象变量】

9、2012-5-16:  【公式与工作表函数在VBA中的写法与使用】

10、2012-5-17:  【Excel中行高、列宽的单位分别代表多少厘米?】、【如何在VBE中调试语句】

11、2012-5-18:  【如何取得动态数据源的大小?】

12、2012-5-19:  【应用于Range对象的Find方法】

13、2012-5-20:  【最常见的人机交互】

14、2012-5-21:  【循环语句补充之一】、【数组之威力初显】

15、2012-5-22:  【循环语句补充之二】、【数组之入门:概念与静态数组的定义】

16、2012-5-23:  【数组之入门:动态数组的定义】、【Transpose的局限性】

17、2012-5-24:  暂未小结

18、2012-5-25:  暂未小结

19、2012-5-26:  暂未小结

20、2012-5-27:  暂未小结

21、2012-5-28:  暂未小结

22、2012-5-29:  暂未小结

23、2012-5-30:  暂未小结

24、2012-5-31:  暂未小结


回复

使用道具 举报

 楼主| 发表于 2012-5-8 18:44:22 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-8 22:11 编辑

2012-5-8:  【几个对象的层次关系】
       上过了第一课时,大家都知道了VBA实际上就是VB这个语言在Excel中的应用。也就是说在Excel VBA中,我们主要操作的对象就是Excel本身的对象。
        Excel中的对象非常多。不可能一一讲解。这里主要讲的是日常工作中最常使用的几个对象:
        Application:代表 Microsoft Excel 应用程序。通常都不会写出来,只要当学习代码到了一定深度,需要同时操作多个Excel应用程序时,或者在多种不同的应用程序中转换时才会明确的写出来。
        Workbook:代表Excel的工作簿。一般写作Workbooks(Index),Index可以是1,2这种具体的数字,也可以是具体的工作簿名,如Workbooks("Excelhome.xls")。需要注意的是Workbooks代表的是当前所有打开了的工作簿的一个集合。
        Worksheet:代表Excel的工作表。一般写作Worksheets(Index),Index代表的意思与上面的相似,有时也可以简写为Sheets(Index),但应该注意:Worksheets≠Sheets。Worksheets代表的是工作表的集合,而Sheets的范围就更广一些,代表了工作表Worksheets,图表Charts,宏表等等。
        Range: 代表Excel的单元格或单元格区域。通常的写法为:Range(“A1”), [A1], Cells(1,1), Cells(1,”A”)。Range(“A:B”),Range(“A1:F5”).
        以上几个对象的关系是:Application→Workbook→Worksheet→Range。一层层的范围从大到小的关系。其实这个关系很像是国家→省份→城市→街道这种层次关系。在Excel中,这个层次关系一定要弄清楚,只有这样,才能使用代码准确操纵自己想要的对象。
        比如:我们要选中当前工作簿中的Sheet1中的A1单元格,应该怎么写呢?
             ActiveWorkbook.worksheets("Sheet1").Range("A1").Select
        如果是当前工作簿,ActiveWorkbook可以省略:
             Worksheets("Sheet1").Range("A1").Select也是对的。
        如果当前活动工作表就是Sheet1,那么Worksheets("Sheet1")也可以省略:
             Range("A1").Select也是对的。
        大概是这么个规律:

   如果是在同一个Excel应用程序中,通常可以省略Application。

   如果是在同一个Excel工作簿中,通常可以省略Workbook。

   如果是在同一个Excel工作表中,通常可以省略Worksheet。

        省略Application就像大家都是中国人,自我介绍肯定不会说我是中国人。只会说我是哪个省哪个市的。
        同理,省略Workbook就像我们都来自四川,那么见面只会说你是成都的,我是宜宾的。
        省略Worksheet就像我们是一个市的,只会说我是大南街的,你是小北街的。
        呵呵。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:30:26 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-9 20:27 编辑

2012-5-9:
一、  VBE中代码存放的几个位置】
要学VBA,首先得知道VBA的编辑器VBE的一个大致构成。课时1视频也讲解了这个编程环境。这里,主要给同学们复习一下VBE中各种模块的组成,及代码放在其中的作用和注意事项。
VBA中的模块组成.jpg
工作表模块:
就是我们最常见到的Sheet,在每一个工作表中的代码,如果使用不写全整个对象的引用关系(就是我们昨天讲的那个关系),那么都是指本工作表中的引用。
[A1].select
这句代码如果放在标准模块中,等价于Activesheet.[A1].select,也就是说,不管我目前激活的是Sheet1还是Sheetn,我们都能选中该Sheet[A1]单元格。
但如果这句代码放在Sheet1工作表模块中,就等价于Sheet1.[A1].select,如果这时我激活的是Sheet1工作表还好,没有问题。但如果我激活的是Sheet2,就会出现如下错误:
错误1004.jpg
原因就是因为Sheet1并没有激活,而Sheet1.[A1].select中的Select必须要求前面的对象被激活,因此就会出现这个错误。
由于工作表模块存在这种情况,因此为了简化代码的书写和保证代码的正确,一般建议将通用性的代码放在标准模块中。
此外,工作表的事件程序代码都是放在该工作表之内(这个是VBA默认的,用户不能更改)
工作簿模块:
Thisworkbook指的就是当前代码所在的工作簿,也就是我们正在操作的这个Excel文件。Thisworkbook中的代码,也可以看做是前面省略了Thisworkbook.Activesheet。比如[A1].select,效果跟放在标准模块中是一样的。但Thisworkbook中的代码仍然应该与标准模块中的代码区分开来。
此外,工作簿的事件程序代码都是放在该工作簿之内(这个是VBA默认的,用户不能更改)
窗体模块:
VB中,窗体是必不可少的,而在VBA中,却不是这样,特别是在VBA初级阶段,用得更是很少,这里就不详细介绍了。大家只要知道窗体中也是可以存放代码的,并且如果在窗体中存放的代码,如果不把前面的对象名写全的话,那么默认也是只作用于该窗体的。
此外,窗体的事件程序代码都是放在该窗体之内(这个是VBA默认的,用户不能更改)
类模块:类模块就是用来保存用户自定义对象的模块用来创建某一个类型的,它就像一个模具,只用来更好的创建对象,使对象拥有我们方便操作的特征,并且通过这个创建的对象来调用类中封装的方法,属性。由于类模块是比较高深的内容,初级班就不用再深究了。
二、【什么叫对象,什么叫方法,什么叫属性】
这三个名词天天都在说,但有些同学可能不太清楚这三者的含义。
先看对象VB是一门面向对象的编程语言,VBA作为VBOfffice应用程序中的应用,也是一样。因此对象就是我们在VBA中碰到的一些东东了。比如工作簿对象,工作表对象,Range对象,Shape对象,Chart对象,窗体对象等等。
属性:就是这个对象的一些特性。比如Range.value表示的是Range对象的Value(值)属性,而Range.text表示的是Range对象的Text(文本显示)属性。附带讲下二者的区别:Range.value表示的是Range中的实际值。Range.text表示的是显示值。一般情况下,二者相等。但在设置了自定义格式的情况下,或者Range中放置的是公式并且在公式审核模式的情况下,二者是不同的。
方法:指的是一个对一个对象执行的动作。比如Workbooks.Add就是添加一个新的工作簿。
此外,从帮助中看可以很明确的看到:那个是对象,那个是属性,那个是方法。
对象.jpg
属性.jpg
方法.jpg
此外,按F2调出对象浏览器,可以很清楚的看到:
对象就是一个类(Class)。注意看前面的小图标(类、属性、方法都不同,也可以据此来分辨)
对象(F2).jpg
属性本身就是一个Property过程。
属性 (F2).jpg
方法本身就是一个Sub过程。
方法(F2).jpg
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:39:56 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-10 21:12 编辑

2012-5-10

一、 【如何看懂属性窗口中的属性所代表的含义】

昨天有同学问看不懂属性窗口中的英文,其实这个问题就是昨天帖子中讲的属性的问题。既然有同学提出来了,那么就我们就来看看如何利用最快捷的方法来查找属性的含义吧。
比如:我们来看Sheet工作表模块的属性窗口:
工作表属性窗口.jpg
这里面一共有12个属性。我们首先要知道,属性窗口中的属性并不是工作表对象的所有属性,这里只是很少的一部分属性。那么,放在这里的意思是指:允许用户在程序设计阶段(就是没有运行代码的时候)手动更改这些属性(怎么更改?这个自己去尝试下吧,呵呵)。
而我们只要选中任意一个属性,按F1键,就可以弹出相应的帮助文件。
属性窗口F1.jpg

而这些属性并不是工作表对象的全部属性,F2调出对象浏览器:
在搜索栏输入我们要查找的对象名称。
F2查看全部属性.jpg

在这个窗口中,选中任意一个属性,F1就可以弹出相关的帮助信息。是不是非常方便呀?呵呵。
也就是说,一个对象没有在其属性窗口中出现的属性,我们需要在代码中去设置其属性值(前提是该属性可以被设置,就是可读写),这样在代码运行时,该属性值才会被设置了。
同样,我们可以来看看工作簿对象的属性窗口:
工作簿模块的属性窗口.jpg

窗体对象的属性窗口:
窗体属性窗口.jpg

二、 【工作表的引用】
大家看了第2课视频,想必对于录制宏已经完全驾轻就熟了吧。那么我们录制出来的代码中,最多的就是Sheets, Range之类的代码了。而这两类对象在Excel中的重要性不言而喻,因此,这两类对象是我们讲解的重点。
前面我们已经知道Sheets包含了WorksheetsWorksheet才是我们要着重讲的工作表对象。
WorksheetWorkbook(工作簿)的下一级对象,在立即窗口我们运行下这个代码:
立即窗口.jpg

可以看到运行的结果是Book1.xls (xls就是工作簿的文件后缀名)Sheets(1)表示Index顺序中的第一个工作表。其parent()对象.(的)name(名字)就是工作簿了。
这里其实有一个很重要的技巧,那就是如何在立即窗口来迅速获得属性的值,或者执行对象的方法,这个大家先观察下,明天再讲,呵呵。
引用工作表的几种方法及适用场合:(注意:为了方便,以下代码都假设是在当前活动工作簿中,所以前面的工作簿对象可以省略)
1.      通过索引号Index来引用。Worksheets(Index)
Worksheets(3),表示的就是Worksheets集合中的第三个工作表,这个顺序是从左往右数的。
Worksheets(3).jpg

【适用场合】:不知道具体的工作表名。
【拓展】:
第一个工作表:Worksheets(1)
最后一个工作表:Worksheets(Worksheets.Count)
i个工作表:Worksheets(i)
2.  通过名称来引用。Worksheets(Name)Sheet1
       Worksheets(“福彩3D”),表示的就是引用工作表标签名为“福彩3D”的工作表。需要特别注意的是:Name属性是很容易就被修改的,因此在代码引用某些表的时候,建议不要使用Worksheets(Name)这种形式,除非能确保Name不会被他人随意修改。
【适用场合】:知道具体的表名,且能确保Name不会被随意改动;同时,由于Name属性可以是一个变量,因此这样用也可以增加自己代码的灵活性。
如果不能确保Name不会被改动,最保险的方法是使用CodenameSheet1这种格式):
工作表的两种名称.jpg

CodeName只有在VBE中手动更改才可以,在程序运行时是无法改动的。同时放在VBE中,也可以在一定程度上保证了不被修改。
【拓展】:
同时引用多个工作表:Sheets(Array("综合数据", "福彩3D", "双色球", "七乐彩", "排列三", "排列五", "超级大乐透", "七星彩", "体彩225")),这样引用就可以同时对多个工作表进行一些一致的操作,如delete,select了。
3.  通过当前活动工作表来引用:Activesheet
【适用场合】:在确保所有的操作都在当前工作表中来进行时。
4.  通过新建的工作表对象来引用。
    With Worksheets.Add
        .Name = "11118"
        .Tab.Color = vbYellow
    End With
这段代码就是对新建的工作表引用。
注意:Worksheets.Add返回的是一个工作表对象,所以可以这样用With语句。当然也可以这样Set sh=Worksheets.Add,然后再:
     With sh
        .Name = "11118"
        .Tab.Color = vbYellow
    End With
【适用场合】:在新建工作表时


【下集预告】:
1. 立即窗口的用处;
2. ……

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:42:28 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-12 08:01 编辑

2012-5-11:
一、    【如何计算一段程序运行的时间】

  1. Sub b()
  2.     Dim i&, t!
  3.     t = Timer         
  4.     For i = 1 To 10000000
  5.         '这个循环只是模拟一个程序运行片段,用来耗时,没有其他意义
  6.     Next i
  7.     MsgBox Timer - t
  8. End Sub
复制代码
首先我们要将当前计时器的秒数赋值给一个变量t(当然是其他名字也可以,只要是符合变量的命名规则),这样我们就得到了初始时间。
中间是程序。
最后我们用 Timer-t ,因为Timer返回的是从午夜开始到现在经过的秒数。因此现在的Timer是不是比最开始的那个Timer要大点,这样一减就可以得到我们想要的程序运行时间了。

这里给大家一个小练习:使用这种方法,为自己在练习4中的代码计算运行时间,看看有多少,然后再使用答案的代码计算时间,看看二者的差异,从而体会代码的好坏对程序运行效率的影响。可能有些同学会觉得一秒与两秒差异不大,呵呵。对一小段程序来说确实如此,不过大家以后学深了就会知道,在实际工作中,有些任务是比较繁重的,程序往往很长,那么累计下来差距也许就是1分钟,2分钟甚至10分钟的时间了,对于一般的结果,相信没有人愿意等待10分钟以上的时间(特别是你的领导),呵呵。

二、 【立即窗口的作用】
1.       调出立即窗口: Ctrl + G
2.       立即窗口主要是用来调试代码的,有时也会用来手动更改某些Excel的设置选项。
3.       几种用法:
1)  ? 变量或表达式  (要运行要按下回车)
在立即窗口中,?变量或表达式  这种写法是显示这个变量或表达式的值。这一点在程序调试过程中是非常有用的,比如入下图,就可以知道程序运行时, Ubound(CaptionArray)的值是1,Ubound的含义我们在练习4的小结中讲过,这里就不多说了,呵呵。
立即窗口的?用法.jpg

       但是要注意的是,?只能显示单个值,不能一次性显示多个值(比如数组中的所有值),下图中的CaptionArray是一个数组。关于数组,大家暂时不明白也没关系,这里只要知道立即窗口的用法就好了。
       立即窗口的?用法(错误用法).jpg

2) 一个语句  (直接回车)
比如我们要设置当前Excel工作簿的某些功能选项属性,而这些功能选项属性在普通的Excel用户界面查找起来不方便,那么我们可以在立即窗口来快速设置这些属性:
比如我们要在当前的Excel工作簿中禁止自动重算,那么我们可以在立即窗口输入:
立即窗口的设置Excel功能选项.jpg

在输入这个语句时,大家应该可以发现,在立即窗口中输入代码与在代码窗口中输入代码一样,都会自动弹出属性列表。

3) 与Debug.print 语句联用
Debug.print是什么意思?学过VB的同学都知道与VB中的Print方法很类似。就是显示Debug.print 后面的变量值到立即窗口。
这个用法非常有用,因为它能够让你在程序运行时,将自己要监控的某些地方的变量值打印到立即窗口中,这样就不用人工一个一个使用 ?变量或表达式 的方法去检查了。
立即窗口的Debug.print的用法.jpg

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:45:34 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-20 08:16 编辑

2012-5-12 (为了今天的小结,我可是费了老劲了,一个个菜单命令的测试,希望同学们能有所获,呵呵)

   一、【录制宏的作用】
录制宏,是我们在学习VBA的道路上必须品尝的一道菜。EH的版主说过:“学会了录制宏VBA就等于会了一半”,由此可见录制宏的作用。通过视频2叶枫老师的生动讲解,大家对于如何录制宏,如何执行宏,如何根据录制的宏来插入到循环中,相比都有了一个清楚的认识。


然而,我们录制了宏,并不代表我们一定要使用这些录制产生的代码。因为录制产生的代码有引用关系不灵活,代码冗繁,某些操作不能被录制的缺点。我们之所以要学会录制宏,在于:“关键词”。


按我的理解和经验,录制宏,就是为了获取关键词,如果说F1帮助是一本大字典的话,那么录制宏就是快速获得到达这本字典中特定内容的“关键词”,很多时候,只需要一个关键词,配合对象浏览器(F2),我们就能顺藤摸瓜,找到自己想要的知识点。甚至还可以得到一些例子。




二、【哪些操作不能被录制宏?】(以下大部分是在03下测试)

1.  过多字符的公式(经03版本测试,为252字符及以上;10版本测试为892字符及以上)。
公式字符过多(252个以上)不能录制.jpg
【解决方法】:录制一部分公式到代码中,再录制剩余部分的公式到代码中,然后把二者拼起来即可。


2.  07版本的Excel在录制插入图片,形状,SmartArt,文本框,艺术字时,都不会录制到任何代码。但0310的都可以。


3.  没有产生Excel应用程序中某个属性值改变的情况:如弹出“打开”对话框,进入VBE编辑器,弹出下拉列表,弹出“查找”,“替换”,“定位”对话框。


4.  某些特殊情况:文件搜索命令,修改文档属性,“显示到文本与语音工具栏”按钮,保护/去除工作表或工作簿的密码。


5.  VBE编辑器中的所有动作都不能被录制。
6.  在03,07中照相机功能都不能录制宏,在10中是可以,但得出的代码ActiveSheet.Shapes.AddShape(, 654#, 51.75, 72#, 72#).Select这句就不能正常运行下去。


三、【哪些操作一般被认为是不能被录制为宏但又会被录制到?】(以下是在03下测试)
1. 设置工作簿共享。(这里有一个技巧,那就是在录制宏时的代码保存位置上选择“新工作簿”)
录制宏选择位置的技巧.jpg


2. 撤销命令:反映到代码中就是录制的代码消失呀,哈哈。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:46:35 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-13 17:51 编辑

2012-5-13

一、 【工作表的常见操作】
工作表的操作,其实就是指工作表的方法。F2调出对象浏览器:
工作表的方法.jpg
1.  Add 新建工作表。
expression.Add(Before, After, Count, Type)
如何来理解Add后面的四个参数呢?我们来看几个例子:
1) Before:在第一个表前面添加新表:
  1. Private Sub CommandButton3_Click()
  2.     Worksheets.Add Before:=Worksheets(1)   '在第一个表前面添加新表
  3.     Sheet1.Select
  4. End Sub
复制代码
2)After: 在最后一个表后面添加新表:
  1. Private Sub CommandButton2_Click()
  2.     Worksheets.Add After:=Worksheets(Worksheets.Count)    '在最后一个表后面添加新表
  3.     Sheet1.Select
  4. End Sub
复制代码
3) Type:在Add工作表后面添加一个图表工作表:
  1. Private Sub CommandButton4_Click()
  2.     Sheets.Add , Worksheets("Add"), , xlChart    '在Add工作表后面添加一个图表工作表
  3. End Sub
复制代码
4) Count:按单元格中的内容批量新建工作表并批量重命名:
  1. Private Sub CommandButton1_Click()    '按单元格中的内容批量新建工作表并批量重命名
  2.     初始表数 = Worksheets.Count
  3.     A列最后一行行号 = Cells(Rows.Count, 1).End(3).Row
  4.     Worksheets.Add , Worksheets(初始表数), A列最后一行行号 - 1
  5.     For i = 2 To A列最后一行行号
  6.         Worksheets(初始表数 + i - 1).Name = Cells(i, 1).Value
  7.     Next i
  8.     Sheet1.Select
  9. End Sub
复制代码

2.  删除多余的工作表:

  1. Private Sub CommandButton6_Click()
  2. Application.DisplayAlerts = False
  3.     For i = Sheets.Count To 1 Step -1
  4.         If Not Sheets(i).CodeName Like "Sheet[1-4]" Then Sheets(i).Delete    '如果工作表的CodeName不是Sheet1-Sheet4,那么该工作表被删除
  5.     Next i
  6.     Application.DisplayAlerts = True
  7. End Sub
复制代码

由于时间关系,今天先讲Add和Delete,明天继续。

附件:

5-13.rar

17.57 KB, 下载次数: 50

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:48:45 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-15 08:57 编辑

2012-5-14

一、 【参数的位置,省略】
1 参数的省略:
前面我们讲了工作表的插入:
Private Sub CommandButton4_Click()
    Sheets.Add , Worksheets("Add"), , xlChart    'Add工作表后面添加一个图表工作表
End Sub
细心的班长在这个代码中发现了有些参数被省略了。对比这个格式expression.Add(Before, After, Count, Type),可以发现省略掉的是BeforeCount参数。
那么,什么时候参数可以省略,什么时候又不能省略?
F1帮助中,可以看到只要是“可选”参数,那么就可以省略。
可以省略的参数.jpg
2 参数的位置:
Private Sub CommandButton2_Click()
    Worksheets.Add After:=Worksheets(Worksheets.Count)    '在最后一个表后面添加新表
    Sheet1.Select
End Sub
这个例子中只有一个参数After,但其位置与格式expression.Add(Before, After, Count, Type)中的不一致,那么什么时候参数的位置必须与定义的一致,什么时候又可以不一致呢?
当参数的名称被明确的写出来时,位置就无所谓了。但如果没有参数的名称,那么必须按照位置去一一对应,如本例,如果不写明参数的名称,那么就应该写为:
Private Sub CommandButton2_Click()
    Worksheets.Add , Worksheets(Worksheets.Count)   '在最后一个表后面添加新表
    Sheet1.Select
End Sub
必须要使用一个逗号去给After参数前面的Before参数占位。
因此,当某个方法的参数比较多,其位置比较难于记忆的时候,我们就可以明确参数名称,简化记忆。同时,由于明确写出参数名称,也有利于明白此参数的角色与作用,否则时间一长,即使是自己写的代码,光靠位置去判断的话也是比较费劲的。

二、  IF End if
VB中,IF End if是使用最多的逻辑判断语句,其语法也非常简单,这里我们就不说了。只是提一下 IF End if的几种结构写法。
1) 不同行写法:
IF 逻辑判断  Then
  执行语句
  End if
2) 同行写法:
IF 逻辑判断 Then 执行语句(只要是一句话,或者多句话使用:来连接)
{后面没有End if}
需要注意的是:二者的作用在大多数情况下都相同。但在实际工作中,如果执行语句有多个,那么使用“不同行写法”会显得更有层次感,思路更清晰,也更易阅读。


三、 【良好的代码输入习惯:配对语句一次性录入】
所谓配对语句,是指像IF……End if For……Next, For each……NextDo……LoopSet d=Createobject(“scripting.dictionary”)……Set d=nothing等等。
比如我们输入IF……Then后,马上按几下回车,然后输入End If,这样不仅能避免漏输入造成以后不必要的麻烦,同时,结构非常清晰,让我们在写代码时就知道自己的目的,层次和节奏,呵呵。

回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:49:28 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-17 22:59 编辑

2012-5-15  (都怪自己没有规划好,结果两个班级的作业小结堆在一起了,这两天累啊,自找的……呵呵)
断了两天,班级里同学就开始问了,呵呵,自己写的东东有人看,感觉挺好,所以当然要继续写下去了。

一、 【用好With语句】

在课时3的视频中,我们可以发现,当我们要对同一个对象进行多个属性的设置,或者是执行它的多个方法时,应该是用With……End With这种结构。

为什么要这样呢?原因是在VBA中每一个.都代表一个层级,那么层级越多,代码解析的时间也就越多。比如Workbooks(1).Sheets(1).Range(“A1”).value就是4个层级。如果我要对Workbooks(1).Sheets(1).Range(“A1”)进行其他的设置,也这么写的话,显然是多余的。随便录制一个设置格式的宏:
With Selection.Interior
        .ColorIndex = 36
        .Pattern = xlGray16
        .PatternColorIndex = xlAutomatic
End With
就可以得到我们想要的结构。可以看出:With语句的作用就是在一个对象上执行一系列语句。通常如果对一个对象的操作超过两次,我们就应该使用With语句去减少对象的引用次数,从而达到提高程序运行效率的目的,而且在写法上也更精简了。
有时,在稍长的代码中,我们可能会遇到With语句嵌套的情况。比如:

With Worksheets.Add(Worksheets(1))      
        .Tab.ColorIndex = 28
        .Name = "ABC"
        With .[A1]
            .Value = "ABC"
            With .Font
                .Size = 16
                .Color = RGB(218, 78, 111)
            End With
        End With
        With ActiveWindow
            .Zoom = 150
            .SplitRow = 1
            .FreezePanes = True
        End With   

End With

就是一层层套的问题了,其实大家只要养成好习惯:写了With后面再马上写End With,层次感就出来了,呵呵。



二、    【设置对象变量】
其实很简单,因为有同学问过,自己以前也是看了帮助好久才看明白,所以还是提出来吧。
Set 变量 =  对象 ,就是把一个对象赋值给变量,相当于建立二者之间的引用关系。
如果不用Set,那么就是把一个非对象值赋给变量。如果是对象赋值给变量,不用Set,如下的话:
就会出现如下错误:
对象变量.jpg

比较常见的设置对象变量的写法:

Dim MyObject As Object    ' 创建对象变量。
Set MyObject = Sheets(1)    ' 创建一个正确的对象引用。


Dim wb as Workbook
Set wb=workbooks.add


Dim d as object
Set d=CreateObject(“Scripting.Dictionary”)


回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-5-8 20:50:16 | 显示全部楼层
本帖最后由 hustnzj 于 2012-5-18 18:46 编辑

2012-5-16 (终于要翻页了,今天讲的内容我觉得是比较实用的,希望大家能有更多的体会,呵呵)

【公式与工作表函数在VBA中的写法与使用】

1) 输入普通公式:
例子1
录制法:ActiveCell.FormulaR1C1 = "=R[-1]C[-2]*R[-1]C[-1]
可以看到,录制的公式是以R1C1样式来表示的,看起来不是很符合我们的日常习惯的A1样式。
实际上,可以在VBE中直接输入公式,写法如下:
[C1] = "=A1 * B1"

例子2
单元格中的公式为:=TRIM(SUBSTITUTE(SUBSTITUTE(B2,LEFT(B2,FIND(".",B2)),),"?",))
录制法:
Range("D2").Select
    ActiveCell.FormulaR1C1 = _
        "=TRIM(SUBSTITUTE(SUBSTITUTE(RC[-2],LEFT(RC[-2],FIND(""."",RC[-2])),),""?"",))"
输入法:
Range("D2") = "=TRIM(SUBSTITUTE(SUBSTITUTE(B2,LEFT(B2,FIND(""."",B2)),),""?"",))"

可以看到,与单元格中的公式只有两点不同:
a. 公式的两端要加上单引号表示返回到单元格中的是一个字符串。
b. 公式中原有的单引号必须变成双引号(相当于告诉VBA我这个是真正的引号,而不是文本字符串的边界),其他的与单元格中的公式完全相同。


2) 输入数组公式:
例子3
单元格中的数组公式为:=INDEX(A:A,SMALL(IF(A$5:A$99<>"",ROW($5:$99),4^8),ROW(1:1)))&""
录制法:
[I5].FormulaArray = _
        "=INDEX(C[-8],SMALL(IF(R5C[-8]:R99C[-8]<>"""",ROW(R5:R99),4^8),ROW(R[-4])))&"""""
输入法:
[I5].FormulaArray = _
        "=INDEX(A:A,SMALL(IF(A$5:A$99<>"""",ROW($5:$99),4^8),ROW(1:1)))&"""""

可以看到FormulaArray这个属性就是设置单元格或区域的数组公式,相当于我们在工作表中按下经典三键 Ctrl + Shift + Enter。
帮助中说:如果用本属性输入数组公式,那么该公式必须使用 R1C1 引用样式,而不能使用 A1 引用样式。我们这里就证明了帮助有时候也有错。呵呵。

3) 快速复制(填充)公式:
录制的代码如下:
Selection.AutoFill Destination:=Range("I5:I37"), Type:=xlFillDefault
这里就是利用了Range对象的AutoFill 方法对指定区域中的单元格进行自动填充。由于填充方式为默认的xlFillDefault,那么就将以数据源来自动判断填充方式,当然我们这里是公式,就会填充公式了。
抽象一下就是这样:sourceRange.AutoFill Destination:=fillRange
实际上,我们只要确定fillRange就可以了。确定fillRange的方法可是有很多呀,哈哈。

4) 只对某区域的公式进行计算。
有时候,我们的表格中可能有很多的公式,但我们可能只需要计算某一部分就可以了,因此,我们可以这样写:
Worksheets("Sheet1").UsedRange.Columns("A:C").Calculate。
这样就只计算 Sheet1 已用区域中 A 列、B 列和 C 列的公式。计算少了,效率自然提高。

5) 将公式结果转换为值,大幅度提高运行速度。

大约有三种方法:
a. [D1] = Evaluate("SUM(A1,B1)"),使用 Evaluate 的优点在于参数是字符串,这样既可以在代码中构造该字符串,也可以使用变量。比如:
For i = 1 To Cells(Rows.Count, 1).End(3).Row
        Cells(i, 4) = Evaluate("=SUM(A" & i & ",B" & i & ")")
Next i

b.  [D1] = [SUM(A1,B1)], 使用[]的优点在于代码较短,但不能使用变量。比如:
For i = 1 To Cells(Rows.Count, 1).End(3).Row
        Cells(i, 4) = ["SUM(A" & i & ",B" & i & ")"]
    Next i
运行后,全是#NAME?错误。

c.  使用Range.value=Range.value,这样写非常方便省事。比如,我们要将[A1:A10]这个区域中的公式转为数值,就可以直接写为[A1:A10].value=[A1:A10].value.

6) 改变工作簿计算方式,提高效率。
当我们的工作簿中的公式比较多时,在不影响最终结果的情况下,我们可以先使用
Application.Calculation = xlCalculationManual来变为“手动重算工作簿中的公式”,然后在运行完程序后,再Application.Calculation =xlCalculationAutomatic恢复正常,这点在易失性函数比较多的情况下非常有用。

7) 在VBA代码中借用工作表函数。
注意是借用,而不是在单元格中直接输入公式,这点与上面几点都很不一样。比如,我们要计算[A1:A10]中的最大值,因为VBA函数中没有Max这个函数,所以我们可以直接借用工作表函数Max。写法为:Application.Max ([A1:A10])或者是WorksheetFunction.Max ([A1:A10])。
有时,在VBA代码中熟练穿插借用工作表函数,会使代码显得更简洁,思路更清晰。在某些情况下,会比自己写的循环代码更加高效,当然这个要测试比较了。呵呵。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 入学

本版积分规则

关闭

站长推荐上一条 /2 下一条

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