正文

Excel VBA - VFP2009-02-11 13:09:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/mozo/40826.html

分享到:

 闻得有人问起我如何把VBA参数的格式改成VFP参数的格式,这是因为很多人,都是从录制宏的直观代码,直接复制过去使用而出现的问题。  其实只要明白了什么是对象,这些问题便能迎刃而解。  几年前,我只守着QB裹足不前,秋水再三建议我去学VB,我却对自己全无信心,我总觉得,到了这个时候,我怎么还有能力学得好那么庞大的VB呢?那么多的控件、对象、属性、方法,一眼看上去密密麻麻,我已经畏缩退后了。  可真正用起来后,很多东西便慢慢积累下来了,微软做的东西确实是有它的系统性,现在回过头来看,却是一点也不难。我现在不敢说懂,只是略知皮毛,而且仅仅是知道一点Excel VBA的使用,再后来在VFP这里浮沉了一两年的事情,大家都看见了。  我之前也常有讨论怎样优化调用EXCEL VBA的办法,但现在记忆力猛降,再也找不着了,也就只好重新整理一下。而现在说的,也只是自己的一点经验看法,肯定会有不少错漏,也请老师们指正。  Excel Visual Basic Application提供了一个很方便的使用EXCEL的接口,更方便的是我们还可以通过录制宏来学习它的代码,但简单的复制代码是不妥的,因为电脑的自动录制仅仅是机械动作,在使用过程中,需要简化那些繁杂的代码,否则,效率将会很低,速度上不去。我以前在阅读录制宏时,便不断的查看帮助文件,去了解对象属性方法的具体参数,然后尝试使代码更简明,避免一些不必要的操作,所以说,帮助文档的内容是最重要的。然后了解VBA中语法与VFP的语法之间的差异,也是必不可少的。我自己也是从录制宏走过来的,就回忆一下走过的路,也许对初接触的人有点启发吧。    对于学习EXCEL,也有一个好网站http://www.excelhome.net/  1.对象   只要明白了各种对象,知道想要使用的对象的名称和引用方法,就能方便准确的调用。还要尝试不同方法引用的区别。在对某一个对象的多项操作,最好就是尽量使用with语句,可以减少了很多对对象引用的查找时间,特别是外部语言调用EXCEL对象的时候。如果每个环节都耗费了多余的操作时间,就会大大的拖慢程序的运行速度了。有时候,编辑器会有自动提示对象的属性或方法,这对于我们在编写代码过程中是很方便的,但在使用with的时候就没有那么便利了,这个时候,其实我们可以先直接书写,写好后再回过头来进行with改写,以最大程度的避免书写错误。   在EXCEL VBA里,有很多对象的默认简写办法,例如 range( ),ActiveSheet 等对象,都暗指当前活动对象,但在VFP里调用的时候,VFP是不认这些对象名的,不知道这些对象是哪里来的,这个时候必须要指定对象的来源和位置。      比如你已经定义了 Excel=CreateObject("Excel.Application"),      就必须注明前缀 Excel.ActiveSheet.Range("A1")。   如果某个对象经常要用到,写一大堆长长的对象引用名称也是很痛苦的,这个时候,就要使用变量,把某个对象赋值到变量去,利用变量来进行对象操作,这不仅仅是方便书写,在程序运行过程中也能加快编译速度的。(VB里变量赋值引用要加Set关键字,在VFP里,直接使用等号就可以了。)   例如: T1=Excel.Workbooks(1).Sheets(1).Range("A1"),之后就直接使用 T1 来进行单元格操作就可以了。同时EXCEL里也有一个默认的变量 Selection ,但这个变量需要有一个 .Select 操作,如无必要,我倒是觉得这种操作可免则免,因为它也是需要耗费时间的,类似的还有.Activate等等。例如一个复制的操作宏录制如下:  Sheets("Sheet3").Select    Range("A2:D10").Select    Selection.Copy    Range("E15").Select    ActiveSheet.Paste    Range("E15").Select我们可以省略交互操作部份,直接使用对象的复制方法  With Sheets("Sheet3")    .Range("A2:D10").Copy    .Range("E15").Select  '因为粘贴不能针对某个单元格,所以这一个选择必不可少。  .Paste    EndWith   在对单个单元格操作的时候,还有在对某区域的单元格循环的时候,建议使用cells( )而不是range( ),因为在range( )的寻址过程中还需要对单元格的地址名称进行计算查找,虽然差别是微乎其微的,但能省则省,差之毫厘,谬之千里用在这里是很贴切的。但在对某个范围区域,或者复合单元格操作的时候,当然就是使用range( )来得方便了,这也是EXCEL最为卓越的一个优点。 例如:Selection=XLApp.Range(XLApp.Cells(3,15),XLApp.Cells(3,16),XLApp.Cells(5,16))    这个对象直接拿Range("O3:P3,P5")来使用就简单明了方便快捷了。  2.方法   在VBA里有SUB过程,甚至可以当作命令使用,在VBA的格式里,后面的参数不需要加括号,只在Call调用的时候才需要加上括号。但在VFP中,只有函数没有过程,过程也是当作一种函数来使用的,必须把函数名后面的参数添加括号。      例如在VBA中的代码: Sheets.Add after:=sheets(2)      := 是EXCEL VBA里的指定参数名操作符,表示after这个参数值,放进VFP的时候需要了解add方法的参数表,而且要把参数用括号括起来。  Excel.Workbooks(1).Sheets.Add(,Excel.Workbooks(1).Sheets(Excel.Workbooks(1).Sheets.count))      表示在已有工作表的末尾添加一个新表。可以看见这一句代码里有很多相同的对象,最好是使用变量来简化引用:        T1=Excel.Workbooks(1)                T1.Sheets.add(,T1.Sheets(T1.Sheets.count))    3.属性       EXCEL的页面设置因为要处理大量的页面数据,所以会耗费更多的时间,如果条件允许,最好是事前先设置好模板,或先设置好格式,再写入数据。比如在页面设置的录制宏得以下代码:    Range("A2").Select    With ActiveSheet.PageSetup        .LeftMargin = Application.InchesToPoints()        .RightMargin = Application.InchesToPoints()        .TopMargin = Application.InchesToPoints(0.82)        .BottomMargin = Application.InchesToPoints()        .HeaderMargin = Application.InchesToPoints()        .FooterMargin = Application.InchesToPoints()        .Zoom = False        .FitToPagesWide = 1        .FitToPagesTall = 1        .PrintErrors = -17256    End With其实我只设置了页面的上边距仅仅一个动作而已,而录制宏为了顾全大局,把所有的可能都记录下来了,这一大段代码,我们只需要改成一句就可以了:   ActiveSheet.PageSetup.TopMargin=59.04我是怎么知道59.04这个值呢?很简单,在VBA编辑器里按<Ctrl>+<G>进入立即窗口,输入?Application.InchesToPoints(0.82)  按回车就得到结果了,顾名思义,InchesToPoints应该是英寸换成点吧,对错不要紧,重要的是现在我们知道了转换的过程,知道怎样得到EXCEL里那么多常量的实际值了。      再比如我们最常用的设置单元格格式,录制左对齐的宏代码如下:Range("A1").Select    With Selection        .HorizontalAlignment = xlLeft        .VerticalAlignment = xlCenter        .WrapText = False        .Orientation = 0        .AddIndent = False        .IndentLevel = 0        .ShrinkToFit = False        .ReadingOrder = xlContext        .MergeCells = False    End With省略掉不必要的代码后,如果是用在EXCEL里的话,我会把它改成   Range("A1").HorizontalAlignment = xlLeftxlLeft是EXCEL里的一个常量,在Excel里非常直观,使用起来很方便,但是VFP并不认得,需要改成具体数值,于是根据上面同样的办法,得知:xlLeft=-4131,在写VFP代码的时候直接替换就行了。还有,在设置单元格边框时,录制宏的代码如下:Range("A1").SelectSelection.Borders(xlDiagonalDown).LineStyle = xlNone    Selection.Borders(xlDiagonalUp).LineStyle = xlNone    With Selection.Borders(xlEdgeLeft)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With    With Selection.Borders(xlEdgeTop)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With    With Selection.Borders(xlEdgeBottom)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With    With Selection.Borders(xlEdgeRight)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With    With Selection.Borders(xlInsideVertical)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With    With Selection.Borders(xlInsideHorizontal)        .LineStyle = xlContinuous        .Weight = xlThin        .ColorIndex = xlAutomatic    End With这一段代码里,有很多常量,都是VFP不认得的,我们同样需要把它们换成常数值,但这一大段代码也仅仅需要一行就可以了:EXCEL.Range("A1").Borders.LineStyle=1坦白说,Borders集合我并没有完全了解,线型有多少种类我也不知道,但实际操作告诉我这一行达到了同样的效果,而且并没有出现明显的错误,最起码,它省略了一大段代码的编译和运行的时间。总结一下,在VFP调用EXCEL对象的时候,要了解具体对象的属性、方法、参数。调整VFP和VBA之间的格式差异,去除冗余代码,获得常数值。

阅读(5427) | 评论(3)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册