回 帖 发 新 帖 刷新版面

主题:回复:“不好意思我又回来了”

再试试以下修改了的命令:
SUM 领料 TO sum_领料 FOR 日期 >= {^2008.3.1} and 日期= <{^2008.4.1} and allt(材料名) = '水晶头'

回复列表 (共2个回复)

沙发


 闻得有人问起我如何把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 = xlLeft
xlLeft是EXCEL里的一个常量,在Excel里非常直观,使用起来很方便,但是VFP并不认得,需要改成具体数值,于是根据上面同样的办法,得知:xlLeft=-4131,在写VFP代码的时候直接替换就行了。还有,在设置单元格边框时,录制宏的代码如下:
Range("A1").Select
Selection.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之间的格式差异,去除冗余代码,获得常数值。

板凳

非常感谢MOZ的回帖!
您的经验起对学习VF与VB命令之间的格式到了画龙点睛的作用!

我来回复

您尚未登录,请登录后再回复。点此登录或注册