VFP编程技巧
谈谈VFP中变量的问题
- 最近一直在忙于开发ActiveX控件,加上没有合适的心得可谈,许多
网友希望我能继续把它写下去,看来我还得继续努力。
这次我们谈谈有关内存变量和方法程序作用域的问题。我在网上发现
许多初学编程的网友对此概念比较模糊,或许这个问题对您来说太简单了,
但对初学者来说,不但难理解,而且又找不到能详细这方面知识的资料。
下面就谈谈我对此的理解,供大家参考:
一、变量
我们在有关VFP的书上常常看到的是局部(私有)和全局(共公)变量
的介绍,而对于学过VB的朋友来说除了这两种变量外,可能知道还有个叫窗
口级的变量,那在VFP中是否也有这种变量呢?“有”。在这里我们不妨就叫
“表单级变量”吧(其实就是:容器或对象的属性)。
1.局部(私有)变量:
局部变量,也可以称动态变量,即可以随时定义,其作用域仅限于定义
它的某个过程、方法和事件,对其他过程、方法和事件来讲它并不存在。定
义它的过程、方法和事件执行完毕,该变量自行释放,不占用内存空间,如
果您再次进入还得重新定义和赋值。
2.全局(共公)变量:
全局变量,也可以称静态变量,需用Public命令定义,往往在程序的开
始部分定义,系统会专门开辟一块空间用于全局变量,一旦定义,其作用域
是整个程序的全过程,即您可以在任何过程、方法和事件中对它读取和赋值,
且所赋的值在未被赋新值前一直有效。
它在整个程序未退出前一直占用着内存空间。要释放全局变量,必须用
RELEASE EXTENDED来一次性全部释放,在程序运行中执行了
RELEASE ALL、RELEASE ALL LIKE 或 RELEASE ALL EXCEPT 时并不释放全局
变量。如果用RELEASE XXX 指明具体要释放的全局变量名,可以在名义上释
放,但它所占用的内存空间并未被真正释放,只是您看不到罢了。
3.表单级变量(也就是:容器或对象的属性):
明白了局部和全局变量,再来了解表单级变量就不难理解了,表单级变
量的作用域为本表单本身及表单内所有对象的方法和事件,它随着表单的打
开而建立,表单的释放而释放。
那么什么样的变量是表单级变量呢?说白了就是:所有可以设置和取出
返回值的表单或对象的属性,都属于表单级变量,比如:
Caption、Height、Enabled等,也可以说凡是在表单编辑器的属性窗口中能
看到的可读写的容器或对象的属性,就是表单级变量。也许有人会问,这些
属性都是系统定义的,我们自己可以定义吗? 可以,但我们只能定义表单
(FORM1)属性,不能给对象定义属性。
那么如何定义呢? 进入表单编辑器,选择主菜单的[表单]-[新建属性]
-在[名称]里填写你要新建的属性名(表单级变量名),如果你用的是VFP3.0
或VFP6.0,你还可以在下面的说明里写上你新建属性 的说明,这样在 Form1
属性窗口中的下方,就可以看到你对该属性的说明。填写完了按添加按钮,
你就定义了一个表单级变量了。不信你到Form1 属性窗口的[其他]里去找,
看看有没有你刚定义的这个属性名,其初始值=.F.。
一旦定义了新的属性,就可以和其他表单属性一样读写了。如果按上面
的办法我们定义了一个名为Bdsx的属性,那你既可以在Form1属性窗口中直接
对它赋值,也可在本表单的任何方法和事件中对它赋值,只是在读写它时必
须加上THIS. 或 THISFORM. 如:
Thisform.Bdsx="hi 网友!您好"
thisform.Label1.Caption=thisform.Bdsx
上面讲了这么多有关变量的概念,那么在具体应用中,究竟用哪种变量好
呢?这要看具体情况,但一般的原则是:
带有全局性质的参数,最好用全局变量,比如用于确定登入者身份的参数、
特定的操作目录等。在一个程序中全局变量越少,各过程、类、表单的独立性
和可移植性就越强。
凡是只在某个过程或事件中起中间过渡用的参数,就一律定义为局部变量,
到需要用时再定义。
凡是需在整个表单的各对象间进行读写的参数,就采用表单级变量,这样
你的这个表单今后如果想移植到其他程序中使用,就只需改变一下数据环境了,
无须再全部重新设计表单,也就是说这个表单相对于整个程序,它是个独立的
整体。
二、方法程序
VFP允许我们自定义函数和过程程序,但如果以.PRG文件名定义的函数和过
程程序,必须用 SET PROCEDURE TO ... 来打开和关闭,同时在这种过程程序
中,无法使用诸如THISFORM.LABEL1....等具体的对象名,那在表单中有一段几
个对象的CLICK的事件都需调用的代码,怎样在不重复写这些代码的情况下执行
这段代码呢?我们可以在表单中建立和调用自定义的方法程序吗?又如何调用
它们呢?
1.直接带对象名加事件名调用,比如在COMMAND1.CLICK的事件中,有如下
一段代码,这段代码在COMMAND2.CLICK和COMMAND3.CLICK中也需要执行,则在:
COMMAND1.CLICK事件中的代码如果是:
IF XXX=1
WAIT WIND ''你好!''
.... ....
.... ....
ELSE
WAIT WIND ''嘿!大家好!''
... ...
... ...
ENDI
... ...
那在COMMAND2.CLICK和COMMAND3.CLICK的事件中只需写一句:
THISFORM.COMMAND1.CLICK
就都可以调用这同一段代码了,无须重复写这段代码。
2.可以象表单级变量那样直接在表单上建立表单的方法程序:
进入表单编辑器,选择主菜单的[表单]-[新建方法程序]-在[名称]里填写你
要新建的方法程序名,如果你用的是VFP3.0或VFP6.0,你也可以在下面的说明里
写上你新建方法程序的说明,这样在Form1属性窗口中的下方,就可以看到你对
该方法程序的说明。填写完了按添加按钮,这样你就建立的一个新的方法程序,
你可以象FORM1.LOAD等方法那样在里面写入你的代码了,比如我们建立了一个名
为:BDFFCX的方法程序,在这个方法程序里我们把上面的这段代码写入BDFFCX:
IF XXX=1
WAIT WIND ''你好!''
.... ....
.... ....
ELSE
WAIT WIND ''嘿!大家好!''
... ...
... ...
ENDI
... ...
那你只要在COMMAND1.CLICK、COMMAND2.CLICK和COMMAND3.CLICK的事件
中写上如下一句就可执行这段代码了:
THISFORM.BDFFCX
如果您还想带参数调用,那首先必须在BDFFCX方法程序的第一句加上:
Rarameters XXX1,XXX2
把THISFORM.BDFFCX这句改为:
THISFORM.BDFFCX(xxx1,xxx2)
就可以带参数调用BDFFCX了。
表单级方法程序和表单级变量一样,随着表单的打开而建立,表单的释放而
释放。
----关于报表打印
VFP所提供的报表设计器虽说功能强大,并能提供所见所得的报表预览,
但我总觉得没有DOS下直接用代码编制的打印程序来得方便和自由,虽然DOS
没有预览功能。也正因为如此,我很少谈及VFP 的打印问题,为了和大家交
流,这次也谈谈VFP的报表打印问题,希望以此和大家共同探讨。
一、部分与打印有关的系统变量
VFP本身为我们提供了几个与打印有直接关系的系统变量,它们是:(部分)
_BOX 是否打印文字边框,.T.=打印
_GETNPD 指定或保存打印机接口驱动程序的文件名。
_PADVANCE 设定打印纸进纸方式,=FORMFEED(默认)整张进纸。
_PAGENO 设定或保存当前的打印页号。
_PBPAGE 设定或返回打印的起始页号。
_PEPAGE 设定或返回打印的终止页号。
_PCOLNO 设定或返回当前打印头的列。
_PLINENO 设定或返回当前打印头的行。
_PCOPIES 设定或返回打印份数。
_PLENGTH 设定或返回打印纸的页长,默认=66行长。
_PPITCH 设定打印机的打印密度。
_PQUALITY 设定打印机的打印质量。
... ...
这些变量在设计报表程序时,有些是很有用的,故在此列出。
二、一些常用的打印技巧
1.怎样打印指定的页
REPORT FORM XXXX RANGE 2,5 TO PRINTER &&从第2起打至第5页止
2.如何计算总页数,以实现“第?页/总?页”
在打印前根据细节区所打印的记录条数,先进行计算,然后再打印,具体代码:
PUBL mPAGE
SELE XXX &&xxx=供打印的数据表
XX=10 &&XX=细节区所打印的记录条数
mPAGE=IIF(RECCOUNT()%XX=0,INT(RECCOUNT()/XX),INT(RECCOUNT()/XX)+1)
mPAGE就是总页数,这样在需要总页数的地方就可直接引用mPAGE变量了。
3.如何使报表打满一页
如果打印的记录不足一页,“页注脚”会自动上移,影响报表的美观,解决的
办法和上面的差不多,即补足一页中所缺少的记录(补足空白记录):
SELE XXX