涪陵职业教育中心 吴玉琼 制作

233
涪涪涪涪涪涪涪涪 涪涪涪涪涪涪涪涪 涪涪涪 涪涪涪 涪涪涪涪涪涪涪 涪 7 涪涪涪 10 涪

description

Visual FoxPro 6.0 操作基础及应用. 第 7 章至第 10 章. 重庆大学出版社. 涪陵职业教育中心 吴玉琼 制作. 目 录. 第 7 章 VFP6 表单设计. 第 8 章 报表与标签设计. 第 9 章 VFP6 菜单设计. 第 10 章 多用户共享技术. 第 7 章 VFP6 表单设计. 7.1 设计表单. 学习要点 1 、表单设计器的使用; 2 、向表单中添加控件的方法; 3 、常用控件的功能和使用方法; 4 、常用控件所具有的事件; 5 、方法程序的编写; 6 、使用表单解决数据输入和输出问题。. - PowerPoint PPT Presentation

Transcript of 涪陵职业教育中心 吴玉琼 制作

Page 1: 涪陵职业教育中心 吴玉琼    制作

涪陵职业教育中心涪陵职业教育中心 吴玉琼 吴玉琼 制作制作

重庆大学出版社

第 7 章至第 10 章

Page 2: 涪陵职业教育中心 吴玉琼    制作

第 7 章 VFP6 表单设计

第 8 章 报表与标签设计

第 9 章 VFP6 菜单设计

第 10 章 多用户共享技术

目 录目 录

Page 3: 涪陵职业教育中心 吴玉琼    制作

第第 77 章 章 VFP6VFP6 表单设计表单设计

7.1 设计表单

7.2 处理对象

7.3 常用表单控件介绍

7.4 综合示例

学习要点1 、表单设计器的使用;2 、向表单中添加控件的方法;3 、常用控件的功能和使用方法;4 、常用控件所具有的事件;5 、方法程序的编写;6 、使用表单解决数据输入和输出问题。

返 回 退 出

Page 4: 涪陵职业教育中心 吴玉琼    制作

7.1 7.1 设计表单设计表单 表单又称为界面或窗体,是 VFP 提供的一种功能强大的界面。各种对话框和窗口都是表单的不同表现形式。它可以使用户在简单明了的界面中查看数据或将数据记录输入到表中。在表单设计器中可以处理下列内容:■ 表单中不同类型的对象■ 与表单相关联的数据■ 顶层表单或子表单■ 能一起操作的多个表单■ 基于自定义模板的表单表单和表单集是拥有自己的属性、事件和方法程序的对象,在表单设计器中可以设置这些属性、事件和方法程序。表单集包含了一个或多个表单,可以将它们作为一个整体来操作。例如,如果一个表单集中有四个表单,可以在运行时用一个命令来显示或隐藏它们。可以通过表单向导、表单设计器和快速表单来创建表单。可以

Page 5: 涪陵职业教育中心 吴玉琼    制作

用如下的三种方法之一新建一个表单:■ 在“项目管理器”中选定“表单”,并选择【新建】按钮。■ 在【文件】菜单中选择【新建】命令,再选定“表单”,再选择【新建文件】按钮。■ 使用 CREATE FORM 命令。

通过项目管理器创建表单示例

1 、选择“文档”选项卡

2 、选择“表单”

3 、单击【新建】

4 、进入新建表单程序,弹出“新建表单”对话框

单击

“ 表单设计器”窗口

新表单 在新表单 (Form1) 上可以可视化地添加控件并进行属性、方法程序设计。

Page 6: 涪陵职业教育中心 吴玉琼    制作

7.1.1 7.1.1 设置数据环境设置数据环境 每一个表单或表单集都包括一个数据环境( Data Environment )。数据环境是一个对象,它包含与表单相互作用的表或视图,以及表单所要求的表之间的关系。可以在“数据环境设计器”中直观地设置数据环境,并与表单一起保存。在表单运行时,数据环境可以自动打开、关闭表或视图。而且,通过设置“属性”窗口中 ControlSource (指定与对象对立联系的数据源)属性设置框,在这个属性框中列出了数据环境中的所有字段,数据环境将帮助设置控件用的 ControlSource 属性。1 、常用数据环境属性

Page 7: 涪陵职业教育中心 吴玉琼    制作

单击打开图片

2 、向数据环境设计器中添加表或视图向数据环境设计器中添加表或视图时,可以看到属于表或视图的字段或索引。若要向数据环境中添加表或视图,可以按如下步骤来进行:( 1 )打开“数据环境设计器”,从“数据环境”菜单中选择“添加” 1 、在表单上右击,

弹出表单的快捷菜单

2 、在快捷菜单中单击“数据环境”菜单项,打开“数据环境设计器”3 、添加表或视图的方法与建立查询时添加表或视图相同

4 、在此框中选择Student 后单击【添加】

Page 8: 涪陵职业教育中心 吴玉琼    制作

在关闭了“添加表或视图”对话框后,若还想向“数据环境”中添加表或视图,可采用以下方法之一: ■ 在“数据环境设计器”中右击,打开数据环境的快捷菜单,从中选择“添加”菜单项,将“添加表或视图”对话框再次打开,添加方法与上述相同。 ■ 在“数据不境设计器”处于激活状态时,系统菜单上会有【数据环境】菜单,可以单击【数据环境】 | 【添加】将“添加表或视图”对话框再次打开。 ■ 将要添加的表或视图从打开的项目或“数据库设计器”拖放到“数据环境设计器”中。 若已将“数据环境设计器”关闭了,要添加表或视图时,除了用前文所介绍的在表单上右击打开表单的快捷菜单,用快捷菜单操作以外,也可以在系统菜单上单击【显示】 | 【数据环境】,将“数据环境设计器”打开,打开了“数据环境设计器”后的添加方法与上相同。 当“数据环境设计器”处于活动状态时,“属性”窗口会显示与数

Page 9: 涪陵职业教育中心 吴玉琼    制作

单击打开动画

据环境相关的对象及属性。在“属性”窗口的“对象”框中,数据环境的每个表或视图,表之间的每个关系,以及数据环境本身均是各自独立的对象。要打开“属性”窗口,可以在表单或“数据环境设计器”中右击,在快捷菜单上选择【属性】菜单项

在“数据环境设计器”中右击,打开快捷菜单。单击【属

性】菜单项打开“属性”窗口。

选项卡

属性或方法程序列表

属性值或方法程序

属性及方法程序功能说明

单击对象选择框

Page 10: 涪陵职业教育中心 吴玉琼    制作

3 、从数据环境设计器中移去表当将表从数据环境中移去时,与这个表有关的所有的关系也随之移去。若要将表和视图从数据环境设计器中移去,可以:( 1 )在“数据环境设计器”中选择要移去的表或视图。( 2 )在“数据环境”快捷菜单中选择【移去】命令。

在“数据环境设计器”中选择要移去的表或视图。

在选定表或视图上右击,打开快捷菜单。

单击【移去】

Page 11: 涪陵职业教育中心 吴玉琼    制作

4 、在数据环境设计器中设置关系如果添加进数据环境设计器的表具有在数据库中设置的永久关系,这些关系将自动地加到数据环境中。如果表中没有永久的关系,可以在数据环境设计器中设置这些关系。要在数据环境设计器中设置这些关系,可以将字段从主表拖到相关表中的相匹配的索引标识上。也可以将字段从主表拖到相关表中的字段上。如果和主表中的字段对应的相关表中没有索引标识,系统将提示是否创建索引标识。

1 、先向表单的“数据环境设计器”添加两个表,如图按“学号”字段设置 Student 表与 Grade 表的一对多关系:

在“数据环境设计器”中的 Student 表中选择“学号”字段并将其拖到 Grade 表的“学号”字段上。

右击表间的关系连接线打开快捷菜单

Page 12: 涪陵职业教育中心 吴玉琼    制作

在快捷菜单中单击“属性”,打开属性窗口:在属性选择列表中选择 OneToMany

单击“属性选择框”弹出属性值选择 .T.-真

表达式生成器按钮

取消按钮

确定按钮

属性选择框

将两表设置为一对多关系

父表别名

如果在建立关系前 Grade 表没有按关联字段(学号)建立索引,则在将“学号”从 Student 表中拖到 Grade 表时将弹出对话框:

单击【确定】时系统将先按“学号”为 Grade 表建立索引,然后才建立两表间的关系。

Page 13: 涪陵职业教育中心 吴玉琼    制作

5 、在数据环境设计器中编辑关系 在数据环境设计器中设置了一个关系后,在表之间将有一条连线指出这个关系。 若要编辑关系的属性,可在“属性”窗口中从属性列表框选择要编辑的关系。关系的属性对应于 SET RELATION 和 SET SKIP 命令中的子句和关键字。RelationalExpr (指定基于父表中的字段而又与子表中的索引相关的表达式)属性的默认设置为主表中主关键字字段的名称。如果相关表是以表达式作为索引的,就必须将 RelationalExpr 属性设置为这个表达式。例如,如果相关表以 UPPER ( cust_id )作为索引,就必须将 RelationalExpr 属性设置为 UPPER ( cust_id )。如果关系不是一对多关系,必须将 OneTOMany 属性(指定是否只有在子表中遍历了所有相关记录之后才移动父表记录的记录指针)设置为“假”( .F. )。这对应于使用 SET RELATION 命令时不发出 SET SKIP 命令。将关系的 OneToMany 属性设置为“真”( .T. ),相当于发出 SET SKIP 命令。当浏览父表时,在记录指针浏览完子表中所有的相关记录之前,记录指针一直停留在同一父记录上。 注意:如果在表单或表单集中想设置一对多关系,必须将 OneToMany 属性设置为“真”( .T. ),甚至在数据库中已经建立了永久一对多关系时也必须如此。

返回

Page 14: 涪陵职业教育中心 吴玉琼    制作

7.1.2 7.1.2 创建单文档和多文档界面创建单文档和多文档界面 VFP允许创建两种类型的应用程序:■ 多文档界面( MDI )各个应用程序由单一的主窗口组成,且应用程序的窗口包含在主 窗口中或浮动在主窗口顶端。 VFP基本上是一个 MDI应用程序,带有包含于 VFP 主窗口中的命令窗口、编辑窗口和设计器窗口。■ 单文档界面( SDI )应用程序由一个或多个独立窗口组成,这些窗口均在 Windows桌面上单独显示。 Microsoft Exchange即是一个 SDI应用程序的例子,在该软件中打开的每条消息均显示在自己独立的窗口中。由单个窗口组成的应用程序通常是一个 SDI应用程序,但也有一些应用程序综合了 SDI 和 MDI 的特性。例如, VFP 将调试器显示为一个 SDI应用程序,而它本身又包含了自己的 MDI 窗口。为了支持这两种类型的界面, VFP允许创建以下几种类型的表单:■ 子表单:包含在另一个窗口中,用于创建 MDI应用程序的表

Page 15: 涪陵职业教育中心 吴玉琼    制作

表单。子表单不可移至父表单(主表单)边界之外,当其最小化时将显示在父表单的底部。若父表单最小化,则子表单也一同最小化。■浮动表单:属于父表单(主表单)的一部分,但并不是包含在父表单中。而且,浮动表单可以被移至屏幕的任何位置,但不能在父窗口后台移动。若将浮动表单最小化时,它将显示在桌面的底部。若父表单最小化,则浮动表单也一同最小化。浮动表单也可用于创建 MDI应用程序。■ 顶层表单:没有父表单的独立表单,用于创建一个 SDI应用程序,或用作 MDI应用程序中其他子表单的父表单。顶层表单与其他Windows应用程序同级,可出现在其前台或后台,并且显示在 Windows任务栏中。1 、指定表单类型创建各种类型表单的方法大体相同,但需设置特定属性以指出表单应该如何工作。如果创建的是子表单,则不仅需要指定它应在另外一个表单中显示,而且还需指定是否是 MDI 类的子表单,

Page 16: 涪陵职业教育中心 吴玉琼    制作

即指出表单最大化时是如何工作的。如果子表单是 MDI 类的,它会包含在父表单中,并共享父表单的标题栏、标题、菜单以及工具栏。非MDI 类的子表单最大化时将占据父表单的全部用户区域,但仍保留它本身的标题和标题栏。 若要建立一个子表单,可以:■ 用“表单设计器”创建或编辑表单。■ 可将表单的 ShowWindow 属性设置为下列值之一: ● 0- 在屏幕中:子表单的父表单将为VFP 的主窗口。● 1- 在顶层表单中。当子窗口显示时,子表单的父表单是活动的顶层表单。如果希望子窗口出现在顶层表单窗口内,而不是出现在 VFP 主窗口内时。可选用该项设置。

Page 17: 涪陵职业教育中心 吴玉琼    制作

■ 如果希望子表单最大化时与父表单组合成一体,可设置表单的MDIForm 属性(指定表单是否为 MDI 窗口)为“真” (.T.) ;如果希望子表单最大化时仍保留为一独立的窗口,可设置表单的 MDIForm 属性为“假” (.F.) 。浮动表单是由子表单变化而来。若要指定为浮动表单,可以:■ 用“表单设计器”创建或编辑表单。■ 可将表单的 ShowWindow 属性设置为以下值之一:●0- 在屏幕中。浮动表单的父表单将出现在 VFP 主窗口。●1- 在顶层表单中。当浮动窗口显示时,浮动表单的父表单将是活动的顶层表 单。■ 将表单的 DeskTop 属性(指定表单是否包含在 VFP 主窗口中)设置为“真” (.T.) 。若要指定顶层表单,可以:■ 用“表单设计器”创建或编辑表单。■ 将表单的 ShowWindow 属性设置为“ 2- 作为顶层表单”。

Page 18: 涪陵职业教育中心 吴玉琼    制作

2 、显示位于顶层表单中的子表单如果所创建的子表单中的 ShowWindow 属性设置为“ 1- 在顶层表单中”,则不需直接指定一顶层表单作为子表单的父表单。而是在子窗口出现时, VFP 指派成为该子表单的父表单。若要显示位于顶层表单中的子表单,可以:■ 创建顶层表单。■ 在顶层表单的事件代码中包含 DO FORM 命令,指定要显示的子表单的名称。例如,在顶层表单中建立一个按钮,然后在按钮的 Click 事件代码中包含如下的命令,如图所示:

注意:在显示子表单时,顶层表单必须是可视的、活动的。因此,不能使用顶层表单的 Init事件来显示子表单,因为此时顶层表单还未激活。■ 激活顶层表单,如有必要,触发用以显示表单的事件。

Page 19: 涪陵职业教育中心 吴玉琼    制作

3 、隐藏 VFP 主窗口在运行顶层表单时,可能不希望 VFP 主窗口是可视的。使用应用程序对象的 Visible 属性(指定对象是可见还是隐藏)按要求隐藏或显示 VFP 主窗口。若要隐藏 VFP 主窗口,可以:■ 在表单的 Init 事件中,包含下列代码行:Appliction.Visible=.F.■ 在表单的 Destroy 事件中,包含下列代码行:Appliction.Visible=.T.在某些方法程序或事件中,可使用 THISFORM.Release 命令关闭表单。注意:也可以在配置文件中包含以下行,用以隐藏 VFP 主窗口:SCREEN=OFF4 、在顶层表单中添加菜单若要在顶层表单中添加菜单,可以:■ 创建顶层表单的菜单。

返回

Page 20: 涪陵职业教育中心 吴玉琼    制作

■ 将表单的 ShowWindow 属性设置为“ 2- 作为顶层表单”。■ 在表单的 Init 事件中,运行菜单程序并传递两个参数:Do menuname.mpr WITH oForm,LAutoRename其中, oForm 是表单的对象引用。在表单的 Init 事件中, THIS作为第一个参数进行传递。 LAutoRename 指定了是否为菜单取一个新的唯一的名字。如果计划运行表单的多个实例,则将 .T.传递给 LAutoRename 。例如,可以使用下列代码调用名为 mySDImenu 的菜单:DO mySDImenu.mpr WITH THIS,.T.

7.1.37.1.3 用表单集扩充表单用表单集扩充表单 可以将多个表单包含在一个表单集中,作为一组处理。表单集有以下优点:■ 可同时显示或隐藏表单集中的全部表单。■ 可以可视的调整多个表单以控制它们的相对位置。 ■因为表单集中所有表单都是在单个 .SCX文件中用单独的数据

Page 21: 涪陵职业教育中心 吴玉琼    制作

环境定义的,可自动地同步改变多个表单中的记录指针。如果在一个表单的父表中改变记录指针,另一个表单中子表的记录指针则被更新和显示。注意:运行表单集时,将加载表单集所有表单和表单的所有对象。加载带着很多控件的多个表单会花几秒钟的时间。1 、创建表单集表单集是一个包含有一个或多个表单的父层次的容器。可在“表单设计器”中创建表单集,若要创建表单集,可从“表单”菜单中,选择“创建表单集”选项。如果不需要将多个表单处理为表单组,则不必创建表单集。创建表单集以后,则可向其中添加表单。2 、添加和删除表单创建了表单集以后,可添加新表单或删除表单。若要向表单集中添加附加的表单,可从“表单”菜单中选择“添加新表单”。若要从表单集中删除表单,可以:■ 在“表单设计器”“属性”窗口的对象列表框中,选择要删除的

Page 22: 涪陵职业教育中心 吴玉琼    制作

表单。■ 从“表单”菜单中选择“移除表单”。如果表单集中只有一个表单,可删除表单集而只剩下表单。若要删除表单集,可从“表单”菜单中选择“移除表单集”。表单以表的格式存储在 .SCX 后缀的文件中。创建表单时, .SCX表包含了一个表单的记录,一个数据环境的记录,和两个内部使用记录。为每个添加到表单或数据环境中的对象添加一个记录。如果创建了表单集,则为表单集及每个新表单添加一个附加的记录。每个表单的父容器为表单集,每个控件的父容器为其所在的表单。注意:当运行表单时,若不想在表单集中的所有表单的初始时就设置为可视的,可以在表单集运行时,将不准备显示的表单的 Visible 属性设置为“假”( .F. )。要显示的表单的 Visib1e 属性设置为“真”( .T. )。

返回

Page 23: 涪陵职业教育中心 吴玉琼    制作

7.2.1 表 单 的 运 行 和 设置属性

7.2 7.2 处理对象处理对象

7.2.2 事 件 处 理

7.2.3 在表单中添加属性和方法程序

7.2.4 表 单 间 传 递 参 数

7.2.5 在表单中使用本地和远程数据

返回 退出

Page 24: 涪陵职业教育中心 吴玉琼    制作

7.2.1 表单的运行和设置属性 1 、表单的运行和退出( 1)从程序中运行表单若想在程序中运行表单,需要在与事件相关联的代码、方法程序代码或在程序或过程中包含 DO FORM 命令。

DO FORM FormName | ? [WITH cParameterList] [TO] VarName

参数描述 :FormName:指定需要运行的表单文件名,可以包含路径。cParameterList:需要传递到表单的参数列表。 VarName:指定该表单运行结束时用于接收返回值的变量名。( 2)关闭活动的表单若想允许用户通过双击控件框,或选择【表单】 |【控件】 |【关闭】来关闭活动的表单,则需要设置表单的 Closable属性。若要允许用户关闭活动表单,可以:①在“属性”窗口中,将 Closable属性设置为“真”( .T.)。②在相应的事件代码中使用 RELEASE 命令。

Page 25: 涪陵职业教育中心 吴玉琼    制作

例如,可以通过在“命令”窗口或程序中发出下面的命令来关闭和释放表单 Student:RELEASE Student RELEASE Student (此为在表单外使用的命令格式)也可以在一个控件,如标题为“退出”的命令按钮的 Click事件代码中包含下面的命令,它允许用户关闭和释放表单:THISFORM.Release THISFORM.Release (此为在表单中调用方法程序的格式)可以在与表单的对象相关联的代码中使用 RELEASE命令,但在 RELEASE方法程序中却不会执行包含的任何代码。如果想要释放表单集,可使用命令:RRELEASE.THISFORMSETELEASE.THISFORMSET ( 3)隐藏和释放表单用户可以隐藏一个表单,使它不可见。在隐藏表单后,用户不能访问表单上的控件,但仍可以用程序完全控制它们。若要隐藏表单,可使用 Hide方法程序。例如,在与命令按钮的 Click事件相关的代码中,可以包含下面一行代码:THISFORM.HideTHISFORM.Hide当用户单击命令按钮时,表单仍在内存中,但不可见。

Page 26: 涪陵职业教育中心 吴玉琼    制作

所谓属性是指控件、字段或数据库等对象的特性。可以对属性进行设置,用于定义对象的特征或某一方面的行为。例如, Visible 属性影响一个控件在运行时是否可见; Enabled属性影响一个控件在运行时是否可操作。属性值可以在设计时指定也可以在运行时通过程序对其进行赋值修改。在设计时指定是指通过“属性”对话框来修改一个对象的属性。图 7-8 所示的为复选框属性设置对话框,也称为属性窗口。

2 、表单中对象的属性设置

图 7-8 复选框属性设置对话框

Page 27: 涪陵职业教育中心 吴玉琼    制作

( 1)常用表单控件的基本属性在 VFP6 中,所有表单控件都有属性。其中有些属性是一般控件都具有的,有些属性是控件或容器所独有的。表 7-2给出了 VFP常用可视表单控件和常用可视容器所共有的属性及其属性说明。

Page 28: 涪陵职业教育中心 吴玉琼    制作

( 2 )表单对象的属性设置方法表单由控件、容器等对象组成。每个对象都有自己的属性,对象的属性是独立存在的,可以分别定义每个对象的属性。对象的属性设置可以有两种方法:一种是在设计表单时设置对象的属性,另一种方法是在表单运行时设置表单对象的属性。在运行时设置表单对象的属性,必须在设计表单时就将要设置的属性名及属性值通过程序的方式加以定义。①在设计表单时设置对象的属性打开“属性”对话框会显示选定对象的属性或事件。如果选择了多个对象,则这些对象共有的属性将显示在“属性”对话框中。要编辑另一个对象的属性或事件时,可在“对象”框中选择这个对象,或者直接在表单中选择这个对象。若要设置属性,则可首先在“属性”对话框的“属性和事件”列表中选择一个属性,然后在“属性设置”框中为选中的属性键入或选择需要的设置。注意:那些在设计时为只读的属性,例如,对象的 Class 属性,在“属性”对话框的“属性和事件”列表框中将以斜体显示。如果属性要求输入字符值,则不必用定界符

Page 29: 涪陵职业教育中心 吴玉琼    制作

通过“属性”对话框可以将属性设置为表达式或函数的结果。若要用表达式设置属性,可以:◆在“属性”对话框中通过单元“函数”按钮来打开“表达式生成器”。◆在“属性设置”框中键入“ =”号,并在后面键入表达式。例如,如果想设置表单的 Caption属性,使它在运行表单时能够指示当前的活动表,则可在“属性设置”框中键入: =Alias()。在“属性”对话框中设置一个属性表达式,并在运行时刻或设计时刻初始化对象时,才对这个属性表达式进行求值。如果将属性设置为用户自定义函数的结果,那么当设置或修改这个属性,以及运行表单时,对这个函数进行求值。如果用户自定义函数出现错误,则有可能打不开这个表单。此外,也可以在对象的 Init事件中将属性设置为用户自定义函数,如:This.CaptionThis.Caption == myfunction( ) myfunction( ) 如果用户自定义函数出现错误,则虽然不能运行表单,但可以修改它。如果要指定表单的图标,则将表单的 Icon 属性设置为一个 .ICO 文件的文件名。

Page 30: 涪陵职业教育中心 吴玉琼    制作

在“表单设计器”中设计表单时,表单是“可视”的。除非 Visible(指定对象是可见还是隐藏)属性设置为 .F.,对表单的外观和行为的修改将立刻在表单上反映出来。如果将WindowState属性设置为 0(普通)、 1(最小化)或 2(最大化),则表单设计器中的表单会立即体现这一设置。如果将Movable属性设置为 .F.,那么不但用户在运行时不能移动表单,即使在设计时也不能移动它。因此应该在设置那些决定表单行为的属性之前,先完成表单的功能设计,并添加所有需要的控件。表 7-3列出了在设计时常用的表单属性,它们定义了表单的外观和行为。

Page 31: 涪陵职业教育中心 吴玉琼    制作

②在运行时设置表单中对象的属性若想在运行时对一个对象的属性设置,首先需要确定它和容器层次的关系,只有在确定关系后方可通过下述格式设置属性。控件的容器、控件名、属性(或方法)由点号( .)分隔。格式: Objectvariable.[form.]control.property=setting

表 7-4 列出的属性或关键字使在对象层次上引用对象变得更容易:

可在表单或表单集中使用 THIS 、 THISFORM 和 THISFORMSET 引用对象。

Page 32: 涪陵职业教育中心 吴玉琼    制作

表 7-5 给出了使用 THISFORMSET、 THISFORM、 THIS和 Paent设置对象的示例:

表单在运行时也可以使用表达式或函数来设置属性。若要在运行时将属性设置为表达式,可为属性指定一个表达式,或者为属性指定一个用户自定义函数的结果。例如,建立一个“属性设置示例”表单,根据一个变量的不同值,将 Command命令按钮的标题设置为“添加”或“保存”。首先在表单的 Init Event 中声明这个变量:PUBLIC gleditingGlediting=.F.然后命令按钮的 Click Event 事件中,包含如下代码:glediting=IIF(glediting,.F.,.T.) &&当点击事件发生时,变量值发生变化this.caption=iif(glediting," 保存 "," 添加 ")

Page 33: 涪陵职业教育中心 吴玉琼    制作

③同时设置一个对象的多个属性可以同时为一个对象设置多个属性,此时可使用 WITH…ENDWITH结构。例如,对于上面例子中的命令按钮,在标题名称变化时还要使它们的宽度、字体、字体风格、背景颜色变化,可在命令按钮的 Click Event方法程序代码中包含下面的语句:glediting=IIF(glediting,.F.,.T.) WITH This

.Caption=IIF(glediting,"保存 ","添加 ")

.Width=IIF(glediting,75,100)

.FontName=IIF(glediting,"宋体 ","黑体 ")

.FontBold=IIF(glediting,.F.,.T.)

.ForeColor=IIF(glediting,RGB(0,0,0),RGB(0,128,255)) ENDWITH

3 、 VFP6 容器的收集和记数属性VFP6 中有很多控件属于是容器控件,所有容器控件都有与它们相关联的记数属性和收集属性。收集属性是引用其每个被包含对象的数组,记数属性是指示其包含的对象数的数值属性。

Page 34: 涪陵职业教育中心 吴玉琼    制作

使用记数属性可以确定表单中究竟有多少个控件,而收集属性允许引用表单上的任何一个控件。下面的程序用于打印出当前活动表单上所有控件的 Name属性:ACTIVATE SCREEN &&将输出打印到 VFP6 主窗口FOR nCnt=1 TO Application.ActiveForm.ControlCount ? Application.ActiveForm.Controls[nCnt].NameENDFOR上述程序中的 Application 也可以用 _Screen 替换。

Page 35: 涪陵职业教育中心 吴玉琼    制作

7.2.2 7.2.2 事件处理事件处理 本节使用下面的表单作为示例,说明响应用户动作的事件其发生次序。 显示事件序列的表单示例

上面示例中,用户在表单上执行以下动作: 运行该表单。1、在 Text1 中键入文本 Test2、选择此文本,并将其复制到剪贴板。3、输入焦点移向 Text2。4 、将文本粘贴至 Text2。5、单击 Command2,关闭表单。 以上动作触发了每个对象的一个或多个系统事件。下表详细说明了响应每个用户动作所触发的事件。

Page 36: 涪陵职业教育中心 吴玉琼    制作

动作动作 11::通过在“命令”窗口中键入以下命令,用户可以运行表单: DO FORM form1 NAME frmObject Visual FoxPro 加载表单,初始化每个对象,然后初始化表单。这时表单被激活,第一个字段开始接收输入焦点。对象 事件

DataEnvironment BeforeOpenTablesForm1 LoadDataEnvironment InitText1 InitText2 InitCommand1 InitCommand2 InitForm1 InitForm1 ActivateForm1 GotFocusText1 WhenText1 GotFocus

Page 37: 涪陵职业教育中心 吴玉琼    制作

动作动作 22::用户在 Text1 中键入 Test ,每次击键激发两个事件: KeyPress 和 InteractiveChange。 KeyPress 事件接收 2 个参数:按下的键和 SHIFT 、 ALT 或 CTRL 键的状态。

对象 事件Text1 KeyPress (84, 1) “T”Text1 InteractiveChangeText1 KeyPress (101, 0) “e”Text1 InteractiveChangeText1 KeyPress (115,0) “s”Text1 InteractiveChangeText1 KeyPress (116,0) “t”Text1 InteractiveChange

Page 38: 涪陵职业教育中心 吴玉琼    制作

动作动作 33::用户双击 Text1 选择文本,然后按下 CTRL+C 复制文本至剪贴板。 Mouse 事件和 Click 事件伴随着 DblClick 事件。MouseMove 事件和 MouseDown 事件接受四个参数:其一表示哪个按钮被按中,其余的表示 Shift 状态及 X 、 Y 的位置。 X 、Y 是相对于表单的坐标位置并使用与表单相同的刻度模式(例如,像素)。 每个控件仅列出一个 MouseMove 事件。事实上,此事件可能触发 6 次或更多。

对象 事件Form1 MouseMove(0, 0, 100, 35) Text1 MouseMove(0,0,44,22)Text1 MouseDown(1, 0, 44, 22)Text1 MouseUp(1, 0, 44, 22)Text1 ClickText1 MouseDown(1, 0, 44, 22)Text1 MouseUp(1, 0, 44, 22)Text1 DblClick

Page 39: 涪陵职业教育中心 吴玉琼    制作

动作动作 44 ::用户通过按下 TAB 键将输入焦点移向 Text2。对象 事件Text1 KeyPress(9, 0)Text1 ValidText1 LostFocusText2 WhenText2 GotFocus

动作动作 55::用户按下 CTRL+V 粘贴已复制的文本。对象 事件Text2 InteractiveChange

Page 40: 涪陵职业教育中心 吴玉琼    制作

动作动作 66 ::用户单击 Command2 关闭表单。 对象 事件Form1 MouseMoveCommand2 MouseMoveText2 ValidCommand2 WhenText2 LostFocusCommand2 GotFocusCommand2 MouseDown(1, 0, 143, 128)Command2 MouseUp(1, 0, 143, 128)Command2 ClickCommand2 ValidCommand2 When

Page 41: 涪陵职业教育中心 吴玉琼    制作

在关闭表单和释放对象之后,将发生附加的事件,其次序正好与动作 1 中的事件相反。对象 事件Form1 DestroyCommand2 DestroyCommand1 DestroyText2 DestroyText1 DestroyForm1 UnloadDataEnvironment AfterCloseTablesDataEnvironment Destroy

Page 42: 涪陵职业教育中心 吴玉琼    制作

下表显示了 Visual FoxPro 事件的一般触发顺序。表中假定数据环境的 AutoOpenTables 属性设置为“真” (.T.)。其他事件的发生是基于用户的交互行为和系统响应。对象 事件数据环境 BeforeOpenTables表单集 Load表单 Load数据环境临时表 Init数据环境 Init对象 1 Init表单 Init表单集 Init表单集 Activate表单 Activate对象 1 2 When表单 GotFocus对象 1 GotFocus对象 1 Message

对象 1 Valid 3对象 1 LostFocus对象 2 3 When对象 2 GotFocus对象 2 Message对象 2 Valid 4对象 2 LostFocus表单 QueryUnload表单 Destroy对象 5 Destroy表单 Unload表单集 Unload数据环境 AfterCloseTables数据环境 Destroy数据环境临时表Destroy

1 、对于每个对象,从最内层的对象到最外层的容器; 2 、 Tab 键次序中的第一个对象3 、下一个获得焦点的对象 ; 4 、 当对象失去焦点时发生5 、对于每个对象,从最外层的容器到最内层的对象

Page 43: 涪陵职业教育中心 吴玉琼    制作

7.2.3 7.2.3 在表单中添加属性和方法程序在表单中添加属性和方法程序

可以添加许多个新的属性和方法程序到一个表单。属性拥有一个值,方法程序具有调用它时被运行的过程代码。新建的属性和方法程序与其它属性与方法程序的引用一样。1、建立一个新属性如果有一个表单集,则在“表单设计器”中添加的属性和方法程序就属于此表单集。如果没有建立表单集,则属性和方法程序属于表单。若要向表单或表单集中添加新属性,可以:①从【表单】菜单项中选择【新建属性】;②在“新建属性”对话框中,键入属性名。还可以加入关于这个属性的说明,它将显示在“属性”窗口的底部的属性描述中。

Page 44: 涪陵职业教育中心 吴玉琼    制作

2、建立一个数组属性一个数组属性可以像其他属性一样都属于表单或表单集,但不同的是数组属性可用 VFP6 的数组命令和函数处理它。若要创建一个数组属性,可以:①添加新属性到表单;②在“新建属性”对话框的“属性名”框中键入数组名称,并包括数组的大小和维数。例如,输入 myarray(10,5) 可创建一个 10 行 5 列的二维数组。当添加数组属性到表单时,属性作为只读显示在属性窗口中。可以在运行时管理数组,重新设置数组的维数,也可对数组属性的元素赋值。

Page 45: 涪陵职业教育中心 吴玉琼    制作

3、创建新方法程序可向表单中添加方法程序,并且可以用调用其它方法程序的方式调用它。若要在表单或表单集中创建一个新方法程序,可以:①从【表单】菜单项中选择【新方法程序】;②在“新方法程序”对话框中,输入方法程序的名称。还可以包含有关这个方法程序的说明,这是可选的。调用用户自定义方法程序使用下面的语法:ObjectName.MethodName建立的方法程序同样可以接受参数并返回值,这种情况下,可以使用赋值语句来调用方法程序:cVariable = ObjectName.MethodName ( cParameter, nParameter )

Page 46: 涪陵职业教育中心 吴玉琼    制作

4 、包含预定义常量为了在方法程序中使用预定义常量,可在表单或表单集中用# INCLUDE命令包含一个头文件。头文件一般包含由#DEFINE预处理器伪指令定义的编译时的常数。若要在表单中包含文件,可以:①从【表单】菜单项中选择【包含文件】;②在“包含文件”对话框的“包含文件”文本框中指定文件,或者选择对话框按钮以打开“包含”对话框并选定文件。

Page 47: 涪陵职业教育中心 吴玉琼    制作

7.2.4 7.2.4 表单间传递参数表单间传递参数 1、将参数传递到表单在运行表单时,为设置属性值或者指定操作的默认值,有时需要将参数传递到表单。若要将参数传递到表单,可以:①创建容纳参数的表单属性,如 ItemName和 ItemQuantity;②在表单的 Init事件代码中,包含 PARAMETERS 语句,如:PARAMETERS cString,nNumber③在表单的 Init事件代码中,将参数分配给属性,如:THIS.ItemName=cStringTHIS.ItemQuantity=nNumber④ 当运行表单时,在 DO FORM命令中包括一个WITH子句,如: DO FORM <表单文件名 > WITH <实际参数表 >

2、从表单接收返回值若要从表单返回值,可以:①将返值表单的WindowType属性设置为 1,使表单成为模式表单;②在表单的 UnLoad事件代码中,包含一个带返回值的 RETURN命令;③在调用表单的程序或方法程序中使用 DO FORM 命令并包含 TO 关键字。

Page 48: 涪陵职业教育中心 吴玉琼    制作

7.2.5 7.2.5 在表单中使用本地和远程数据在表单中使用本地和远程数据 可以创建这样的表单,它可以很容易地在使用本地数据和远程数据之间切换。这样就可以使用本地或测试数据来创建应用程序的原型,然后切换到远程或实际的数据上,而不对表单做实质性的修改。能够在本地和远程数据库之间切换的关键在于使用的是视图而不是直接将表单(及其控件)与表链接。若要访问远程数据,则必须在任何事件中使用视图。因此为了方便本地数据与远程数据的切换,也需为本地数据创建视图。创建表单时,将这两个视图都添加到它的数据环境中,根据需要进行切换。若要创建可在本地和远程数据间切换的表单,可以:①创建数据的两个视图,一个指向远程数据,另一个指向本地数据。②新建表单。③在“数据环境”中添加这两个视图并为两个临时表设置同样的 Alias属性;④ 将“数据环境”的 OpenViews属性设置为 1: Local Only或 2: Remote Only;注意:由于两个视图使用同样的别名,不要选择默认的 0: Local和 Remote。⑤ 在表单中,添加需要的控件,将 ControlSource属性设置为视图的相应字段。由于两个视图使用同样的别名,表单运行时控件将自动对那个活动的视图作出反应。创建表单后,通过改变“数据环境”的 OpenView属性切换视图的别名。可以在使用“表单设计器”时在“数据环境”中做此工作。如果要在运行时切换视图,可以写出代码并将其附加到某个事件中。

Page 49: 涪陵职业教育中心 吴玉琼    制作

例如,可将这些代码放入 Activate Enevt事件中: THISFORM.DataEnvironment.OpenViews= 2 &&使用远程视图如果要创建一个可在本地和远程数据间切换的表单,还必须设计定位代码用以容纳两个视图,尤其是设计具有一对多关系的表单。例如,如果表单只访问本地表或视图,可在 Next命令按钮中使用下列代码,用来移动指针到临时表的下一个记录SKIP 1THISFORM.Refresh()但是,当在远程视图中定位时,此代码无效。因为代码假设临时表包含了表单需要的所有数据。通常情况下,希望从远程数据源上下载的数据越少越好。解决的办法是使用带参数的视图。如:SELECT * FORM CUSTOMERS WHERE CUSTOMERS.COMPANY_NAME=?PCompanyName表单运行时,会在对话框中提示用户输入客户名或允许用户在文本框中输入一个名称。“显示”按钮的代码可能与以下代码相似:pCompanyName=THISFORM.txtpCompanyName.ValueREQUERY(“Customer”)THISFORM.refresh()

Page 50: 涪陵职业教育中心 吴玉琼    制作

7.3 7.3 常用表单控件简介常用表单控件简介

7.3.1 标 签

7.3.2 文 本 框

7.3.3 编 辑 框

7.3.4 命令 按钮

7.3.5 命令按钮组

7.3.6 选项按钮组

7.3.7 复 选 框

7.3.8 组 合 框

7.3.9 列 表 框

7.3.10 微调 控件

7.3.11 表格 控件

7.3.12 图像 控件

7.3.13 计时器控件

7.3.14 页框 控件

7.3.15 形状和线条

返回 退出

Page 51: 涪陵职业教育中心 吴玉琼    制作

7.3.1 7.3.1 标签标签 标签是最常用的一种控件,顾名思义,标签只能用作输出信息,而不能接受输入或进行编辑,如图 7-9 所示。但在程序运行过程中,标签显示的文本可以改变。标签有如下特点 : ① 标签没有数据源。② 标签不能直接编辑。③ 标签不能用 Tab 键选择。常用标签的属性如表 7-9 所示。

表 7-9 常用标签属性属 性说 明Caption 由标签显示的文本AutoSize 确定是否根据标题的长度来调整大小BackStyle 确定标签是否透明WordWrap 确定标签上显示的文本能否换行

Page 52: 涪陵职业教育中心 吴玉琼    制作

7.3.2 7.3.2 文本框文本框 与标签控件不同的是,文本框有自己的数据源,并可以进行输入和更改操作。相对于标签固定的文本信息,文本框通常以表的一个字段或一个内存变量作为自己的数据源。文本框应用示例如图。

1、常用属性文本框的常用属性如表 7-10所示。2、文本框的应用① 检验文本框中的数据有效性。在 Valid 事件相关的方法中写进代码,例 : IF CTOD( )<DATE( ) =MESSAGEBOX("你需要输入将来值 ", 1) RETURN .F. ENDIF

Page 53: 涪陵职业教育中心 吴玉琼    制作

1、常用属性文本框的常用属性如 下 :

属 性 说 明ControlSource 指定与对象建立联系的数据源。DisabledBackColor 当文本框废止时文本框的背景色DisabledForeColor 当文本框废止时文本框的前景色Format 属性决定在文本框中值的显示方式InputMask 指定每个字符输入时必须遵守的规则PasswordChar 输入口令时在文本框中显示的字符SelectBackColor 文本框中选定文本的背景色SelectedForeColor 文本框中选定文本的前景色SelLength 选定字符的数目或指定要选定的字符数目SelStart 选定文本起始点位置或指出插入点的位置Seltext 返回用户在文本框的文本输入区所选定的文本TabStop 用户能否用 Tab键选择该控件Value 文本框当前状态的值

Page 54: 涪陵职业教育中心 吴玉琼    制作

② 指明当前选定的文本框。改变文本框的颜色可以指明用户当前编辑的文本框,如在 GotFocus事件中更改 ForeColor、 BackColor属性;再在 LostFocus事件中恢复原来的设置。③ 当文本框得到焦点后选择文本在 GotFocus中包含以下代码: This.SelStart=0 This.SelLength=LEN(ALLTRIM(This.Value))④ 对文本框中的文本进行格式编辑。InputMask属性决定在文本框中可以键入的值格式。⑤ 接收用户的输入。用户在文本框中输入的值被保存在 Value属性和 Text属性中。并可以使用 ControlSource属性与数据环境中一个表的某一字段建立连接。

Page 55: 涪陵职业教育中心 吴玉琼    制作

7.3.3 7.3.3 编辑框编辑框 编辑框一般用于对表中的备注型字段的内容进行编辑。编辑框的常用属性如表 7-11 所示。属 性 说 明AllowTabs 确定在编辑框中用户能否插入 Tab键ControlSource 指定与对象建立联系的数据源。Format K 当该控件得到焦点时选择所有文本

D 使用当前的 SET DATA 设置的日期格式HideSelection 确定在编辑框中选定的文本在编辑框没获得焦点时是否仍然显

示为被选定ReadOnly 用户能否修改编辑框中的文本ScrollBars 是否具有垂直滚动条SelLength 返回所选定字符的数目或指定要选定的字符数目SelStart 返回所选定文本的起始点位置或指出插入点的位置SelText 返回用户在编辑框的文本输入区所选定的文本

Value 编辑框当前状态的值

Page 56: 涪陵职业教育中心 吴玉琼    制作

【例 7-1】在编辑框中选择截止到第一个逗号前的所有字符,并在消息框中显示当前所选中的字符串。 Student表包含一个名为 BZ的备注型字段 , 其值“该同学在校期间表现良好,学习成绩优秀。”新建一个表单,在【数据环境】中添加 Student表,再在表单上添加一个编辑框,并设置编辑框的 ControlSource属性为 Student.BZ在表单的 Click Event过程中添加如下代码:ThisForm.EDIT1.SELSTART=0ThisForm.EDIT1.SELLENGTH=AT(", ",ThisForm.EDIT1.Value)–1=MessageBox(ThisForm.Edit1.SelText,64)运行表单,然后在表单上任意位置单击,结果如下图所示。

Page 57: 涪陵职业教育中心 吴玉琼    制作

7.3.4 7.3.4 命令按钮命令按钮 命令按钮在表单里是很常用的控件之一,通常被用来进行某一操作。命令按钮的常用属性如表 :

属 性 说 明Cancel 当该项为 .T.时,回车时相当于执行“ Esc”Caption 在按钮上显示的标题Default 当该项为 .T.时,回车时相当于“ Click”DisablePicture当按钮失效时,显示的 .BMP 图片DownPicture 当按钮按下时,显示的 .BMP 图片Enabled 能否选择此按钮Picture 显示在按钮上的 .BMP 图片 在使用 Picture、 DisablePicture和 DownPicture属性时,这3个属性允许选择一个 .BMP文件作为命令按钮的标题显示。

Page 58: 涪陵职业教育中心 吴玉琼    制作

命令按钮的属性只是对命令按钮进行布局设置的一些参数,但命令按钮在表单中最主要的作用还是执行一些相应的操作,命令按钮最主要的事件如下表。事 件 说 明Click 在按钮上按下并释放主鼠标键时产生此事件MiddleClick 在按钮上按下并释放鼠标的中间键时产生此事件MouseDown 在按钮上按下主鼠标键时产生此事件MouseUp 在按钮释放主鼠标键时产生此事件RightClick 在按钮上按下并释放辅鼠标键时产生此事件命令按钮的事件除了使用鼠标操作产生以外,也可以通过方法程序触发相应的事件。要使用 VFP6 对某一事件产生相应的响应,还应在相应事件的方法程序中编写事件代码,指定在产生事件时执行相应的操作。

Page 59: 涪陵职业教育中心 吴玉琼    制作

【例 7-2 】 建立如图所示的表单,在该表单中可以打开一个指定的表或浏览指定的表。注意:演示此程序时要将指定的表设置在系统的搜索路径上。

其中的对象及属性设置如表 7-14 所示

Page 60: 涪陵职业教育中心 吴玉琼    制作

命令按钮的 Click 方法程序如下: ① Command1 (打开表)的 Click 方法程序。

cTABLENAMESR=ALLTRIM(ThisForm.TEXT1.Value) && 将输入的表名存入一个变量nPOINT=AT(".DBF",UPPER(cTABLENAMESR)) && 判断输入表名的扩展名位置cTABLENAME=IIF(nPOINT=0,cTABLENAMESR,LEFT(cTABLENAMESR,;

nPOINT–1)) && 提取不含扩展名的表名IF FILE(cTABLENAME+“.DBF”) && 判断输入的表文件是否存在IF USED(cTABLENAME) && 判断输入的表是否已打开 Select (cTABLENAME) ELSE Select 0 USE (cTABLENAME) ENDIFELSE =MESSAGEBOX(" 所输入的表不存在! ",32) && 提示输入的表不存在ENDIF

② Command2 (浏览表)的 Click 方法程序。ThisForm.COMMAND1.CLICK && 通过程序触发“打开表”命令按钮的 Click 事件BROWSE NOEDIT && 在浏览窗口中浏览表,但不允许编辑USE

③ Command3 (退出)的 Click 方法程序。ThisForm.RELEASE

Page 61: 涪陵职业教育中心 吴玉琼    制作

7.3.5 7.3.5 命令按钮组命令按钮组 命令按钮组是将能执行一系列相关操作的命令按钮放在一起而编成的组。这样做的优点是可以将公共代码放在组内的同一个方法程序里。命令按钮组内的每一个命令按钮都具有命令的常用属性和常用事件,命令按钮组还有表 7-15 所示的常用属性。 表 7-15 命令按钮组常用的一些属性

属 性 说 明BackStyle 命令按钮组是否有透明或不透明的前景ButtonCount 命令按钮组中按钮的数目Value 当前选中的命令按钮的序号

【例 7-3 】利用命令按钮组设计一个简单的计算器。表单格式设计右图 , 表单及其对象属性设置如表 7-16 所示。

Page 62: 涪陵职业教育中心 吴玉琼    制作

命令按钮组的 Click 事件的方法程序代码( CommandGroup1.Click() ):Do Case Case This.Value=1

ThisForm.Text3.Value=ThisForm.Text1.Value+ThisForm.Text2.Value Case This.Value=2

ThisForm.Text3.Value=ThisForm.Text1.Value-ThisForm.Text2.Value Case This.Value=3

ThisForm.Text3.Value=ThisForm.Text1.Value*ThisForm.Text2.Value Case This.Value=4

If ThisForm.Text2.Value#0 ThisForm.Text3.Value=ThisForm.Text1.Value/ThisForm.Text2.ValueElse =MessageBox(" 除数不能为零! ",48)EndIf

OtherwiseThisForm.Text1.Value=0ThisForm.Text2.Value=0ThisForm.Text3.Value=0

EndCase

Page 63: 涪陵职业教育中心 吴玉琼    制作

7.3.6 7.3.6 选项按钮组选项按钮组 选项按钮组 又称为单选按钮,它有两种工作状态:选中的单选按钮,这时圆按钮的中心有黑色圆点醒目显示;未选中的单选按钮,这时圆按钮的中心无黑色圆点。单选按钮的常用属性如下表。属 性 说 明ButtonCount 单选按钮的数目ControlSource 单选按钮的数据来源DisabledBackColor单选按钮失效时的背景颜色DisabledForeColor 单选按钮失效时的前景颜色Value 当前选中的单选按钮序号或当前选中的单选按

钮的 Caption属性值Caption 单选按钮的显示文本 说明: Value的初始值若为数值型,则该属性返回当前选中的单选按钮的序号;若初始值为字符型,则该属性返回当前选中的单选按钮的 Caption属性值。在每组单选按钮中任何时刻最多只能有一个选中的单选按钮。

Page 64: 涪陵职业教育中心 吴玉琼    制作

【例 7-4 】利用选项按钮组改变标签前景色和字体。表单布局设计如右图 ,表单及其对象属性设置下表。

选项按钮组还有两个常用的事件: Click 和 InteractiveChange (此事件是当用户通过鼠标或键盘更改控件的值时发生的)

Page 65: 涪陵职业教育中心 吴玉琼    制作

本示例的方法程序代码如下:① 表单的 Init事件代码 (Form1.Init()):ThisForm.Label1.ForeColor=RGB(255,0,0)② 选项按钮组 1的 Click事件代码 (OptionGroup1.Click()):Do Case Case This.Value=1 ThisForm.Label1.ForeColor=This.Option1.BackColor Case This.Value=2 ThisForm.Label1.ForeColor=This.Option2.BackColor Case This.Value=3 ThisForm.Label1.ForeColor=This.Option3.BackColor Case This.Value=4 ThisForm.Label1.ForeColor=This.Option4.BackColorEndCase ③ 选项按钮组 2的 Click事件代码 (OptionGroup2.Click( )):ThisForm.Label1.FontName=This.Value

Page 66: 涪陵职业教育中心 吴玉琼    制作

7.3.7 7.3.7 复选框复选框 复选框 又叫选择框,它有 3 种状态:打开的选择框,这时框中有一个“√”,表示用户选择了该选择框;关闭的选择框,这时框中无任何标志;灰色的选择框,这时选择框和文本为暗淡色。复选框的常用属性如下表。 属 性 说 明Caption 指定选择项功能或值的文本ControlSource 指定用作选择项的数据源。通常是表中的逻辑型字段Value 返回选择项状态值。选中时为 .T.,未选中时

为 .F.,无效状态为 .Null.【例 7-5】使用复选框设置文本框中字体的式样。表单设计如图

Page 67: 涪陵职业教育中心 吴玉琼    制作

复选框应用示例表单中对象属性如下表:

方法程序代码如下:① Check1.Click( ):ThisForm.Text1.FontBold=This.Value② Check2.Click( ):ThisForm.Text1.FontItalic=This.Value③ Check3.Click( ):ThisForm.Text1.FontUnderLine=This.Value④ Check4.Click( ):ThisForm.Text1.FontStrikethru=This.Value

Page 68: 涪陵职业教育中心 吴玉琼    制作

7.3.8 7.3.8 组合框组合框 组合框又称为下拉列表框或下拉组合框。它提供给用户从一组数据项中选择其中一个数据项的控件。常用的组合框属性如下表。属 性 说 明ColumnCount 指定组合框控件中列对象的数目ColumnLines 显示或隐藏列之间的分隔线ColumnWidths 指定组合框控件的列宽。有多列时指定ControlSource 用户从列表框中选择的值保存在何处IncrementalSearch 指定用户在键入每一个字母时,控件是否和列表中的

项匹配ListCount 组合框列表部分数据项的数目ListIndex 组合框中选定数据项的索引值RowSource 组合框中显示的值的数据来源RowSourceType 指定与组合框建立联系的数据源的类型,可以是下面

的一种: 0—无; 1— 值; 2—别名; 3—SQL语句; 4— 查询; 5— 数组; 6— 字段; 7— 文件; 8—结构;9— 弹出式菜单Selectd 判断用户是否选中了该列表项Style 指定控件的样式。 0— 下拉组合框; 2— 下拉列表框

Page 69: 涪陵职业教育中心 吴玉琼    制作

组合框通常用于对数据项的选择,对其操作时有一些经常用到的事件,如下表所示。 表 7-22 组合框中常用的事件方法事 件 说 明AddItem 向组合框中添加新的数据项的方法程序,是

否指定该数据项的索引是可选的Click 单击鼠标左键时发生GotFocus 当组合框获得焦点时发生InteractiveChang 当通过键盘或鼠标更改组合框的值时发生LostFocus 当组合框失去焦点时发生RemoveItem 从组合框中移去一个数据项时发生Requery 重新查询与组合框建立联系的行源 组合框使用方法的难点在于掌握数据源类型( RowSourceType )的使用。通过设置 RowSource 和 RowSourceType 属性,可以用不同数据源中的项填充组合框。下面以组合框 Combo1 对象加以说明。

Page 70: 涪陵职业教育中心 吴玉琼    制作

■RowSourceType设为 0-无:此时不能自动填充数据项,可用Additem方法添加数据项。Form1.Combo1.RowsurceType=0Form1.Combo1.AddItem(“ 数据项 1”)Form1.Combo1.AddItem(“ 数据项 2”)但是在添加一个数据项之前,最好检查一下,保证在组合框中没有该值。如使用下面的程序代码添加在组合框中输入的数据项: lItemExists=.F.For ii=1 to This.ListCount If This.List(ii)=This.Text LItemExists=.T. Exit EndIfEndForIf ! lItemExists This.AddItem(This.Text)EndIf

RemoveItem方法程序将从数据项列表中移去指定的列表项。例如,下面的代码从列表中移去数据项中的第 2项数据:Form1.combo1.RemoveItem(2)

Page 71: 涪陵职业教育中心 吴玉琼    制作

■RowSourceType设为 1-值:若将 RowSourceType属性设置为 1,可用 RowSource属性指定多个要在数据项中显示的值。如果在“属性”对话框中设置 RowSource属性,则要用逗号分隔列表项;要在程序中设置 RowSource属性,则要用逗号分隔列表项,并用引号括起来。Form1.Combo1.RowSourceType=1Form1.Combo1.RowSource="one,two,three,four"■RowSourceType设为 2- 别名:若将 RowSourceType属性设置为 2,可以在列表中包含打开表的一个或多个字段值。如果 ColumnCount属性设为 0或 1,则列表将显示表中第一个字段值;如果 ColumnCount属性设为 2,则列表将显示表中最前面的 2个字段的值。依此类推。注意:如果 RowSourceType属性设置为 2或 6,则当用户在列表中选择新值时,表的记录指针将移动到用户所选项的记录上。

Page 72: 涪陵职业教育中心 吴玉琼    制作

■RowSourceType设为 3-SQL 语句:此时在 RowSource属性中包含一个 SQL 语句。例如:Form1.Combo1.RowSourceType=3Form1.Combo1.RowSource=;"Select * From Student Into Cursor Mylist"在程序中设置 RowSource属性时,要将 Select 语句用引号括起来。默认情况下,不带 Into子句的 Select 语句立刻在“浏览”窗口中显示得出的临时表。■RowSourceType设为 4-查询:如果将 RowSourceType属性设置为 4 ,则可以用查询的结果填充组合框,即要将 RowSource属性设置为 .QPR文件。例如,用下面的一行代码可将组合框的 RowSource属性设置为一个查询MyQuery.qpr:Form1.Combo1.RowSource="MyQuery.qpr" ■RowSourceType设为 5-数组:如果将 RowSourceType属性设置为 5,可以用数组中的项填充列表。例如,将一个属于表单 Form1的数组作为填充列表数据源。Form1.Combo1.RowSourceType=5Forml.Combo1.RowSourc="ThisForm.Myarray"

Page 73: 涪陵职业教育中心 吴玉琼    制作

■RowSourceType设为 6-字段:如果将 RowSourceType设置为 6 ,则可指定一个字段或多个字段来填充列表。例如:Form1.Combo1.RowSourceType=6Form1.Combo1.RowSource="Student.Name,Student_ID,Birthday"对于 RowSourceType属性为 6 的组合框,可在 RowSource属性中包含下列几种信息:① 字段。② 别名 .字段。③ 别名 .字段 ,字段 ,字段…■RowSourceType设为 7-文件:如果将 RowSourceType设置为 7,则表示可将当前目录下的文件填充列表,且列表中的选项允许选择不同的驱动器和目录,并在列表中显示其中的文件名。可将 RowSource属性设置为列表中显示的文件类型(如: *.bmp)。■RowSourceType设为 8- 结构:此时表示用 RowSource属性指定的表中的字段名来填充列表。■RowSourceType 设为 9- 弹出式菜单:用已定义的弹出式菜单来填充列表。

Page 74: 涪陵职业教育中心 吴玉琼    制作

【例 7-6 】使用组合框和选项按钮组配合对 Student 表中的记录进行查询。表单界面设计如右图,表单上控件的主要属性如下表。

Page 75: 涪陵职业教育中心 吴玉琼    制作

表单中的方法程序如下:◆ Form1.OptionGroup1.InteractiveChange():ThisForm.Combo1.DisplayValue=" "ThisForm.Combo1.Visible=.T.ThisForm.Combo1.RowSourceType=3Do Case Case This.Value=1 ThisForm.Combo1.RowSource="Select DISTINCT Student.Classes From ; Xsglxt!Student Into CURSOR newquery" Case This.Value=2 ThisForm.Combo1.RowSource="Select DISTINCT Student.Sex From ; Xsglxt!Student Into CURSOR newquery" Case This.Value=3ThisForm.Combo1.RowSource="Select DISTINCT Left(Student.Name,2) From

;Xsglxt!Student Into CURSOR newquery" Otherwise ThisForm.Combo1.RowSourceType=0 ThisForm.Combo1.RowSource=" " ThisForm.Combo1.Visible=.F. Set Filter To Locate ThisForm.RefreshENDCase

Page 76: 涪陵职业教育中心 吴玉琼    制作

ThisForm.Combo1.ListIndex=1ThisForm.Combo1.SetFocusThisForm.Refresh◆ Form1.Combo1.GotFocus():This.InteractiveChange◆ Form1.Combo1.InteractiveChange():cExact=Set("Exact")Set Exact OnDo Case Case ThisForm.OptionGroup1.Value=1 cExpr='Set Filter To Classes="'+AllTrim(This.Value)+ '" ' Case ThisForm.OptionGroup1.Value=2 cExpr='Set Filter To Sex="'+AllTrim(This.Value)+'"' Case ThisForm.OptionGroup1.Value=3 Set Exact Off cExpr='Set Filter To AllTrim(Name)="'+AllTrim(This.Value)+'"' Case ThisForm.OptionGroup1.Value=4 cExpr='Set Filter To'EndCase&cExprLocateThisForm.Combo2.RowSourceType=6ThisForm.Combo2.RowSource="Student.Name"ThisForm.Combo2.ControlSource="Student.Name"

续:ThisForm.RefreshSet Exact &cExact◆ Form1.Combo2.Init( ):This.ListIndex=1◆ Form1.Combo2.InteractiveChange( ):ThisForm.Text1.Refresh

Page 77: 涪陵职业教育中心 吴玉琼    制作

7.3.9 7.3.9 列表框列表框列表框和下拉列表框(即 Style属性值为 2的组合框)为用户提供了包含一些选项和信息的可滚动列表。在列表框中,任何时候都能看到多个项;而在下拉列表中,只能看到一个项,用户可以单击向下按钮来显示可滚动的下拉列表。列表框具有组合框中除 Style 以外的所有属性,另外还有下表所示的常用属性。属 性说 明MoverBars 是否在列表框左侧显示移动按钮,MultiSelect 用户能否从列表中一次选择一个以上的项注意:列表框的 Value属性可以是数值型,也可以是字符型,默认值为数值型。如果 RowSource是一个字符型值,并且想让 Value属性反映列表框中选定的字符串,则要将 Value属性设置为空字符串。方法是先按空格键,再按“←”或“ BackSpace”键。列表框也具有组合框的常用事件和方法。列表框的 RowSourceType属性和组合框相同,因而其 RowSource属性和 ControlSource属性的设置方法也基本相同。下面介绍一些列表框的其他使用方法。

Page 78: 涪陵职业教育中心 吴玉琼    制作

1、创建具有多列的列表框虽然列表框默认为一列,但 VFP6 中的列表框可以包含任意列。多列列表框和表格的区别在于,在多列列表框中一次选择一行,而在表格中可以选择每一个单元。另外,不能直接编辑列表框中的数据。要在列表框中显示多列,有如下方法:① 将 ColumnCount属性设置为所需要的列数。② 设置 ColumnWidths属性。例如,如果列表框中有 3项,下面的命令将各列的宽度分别设置为 25、 40和 75。ThisForm.List1.ColumnWidths="25,40,75"③ 将 RowSourceType属性设置为 6-字段。④ 将 RowSource属性设置成为列中显示的字段。例如,用下面的命令将 3列列表框的 3个列数据源设置为 Student表中的 Student_ID 、 Name和 Sex 字段。ThisForm.List1. RowSource="Student_ID,Name,Sex“2、允许用户选择列表框中的多项默认情况下,一次只能选定列表框中的一项,但也允许用户选择列表框中的多个项。若要选择列表框中的多项,可将列表框的 MultiSelect属性设置为 .T.。

Page 79: 涪陵职业教育中心 吴玉琼    制作

为了处理选定的项,例如,把它们复制到一个数组或在应用程序的其他地方使用它们,可以循环遍历各列表项,处理 Selected属性为 .T.的项。下面的代码包含在列表框的 InteractiveChange事件中,在 Combo1 组合框中显示这个列表框中的选定项,并且在 Text1文本框中显示选定项的数目。nNumberSelected=0 &&跟踪数目的变量 ThisForm.cboSelected.Clear &&清除组合框 For ii=1 To This.ListCount If This.Selected(ii) nNumberSelected= nNumberSelected +1 ThisForm.Combo1.AddItem(This.List(ii)) EndIfEndForThisForm.Text1.Value= nNumberSelected3、允许用户在列表框中添加项除了让用户从列表框中选择项外,还允许用户交互地向列表框中添加项。若要以交互方式向列表框添加项,则需使用 Additem 方法程序。

Page 80: 涪陵职业教育中心 吴玉琼    制作

在下面示例中,当用户按 Enter 键时,文本框 KeyPress的事件中的代码将文本框中的文本添加到一个列表框中,并且清除文本框中的文本。Lparameters nKeyCode,nShiftAltCtrlIf nKeyCode=13 && Enter 键 Thisform.List1.Additem(This.Value) This.Value="" EndIf【例 7-7 】 建立一个具有两个列表框的表单,列表框中的数据项可以在两个列表框中互移。在数据环境中添加 Student 表,表单布局如右图,主要属性如后表。

Page 81: 涪陵职业教育中心 吴玉琼    制作

表单中的方法程序如下。◆Form1.Init( ) :Public nNoSelectednNoSelected = 0ThisForm.List1.ListIndex=1◆ Form1.CommandGroup1.Click( ) :Do Case Case This.Value=1 lFirstSelected=.T. && 用于判断一个选择项 For i = 1 To ThisForm.List1.ListCount If ThisForm.List1.Selected(i) If lFirstSelected nOldIndex=I && 保存第一个选择项的索引值 lFirstSelected=.F. EndIf nNoSelected = nNoSelected + 1 ThisForm.list2.Additem (ThisForm.List1.List(i)) && 向列表框 2 添加数据项 ThisForm.List1.RemoveItem(i) && 从列表框 1 移去数据项 i=i–1 && 保持索引号不变 EndIf EndFor If ThisForm.List1.ListCount<nOldIndex ThisForm.List1.ListIndex=nOldIndex–1 && 设置列表框 1 的选择项 Else

Page 82: 涪陵职业教育中心 吴玉琼    制作

ThisForm.List1.ListIndex=nOldIndex EndIf ThisForm.List2.ListIndex=nNoSelected Case This.Value=2 For i = 1 To ThisForm.List1.ListCount nNoSelected = nNoSelected + 1 ThisForm.list2.Additem (ThisForm.List1.List(1)) ThisForm.List1.RemoveItem(1) EndFor ThisForm.List2.ListIndex=nNoSelected Case This.Value=3 nOldIndex=ThisForm.List2.ListIndex nNoSelected = nNoSelected-1 ThisForm.List1.AddItem(ThisForm.List2.Value) ThisForm.List2.RemoveItem(ThisForm.List2.ListIndex) If ThisForm.List2.ListCount<nOldIndex ThisForm.List2.ListIndex=nOldIndex–1 Else ThisForm.List2.ListIndex=nOldIndex EndIf Case This.Value=4 For i = 1 To ThisForm.List2.ListCount ThisForm.list1.Additem (ThisForm.List2.List(1)) ThisForm.List2.RemoveItem(1)

Page 83: 涪陵职业教育中心 吴玉琼    制作

EndFor nNoSelected = 0 Case This.Value=5 ThisForm.ReleaseEndCaseIf ThisForm.List1.ListCount=0 ThisForm.CommandGroup1.Command1.Enabled=.F. ThisForm.CommandGroup1.Command2.Enabled=.F.Else ThisForm.CommandGroup1.Command1.Enabled=.T. ThisForm.CommandGroup1.Command2.Enabled=.T.EndIfIf ThisForm.List2.ListCount=0 ThisForm.CommandGroup1.Command3.Enabled=.F. ThisForm.CommandGroup1.Command4.Enabled=.F.Else ThisForm.CommandGroup1.Command3.Enabled=.T. ThisForm.CommandGroup1.Command4.Enabled=.T. EndIfThisForm.text1.Value = nNoSelectedThisForm.Refresh

Page 84: 涪陵职业教育中心 吴玉琼    制作

7.3.10 7.3.10 微调按钮微调按钮

微调按钮主要用于接受一定范围内的数值的输入,其常用属性如下表。微调按钮的向上箭头和向下箭头允许用户增加和减少数值。默认情况下,每次增加或减少的值为 1.00 ,但可以通过设置微调按钮的 Increment 属性来设置增加或减少的值。属 性 说 明Increment 用户每次单击向上或向下按钮时增加或减少的数值KeyboardHighValue 用户能输入到文本框中的最高值KeyboardLowValue 用户能输入到文本框中的最低值SpinnerHighValue 用户单击向上按钮时,微调控件能显示的最高值SpinnerLowValue 用户单击向下按钮时,微调控件能显示的最低值 【例 7-8】利用两个文本框设置微调按钮的最高值和最低值。表单设计如下图,表单中各控件的基本属性如下表。

Page 85: 涪陵职业教育中心 吴玉琼    制作

表单中控件的方法程序如下。◆Form1.Text1.InteractiveChange() :ThisForm.Spinner1.KeyboardHighValue=This.ValueThisForm.Spinner1.SpinnerHighValue=This.Value◆ Form1.Text1.Valid( ) :IF This.Value<ThisForm.Text2.Value =MessageBox("最大值不能小于最小值! ",48) This.Value=ThisForm.Text2.Value EndIf◆ Form1.Text1.LostFocus( ) :ThisForm.Spinner1.Value=IIF(ThisForm.Spinner1.Value>This.Value,This.Value,;ThisForm.Spinner1.Value)◆ Form1.Text2.InteractiveChange( ) :ThisForm.Spinner1.KeyboardLowValue=This.ValueThisForm.Spinner1.SpinnerLowValue=This.Value◆ Form1.Text2.Valid( ) :IF This.Value>ThisForm.Text1.Value =MessageBox("最小值不能大于最大值! ",48) This.Value=ThisForm.Text1.Value EndIf◆ Form1.Text2.LostFocus( ) :ThisForm.Spinner1.Value=IIF(ThisForm.Spinner1.Value<This.Value,This.Value, ;ThisForm.Spinner1.Value)

Page 86: 涪陵职业教育中心 吴玉琼    制作

7.3.11 7.3.11 表格控件表格控件 VFP6 拥有一个强有力的工具:表格对象。它可显示和操作多行数据。表格控件是一个容器对象,它能包含列。这些列除了包含标头和控件外,每一个列还拥有自己的一组属性、事件和方法程序。表格对象能在表单或页面中显示并操作行和列中的数据。如果没有指定表格的 RecordSource属性,同时在当前工作区中有一个打开的表,那么表格将显示这个表的所有字段。1、常用的表格属性和列属性下表列出了设计时常用的表格属性,表 7-29 列出了在设计时常用的列属性。 属 性 说 明ChildOrder 和父表主关键字相连的子表中的外部关键字ColumnCount 列的数目。如果 ColumnCount 设置为– 1 ,表格将具有 和表格数据源中字段一样多的列LinkMaster 显示在表格中的子记录的父表RecordSource 表格中要显示的数据RecordSourceType 表格中显示数据来源于何处:表、别名、查询

或用户根据提示选定的表

Page 87: 涪陵职业教育中心 吴玉琼    制作

表 7-29 设计时常用的列属性 属 性 说 明ControlSource 在列中要显示的数据。Sparse 如果将 Sparse 属性设置为 .T. ,表格中控件只有在列中的单元

被 选中时才显示为控件。列中的其他单元将显示文本框中下面的 数据值。将 Sparse 设置为 .T. ,允许用户在滚动一个有很多显

示 行的表格时能快速重画CurrentControl 表格中哪一个表格是活动的。默认值为“ Textl” 。如果在列中

添 加了一个控件,则可以将它指定为 CurrentControl

注意:列中控件的 ReadOnly属性被列的 ReadOnly属性覆盖。如果在和 AfterRowColChange事件相关的代码中设置列中控件的 ReadOnly属性,则当指针位于该列时,新的设置有效。2、向表格添加记录将表格的 AllowAddNew 属性设置为 .T. ,可以允许用户向表格中显示的表中添加新的记录。如果将 AllowAddNew 属性设置为 .T. ,当用户选中了最后一条记录,并且按下“↓”键时,就向表中添加新记录。如果还想进一步控制用户什么时候向表中添加新记录,则可以将 AllowAddNew 属性设置为默认的 .F. ,并使用 APPEND BLANK 或 INSERT 命令添加新记录。

Page 88: 涪陵职业教育中心 吴玉琼    制作

3、使用表格控件创建一对多表单表格最常见的用途之一是:当文本框显示父记录数据时,表格显示表的子记录;当用户在父表中浏览记录时,表格记录显示相应变化。如果表单的数据环境包含两表之间的一对多关系,那么要在表单中显示这个一对多关系非常容易。设置具有数据环境的一对多表单时,有如下方法:① 将需要的字段从“数据环境”中的父表拖动到表单中。② 从“数据环境”中将相关的表拖动到表单中。4 、在表格列中显示控件除了在表格中显示字段数据外,还可以在表格的列中嵌入控件,如嵌入的文本框、复选框、下拉列表框、微调按钮等控件。例如,如果表中有一个逻辑字段,当运行该表单时,通过辨认复选框就可以判定哪条记录值是 .T.和哪条记录值是 .F.。修改这些值只需设置或清除复选框即可。可以在“表单设计器”向表格列中添加控件,也可以通过编写代码在运行时添加控件。

Page 89: 涪陵职业教育中心 吴玉琼    制作

■ 要在“表单设计器”中向表格列中添加控件时,可用如下方法:①在“属性”窗口的“对象”框中为控件选择父列;②在“表单控件”工具栏中选择所要的控件,然后单击父列。在“表单设计器”中,新控件不在表格列中显示,但在运行时会显示出来;注意:如果新加入的控件是一个复选框,则应将复选框的 Caption 属性设置为空字符串,并将列的 Sparse 属性设置为 .F. 。③将父列的 ControlSource属性设置为需要的表字段;④ 将父列的 CurrentControl属性设置为新加入的控件。注意:如果想让复选框在表格列中居中,则可先创建一个容器类,将复选框添加到容器类中,并调整复选框在容器类中的位置。然后将容器类添加到表格列中,并将复选框的 ControlSource属性设置为需要的字段。■ 要在“表单设计器”中移去表格列中的控件时,可用如下方法:① 在“属性”窗口的“对象”框中选择要移去的控件;② 激活“表单设计器”。如果“属性”窗口可见,则控件的名称将显示在“对象”框中。③ 按 Delete 键。注意:在表格级上设置的属性并不会传到列或标头上。因此,必须直接设置标头属性或包含控件,它们不从列级别的设置中继承属性。

Page 90: 涪陵职业教育中心 吴玉琼    制作

5、使用表格“生成器”生成表格■ 要使用表格“生成器”生成单表表格时,可用如下方法:① 向表单“数据环境”中添加所需要的表,并将表格控件添加到表单中调整到所需大小;② 在表格控件上单击鼠标右键,在快捷菜单中选择【生成器】。在当前数据库中选择一个表,并将需要在表格中显示的字段添加到“选定字段”列表框中;③ 其它设置根据提示完成。■ 要使用表格“生成器”生成一对多表表单时,可用如下方法:① 向表单“数据环境”中添加所需要的表,添加表的顺序是先加主表,后加子表;② 在表格控件上单击鼠标右键,在快捷菜单中选择【生成器】。在当前数据库中选择子表,并将需要在表格中显示的字段添加到“选定字段”列表框中;③ 主表和子表关系设置。可以通过选择“ 4.关系”,在“父表中的关键字段”组合框中选择父表的主关键字,然后在“子表中的相关索引”组合框中选择与父表主关键字相匹配的子表索引;④其它操作按提示完成。

Page 91: 涪陵职业教育中心 吴玉琼    制作

6 、 表格控件应用示例【例 7-9 】建立一个多表表单,以文本框反映主表( Student)中的部分信息,用表格反映子表( Grade)的信息,同时通过其他控件改变表格的样式。表单设计如下图。

表单中的所有控件的主要属性此处略去,见教材。

Page 92: 涪陵职业教育中心 吴玉琼    制作

表单中控件的方法程序如下。◆ Form1.Init( ) :ThisForm.Spinner1.Value=Fcount(ThisForm.Grid1.RecordSource)ThisForm.Combo1.ListIndex=4ThisForm.Combo2.ListIndex=4For ii=1 To Fcount(ThisForm.Grid1.RecordSource) ThisForm.FieldArray(ii)=ThisForm.Grid1.Columns(ii).Header1.CaptionEndFor◆ Form1.Check1.Click( ) :IF This.Value=0 ThisForm.Grid1.DeleteMark=.T.Else ThisForm.Grid1.DeleteMark=.F.EndIf◆ Form1.Spinner1.InteractiveChange( ) :ThisForm.Grid1.ColumnCount=This.Value◆ Form1.Spinner1.UpClick( ) :ThisForm.Grid1.Columns(This.Value).Header1.Caption=ThisForm.FieldArray(This.Value)◆ Form1.Combo1.InteractiveChange( ) :ThisForm.Grid1.ScrollBars=Val(Left(This.Value,1))◆ Form1.Combo2.InteractiveChange( ) :ThisForm.Grid1.GridLines=Val(Left(This.Value,1))

Page 93: 涪陵职业教育中心 吴玉琼    制作

◆ Form1.CommandGroup1.Click( ) :Do Case Case This.Value=1 Go Top Case This.Value=2 Skip –1 IF Bof( ) Go Top EndIf Case This.Value=3 Skip IF Eof( ) Go Bottom EndIf Case This.Value=4 Go Bottom Case This.Value=5 ThisForm.ReleaseEndCaseThisForm.Refresh

Page 94: 涪陵职业教育中心 吴玉琼    制作

7.3.12 7.3.12 图像控件图像控件 图像控件的常用属性如下表所示。属 性 说 明Picture 要显示的 .BMP 文件BorderStyle 决定图像是否具有可见的边框Stretch 设为 0( 裁剪 ) ,超出图像控件范围的部分不显示,设 为 1( 恒定比例 ) ,将保留 .BMP 图片的原有比例,并在 图像控件中显示最大可能的图片,设为 2( 伸展 ) ,将 图片调整到正好与图像控件的高度和宽度匹配

【例 7-10 】图像控件应用示例。建立表单如右图所示,表单上控件的主要属性如下表所示。

Page 95: 涪陵职业教育中心 吴玉琼    制作

表单中控件的方法程序如下。◆Form1.Init( ) :Public cPictureTypecPictureType="*.JPG“ThisForm.Combo1.ListIndex=1◆Form1.Command1.Click( ) :ThisForm.Release◆Form1.Check.Click( ) :ThisForm.Image1.BorderStyle=This.Value◆Form1.Combo1.InteractiveChange( ) :ThisForm.Image1.Stretch=Val(Left(This.Value,1))◆Form1.List1. InteractiveChange( ) :cSelectedFile=Alltrim(this.listitem(2))+alltrim(This.Value)IF Upper(Right(cSelectedFile,4))=Right(Upper(cPictureType),4) ThisForm.Image1.Picture=cSelectedFile EndIf◆Form1.OptionGroup1. InteractiveChange( ) :cPictureType=IIF(This.Value=1,"*.JPG","*.BMP")

ThisForm.List1.RowSource=cPictureType

Page 96: 涪陵职业教育中心 吴玉琼    制作

7.3.13 7.3.13 计时器控件计时器控件 计时器控件 :每个计时器都有一个 Interval属性,它指定一个计时器事件到下一个计时器事件之间的时间间隔 (毫秒 )。如果计时器有效,它将以近似等间隔的时间触发Timer事件。在使用计时器编程时,必须考虑 Interval属性的几条限制。① 间隔的范围从 0到 2147483647,包括 0和 2147483647,这意味着最长的间隔约为 596.5 小时 (超过 24 天 )。② 间隔并不能保证经过时间的精确性。为确保精确,计时器应及时检查系统时钟,不以内部累积的时间为准。③ 系统每秒钟产生 18次时钟跳动,虽然 Interval属性是以毫秒作为计量单位的,但间隔的真正精确度不会超过 1/18 秒。计时器控件有以下两个主要属性。Enabled:决定计时器是否工作。Interval: Timer事件之间的毫秒数。注意:计时器的 Enabled 属性和其他对象的 Enabled 属性不同。对大多数对象来说, Enabled 属性决定对象是否能对用户引起的事件作出反应。对计时器控件来说,将 Enabled 属性设置为 .F. ,会挂起计时器的运行 。

Page 97: 涪陵职业教育中心 吴玉琼    制作

【例 7-11】使用计时器控件来设计两个数字时钟——自定义时钟和系统时钟,使自定义时钟能与系统时钟同步。设计表单如右图所示,表单中各控件的主要属性如右下表所示:

表单中控件的方法程序如下。◆Form1.Init( ) :Public nHour,nMinute,nSecondsnHour=Hour(DateTime( ))nMinute=Minute(DateTime( ))

nSeconds=Sec(DateTime( ))

Page 98: 涪陵职业教育中心 吴玉琼    制作

◆Form1.Timer( ) :ThisForm.Text1.Value=Time( )nSeconds=nSeconds+1IF nSeconds=60 nMinute=nMinute+1 nSeconds=0

IF nMinute=60nHour=nHour+1nMinute=0nHour =IIF(nHour=24,0, nHour)

EndIF EndIFThisForm.Text2.Value=IIF(nHour<10,"0"+Alltrim(Str(nHour)),Alltrim(Str(nHour))) ;

+":"+IIF(nMinute<10,"0"+Alltrim(Str(nMinute)),Alltrim(Str(nMinute)))+ ; ":"+IIF(nSeconds<10,"0"+Alltrim(Str(nSeconds)), Alltrim(Str (nSeconds)))

◆Form1.Command1( ) : nHour=Hour(DateTime( )) nMinute=Minute(DateTime( )) nSeconds=Sec(DateTime( ))◆Form1.Command2( ) : ThisForm.Release

Page 99: 涪陵职业教育中心 吴玉琼    制作

7.3.14 7.3.14 页框控件页框控件页框控件是由若干页组成的容器对象,页中还可以包含若干控件。页框中定义了每页的位置和可见的页数,每页的左上角固定在页框的左上角上,而控件则置于每页上,只有顶层页中的控件是可见和活动的。页框的常用属性如表 7-34 所示:属 性 说 明TabStretch 用于显示选项卡的长标题。如果选项卡的标题太长,

应设为 0( 堆积 ) 。默认为 1( 裁剪 )Tabs 确定页面的选项卡是否可见PageCount 页框的页面数,默认值为 2Activepage 页框当前活动的页面

Page 100: 涪陵职业教育中心 吴玉琼    制作

【例 7-12】使用一个页框控件进行记录筛选。表单设计如下图所示,表单中各控件的主要属性如右表所示:

Page 101: 涪陵职业教育中心 吴玉琼    制作

表单中控件的方法程序如下:◆Form1. PageFrame1.Page1.Command1.Click( ) :Exps=".T."IF NOT Empty(ThisForm.Pageframe1.Page1.Text1.Value) Exps=Exps+[ AND Student_ID="]+Alltrim(ThisForm.Pageframe1.Page1.Text1.Value)+["]EndIFIF NOT Empty(ThisForm.Pageframe1.Page1.Text2.Value) Exps=Exps+[.AND."]+Alltrim(ThisForm.Pageframe1.Page1.Text2.Value)+["$Name]EndIFIF NOT Empty(ThisForm.Pageframe1.Page1.Text3.Value) Exps=Exps+[ AND Sex="]'+Alltrim(ThisForm.Pageframe1.Page1.Text3.Value)+["]EndIFIF NOT Empty(ThisForm.Pageframe1.Page1.Text4.Value) Exps=Exps+[AND Classes="]+Alltrim(ThisForm.Pageframe1.Page1.Text4.Value)+["]EndIFIF NOT Empty(ThisForm.Pageframe1.Page1.Text5.Value) Exps=Exps+' AND Birthday={^'+Alltrim(ThisForm.Pageframe1.Page1.Text5.Value)+'}'EndIFIF Len(Exps)>10 Exps1=Substr(Exps,9) ThisForm.Pageframe1.Page1.Expression.Value=Exps1EndIF

Page 102: 涪陵职业教育中心 吴玉琼    制作

◆Form1.PageFrame1.Page2.Activate( ) :IF NOT Empty(ThisForm.Pageframe1.Page1.Expression.Value) Exprs=ThisForm.Pageframe1.Page1.Expression.Value Select * From Student Where &Exprs Into Cursor Temp1Else Wait Window " 没有指定任何条件 !" NoWait Select * From Student Into Cursor Temp1EndIFThisForm.Pageframe1.Page2.Grid1.RecordSourceType=1ThisForm.Pageframe1.Page2.Grid1.RecordSource="Temp1"ThisForm.Pageframe1.Page2.Grid1.ColumnCount=5ThisForm.Pageframe1.Page2.Grid1.Column1.Header1.Caption="学号 "ThisForm.Pageframe1.Page2.Grid1.Column2.Header1.Caption=" 姓名 "ThisForm.Pageframe1.Page2.Grid1.Column3.Header1.Caption=" 性别 "ThisForm.Pageframe1.Page2.Grid1.Column4.Header1.Caption=" 出生日期 "ThisForm.Pageframe1.Page2.Grid1.Column5.Header1.Caption=" 班级 "ThisForm.Pageframe1.Page2.Grid1.Column1.Width=75ThisForm.Pageframe1.Page2.Grid1.Column2.Width=60ThisForm.Pageframe1.Page2.Grid1.Column3.Width=30ThisForm.Pageframe1.Page2.Grid1.Column4.Width=60ThisForm.Pageframe1.Page2.Grid1.Column5.Width=80

Page 103: 涪陵职业教育中心 吴玉琼    制作

7.3.15 7.3.15 形状和线条形状和线条 形状和线条是设计图形用户界面时常要用到的控件,它们有助于可视地将表单中的组件归成组。需要注意的是,形状和线条均为对象,只有通过它们的方法来改变自身的属性才能改变显示效果。形状和线条的常用属性如表 7-36 所示。

Page 104: 涪陵职业教育中心 吴玉琼    制作

【例 7-13】 形状和线条的应用示例。设计表单如图 7-23 所示,表单上各控件的主要属性如表 7-37 所示:

Page 105: 涪陵职业教育中心 吴玉琼    制作

表单中控件的方法程序如下。◆Form1.Init( ) :ThisForm.Combo1.ListIndex=1ThisForm.Combo2.ListIndex=2ThisForm.Combo3.ListIndex=3◆Form1.Spinner1,interactiveChange( ) :ThisForm.Shape1.Curvature=This.Value◆Form1.Combo1.interactiveChange( ) :ThisForm.Shape1.FillStyle=Val(This.Value)◆Form1.Combo2.interactiveChange( ) :ThisForm.Shape1.BorderStyle=Val(This.Value)ThisForm.Line1.BorderStyle=Val(This.Value)◆Form1.OptionGroup1.interactiveChange( ) :ThisForm.Shape1.SpecialEffect=ThisForm.OptionGroup1.Value–1ThisForm.Combo2.InteractiveChange◆Form1.Check1.interactiveChange( ) :ThisForm.Line1.LineSlant=IIF(This.Value=1,'/','\')◆Form1.Combo3.interactiveChange( ) :ThisForm.Line1.Height=Val(This.Value)◆Form1.Spinner2.interactiveChange( ) :Thisform.Line1.BorderWidth=This.Value

Page 106: 涪陵职业教育中心 吴玉琼    制作

7.4 7.4 综合示例综合示例 数据查询在数据库管理系统中占很重要的地位,本节通过一个示例程序介绍一个数据查询表单的基本设计方法。【例 7-14 】 设计一个查询并输出学生成绩册的表单。要求所有成绩能分班级、考试类型和时间输出。1、分析:由于要求所有成绩能分班级、考试类型和时间输出,因此,在表单中应设置这 3个项的选择筛选控件。又因为这 3个项的值已存在于 Grade表中,因此,为了能准确查询到相关数据就不能让用户在控件中输入值,而是应该从已有的值中进行选择。再者对于课程的选择可以使用两个列表框,一个显示按所设条件筛选出来的课程,另一个显示已选择的课程。操作方法可以设为通过命令按钮控制选择或取消所要选择的课程。由于本例要求输出的格式为报表输出格式,在还没有学习报表的情况下,可以先使用表格对象显示所查询出的结果集。由于在表单中的控件和要显示的内容太多,在一个窗口中不能完全显示,为了解决这一问题,可以在表单中添加页框控件。

Page 107: 涪陵职业教育中心 吴玉琼    制作

2、数据环境和界面设计: 设置数据环境。在数据环境设计器中按顺序添加 Student、 Grade、 Courses 等 3个表。表与表之间不设任何关联。

设计表单上控件布局。按上述分析,在表单上先添加一个页框控件,并将页框设置为包含 2 个页面,在表单上添加一个命令按钮 Command1,使其可供所有页面使用,在第 2 个页面上只加一个标签和一个表格,第 1 个页面添加控件后的表单上控件布局如图。

Page 108: 涪陵职业教育中心 吴玉琼    制作

各控件的属性设置如表 7-38~ 表 7-41 所示(本示例中按容器的包含关系分别说明) 图 7-40

◆Form1.Init( ) :****** 控件初始化及变量定义 ******Public Selectbj,kslb,ReportTitlThisForm.PageFrame1.Page1.Combo1.ListIndex=1ThisForm.PageFrame1.Page1.Combo2.ListIndex=1Selectbj=ThisForm.PageFrame1.Page1.Combo1.Valuekslb=ThisForm.PageFrame1.Page1.Combo2.ValueThisForm.SetCombo3RowSource &&调用自定义方法程序ThisForm.PageFrame1.Page1.Combo3.ListIndex=1

3、各控件的方法程序如下。

Page 109: 涪陵职业教育中心 吴玉琼    制作

◆Form1.AddNewCourse( ) : && 自定义的方法程序****** 功能:将列表框 1 中的一个选定数据项添加到列表框 2 中 ************ 判断所选数据项是否为最后一项 ******lISEnd=.F.nListIndex=ThisForm.PageFrame1.Page1.List1.ListIndexIF nListIndex=ThisForm.PageFrame1.Page1.List1.ListCount

lISEnd=.T.EndIf****** 向列表框 2 添加选定数据项并从列表框 1 中移去该项 ******ThisForm.PageFrame1.Page1.List2.AddItem(ThisForm.PageFrame1.Page1.List1.;List(ThisForm.PageFrame1.Page1.List1.ListIndex)) ThisForm.PageFrame1.Page1.List1.RemoveItem(ThisForm.PageFrame1.Page1. ;List1.ListIndex) ThisForm.PageFrame1.Page1.List2.ListIndex=ThisForm.PageFrame1.Page1. ;List2.ListCount****** 设置列表框 1 中的索引数据项 ******IF lISEnd AND ThisForm.PageFrame1.Page1.List1.ListCount>0

ThisForm.PageFrame1.Page1.List1.ListIndex=nListIndex-1EndIf◆Form1.PageFrame1.Page1.Combo1.InterActiveChange( ) :Selectbj=This.ValueThisForm.SetCombo3RowSource

Page 110: 涪陵职业教育中心 吴玉琼    制作

◆Form1.RemoveCourse( ) : && 自定义的方法程序****** 功能:将 List2 中的选定数据项添加到 List1 中并将其从 List2 中移除 ******lISEnd=.F.nListIndex=ThisForm.PageFrame1.Page1.List2.ListIndexIF nListIndex=ThisForm.PageFrame1.Page1.List2.ListCount

lISEnd=.T.EndIfThisForm.PageFrame1.Page1.List1.AddItem(ThisForm.PageFrame1.;Page1.List2.List(ThisForm.PageFrame1.Page1.List2.ListIndex))ThisForm.PageFrame1.Page1.List2.RemoveItem(ThisForm.PageFrame1.;Page1.List2.ListIndex)ThisForm.PageFrame1.Page1.List1.ListIndex=ThisForm.PageFrame1.Page1.List1.ListCountIF lISEnd AND ThisForm.PageFrame1.Page1.List2.ListCount>0

ThisForm.PageFrame1.Page1.List2.ListIndex=nListIndex-1EndIf◆Form1.SetCombo3RowSource( ) : && 自定义的方法程序****** 功能:设置 Combo3 的数据 ******ThisForm.PageFrame1.page1.Combo3.RowSourceType=3ThisForm.PageFrame1.page1.Combo3.RowSource="SELECT DISTINCT Grade.testdate; FROM xsglxt!student INNER JOIN xsglxt!grade ON Student.student_id = ;

Grade.student_id WHERE Student.classes =Selectbj AND Grade.testtype =kslb; ORDER BY Grade.testdate DESC INTO CURSOR cursortable"ThisForm.PageFrame1.page1.Combo3.ListIndex=1ThisForm.PageFrame1.page1.Combo3.Refresh

Page 111: 涪陵职业教育中心 吴玉琼    制作

◆Form1.ButtonStatus( ) : && 自定义的方法程序****** 功能:设置按钮组中各按钮的 Enabled 的状态 ******IF ThisForm.PageFrame1.Page1.List1.ListCount=0 ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(1).Enabled=.F. ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(2).Enabled=.F.Else ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(1).Enabled=.T. ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(2).Enabled=.T.EndIfIF ThisForm.PageFrame1.Page1.List2.ListCount=0 ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(3).Enabled=.F. ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(4).Enabled=.F. ThisForm.PageFrame1.Page1.Command2.Enabled=.F.Else ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(3).Enabled=.T. ThisForm.PageFrame1.Page1.CommandGroup1.Buttons(4).Enabled=.T. ThisForm.PageFrame1.Page1.Command2.Enabled=.T.EndIf◆Form1.PageFrame1.Page1.Combo2.InterActiveChange( ) :kslb=This.ValueThisForm.SetCombo3RowSource ◆Form1.PageFrame1.Page1.Command1.Click( ) : && 清除 List1 和 List2 中的数据项ThisForm.PageFrame1.Page1.List1.ClearThisForm.PageFrame1.Page1.List2.Clear

Page 112: 涪陵职业教育中心 吴玉琼    制作

ThisForm.PageFrame1.Page1.Command2.Enabled=.F.Thisform.PageFrame1.Page2.Enabled=.F.****** 使用查询为 List1准备数据 ******SELECT DISTINCT Grade.course_id; FROM xsglxt!student INNER JOIN xsglxt!grade ON Student.student_id = ;Grade.student_id WHERE Student.classes = Selectbj AND Grade.testtype = kslb; AND Grade.testdate = CTOD(ThisForm.PageFrame1.Page1.Combo3.value); ORDER BY Grade.course_id INTO CURSOR cursortable2Select cursortable2****** 将查询结果转换后作为数据项添加到 List1 中 ******Scan Select Courses Locate For Courses.Course_id=cursortable2.Course_id IF Found( ) ThisForm.PageFrame1.Page1.List1.Additem(Courses.Course_Name) EndIf Select cursortable2EndScan****** 设置 List1 的索引数据项和按钮的状态 ******IF ThisForm.PageFrame1.Page1.List1.ListCount>0 ThisForm.PageFrame1.Page1.List1.ListIndex=1EndIf

ThisForm.ButtonStatus

Page 113: 涪陵职业教育中心 吴玉琼    制作

◆Form1.PageFrame1.Page1.CommandGroup1.Click( ) :****** 功能:控制数据项在 List1 和 List2两个列表框中移动 ******Do CaseCase This.Value=1

ThisForm.AddNewCourseCase This.Value=2

For ii=1 To ThisForm.PageFrame1.Page1.List1.ListCountThisForm.PageFrame1.Page1.List2.AddItem(ThisForm.;

PageFrame1.Page1.List1.List(1))ThisForm.PageFrame1.Page1.List1.RemoveItem(1)

EndForThisForm.PageFrame1.Page1.List2.ListIndex=1

Case This.Value=3ThisForm.RemoveCourse

Case This.Value=4For ii=1 TO ThisForm.PageFrame1.Page1.List2.ListCount

ThisForm.PageFrame1.Page1.List1.AddItem(ThisForm.; PageFrame1.Page1.List2.List(1))

ThisForm.PageFrame1.Page1.List2.RemoveItem(1)EndForThisForm.PageFrame1.Page1.List1.ListIndex=1

EndCaseThisForm.ButtonStatus

Page 114: 涪陵职业教育中心 吴玉琼    制作

◆Form1.PageFrame1.Page1.Command2.Click( ) :*** 功能:将 Grade 表中符合条件的记录取出后进行格式变换 **************** 创建一个临时表 **********cStr="Student_ID C(10),Name C(8)" && 为根据选定字段创建临时表添加字段For ii=1 To ThisForm.PageFrame1.Page1.List2.ListCount

cStr=cStr+","+ThisForm.PageFrame1.Page1.List2.List(II)+SPACE(1)+"N(5,1)"EndForCSTR="Xgrade ("+CSTR+")" && 为创建临时表生成一个可供宏代换的字符表达式CREATE CURSOR &cStr && 创建临时表********** 通过查询对 grade 表数据格式进行转换 **********SELECT DISTINCT Student.Student_ID,Courses.Course_Name,Grade.TestGrade;From Xsglxt!Student INNER JOIN Xsglxt!Grade INNER JOIN Xsglxt!Courses;ON Grade.Course_id=Courses.Course_id ON Student.Student_id = Grade.Student_id ;WHERE Student.Classes = ThisForm.PageFrame1.Page1.Combo1.Value;AND Grade.TestType = ThisForm.PageFrame1.Page1.Combo2.Value;AND Grade.TestDate = CTOD(ThisForm.PageFrame1.Page1.Combo3.Value);GROUP BY Student.Student_id, Courses.Course_Name; ORDER BY Student.Student_id, Courses.Course_Name; INTO CURSOR SYS(2015) DO (_GENXTAB) WITH 'Grade1' && 通过系统内存变量建立交叉表 ********** 将查询结果复制到所建的 Xgrade 临时表中 ********** Curname=DBF( ) && 保存临时交叉表的文件名和路径 SELECT Xgrade APPEND FROM &Curname && 向 Xgrade 表添加记录

Page 115: 涪陵职业教育中心 吴玉琼    制作

********** 向临时表添加与 Student_ID (学号)相关联的姓名 ********** SCAN SELECT Student LOCATE FOR ALLTRIM(Student.Student_id)=ALLTRIM(Xgrade.Student_id) IF FOUND( ) REPLACE Xgrade.Name WITH Student.Name ELSE =MESSAGEBOX("Student 表中的学号 "+ALLTRIM(Xgrade.Student_id); +" 已被删除! ",48,"学生管理系统 --成绩查询打印 ") EndIf SELECT XgradeENDSCAN********** 禁用本身,同时激活向报表输出数据的按钮 **********ThisForm.PageFrame1.Page1.Command2.Enabled=.F.ThisForm.PageFrame1.Page1.Command3.Enabled=.T.ThisForm.PageFrame1.Page1.Command4.Enabled=.T.ThisForm.PageFrame1.Page2.Enabled=.T.********** 设定报表标题和系名 **********ReportTitl=LEFT(ThisForm.PageFrame1.Page1.Combo1.Value,2)+"级 ";+ALLTRIM(SUBSTR(ThisForm.PageFrame1.Page1.Combo1.Value,3))+;" 专业 "+ALLTRIM(ThisForm.PageFrame1.Page1.Combo3.Value)+;" 考试 ("+ALLTRIM(ThisForm.PageFrame1.Page1.Combo2.Value)+")成绩册 "◆Form1.PageFrame1.Page1.Command3.Click( ) :Report Form Reports\GradeReport Preview &&GradeReport 为成绩报表文件名

Page 116: 涪陵职业教育中心 吴玉琼    制作

◆Form1.PageFrame1.Page1.Command4.Click( ) :Report Form Reports\GradeReport TO Print Prompt NoConsole

注意:由于报表还没有建立,先不要使用与报表有关的“预览报表”、“打印报表”功能!◆Form1.Command1.Click( ) :ThisForm.Release

下面是页面 2中显示查询结果的方法程序。 ◆Form1.PageFrame1.Page2.Activate( ) :****** 功能:设置标题及表格中的数据和表头 ******Select Xgrade &&经过格式变换后生成的成绩表Go topThisForm.PageFrame1.Page2.Label1.Caption=ReportTitlThisForm.PageFrame1.Page2.Grid1.ColumnCount=ThisForm.PageFrame1.;Page1.List2.ListCount+2ThisForm.PageFrame1.Page2.Grid1.RecordSourceType=1ThisForm.PageFrame1.Page2.Grid1.RecordSource="Xgrade"ThisForm.PageFrame1.Page2.Grid1.Column1.Header1.Caption="学号 "ThisForm.PageFrame1.Page2.Grid1.Column2.Header1.Caption=" 姓名 "For ii=1 To ThisForm.PageFrame1.Page1.List2.ListCountThisForm.PageFrame1.Page2.Grid1.Columns(II+2).Header1.Caption=; ThisForm.PageFrame1.Page1.List2.List(II)EndFor

Page 117: 涪陵职业教育中心 吴玉琼    制作

小 结小 结

表单是 VFP6 人机交互的主要工具,表单设计器是 VFP6 中功能最强大的设计器。本章从不同的角度来说明了如何设计表单的问题。设计一个表单,第一步是如何选择数据源,也就是数据环境的问题,第二步是向表单或表单集中添加对象,第三步是对表单或表单集中的对象进行处理问题。重点掌握表单设计器的使用、各控件的主要属性、设定数据环境、在表单中加入和修改控件对象,了解表单基本事件处理顺序。设计表单最重要的是掌握几种常用表单控件的使用方法,如标签、文本框、组合框、列表框、表格、命令按钮、命令按钮组、选项按钮组、复选框等。具体使用什么控件,要根据任务选择合适的控件。

Page 118: 涪陵职业教育中心 吴玉琼    制作

第第 88 章:报表、标签设计 章:报表、标签设计

8.1 创建报表和标签 8.2 报表与标签的布局和数据

8.3 集成查询和报表 8.4 报表和标签的输出

小 结 返回 退出

学习要点1 、报表设计器和标签设计器的使用方法。2 、报表域控件的使用方法及页面设置。3 、报表与应用程序的集成与数据查询。4 、报表和标签的输出。

Page 119: 涪陵职业教育中心 吴玉琼    制作

8.1 8.1 创建报表和标签创建报表和标签报表和标签的建立方法基本上是相同的,它们都可以通过向导或设计器来创建,即创建报表可以使用“报表设计器”、创建标签可以使用“标签设计器”。用向导创建报表和标签只需按提示一步一步地执行即可,本章不再介绍。8.1.1 创建快速报表首先打开报表设计器,并向数据环境添加报表数据源,然后选择【报表】 |【快速报表】 VFP6 会打开“快速报表”,如图 8-1所示。

图 8-1 快速报表

Page 120: 涪陵职业教育中心 吴玉琼    制作

在这里可以选择字面布局和选择是否包含标题,如果要在报表中对表中的字段有所选择,还可以单击【字段】,打开“字段选择器”选择所需包含的字段。如图 8-2所示。

图 8-2 快速报表的“字段选择器 设置完成后,快速报表如图8-3 所示。保存该报表,则创建快速报表完成。

图 8-3 生成的快速报表

Page 121: 涪陵职业教育中心 吴玉琼    制作

8.1.2 利用报表设计器设计报表标签 如果用户不想使用“报表向导”,也可以用报表设计器生成一个新的报表。如果已有一个空白报表或标签,或者已由“报表设计器”生成了一个报表,但它不十分适合要求,则可以在“报表设计器”中修改它。下面将介绍报表设计器的使用方法。 1 、进入报表设计器 进入报表设计器的方法与前面介绍的“表设计器”、“表单设计器”基本相同,其步骤如下:选定一个项目文件打开项目管理器,选择“文档”选项卡中的“报表”,再单击【新建】 | 【新建报表】,弹出“报表设计器”窗口。

带区页标头带区

细节带区页注脚带区

Page 122: 涪陵职业教育中心 吴玉琼    制作

窗口中包含“页标头”、“细节”和“页注脚”三个带区,若使用【新建】 | 【报表向导】方法进入报表向导,则还会在报表的最上面增加一个“标题”带区,若在向导中加入了数据分组,还会有“组标头”和“组注脚”等带区。在“报表设计器”的带区中,可以插入各种控件,它们包含报表中想要的标签、字段、变量和表达式。要增强报表的视觉效果和可读性,还可以添加直线、矩形以及其它一些控件,也可以包含图片 /OLE 绑定型控件。使用报表的带区可以决定报表的每页、分组及开始与结尾的式样。可以调整报表的带区的大小。在报表的带区内,添加报表控件,然后移动、复制、调整大小、对齐方式以及调整它们,从而安排报表中的文本和域控件。可以在任何带区中设置任何报表控件。也可以添加运行报表时执行的用户自定义函数。

Page 123: 涪陵职业教育中心 吴玉琼    制作

2 、设计报表 仍以建立 Student 报表为例,先打开“报表设计器”,选定【显示】 | 【报表控件工具栏】,将“报表控件”工具栏打开,一般情况下,在打开“报表设计器”时,“报表控件”工具栏会自动打开。“报表控件”工具栏中各控件的功能如图

在此工具栏上有八个按钮,其中:“ 选定对象”按钮:用于在报表设计或修改过程中从报表上选定一个对象。“标签”按钮:用于在设计时向报表中添加一个标签对象,用于存放文本。“域控件”按钮:用于在设计时向报表中添加一个域控件,在域控件中可以存放任何合法的 VFP 表达式、内存变量和字段变量等。

Page 124: 涪陵职业教育中心 吴玉琼    制作

“线条”按钮:用于在报表中设计各种分隔线。“ 矩形”、“圆角矩形”按钮:用于在报表中画一个矩形框或圆角矩形框。“ 图片 /ActiveX 绑定控件”按钮:用于向报表中添加一个图片或 ActiveX 绑定控件。“ 按钮锁定”按钮:使用此按钮可以锁定被选定的按钮。当要向报表中连续添加几个相同的控件时,可以利用“按钮锁定”功能,即先选定要向报表中添加的对象的按钮(如矩形),然后再选定“按钮锁定”按钮,这时就可以连续向报表中添加矩形框对象。 设计 Student 报表步骤:第 1 步:设置报表的数据环境。打开报表设计器后,选择系统菜单上的【显示】 | 【数据环境】在系统菜单上增加【数据环境】菜单 ,然后再选择【数据环境】 | 【添加】。在弹出的“添加表或视图”对话框中先在“选定”下选择“表”,然后在列表框中选择 Student 表,再单击【添加】,再单击【关闭】,最后关闭“数据环境设计器”。

Page 125: 涪陵职业教育中心 吴玉琼    制作

选择【数据环境】

在系统菜单上增加了【数据环境】菜单,同时打开了“数据环境设计器”。单击【数据环境】菜单并选择【添加】,打开“添加表或视图”对话框。

在“添加表或视图”对话框中从“数据库中的表”下选择 Student 表,再单击【添加】,然后单击【关闭】,即可将 Student 表添加到“数据环境设计器”中。若要添加视图,可在“选定”选项组中先选择“视图”,再进行上述操作。添加后表或视图后关闭“数据环境设计器”。

Page 126: 涪陵职业教育中心 吴玉琼    制作

第 2 步:为报表添加标题。

选择菜单上的【报表】 |【标题 / 总结】,弹出的【标题 / 总结】对话框。

选中“标题带区”再单击【确定】按钮

在“报表设计器”中增加了标题带区

欲在标题带区中加入标签“学生报表”的操作步骤:先单击“报表控件”工具栏上的(标签)按钮;

在标题带区中单击出现闪烁的光标。

在光标处开始输入标题名“学生报表”;

学生报表

字号设置:先选中“学生报表”标签,再在系统菜单中选择【格式】 | 【字体】,在弹出的“字体”对话框中选择所需要的字体和字号以及字体样式。如选择“黑体”、“规则”、“二号”。

接着再进行版面设置,选择【格式】 | 【对齐】 | 【水平居中】。

Page 127: 涪陵职业教育中心 吴玉琼    制作

第 3 步:设置报表的页标头。设置报表的页标头与上面设置标题的方法相同。

系部代号班级代号 学号 姓名 性别 出生日期 班级 宿舍 电话 年龄 新生类别

1 、在页标头中分别添加标签“系部代号”、“班级代号”、“学号”、“姓名”等。

2 、按住 Shift键后分别单击每一个标签,将其全部选中。

3 、用与设置标题相同的方法将页标头的字体设为 “黑体” 、“规则”、 “五号” 。

4 、标签布局调整。选中单个标签后用光标键可调整其位置,也可选中一批后使用光标键调整位置。

Page 128: 涪陵职业教育中心 吴玉琼    制作

第 4 步:设置细节。 在第 3 步设计完成后,可以将“数据环境设计器”打开。

将要列在报表中的字段从“数据环境设计器”中逐个拖到细节带区。设置字体字号及调整布局:方法同页标题。使用报表默认的字体和字号。

控件对齐:选中细节中的全部域控件,然后在系统菜单中选择【格式】 |【对齐】 | 【顶边对齐】。

Page 129: 涪陵职业教育中心 吴玉琼    制作

设置细节时也可以不从“数据环境设计器”中将字段拖到细节,而使用 报表控件工具栏。

单击工具栏上的“域控件”按钮,再单击“按钮锁定”按钮,可以向报表中多次添加域控件。然后在“细节”带区合适的位置单击添加一个域 控件。在报表上单击时系统将打开“报表表达式”生成器。

“ 表达式生成器”按钮“格式”按钮

单击“表达式生成器”按钮从“字段”列表框中选择一个字段双击

单击【确定】

Page 130: 涪陵职业教育中心 吴玉琼    制作

设置细节时也可以不从“数据环境设计器”中将字段拖到细节,而使用 报表控件工具栏。

单击工具栏上的“域控件”按钮,再单击“按钮锁定”按钮,可以向报表中多次添加域控件。然后在“细节”带区合适的位置单击添加一个域 控件。在报表上单击时系统将打开“报表表达式”生成器。

“ 表达式生成器”按钮“格式”按钮

单击【确定】

Page 131: 涪陵职业教育中心 吴玉琼    制作

设置细节时也可以不从“数据环境设计器”中将字段拖到细节,而使用 报表控件工具栏。

单击工具栏上的“域控件”按钮,再单击“按钮锁定”按钮,可以向报表中多次添加域控件。然后在“细节”带区合适的位置单击添加一个域 控件。在报表上单击时系统将打开“报表表达式”生成器。

采用同样的方法添加其它域控件并调整域控件到合适的大小。

调整域控件大小:每个域控件都有 8 个控制柄,按住控制柄拖动鼠标可以调整域控件的大小。现将“系代号”域控件宽度缩短。

控制柄

Page 132: 涪陵职业教育中心 吴玉琼    制作

第 5 步:在页注脚中设置报表页码。方法基本同上一步,只不过在“表达式生成器”对话框中不是从“字段”列表框中选择,而是从“变量”列表框中选择“ _pageno” 。在此报表中,数据之间没有分隔线,若要求要有网格线,也可以用同上的基本方法,在“页标头”中的字段名上加上方框线,在“细节”中的域控件上加分隔线。

先选中页标头中的所有标签,并将其移到页标头带区的顶部,然后对细节带区中的所有域 控件进行同样的处理。再将鼠标移到页标头分隔带上,按住左键向上移动,调整页标头带区的宽度,用同样的方法调整细节带区的宽度。若要精确设置宽度,可以双击分隔带弹出对话框。

在高度微调框中调整高度。再单【确定】

Page 133: 涪陵职业教育中心 吴玉琼    制作

第 5 步:在页注脚中设置报表页码。方法基本同上一步,只不过在“表达式生成器”对话框中不是从“字段”列表框中选择,而是从“变量”列表框中选择“ _pageno” 。在此报表中,数据之间没有分隔线,若要求要有网格线,也可以用同上的基本方法,在“页标头”中的字段名上加上方框线,在“细节”中的域控件上加分隔线。

在工具栏上单击“矩形”按钮,然后在“页标题”带区划一个矩形框。再单击工具栏上的“线条”按钮,然后在标签间划竖向分隔线。然后再在细节带区域控件的下部划一条水平线,再在域控件的中间及前后划竖向分隔线。

Page 134: 涪陵职业教育中心 吴玉琼    制作

报表设计完成后,可以先单击系统菜单“常用”工具栏上的打印预览按钮,查看报表设计的效果,如果不满意还可以用上述方法进行修改,如果满意则可以结束“报表设计器”的设计工作,将报表保存到预定的目录中。 预览结果如下:

Page 135: 涪陵职业教育中心 吴玉琼    制作

3 、修改报表文件 要修改已生成的报表文件,应先将它打开。 在项目管理器的“文档”选项卡中选择“报表”,并在展开的报表列表中选择要修改的报表,然后单击项目管理器上的【修改】按钮。如对刚建立的 Student 报表。

在“报表设计器”中可以用建立报表的方法修改已存在的报表。

Page 136: 涪陵职业教育中心 吴玉琼    制作

4 、规划数据位置 下图说明了报表中可能出现的各类带区以及每个带区应放置的数据等典型内容。

Page 137: 涪陵职业教育中心 吴玉琼    制作

用“报表设计器”设计报表时,报表中要用的数据以及各数据在报表中什么位置显示和打印,均要在设计时加以考虑,这就是对报表布局的规划。通过规划报表布局,可以设计和修改数据在报表页面上的位置。将数据对象放在报表中的不同的带区,将有不同的显示结果,例如,如果将数据对象放在报表的“标题”带区中,则此数据在报表中只显示或打印一次,但如果将表的字段对象放在报表的“细节”带区中,则可以每条记录显示或打印一次。可以用下表决定所要使用的带区以及在带区中应放入何种控件。

返回

Page 138: 涪陵职业教育中心 吴玉琼    制作

8.2 8.2 报表与标签的布局和数据 报表与标签的布局和数据 8.2.1 重定义页面布局

8.2.2 在域控件中使用表达式和函数

返回 退出

8.2.3 定义报表变量

8.2.4 域控件的格式化

Page 139: 涪陵职业教育中心 吴玉琼    制作

8.2.1 8.2.1 重定义页面布局重定义页面布局 在报表中,可以定义多个列,也可以改变页面中的带区的高度,从而重新设计页面布局。1 、在页面上定义多个列若要定义多个列的报表,可以:( 1 )在【文件】菜单上选择【页面设置】,打开“页面设置”对话框,如图。

输入页面所需的数目,该数目就是一页上将要排列显示和打印的记录列数。

输入列的宽度值。

输入所需要的列间距,若在“列数”框中只设 1 列,则“间隔”框为不可选。 输入报表的左页边距值。 按钮用于设置报

表中多列显示时数据打印的顺序

( 2 )根据要求在对话框中进行设置,最后选择【确定】,“报表设计器”将反映出设置的改变。

Page 140: 涪陵职业教育中心 吴玉琼    制作

2 、设置报表带区高度在设计报表时,可以改变报表带区的高度。报表带区的高度是指一个报表带区可用的页面空间(在页边距的范围内)。例如:如果“标题”带区设置为 2英寸,则“标题”将在顶部页边距下2英寸区域内显示和打印。“细节”带区指定每个要显示的记录所需要的区域。对于“组标头”和“页注脚”带区,还可以设置附加的参数。若要精确设置带区的高度,可以通过先双击相应带区的条形栏,在出现的一个与该带区对应的对话框中的“高度”框中输入所需要的高度值,然后再单击【确定】。带区高度设置在前文已作说明。

返回

Page 141: 涪陵职业教育中心 吴玉琼    制作

8.2.2 8.2.2 在域控件中使用表达式和函数在域控件中使用表达式和函数

在报表或者标签中,可以包含域控件来显示一些表达式。例如,表或视图的字段、内存变量,以及它们之间的运算的值等。1 、添加域控件用户可以使用几种方法向报表中添加域控件,在上一节的报表设计中介绍了二种方法。一是直接使用工具栏上的域 控件按钮向报表中添加域 控件;二是从“数据环境设计器”中添加表的字段作为域控件。2 、插入字段连接构成的域控件把表的字段添加到报表之后,在预览时可能会看到这些字段没有按照在页面上所希望的方式显示。有时想要将几个字段连在一起显示,这时可以将这些字段连成一个域表达式,同时删除多余的空格。每个控件所对应的值所需的空间可能不同,这时可以适当调整控件。若要将几个字段连接成为一个域表达式,可以按以下步骤进行:

Page 142: 涪陵职业教育中心 吴玉琼    制作

( 1 )选择“报表控件”工具栏中的“域控件”,在报表中插入一个域控件。将域控件的大小设为表达式求值后所必须的最小值。也可以先双击一个选中的域控件,然后在“报表表达式”对话框中的“溢出时伸展”前的复选框中做上选中标记,使它能够在表达式求值后需要更多的空间时自动伸展;若所需空间较小,则控件不会缩小,但控件的所占的空间不会比在设计时设定的更小。

在带区的最上一个域控件可设置为“相对带区顶端固定”和“溢出时伸展”。

溢出时伸展

浮动

在带区最上一个域 控件下面的其它域控件要设为浮动。

Page 143: 涪陵职业教育中心 吴玉琼    制作

( 2 )在“报表表达式”对话框中,选择“表达式生成器”按钮。( 3 )在弹出的“表达式生成器”中,从“字符串”框中选择 Alltrim(expC)函数。该字符串出现在“报表字段的表达式”框中,同时选定了 expC 。( 4 )在“字段”列表框中双击想要在控件中显示的第一个字段名。该字段名将代替“报表字段表达式”框中的 expC 。在字段名后输入一个“ +”号也可以从“字符串”函数框中选择一个“ +”号。( 5 )重复上面的第三步和第四步来处理其它字段,直至完成表达式,再选择【确定】。( 6 )在“报表表达式”对话框中选择“溢出时伸展”。在显示报表时,若设计时设定的控件大小不能包含其中的表达式的值,则控件自动向后伸展,直至完全能够显示整个值。为了将几个字段合为一个表达式,对每个字段名前使用 ALLTRIM()函数,要注意,此函数只能用于字符型字段,若字段为非字符型字段,则还要使用转换函数,将非字符型值转换为字符型的值。而每个表达式元素之间用“ +”号连接。 返回

Page 144: 涪陵职业教育中心 吴玉琼    制作

若要在报表中操作数据或显示计算结果,则需要用到报表变量。使用报表变量可以计算与报表数据环境中提供的数据有关的各种值,并且可以用这些值来计算其它一些值。如果要使用报表变量,则必须在使用前先定义。 1 、定义报表变量若要定义报表变量可以使用下述方法:( 1 )若已经建立了报表,则先将报表打开;若还没有建立报表,则创建一个新报表。( 2 )从系统菜单中选择【报表】 | 【变量】,将弹出图示的“报表变量”对话框。

( 3 )输入一个变量名

( 4 )输入一个变量名或一个其它的表达式,也可以单击后面的按钮,再在弹出的“表达式生成器”中用前面已经介绍过的方法创建一个表达式。

( 5 )如果需要,还可以从“计算”列出的七种计算方式中任选一种作为该表达式的计算选项。系统默认值为“不计算”。

( 6 )如果需要,也可以定义一个初始值或初始值的表达式。

( 7 )重复操作定义完成后单击

8.2.3 8.2.3 定义报表变量定义报表变量

Page 145: 涪陵职业教育中心 吴玉琼    制作

定义一个报表变量 nCount ,用存保存表中一个班级的人数第 1 步:在项目管理器中选择“文档”选项卡中的 Student 报表后单击【打开】。

第 2 步:从系统菜单中选择【报表】 | 【变量】,打开“报表变量”对话框。

第 3 步:输入报表变量名 nCount 。 nCount

第 4 步:输入一个变量名或一个其它的表达式 第 5 步:选择总和作为变量的计算方式

第 6 步:初始值取系统默认值 0 。

第 7 步:单击【确定】结束变量定义

第 8 步:在报表的页注脚区域添加一个域控件,该域控件的表达式选择变量中已定义的变量 nCount 。

Page 146: 涪陵职业教育中心 吴玉琼    制作

2 、重新排序报表变量 报表变量是根据它们出现的先后顺序来计算的,并且影响引用这些报表变量的表达式的值。例如,如果定义一个变量时,用到了另外一个变量,那么被引用的报表变量应该在引用之前先出现(先被定义)。 若要更改报表变量的顺序,可以先从“报表”菜单中选择“变量”,打开“报表变量”对话框。 在“报表变量”对话框中的“变量”列表框中拖动其左边的“移动”按钮,便可以重新调整所定义的报表变量的顺序。 调整完成后按【确定】按钮。

返回

Page 147: 涪陵职业教育中心 吴玉琼    制作

8.2.4 8.2.4 域控件的格式化域控件的格式化 在插入一个域控件后,可以改变控件的数据类型和显示格式。数据类型可为:字符型、数值型或日期型。每个数据类型都有自己的格式选项,其中包括用户建立自己格式模板的选项。当打印报表或标签时,格式可以控制字段的显示。可以在“报表表达式”对话框的“表达式”框中直接输入格式函数,也可以在“格式”对话框中进行选择。下面列出一些可能遇到的典型情况:可能需要将所有的输出字母转化为大写,也可能需要用逗号或小数点分隔数值输出,或用货币格式显示数值输出,将日期类型的输出转化为其他格式等等。

Page 148: 涪陵职业教育中心 吴玉琼    制作

1 、报表控件的格式化选项 在域控件中,可以对每种数据类型设置不同的格式选项。若要

“ ” “将一个域控件格式化,可以先双击 域控件 ,然后在 报表表达” “ ”式 对话框中,选择 格式 对话框后的按钮,为该字段选择数据

“ ” “ ” “ ” “ ”类型: 字符型 、 数值型 或 日期型 , 编辑选项 区域将会显示该数据类型下的各种格式选项。如图 8-18所示。最后选择对齐方式和所需的格式选项。

域控件

1 、双击“域 控件”,如“学号”

2 、单击“格式”按钮

字段为字符型则自动选定为“字符型”

3 、取消“左对齐”格式再选择“居中对齐”

4 、单击【确定】

Page 149: 涪陵职业教育中心 吴玉琼    制作

1 、报表控件的格式化选项 在域控件中,可以对每种数据类型设置不同的格式选项。若要

“ ” “将一个域控件格式化,可以先双击 域控件 ,然后在 报表表达” “ ”式 对话框中,选择 格式 对话框后的按钮,为该字段选择数据

“ ” “ ” “ ” “ ”类型: 字符型 、 数值型 或 日期型 , 编辑选项 区域将会显示该数据类型下的各种格式选项。如图 8-18所示。最后选择对齐方式和所需的格式选项。1 、双击“域 控件”,如“学号”

表示居中对齐

单击【确定】

返回到报表后,在域控件看不到所定义的格式,格式只在显示或打开时有效。

Page 150: 涪陵职业教育中心 吴玉琼    制作

2 、在域中对齐文本在域控件中对齐文本不会改变控件在报表上的位置,只是在控件内对其内容进行格式调整。有两种方法可以调整控件中内容的位置。要直接在域控件中调整文本对齐,可以:①选择要操作的控件。②在 VFP 系统菜单上选择【格式】 | 【文本对齐方式】。③从该子菜单中选择合适的选项。 要在域中调整文本对齐,可以按上例的方法在“格式”选项中调整文本对齐方式。

Page 151: 涪陵职业教育中心 吴玉琼    制作

3 、定义域格式模板格式模板允许自己定义域中数据的格式。在“报表表达式”对话框的“格式”框或者“格式”对话框里输入一系列普通字符或代码,就可以建立各种打印格式。所输入的普通字符将与域中的值一同出现在域中,而输入的代码则用来确定字段输出的外观。例如,如果为一个十位数的数值字段指定如 (999) 999-9999 所示的格式模板,那么,像括号、空格和破折号这样的字符将和数值型数据一起打印。4 、改变字体对于每个域控件或标签控件,可以改变字体和文本的大小,还可改变整个报表的默认字体。要在一个报表中改变字体和字号,可以:①选择控件。②从系统菜单中选择【格式】 |【字体】,这时出现“字体”对话框。③选择合适的字体和大小,然后单击【确定】。若要改变默认的字体,可以:①从系统菜单中选择【报表】 |【默认字体】。②在“字体”对话框中,选择需要作为默认值的合适字体和大小,然后单击【确定】。只有在改变默认的字体后插入的控件才反映出新的字体设置。对于已存在的对象,须将它们全部选定,然后再使用【格式】菜单上的【字体】选项修改设置。

返回

Page 152: 涪陵职业教育中心 吴玉琼    制作

8.3 8.3 集成查询和报表 集成查询和报表

8.3.1 集成查询的报表

8.3.2 用查询收集用户输入

返回 退出

Page 153: 涪陵职业教育中心 吴玉琼    制作

8.3.1 8.3.1 集成查询的报表集成查询的报表 在创建好了应用程序的各个组件之后,就可以将它们集成起来。下图显示了将查询和报表添加到应用程序的一些方法。

Page 154: 涪陵职业教育中心 吴玉琼    制作

VFP 中的报表在一般情况下总是和其它应用程序一同使用的,对于利用 VFP 开发的应用系统而言更是如此。提供给用户的是一些简单、明了、易操作的表单界面,只是由用户根据自己要达到的目的在表单上选择不同的对象达到各种要求。这就要求应用程序设计人员将报表和标签功能有机地集成到其它应用程序中。为了达到上述要求,可以将执行查询或报表的代码添加到应用程序的表单按钮、菜单上的一个选项或工具栏上的一个按钮等对象中。若要添加查询、视图或程序,可将 DO 或 USE等命令添加到表单命令按钮、工具栏按钮或菜单项的相关代码中。例如,如果想在一个表单中由用户通过单击表单上的按钮来运行一个查询、程序或打开一个视图,则可以建立如图所示的表单: 在 Click 事件代码中添加 DO Myqu-ery.qpr ( Myquer-y.qpr 用实际要运行的查询文件替换) 。

在 Click 事件代码中添加 DO MyProgram ( MyProgram 要用实际要运行的程序文件替换)

Click 事件代码中添加 USE MyView ( Myview 要用实际要打开的视图文件替换)

Page 155: 涪陵职业教育中心 吴玉琼    制作

若将报表加入到应用程序时,有以下几种选择:■ 如果只是想让用户简单地启动报表并得到打印结果,可以把REPORT 命令添加到表单控件、菜单命令或工具栏按钮中。■ 如果报表中用到的某些变量允许用户输入,则可以像参数化查询那样从用户那里获得变量的值 , 或从表单中某些文本框获得变量值等。■ 如果想让用户创建自定义报表,可以向用户提供使用报表设计器创建新报表或修改已有报表的能力。若要运行报表和标签,则要使用 REPORT 或 LABEL 命令。1 、 REPORT 命令

格式: REPORT FORM < 报表文件名 >/< ? > [< 范围 >] [FOR < 条件 >] [WHILE < 条件 >] [HEADING < 标题文本 >] [PREVIEW [WIINDOW < 窗口名 >]] [TO PRINTER [PROMPT]]/[TO FILE < 文件名 > [ASCII]] [SUMMARY]

格式: REPORT FORM < 报表文件名 >/< ? > [< 范围 >] [FOR < 条件 >] [WHILE < 条件 >] [HEADING < 标题文本 >] [PREVIEW [WIINDOW < 窗口名 >]] [TO PRINTER [PROMPT]]/[TO FILE < 文件名 > [ASCII]] [SUMMARY]

功能:根据报表定义文件显示或打印报表。

Page 156: 涪陵职业教育中心 吴玉琼    制作

参数描述:< 报表文件名 > :指定报表定义文件的名称。<?> :显示“打开”对话框,从中可以选择报表文件。[HEADING < 标题文本 >] :指定放在报表每页上的附加标题文本。PREVIEW [WIINDOW < 窗口名 >] :以页面预览方式显示报表,而不把报表送到打印机中打印。TO PRINTER [PROMPT] :把报表送到打印机打印。包含 PROMPT 子句在打印前显示设置打印机的对话框。可调整的打印设置取决于当前安装的打印机驱动程序。TO FILE < 文件名 > [ASCII] :指定报表要送往的文本文件。包含 ASCII 子句可用报表定义文件创建一个 ASCII 文本文件。SUMMARY :不打印细节行,只打印总计和分类总计信息。例如,要将当前目录中的 Student 报表送到打印机打印出来,可使用下面的命令:REPORT FORM Student TO PRINTER PROMPT

Page 157: 涪陵职业教育中心 吴玉琼    制作

功能:根据表文件和标签文件打印标签。参数描述:FORM < 标签文件名 > :指定要打印的标签所对应的标签定义文件名。若标签定义文件不在当前目录中,则必须指定目录。FORM < ? > :显示“打开”对话框,从中可以选择一个已经定义了的标签定义文件。PREVIEW <NOWAIT> :在预览窗口中显示标签而不打印。若包含可选项 NOWAIT ,则在运行时 VFP 将不等待关闭“页面预览”窗口,而是在该窗口打开的情况下继续往下执行。SAMPLE :显示并打开一个样本来检验标签的对齐方式。TO PRINTER [PROMPT] :把标签送到打印机打印。包含 PROMPT 子句在打印前显示设置打印机的对话框。

2 、 LABEL 命令 格式: LABEL [FORM < 标签文件名 >/FORM < ? >] [< 范围 >] [FOR < 条件 >] [WHILE < 条件 >] [PREVIEW <NOWAIT>] [SAMPLE] [TO PRINTER [PROMPT]]

格式: LABEL [FORM < 标签文件名 >/FORM < ? >] [< 范围 >] [FOR < 条件 >] [WHILE < 条件 >] [PREVIEW <NOWAIT>] [SAMPLE] [TO PRINTER [PROMPT]]

返回

Page 158: 涪陵职业教育中心 吴玉琼    制作

8.3.2 8.3.2 用查询收集用户输入用查询收集用户输入 以打印学生情况报表为例,说明用查询收集用户输入的方法。在 Student.dbf 表中如果有很多的记录,而在打印报表时又不想一次将所有记录打印出来,而只想以班级为单位有选择性的打印,则可以先建立表单如图所示。

在 Combo1组合框中,将 RowSourceType 属性设置为 3-SQL语句,将 RowSo-urce 属性设置为:SELECT DISTINCT 班级 FROM STUDENT INTO CURSOR BJCX 通过 SQL 查询语句,将 Student 表中所有的班级在 Combo1组合框中列出来供用户操作时进行选择。其中 BJCX 为保存查询结果的临时表文件名,若省略 INTO CURSOR BJCX 子句,则在执行表单时, SELECT 命令执行的结果将会在浏览窗口中显示。

Page 159: 涪陵职业教育中心 吴玉琼    制作

在【打印】按钮的 Click事件中添加如下代码:SELECT * FROM STUDENT WHERE STUDENT. 班级 =THISFORM. ; COMBO1.VALUE INTO CURSOR CURSOR_BJ &&用查询收集用户的输入*****以下程序是由用户选择是预览报表还是要打印报表 *****MM=MESSAGEBOX(' 想要预览“ STUDENT” 报表吗? ',35," 打印 Student 报表 ")IF MM=6 REPORT FORM D:\XSGLXT\REPORTS\STUDENT PREVIEWELSE IF MM=2

RETURN ENDIFENDIFMM=MESSAGEBOX(' 想要打印“ STUDENT” 报表吗? ',33," 打印 Student 报表 ")IF MM=1

REPORT FORM D:\XSGLXT\REPORTS\STUDENT TO PRINTER PROMPT*****上一行命令中加下划线的部分是指定要运行的报表文件名,若不在当前***** 目录下,则要加上路径。ELSE RETURNENDIF

Page 160: 涪陵职业教育中心 吴玉琼    制作

要注意:建立的 Student 报表要将其中数据环境中的表移去,即在报表的数据环境中不含有任何表。对于本例,也可以不用 SQL 查询语句而直接使用 REPORT 命令,即将 SELECE 命令删除,在 REPORT语句中增加下列可选项:FOR 班级 =THISFORM.COMBO1.VALUE其中: THISFORM.COMBO1.VALUE 是对用户选择的引用。即通过 REPORT 命令的条件子句,对表中的记录进行筛选,从而达到按用户选择的班级输出报表的目的。

返回

Page 161: 涪陵职业教育中心 吴玉琼    制作

8.4 8.4 报表和标签的输出 报表和标签的输出 8.4.1 为控件设置打印选项

8.4.2 为组设置打印选项

返回 退出

8.4.3 控制报表和标签的输出

Page 162: 涪陵职业教育中心 吴玉琼    制作

8.4.1 8.4.1 为控件设置打印选项为控件设置打印选项 总的来说,控件的位置和它所处的带区的位置决定了它打印时的位置和时间。除此之外,还可以为每个控件设置特定的打印选项。每个控件都有一个默认的尺寸,该尺寸或是由它的值(对于字段或标签来说)决定,或是在创建该控件的时候确定(对于线条、矩形或者图形来说)。控件在页面上的长度指定了该控件的显示宽度。由于有些控件的值根据记录的不同而不同,可将控件的高度设置为可向下伸展,以显示整个的值,否则,有些数据将在显示的时候被截断。除了标签控件之外,所有的控件的大小均可变。1 、打印变长度值的控件为了使控件尽可能少的占用报表的地方,可将其设置为可伸展的。例如,一个表达式的值可能依记录的不同而不同,这时,最好不要在报表上为这个控件分配一个固定的可容最长记录值的空间,而应将控件设置为可伸展,即可容纳所有的数值。对于该控件下方的控件,可将其设置为可向下浮动的。

Page 163: 涪陵职业教育中心 吴玉琼    制作

注意:在如下情况下,某些数据在打印时会被覆盖:( 1 )将一个域设置为相对于带区底端固定,同时在这个域的下面还有一个域,设置为相对于带区顶端固定并且选择了溢出时伸展选项;

设置为相对带区底端固定

高度就被固定了带区

向下浮动时没有空间

( 2 )将一个域设置为相对于带区顶端固定,同时在这个域的上面还有一个域,设置为相对于带区顶端固定并且选择了溢出时伸展选项。

设置为相对带区底端固定

带区高度被固定

没有溢出时伸展的空间

Page 164: 涪陵职业教育中心 吴玉琼    制作

2 、不输出重复值对于域控件,可以不输出连续记录的重复值。也就是说,如果某域中的同一个值在连续的记录中重复出现,则只须在第一次出现时打印该值,在后面的记录中不打印该值,直至数值发生改变。若要不输出重复值,可以先双击该控件,在显示控件的对话框中选择“打印条件”以显示“打印条件”对话框,在该对话框中的“打印重复值”区域,选择“否”,然后选择【确定】。1 、双击域 控件如“系部代号”

2 、单击【打印条件】

6 、在“文本”对话框中单击【确定】

7 、预览显示报表数据

3 、选择“否”

5 、单击【确定】

4 、选择“在新页 / 列的第一个完整信息带内打开”和“当细节区数据溢出到新页 / 列时打印”

Page 165: 涪陵职业教育中心 吴玉琼    制作

系部代号与上一条记录相同不打印

选择“在新页/列的第一个完整信息带内打印”指定换页(或列)后,遇到第一个新记录时,打印重复值。选择“当细节区数据溢出到新页/列时打印”指定当细节带区内容溢出到新页(或列)中时,输出重复值。3 、建立打印表达式可以为控件设置表达式,该表达式在打印之前被计算出来。如果表达式的值为“假”,则不打印该字段。添加表达式之后,在“打印条件”对话框中除了“若是空白行则删除”选项外,其他选项全部

Page 166: 涪陵职业教育中心 吴玉琼    制作

无效。若要添加一个打印表达式,可以先双击该控件,再选择“打印条件”,然后在“仅当下列表达式为真时打印”框中,输入一个表达式。或者单击对话按钮,使用“表达式生成器”建立一个表达式,最后选择【确定】。4 、不打印空行对于报表中的某些域控件,记录中往往会没有数值。默认情况下,VFP 将为那些空的域保留区域。可以将这些空白的区域清除,使所显示的信息更为理想、更为连续。若要不打印空行,可以先双击在报表中可能会引起空行的控件,再选择“打印条件”,然后选择“若是空白行则删除”,最后选择【确定】。如果一行中所有域的值经计算后都为空,则 VFP 从报表中删除此行。如果不打印该域,或者域中的值为空, VFP 将会检查该行的其他控件:找不到的话,此行被删除。如果没有选择该选项,而且该行中没有其他的控件,那么会打印一个空行。

返回

Page 167: 涪陵职业教育中心 吴玉琼    制作

8.4.2 8.4.2 为组设置打印选项为组设置打印选项 在报表中,可以对组的打印方式进行控制。有时可能希望同一个组中的内容不要跨页显示;有时可能希望控制是否打印组标头。1 、设置组的分页及组标头选项 (1) 在系统菜单中选择【报表】 | 【数据分组】

在“数据分组”对话框中,除了可选择(或输入)用于分组的域或表达式外,还可以对组的分页选项进行设置 。如:

Left(学号 ,2)

对组(及其标头)的显示可能有特别的要求。比如,可能希望一个组不要横跨两列(对于多列的报表);不要纵跨两页;或者每一组的页码都从 1 开始重编。该对话框提供了四个选项来完成这些任务。

Page 168: 涪陵职业教育中心 吴玉琼    制作

2 、防止出现孤立的组标头设置合适的值,可以防止出现孤立的组标头

如果标头和底部的相对位置比所规定的尺寸(用英寸或厘米表示)要小,VFP 会将标头移到新的一页中打印。注意:为了给孤立控件确定一个比较理想的值,可以将组标头带区的高度扩大到细节带区高度的一至三倍。

在组纵跨两页时,可能需要在新的一页中重复打印组标头,将其显示在连续信息的顶部。如果报表中存在嵌套的多个数据组,那么在连续页中,标头应是嵌套结构中最内层的组的标头。所以,应该将所有组标头中要打印的控件放置在最内层的组标头带区中。

3 、重复输出组标头

选择“每页都打印组标题”,可以重复输出组标头

返回

Page 169: 涪陵职业教育中心 吴玉琼    制作

8.4.3 8.4.3 控制报表和标签的输出控制报表和标签的输出

使用 REPORT 或 LABEL 命令的下列某一关键字,可以控制报表和标签输出到什么地方: PRINT 、 PREVIEW 或 FILE ,如果不使用任何关键字,报表将输出到屏幕或活动窗口。 PRINT—— 输出到打印机; PREVIEW—— 在系统默认窗口显示; FILE—— 输出到文件。1 、选择要打印的记录在打印一个报表时,若要限制在报表中出现的记录,可以使用筛选条件:■ 指定一定数量或者范围内的记录。■ 使用 FOR 表达式,选择满足条件的记录。■ 使用 WHILE 表达式选择记录,直到找到一个不满足条件的记录。可以任意组合使用上述方法,使用 WHILE 表达式将忽略其他的条件。

Page 170: 涪陵职业教育中心 吴玉琼    制作

(1) 打印一定数量或者范围内的记录限制记录数目的一种方法是指定一定数量或者一定范围内的记录。使用“范围”选项,可以在文件中选择单个记录或者一组连续存放的记录。注意:活动的索引或者当前记录的指针会影响 [< 范围 >] 子句中Next 和 Rest 选项,但 Record 选项不会受影响,这是因为当表被设置索引之后,表中每个记录号并不会变化。若要选择一定数目的记录,可以从选择【文件】 | 【打印】

单击【选项】

单击【选项】

设置“作用范围”可以打印一定数量或者范围内的记录

(2) 打印满足某个条件的记录

在此设置条件

ALLTRIM( 班级 )="99 电子 "

Page 171: 涪陵职业教育中心 吴玉琼    制作

2 、打印报表和标签 若要把报表送到打印机,可以直接将它输出到打印机,也可以先显示“打印设置”对话框。若要将报表送到打印机,可以 REPORT 命令或 LABEL 命令中使用 TO PRINTER 关键字。

REPORT FORM C:\GXGLXT\STUDENT TO PRINTER PROMPT 如果想在指定的窗口中预览结果,可以使用 WINDOW 子句指定这个窗口,该窗口或是一个表单、或是一个用 DEFINE WINDOW 命令建立的窗口。例如下面的命令将报表输出到自定义的窗口 MYPREVIEWWINDOW 中预览。REPORT FORM D:\XSGLXT\REPORTS\STUDENT PREVIEW WINDOW ;MYPREVIEWWINDOW 若要创建一个报表的电子版本,可以将它发送到一个打印机格式的文件中,或者发送到一个 ASCII 文件中。把报表发送到文件中,可以方便以后用打印机成批打印。若要创建 ASCII 文件,可以创建一个仅包含文本、虚线和加号以代表线条和形状的文件,但文件中不包含对字体和颜色的设置。此外,还可以指定每行的字符数和每页的行数。将报表打印到 ASCII 文件中,可以在 REPORT 命令中使用 FILE 和 ASCII 关键字。如:REPORT FORM D:\XSGLXT\REPORTS\STUDENT TO FILE MYTILE ASCII

返回

Page 172: 涪陵职业教育中心 吴玉琼    制作

小 结小 结1 、利用报表向导设计报表和标签。2 、利用报表设计器设计报表,报表工具栏中各控件的作用及使用。3 、重定义报表的页面布局。4 、报表中的域控件的使用方法,域控件的溢出伸展设置方法。5 、定义报表变量及报表变量在报表中的作用。6 、将报表集成到应用程序中,使用表单收集用户的输入信息。7 、报表的输出命令: REPORT 。8 、为控件设置打印选项及控制报表的输出。

返回

Page 173: 涪陵职业教育中心 吴玉琼    制作

第第 99 章 章 VFP6VFP6 菜单设计菜单设计

学习要点1 、规划应用程序菜单系统。2 、使用菜单设计器设计应用系统菜单,为菜单指定任务。3 、自定义工具栏及在表单集中添加自定义工具栏。

9.1 在应用程序中使用菜单

9.2 创建自定义工具栏

退 出

小 结

返 回

Page 174: 涪陵职业教育中心 吴玉琼    制作

9.1 9.1 在应用程序中使用菜单在应用程序中使用菜单

9.1.1 创建菜单系统

9.1.2 规划菜单系统

9.1.3 创建菜单

9.1.4 在应用程序中包含菜单

9.1.5 为菜单系统指定任务

返 回 退 出

Page 175: 涪陵职业教育中心 吴玉琼    制作

9.1.1 9.1.1 创建菜单系统创建菜单系统 用户在查找信息之前,首先看到的便是菜单。如果把菜单设计得很好,那么只要根据菜单的组织形式和内容,用户就可以很好地理解应用程序。为此, VFP 提供了“菜单设计器”,可以用来创建菜单,提高应用程序的质量。 创建菜单系统的大量工作是在“菜单设计器”中完成。 在项目管理器中选择“其他”选项卡,从中选择“菜单”,然后单击“新建”打开“新建菜单”对话框。 选择“菜单”,打开“菜单设计器”。

Page 176: 涪陵职业教育中心 吴玉琼    制作

创建一个菜单系统包括若干步骤。不管应用程序的规模多大,打算使用的菜单多么复杂,创建菜单系统都需以下步骤: 第 1 步、规划与设计系统:确定需要哪些菜单、出现在界面的何处以及哪几个菜单要有子菜单等等。有关规划菜单系统的详细内容,请参阅本章稍后的规划菜单系统。第 2 步、创建菜单和子菜单:使用菜单设计器可以定义菜单标题、菜单项和子菜单。第 3 步、按实际要求为菜单系统指定任务:指定菜单所要执行的任务,例如显示表单或对话框等。另外,如果需要,还可以包含初始化代码和清理代码。初始化代码在定义菜单系统之前执行,其中可以打开文件;声明变量;或将菜单系统保存到堆栈中,以便可以在后面的程序执行中恢复。清理代码中包含的代码在菜单的定义代码之后执行,使菜单和菜单项可用或不可用。第 4 步、生成菜单程序。第 5 步、运行生成的程序,测试菜单系统。

返 回

Page 177: 涪陵职业教育中心 吴玉琼    制作

9.1.2 9.1.2 规划菜单系统规划菜单系统 应用程序的实用性一定程度上取决于菜单系统的质量。花费一定时间规划菜单,有助于用户接受这些菜单,同时也有助于用户对这些菜单的学习。设计菜单系统时,要考虑下列准则:以建立 Gxglxt 菜单为例说明规划菜单系统的准则:1 、按照用户所要执行的任务组织系统,而不要按应用程序的层次组织系统。只要查看菜单和菜单项,用户就应该可以对应用程序的组织方法有一个感性认识。因此,要设计好这些菜单和菜单项,必须清楚用户思考问题的方法和完成任务的方法。根据简单的 Gxglxt 项目的基本任务,可以将所建立的菜单系统分为和系统有关的操作(如操作员注册、添加、删除操作员、退出系统等);与数据输入有关的操作(如添加新系、添加新班级、添加新专业、添加新课程等、学生注册、成绩录入);与数据输出有关的操作(如学生情况报表、学生成绩报表);与信息查询有关的操作(如系查询、班级查询、专业查询、课程查询、学生查询等);最后是帮助。

Page 178: 涪陵职业教育中心 吴玉琼    制作

2 、给每个菜单一个有意义的菜单标题。第一个菜单笺命令名为【系统管理】,其中包括菜单项【操作员注册】、【添加操作员】、【删除操作员】、【退出】;第二个菜单笺命令名为【输入数据】,其中包括菜单项【添加新系】、【添加新班级】、【添加新专业】、【添加新课程】、【学生注册】、【成绩录入】;第三个菜单笺命名为【报表】,其中包括【学生情况报表】、【打印学生成绩】;第四个菜单笺命名为【查询】,其中包括【系查询】、【班级查询】、【专业查询】、【课程查询】、【学生查询】;第五个菜单笺命名为【帮助】,其中只包含【关于】菜单项。3 、按照估计的菜单项使用频率、逻辑顺序或字母顺序组织菜单项。如果不能预计频率,也无法确定逻辑顺序,则可以按字母顺序组织菜单项。当菜单中包含有八个以上的菜单项时,按字母顺序特别有效。太多的菜单项需要用户花费一定的时间才能浏览一遍,而按字母顺序则便于查看菜单项。通常是将【系统管理】放在第一位,然后才是对数据的有关操

Page 179: 涪陵职业教育中心 吴玉琼    制作

作的菜单。可按【系统管理】、【数据输入】、【查询】、【报表】、【帮助】的次序设置菜单。 4 、 放置分隔线:第一个菜单笺中在【退出】菜单项上设置一条,第二个菜单笺将【学生注册】、【成绩录入】菜单项与其它菜单项分开,第三个菜单笺不设分隔线,第四个菜单笺分成三个部分:【系查询】、【班级查询】为第一部分;专业查询】、【课程查询】为第二部分;【学生查询】为第三部分,第五个菜单笺不设分隔线。 5 、将菜单上菜单项的数目限制在一个屏幕之内。6 、如果菜单项的数目超过了一屏,则应为其中的一些菜单项创建子菜单。 7 、为菜单项指定任务:

Page 180: 涪陵职业教育中心 吴玉琼    制作

8 、为菜单和菜单项设置访问键或键盘快捷键。

说明:【退出】习惯用 Alt+E ,【帮助】习惯用 Alt+H 、【关于】习惯用 Alt+A 作为访问键,其它可任意设定,但最好是使用Ctrl+ 或 Alt+ 和能代表菜单项功能的某一个特殊的字母组合为快捷键,快捷键的定义在一个菜单中不要有重复。 9 、使用能够准确描述菜单项的文字。描述菜单项时,要使用日常用语而不要使用计算机术语。同时,说明选择一个菜单项产生的效果时,应使用简单、生动的动词,而不要将名词当作动词使用,另外,要用相似语句结构说明菜单项。10 、在菜单项中混合使用大小写字母。 返 回

Page 181: 涪陵职业教育中心 吴玉琼    制作

9.1.3 9.1.3 创建菜单创建菜单 规划好菜单系统之后,就可以使用菜单设计器创建该系统了。这时,可以创建菜单、快捷菜单、菜单项、子菜单和菜单项组之间的分隔线等等。1 、创建菜单 按前述方法打开“菜单设计器”。

“ 菜单设计器”中选项说明:“ 菜单名称”:在菜单系统中指定菜单标题和菜单项的名称。

Page 182: 涪陵职业教育中心 吴玉琼    制作

“结果”:指定在选择菜单标题或菜单项时发生的动作。例如,可执行一个命令,打开一个子菜单或运行一个过程。“ 创建”:在“结果”项中选择“子菜单”或“过程”时,用于指定菜单标题或菜单项的子菜单或过程。“ 编辑”:在创建了“子菜单”或“过程”后,可以更改与菜单标题或菜单项相关的子菜单或过程。“ 选项”:显示“提示选项”对话框,可以在其中定义键盘快捷键和其它菜单选择。“ 菜单级”:弹出下拉菜单,让用户选择要处理的菜单或子菜单。“ 预览”:显示正在创建的菜单的预览结果。“ 插入”:在“菜单设计器”窗口中插入新的一行。“ 插入栏”:显示“插入系统菜单条”对话框,使用户可以插入标准的 VFP 菜单项。“删除”:从“菜单设计器”中删除当前菜单行。利用菜单设计器窗口各个选项就可以设计完整的菜单。

Page 183: 涪陵职业教育中心 吴玉琼    制作

1 、创建 Gxglxt 菜单1 、创建【系统】管理菜单笺 系统管理 (\<S)

创建【数据输入】菜单笺

数据输入 (\<I)

创建【报表】菜单笺

报表 (\<R)

创建【查询】菜单笺

查询 (\<Q)

创建【帮助】菜单笺

帮助 (\<H)

2 、创建【系统管理】的子菜单:选择【系统管理】

单击【创建】 创建【操作员注册】菜单项

操作员注册

单击【选项】按钮设置快捷键

在光标置于此栏后按下要定义的快捷键 Ctrl+O

单击【确定】“提示选项”对话框

Page 184: 涪陵职业教育中心 吴玉琼    制作

按相同的方法创建【添加操作员】、【删除操作员】、【退出】三个菜单项。

在指定的菜单项(【删除操作员】与【退出】菜单项之间)中添加分隔线:选中下面的菜单项【退出】后单击【插入】按钮。

删除“新菜单项”几个字后输入“ \-”

【系统管理】菜单笺定义后,单击“菜单级”下拉选择框,从中选择“菜单栏”。

按创建子菜单的方法创建其他菜单笺下的菜单项(子菜单),过程略。

Page 185: 涪陵职业教育中心 吴玉琼    制作

3 、为菜单项指定任务

子菜单创建后,此处的“创建”将变为“编辑”。

单击【编辑】

单击“结果”下拉选择框,从中选择“命令”。在此框中输入该菜单

项应执行的命令: Do Form Forms\operator

说明:表单按《上机指导》中的定义,使用同样的方法为另三个菜单项指定任务。

【系统管理】菜单笺中各菜单项的任务指定完成后,单击“菜单级”下拉选择框,从中选择“菜单栏”。

按相同的方法分别为【数据输入】、【报表】、【查询】、【帮助】的子菜单中各菜单项指定任务。 菜单设计完成后,选择系统菜单上的【菜单】 | 【生成】,生成 .MPR 文件。

Page 186: 涪陵职业教育中心 吴玉琼    制作

生成 gxglxt.mpr 文件后,便可以在项目管理器中运行该文件:在项目管理器中选择“其他”选项卡,然后从“菜单”中选择“ gxglxt” ,再单击【运行】。运行的结果格式如下:

各子菜单格式如下:

最后的一项【项目】并不是我们所定义的共单笺。因为我们是在“项目管理器”中运行的 gxglxt.mpr 文件,项目管理器没有关闭才有【项目】这一项。如果在菜单运行后将“项目管理器”关闭,则这一项将会变为【格式】。在应用程序中将菜单连编后脱离 VFP 运行时,就不会有这一项。

Page 187: 涪陵职业教育中心 吴玉琼    制作

2 、通过修改快速菜单得到自户自定义菜单 若要从已有的 VFP 菜单系统开始创建菜单,则可以使用“快速菜单”功能。若要用“快速菜单”创建菜单系统,可以按下列步骤进行: 打开“菜单设计器”,然后从系统菜单上的【菜单】中选择【快速菜单】。

在“快速菜单”中通过【插入】、【删除】或修改得到所要求的菜单格式。

Page 188: 涪陵职业教育中心 吴玉琼    制作

例如,如果要在“帮助”菜单前插入“客户”菜单,可以选择与“帮助”菜单行,再选择“插入”按钮,然后在“菜单名称”栏中键入“客户”,其结果如图 。

移动按钮

注意:拖动移动按钮可以改变菜单栏上各菜单的位置。 如果需要“帮助”菜单,应将它安排在菜单栏上的最后,这样用户能够很快找到它。 在应用程序中使用菜单之前,必须将它生成。

Page 189: 涪陵职业教育中心 吴玉琼    制作

3 、创建快捷菜单 在 VFP6 或者在 Windows 中,选定某个控件或对象后单击右键时,就会显示快捷菜单,可以快速展示对当前对象进行操作的各种可用的功能。正是因为这种菜单的方便快捷,它才被称为快捷菜单。可用 VFP 创建快捷菜单,并将这些菜单附加在控件中。若要创建快捷菜单。可从“项目管理器”中选择【其他】选项卡,选择“菜单”,并选定【新建】。接下来选择【快捷菜单】,则出现“快捷菜单设计器”。

进入“快捷菜单设计器”后,添加菜单项的过程与创建菜单完全相同。

Page 190: 涪陵职业教育中心 吴玉琼    制作

例如,创建一个包含有二个选项【运行表单】和【关闭】的快捷菜单。浏览命令的代码是 DO FORM ? ,在关闭菜单定义时,“结果”栏中选择“菜单项 #” ,在“结果”栏后的栏中输入“ _mfi_close” ,表示调用系统菜单中的“关闭”功能。创建完成后,将生成一个菜单名为 Myquickmenu.mpr ,其中 Myquickmenu 是自己命名的菜单文件名。所创建的菜单结果如图

然后在系统菜单中选择【菜单】 | 【生成】,生成 QuickMenu.mpr 。

最后在“属性示例”表单的 RightClick Event 方法程序中添加下行代码:Do Menus\QuickMenu.mpr

返 回

Page 191: 涪陵职业教育中心 吴玉琼    制作

9.1.4 9.1.4 在应用程序中包含菜单在应用程序中包含菜单 创建了菜单系统后,可将其包含在应用程序中。若要在应用程序中包含菜单,可将 .mnx 文件添加到项目中,并由项目建立应用程序。创建并生成了快捷菜单以后,就可将其附加到控件中。当用户在控件上单击鼠标右键时,显示典型的快捷菜单。在控件的 Rig-htClick (单击鼠标右键)事件中输入少量代码,即可将快捷菜单附加到特定的控件中。先选择要附加快捷菜单的控件,然后在“属性”窗口中选择“方法程序”选项卡并选择“ RightClick Event”最后在代码窗口中键入 Do menu.mpr ,其中 menu 是快捷菜单的文件名。注意:引用快捷菜单时,必须使用 .mpr 扩展名。如在上一节中,在“属性示例”表单的 RightClick Event 事件代码中添加代码 DO Menus\Quickmenu.mpr 。

Page 192: 涪陵职业教育中心 吴玉琼    制作

如果想将此快捷菜单应用于所有新创建的表单,则可以修改表单的类定义。步骤如下:( 1 )打开“项目管理器”并选择“类”选项卡。 ( 2 )选择【添加】,将 C:\Program Files\Microsoft Visual Studio\Vfp98\ Wizar-ds\Wizembss.vcx 添加到“类”中。

单击【确定】

( 3 )单击 Wizembss 类前的“ +”号,再选择 Embossedform 子类 ( 4 )选择“项目管理器”上的【修改】按钮,打开“类设计器” ( 5 )选择“属性”

对话框中的“方法程序”选项卡,再选定 RightClick Event 事件。 ( 6 )双击 RightClick Event ,打开方法程序代码编辑窗口,在该窗口中输入命令 :

DO MENUS\QUICKMENU.MPR

Page 193: 涪陵职业教育中心 吴玉琼    制作

( 7 )关闭“方法程序”编辑窗口,关闭“类设计器”窗口,将所做的修改保存到 Embossedform 子类中。 说明: Embossedform 子类是建立表单的类( Class ),以后所建的表单均含有单击右键时调用Myquickmeun 菜单的功能。

若要将 SDI 菜单附加到表单中可在创建了 SDI 菜单后,将其附加到 SDI 表单中,其步骤如下:

( 1 )在“表单设计器”中,将表单的 Show Window 属性设置为“ 2- 作为顶层表单”。

( 2 )在表单的 Init 事件中调用该菜单。例如,假设菜单名为 Quickmenu.mpr ,添加此代码:

DO Quickmenu.mpr WITH THIS,.T.

返 回

Page 194: 涪陵职业教育中心 吴玉琼    制作

9.1.5 9.1.5 为菜单系统指定任务为菜单系统指定任务 在创建菜单系统时,需要考虑系统访问的简便性,也必须为系统指定任务。必须为菜单和菜单项指定所执行的任务,如显示表单、工具栏以及其他的菜单系统。用户应该定义可以访问菜单系统的访问键,还可以添加键盘快捷键,并且控制菜单何时可用。1 、指定访问键设计良好的菜单都具有访问键,从而通过键盘可以快速地访问菜单的功能。在菜单标题或菜单项中,访问键用带有下划线的字母表示。例如, VFP 的【文件】菜单使用“ F” 作为访问键。如果没有为某个菜单标题或菜单项指定访问键, VFP 将自动指定第一个字母作为访问键。例如,假定没有给创建的“ EDIT”菜单定义访问键, VFP 将指定第一个字母( E )作为它的访问键。若要为菜单或菜单项指定访问键,可在希望成为访问键的字母左侧键入“ \<” 。例如,要在“ EDIT” 菜单标题中设置“ I” 作为访问键,可在“菜单名称”栏中将“ EDIT” 替换为“ ED\<IT” 或“ EDIT\<I” 。

Page 195: 涪陵职业教育中心 吴玉琼    制作

2 、指定键盘快捷键除了指定访问键以外,还可以为菜单或菜单项指定键盘快捷键。和使用访问键一样,使用键盘快捷键是让用户在按下某个键的同时,再按另一个键而选择菜单或菜单项。访问键与键盘快捷键的区别是:使用快捷键可以在不显示菜单的情况下选择此菜单中的一个菜单项。VFP 菜单项的快捷键一般用 Ctrl 或 Alt键与另一个键相组合。例如,按 Ctrl+N 可在 VFP 中创建新文件。若要为菜单或菜单项指定快捷键,可以先在“菜单名称”栏中,选择相应的菜单标题或菜单项,再选择“选项”栏中的按钮,显示“提示选项”对话框,如图 9-9 所示。然后在“键标签”框中,按下一组合键,可创建快捷键,如果一个菜单项没有快捷键, VFP 将在“键标签”框中显示“按下要定义的键”,最后在“键说明”框中,添加希望在菜单项的旁边出现的文本。注意: Ctrl+J 是无效的快捷键,因为在 VFP 中,经常将其作为关闭某些对话框的快捷键。

Page 196: 涪陵职业教育中心 吴玉琼    制作

3 、启用和废止菜单项 可以根据逻辑条件启用或废止菜单及菜单项。设 Gxglxt 菜单中各项启用和废止条件如下表

说明: czyqx 为在菜单运行前所赋值的一个字符型内存变量,在《上机指导》中是在 Operator 表单中赋的值。菜单的启用或废止是根据所给条件计算得到,当条件为 .T. 时即将菜单笺或菜单项废止,如不给条件,默认为 .F. ,即启用。如果菜单笺废止,那么菜单笺中的所有菜单项均废止。如“系统管理”菜单笺下的“操作员注册”没有设置条件,即它按该菜单笺的条件执行。

Page 197: 涪陵职业教育中心 吴玉琼    制作

菜单启用和废止的设置方法:①在“菜单设计器”的“菜单名称”栏中,选择相应的菜单标题或菜单项。如“系统管理”菜单笺中的“操作员注册”共单项 。

②单击“选项”按钮,显示“提示选项”对话框。 ③选择“跳过”按钮,打开“表达式生成器”或直接在“跳过”文本框中输入条件表达式。

UPPER(CZYQX)>"A"

④ 单击【确定】按钮返回到“菜单设计器”

返回到“菜单设计器”后,可用同样的方法设置其他菜单项启用或废止。

Page 198: 涪陵职业教育中心 吴玉琼    制作

4 、输入过程或程序 如:在 Gxglxt 菜单的【查询】菜单笺中所有的菜单项均调用同一个表单查询界面(表单中的数据源来自系统当前工作区中的表),不同处是对不同的查询菜单项使用不同的表。由于使用同一表单界面,为菜单项指定任务时可以通过调用过程完成。 打开“菜单设计器”,进入到【查询】菜单笺中,如图:

将【查询】菜单笺中的所有菜单项的“结果”设置为“过程”。方法同前。然后选择【系查询】,单击【创建】按钮。

在“系查询” - 过程编辑窗口中输入过程代码:

PUBLIC NWORKAREA,LUSEEDNWORKAREA=SELECT(0)LUSEED=.T.IF !USED("DEPARTMENT")

LUSED=.F.SELECT 0USE DATA\DEPARTMENT

ENDIFSELECT DEPARTMENTDO FORM FORMS\DATAQUERY

然后关闭“过程”编辑窗口。

返回“菜单设计器”后,使用同样的方法为其他菜单项编辑过程。

共用的查询表单名

Page 199: 涪陵职业教育中心 吴玉琼    制作

可以为菜单或菜单项指定一个过程,指定过程的方式取决于菜单或菜单项是否有子菜单。若要为不含有子菜单的菜单或菜单项指定过程,可以在“菜单名称”栏中,选择相应的菜单标题或菜单项,再在“结果”框中选择“过程”,“创建”按钮出现在列表的右侧。如果先前已定义了一个过程,则这里出现的是“编辑”按钮,再选择“创建”或“编辑”,在窗口中键入正确的代码。由于 VFP 会自动地生成 PROCEDURE语句,因而不必在过程编辑窗口中键入此语句,只有在清理代码中才需要 PROCEDURE语句。为含有子菜单的菜单或菜单项指定过程的步骤如下:( 1 )请在“菜单级”框中,选择包含相应菜单或菜单项的菜单级。( 2 )从系统菜单中选择【显示】 | 【菜单选项】。( 3 )可以用下列方法之一指定一个过程:在“过程”框中编写或调用过程,或者选择“编辑”,然后再选择“确定”,打开独立的编辑窗口并编写或调用过程。

Page 200: 涪陵职业教育中心 吴玉琼    制作

5 、向菜单系统添加初始化代码和清理代码向菜单系统添加初始化代码可以定制菜单系统,初始化代码可以包含创建环境的代码、定义变量的代码、打开所需文件的代码,以及使用 PUSH MENU 和 POP MENU 保存或恢复菜单系统的代码。向菜单系统中添加初始化代码,可以从系统菜单中选择【显示】 | 【常规选项】,在“菜单代码”区域,选择“设置”,然后再选择【确定】,再在初始化代码窗口中,键入适当的初始化代码。向菜单系统添加清理代码可以减小菜单系统的大小。清理代码常包含一些代码,在初始时启用或废止菜单系统中的菜单或菜单项。在生成并运行菜单程序时,初始化代码及菜单定义代码在清理代码之前执行。向菜单系统中添加清理代码,可以从系统菜单中选择【显示】 | 【常规选项】,在“菜单代码”区域,选择“清理”,然后再选择【确定】,再在清理代码窗口中,键入适当的清理代码。关闭“菜单设计器”时,同时保存所做的变更。注意:如果设计的菜单是应用程序的主菜单,则应该在清理代码中包含 READ EVENTS 命令,并为退出菜单系统的菜单命令指定一个 CLEAR 命令。这可以防止应用程序的运行过早地中断。 返 回

Page 201: 涪陵职业教育中心 吴玉琼    制作

9.2 9.2 创建自定义工具栏创建自定义工具栏

9.2.1 定义工具栏类

9.2.2 在表单集中添加自定义工具栏

退 出返 回

如果应用程序中包含一些用户经常重复执行的任务,那么可以添加相应的自定义工具栏,简化操作,加速任务的执行。 下面各节介绍的是为应用程序创建自定义工具栏的方法。

Page 202: 涪陵职业教育中心 吴玉琼    制作

9.2.1 9.2.1 定义工具栏类定义工具栏类 如果要创建一个工具栏,要它包含己有工具栏所没有的按钮,则可通过定义一个自定义工具栏类完成此任务。 VFP 提供了一个工具栏基类,在此基础上可以创建所需的类。创建新类的方法在 5.4.5 类的操作方法中已作详细的讲解。定义了工具栏类以后,可向工具栏类添加对象,并为自定义工具栏定义属性、事件和方法程序,最后可将工具栏添加到表单集中。

返 回

Page 203: 涪陵职业教育中心 吴玉琼    制作

9.2.2 9.2.2 在表单集中添加自定义工具栏在表单集中添加自定义工具栏 在定义一个工具栏类之后,便可以用这个类创建一个工具栏。可以用“表单设计器”或者用编写代码的方法,将工具栏与表单对应起来。1 、在“表单设计器”中协调工具栏和表单可以在表单集中添加工具栏,让工具栏与表单集中的各个表单一起打开。但不能直接在某个表单中添加工具栏。使用“表单设计器”在表单集中添加工具栏的步骤如下:( 1 )先注册并选定包含工具栏类的类库。( 2 )打开要使用上述工具栏类的表单集,再从“表单控件”工具栏选择“查看类”,然后从显示的列表中选择该工具栏类。( 3 )从“表单控件”工具栏中选择工具栏类。( 4 )在“表单设计器”中单击,添加此工具栏,然后将工具栏拖动到适当的位置, VFP 将在表单集上添加工具栏,如果表单集尚未打开, VFP 将提示用户打开一个。 ( 5 )为工具栏及其按钮定义操作。

Page 204: 涪陵职业教育中心 吴玉琼    制作

2 、使用代码协调工具栏和表单 除了使用“表单设计器”外,还可以使用代码在表单集中添加工具栏。如果要使用代码在表单集中添加工具栏,可以在表单集的 Init 事件中,使用 SET CLASSLB 命令,指定包含工具栏类的类库,然后在表单集中由此类创建工具栏。例如,要添加并显示基于 _base 类库中 _toolbar 类的工具栏 mytoolbar ,可以在表单集的 Init 事件中添加下列代码: SET CLASSLIB TO LIBS\_BASE THIS.ADDOBJECT("MYTOOLBAR","_TOOLBAR") THIS.MYTOOLBAR.SHOW

如果使用已经定义了的一个工具栏,如在第五章中定义的 NEWTOOLBAR工具栏,则可以在表单集的 Init 事件添加如下代码: SET CLASSLIB TO LIBS\NEWTOOLBAR ADDITIVE THIS.ADDOBJECT("MYTOOLBAR","NEWTOOLBAR") THIS.MYTOOLBAR.SHOW 注意:如果工具栏类没有定义工具栏及其按钮要执行的操作,那么必须在与工具栏及其按钮相关的事件过程中定义操作。

Page 205: 涪陵职业教育中心 吴玉琼    制作

3 、创建自定义工具栏示例可以在代码中定义工具栏的各个要素。例如,在第五章中定义的 NEWTOOLBAR工具栏没有指定工具栏及其按钮等要执行的操作,现以该工具栏添加到表单集为例,说明其方法。先在表单集的 Init 事件中添加下列代码,当加载表单集时, VFP 将创建并显示代码中定义的工具栏,该工具栏如图:

SET CLASSLIB TO LIBS\NEWTOOLBAR ADDITIVE THIS.ADDOBJECT("MYTOOLBAR","NEWTOOLBAR")

THIS.MYTOOLBAR.SHOW 对 NEWTOOLBAR工具栏中各控件的执行代码定义的步骤及代码如下:( 1 )选择“项目管理器”中的“类”选项卡。( 2 )找到并选择以前定义的 NEWTOOLBAR 类。( 3 )单击“项目管理器”的【修改】按钮。

Page 206: 涪陵职业教育中心 吴玉琼    制作

( 4 )分控件进行代码设计。■ 对 Combo1组合框的代码进行定义:●选择 Combo1 控件,在“属性”中选择“其它”选项卡,将 Enabled 属性设为“假” 。(在表单集中不设文章排版)。■ 对 Combo2组合框的代码进行定义:●选择 Combo2 控件,在“属性”中选择“数据”选项卡,将 RowSourceType 属性设为“ 1- 值”,将 RowSource 属性设为 宋体 ,黑体 ,仿宋 ,楷体(还可以添加其它 VFP 能识别的字体名)。设置初始值,将 Value 属性设为 =" 宋体 " 。●选择“方法程序”选项卡,双击 Click Event ,在弹出的代码编辑框中写入如下代码:THISFORMSET.ActiveForm.ActiveControl.FontName=THIS.VALUE

Page 207: 涪陵职业教育中心 吴玉琼    制作

■ 对 Combo3组合框的代码进行定义:●在上一步的方法程序编辑框中,从“对象”后的组合框中选择 Combo3 ,然后在 Click Event 方法程序编辑框中输入如下的代码:THISFORMSET.ActiveForm.ActiveControl.FontSize=;VAL(ALLTRIM(THIS.VALUE))

●在“属性”中的对象选择框中选择 Combo3 对象,再选择“数据”选项卡,将 RowSourceType 属性设为“ 1- 值”,将 RowSource 属性设为 8,9,10,11,12,14,16,18,20,22,24,26,28, 36,48,72 。设置初始值,将 Value 属性设为 ="9" 。■ 对 Command1 命令按钮的代码进行定义:在上一步的方法程序编辑框中,从“对象”后的组合框中选择 Command1 对象,然后在 Click Event 方法程序编辑框中输入如下的代码:THISFORMSET.ActiveForm.ActiveControl.FontBold=;!THISFORMSET.ActiveForm.ActiveControl.FontBoldTHIS.FontBold=THISFORMSET.ActiveForm.ActiveControl.FontBold

■ 对 Command2 命令按钮的代码进行定义:

Page 208: 涪陵职业教育中心 吴玉琼    制作

在上一步的方法程序编辑框中,从“对象”后的组合框中选择Command2 对象,然后在 Click Event 方法程序编辑框中输入如下的代码: THISFORMSET.ActiveForm.ActiveControl.FontItalic=;!THISFORMSET.ActiveForm.ActiveControl.FontItalicTHIS.FontItalic=THISFORMSET.ActiveForm.ActiveControl.FontItalic

■ 对 Command3 命令按钮的代码进行定义: 在上一步的方法程序编辑框中,从“对象”后的组合框中选择 Command3 对象,然后在 Click Event 方法程序编辑框中输入如下的代码:THISFORMSET.ActiveForm.ActiveControl.FontUnderline=;!THISFORMSET.ActiveForm.ActiveControl.FontUnderlineTHIS.FontUnderline=THISFORMSET.ActiveForm.ActiveControl.FontUnderline

到此,对类设计定义完成,可关闭“方法程序编辑框”,关闭“类设计器”并将所做修改保存。

Page 209: 涪陵职业教育中心 吴玉琼    制作

将该工具栏加入到 Student 表单集运行后,选择表单上的“说明”后面的编辑框对象,进行图中工具栏状态设置后(黑体、 12磅字号、粗斜体、加下划线)的结果:

返 回

Page 210: 涪陵职业教育中心 吴玉琼    制作

小 结小 结1 、进行菜单系统设计前应先做好规划:①按要执行的任务组织系统:即菜单系统中要设计哪几个菜单笺以及菜单笺在菜单系统中的顺序;②每个菜单笺中应设置的菜单项以及菜单项的先后顺序,菜单项是否分组;③菜单笺以及菜单项的中文名,访问键和键盘快捷键设置和定义;④ 为菜单项指定任务,可以使用命令、菜单项、过程等;⑤ 设置菜单的启用和废止条件以及菜单的说明信息。2 、使用“菜单设计器”根据所规划的菜单系统定义菜单系统:①先设计菜单笺(包含中文名、先后顺序、访问键、启用及废止条件等);②再设计菜单项(包含中文名、先后顺序、分隔线、快捷键、启用及废止条件、菜单项信息、菜单项应执行的任务等)。3 、使用“快捷菜单设计器”设计快捷菜单并在表单中包含快捷菜单或者在表单类中包含调用快捷菜单的命令。4 、使用“快速菜 单”设计系统菜单。5 、菜单设计完成后要生成菜单文件( .mpr 文件)。6 、自定义工具栏,并在表单集中通过注册类的方法或在表单集的 Init 事件中使用命令的方法添加自定义工具栏。

返 回

Page 211: 涪陵职业教育中心 吴玉琼    制作

返回

注意:①全部标签的 AutoSize 均 设 为 .T. ,其它 控 件 的 大小适中。

②SQL : SELECT DISTINCT Student.classes FROM xsglxt!student INTO CURSOR ClassQuery

Page 212: 涪陵职业教育中心 吴玉琼    制作

第第 1010 章:多用户与共享技术 章:多用户与共享技术

10.1 多用户环境中的数据访问技术

10.2 数 据 更 新 技 术

10.3 对 访 问 冲 突 的 处 理

小 结 返回 退出

学习要点1 、多用户环境中文件的访问形式。2 、表的锁定、记录的锁定与解锁。3 、数据的更新技术。4 、访问冲突。

Page 213: 涪陵职业教育中心 吴玉琼    制作

10.1 10.1 多用户环境中的数据访问技术多用户环境中的数据访问技术 多用户条件下数据的访问技术其核心就是以共享的方式打开一个文件让其它用户则可以访问它。10.1.1 在多用户环境中访问数据 在多用户环境中,如果用户不希望接受其它用户的干扰或者为了保证数据的完整性和一致性,那么用独占的方式打开它也是最严格的限制方式。如果用户以界面的方式打开一个表时,它就一定是以独占的方式打开。另外,用户也可以用 VFP6 的命令明确的打开一个表。 1 、 SET EXCLUSIVE ON

USE student.dbf2 、 USE student EXLUSIVE

在 VFP6 中,要求以独占的方式打开表命令有 INDEX 、 ALTER 、 TABLE 、 INSERT 、 PACK 、 REINDEX 、 ZAP等,如果在共享的表中执行以上的这些命令,那么将以给出“文件必需以独占方式打开”的提示信息。

Page 214: 涪陵职业教育中心 吴玉琼    制作

多个用户如果要在同一时间内使用同一个文件中的数据,那么该文件必需用共享的方式打开,也可以采用命令的方式打开表。

1 、 SET EXCLUSIVE OFFUSE student.dbf

2 、 USE student.dbf SHARED

用户也可以用这些命令来共享那些以界面的方式打开的表,当用户要在共享表中添加或者更改数据时,必须首先将该表或者需要修改的记录锁定。

例如,下面的语句可以判断表 student.dbf 的打开方式set exclusive off use student.dbf && 以共享的方式打开表 student.dbfif isexclusive() && 判断表 student.dbf 的打开方式 ?" 表 student.dbf 是以独占的方式打开 "else ?" 表 student.dbf 是以共享的方式打开 "endif

Page 215: 涪陵职业教育中心 吴玉琼    制作

10.1.2 锁定数据的方式 如果要共享访问一个文件时,必须通过表和记录的锁定来实现数据的访问,锁定和访问权限的限制存在着本质的区别,访问权限是一种长期的控制数据访问的方法,而锁定是一种既可以短期内实施的方式,也可以是在长期内实现的方式。数据的锁定可以分为表的锁定和记录的锁定,表的锁定可以防止多个用户同时对表进行写操作但可以读整个表。因为表的锁定限制其他的用户对表中记录的更改,所以用户一般很少用它。记录锁定是防止多个用户同时对同一记录进行写操作,但其它用户可以对其它记录进行写操作,所以记录的锁定应用比较广泛,同时记录的锁定比表的锁定破坏性小得多。

例如,下面以表锁定的方式实现数据的替换use student.dbf share && 以共享的方式打开表if flock() && 判断是否已经锁定表 replace all VFP6 with VFP6+15else wait 'Unalbe to open products file ; please try again later!'endif

Page 216: 涪陵职业教育中心 吴玉琼    制作

不论是记录的锁定还是表的锁定都可以分为人工锁定和自动锁定。1 、自动锁定许多 VFP6 命令在执行前都会将操作对象表或记录自动锁定。锁定了后就执行该命令,命令执行完后再解锁。常见的自动锁定有如表 10-1 中的一些命令:下面列举出了以共享的方式打开表 Student.dbf文件。用户为了删除第三条记录而自动锁定整个表执行完后自动解锁。

SET EXCLUSIVE OFF Use student.dbf Go 3 Delete 2 、人工锁定

人工锁定是用函数来实现表和记录的锁定,并返回相应的值,能够完成人工锁定的函数有如下一些:函 数 范 围RLOCK() 锁定当前表中一个或多个记录LOCK() 锁定当前表中一个或多个记录FLOCK() 锁定当前整个表

Page 217: 涪陵职业教育中心 吴玉琼    制作

例如,若要锁住表 student.dbf 前四条记录的代码如下:SET EXCLUSIVE OFFSELECT 0USE student.dbf && 打开表 student.sbf

? LOCK('1,2,3,4', 'student') && 锁主表的 1~4条记录 人工锁定的函数可以完成下面的操作:■首先测试记录对象是否被锁定。■ 如果对象未被锁定则锁定,并返回逻辑值 .F.■ 如果对象不能被锁定则根据设置 SET REPROCESS进行重新锁定。■ 返回锁定成功与否的逻辑值。右面的例子以共享的方式打开表 student.dbf 文件,如果用 FLOCK() 锁定成功则输出 " You are Very good "否则输出 " you are bad. "

SET EXCLUSIVE OFFUse student.dbfIF FLOCK() ? "You are good"ELSE ? "You are very bad"ENDIF

Page 218: 涪陵职业教育中心 吴玉琼    制作

10.1.3 解锁数据的方式用户在对表或记录加锁后执行相关的操作、执行完后必须立即

解锁,以便其它用户方便操作。用户如果用自动锁定对象的方法解锁时只需移动记锁的指针就能解锁,而人工加锁则需要如下的命方去解锁,仅靠移动记录的指针是不行的。表 10-2列出了常用的一些解锁命令 :

例如,若在执行完锁住表 student.dbf 前四条记录后解锁的代码如下:SET EXCLUSIVE OFFSELECT 0USE student.dbf && 打开表 student.sbf? LOCK('1,2,3,4', 'student') && 锁主表的 1~4条记录unlock in student.dbf

Page 219: 涪陵职业教育中心 吴玉琼    制作

10.1.4 数据工作期数据工作期( Data sessions)是对用户当前工作环境的描述。可以把数据工作期看成是一个数据环境。每个数据工作期应该包括表单的数据环境中的各项备份和临时表打开的表索引及其关系,使用数据工作期可以确保在共享环境中每个用户有一个独立的操作环境和表单的多个实例可以单独操作。1 、使用私有数据工作期 应用程序创建的表单,表单集或者工具栏控件的每个实例新建一个数据工作期,那么用户可以使用私有数据工作期。私有数据工作期应该包括:■ 表单的数据环境中相关的备份。■较多的工作区。■ 独立于表单基表的每个表的记录指针。数据工作期的数量也不是无限制的,将受到系统内存和磁盘内空间的限制。

Page 220: 涪陵职业教育中心 吴玉琼    制作

2 、设置私有数据工作区。用户可以用两种方法来实现私有数据工作区的设置。■ 在表单设计器中,将该表单的 DataSession的属性设置选“2-私有数据工作

■ 在代码中设置 FrmFormName.DataSession=2.3 、标识数据工作期每个私有数据期都有自己的标识。标识在数据工作期窗口中查看

数据工作期的内容。表单的 DataSession的属性只用于表示那些特定的工作期。在程序设计的过程中,尽量不要改变数据工作期的标识,否则将丢失部分数据源。

4 、控制数据工作期的环境。数据工作期可以控制部分 SET命令的作用范围。所以可以在 VFP6工作期中使用私有数据工作期,建立自定义的 SET命令设置来控制特定的环境。

Page 221: 涪陵职业教育中心 吴玉琼    制作

10.1.5 数据缓冲技术为了保证安全的数据更新, VFP6 采用了缓冲技术。 VFP6 的缓冲技术是在多个用户环境中保护单个或多个记录的数据更新的数据维护操作运用,可以方便的检测和解决数据更新出现的问题,缓冲的方式可以分为表缓冲和记录缓冲二种方式。例如,下面的代码通过缓冲技术来实现数据的替换:

CLOSE DATABASESCREATE TABLE student(Name C(10))SET MULTILOCKS ON &&确定可以为多个记录加锁= CURSORSETPROP(‘Buffering’, 5, ‘student’ ) INSERT INTO student (Name) VALUES ('杰克 ')CLEAR? 'Original Name value: '+ Name && 显示原来的 nameREPLACE Name WITH '乔丹 '? 'New Name value: '+ Name = TABLEUPDATE(.T.) ? 'Updated Name value: '+ name

Page 222: 涪陵职业教育中心 吴玉琼    制作

10.2 10.2 数据更新技术数据更新技术用户可以选择事务处理或者视图来更新数据,缓冲技术用户在以前有所阐述,事务处理仅仅是将数据更新操作缓冲到内存或磁盘,并不是将这些操作直接作用于数据库。10.2.1 使用缓冲技术进行数据更新VFP6 中有两种缓冲:表缓冲和记录缓冲两种类型。表缓冲是在多用户环境中对表进行更新。先把要更新的表存放到缓冲处,再对缓冲去区的表进行更新,更新完成后再将缓冲区的数据保存回来。用户可以用两种办法来设置使用缓冲的方法。1、在表单设计器中,设置该表单的数据环境中临时表的 Buffer Mode Override的属性;2、在代码行中设置 Buffering属性。在 VFP6 中根据记录锁定的时间、释放的方式和释放的时间缓冲的锁定可以分为开放式和保守式。■ 保守式缓冲方式用户采用保守式的缓冲可以防止记录或者表正在修改的时候被其它的用户访问。所以保守式的缓冲对于单个记录的更新是最安全的环境。另一方面却降低了用户的使用效率。

Page 223: 涪陵职业教育中心 吴玉琼    制作

■ 开放式缓冲方式开放式缓冲对用户来说是一个比较有效的记录更新的方法,它的每次锁定只在写记录的时候进行。所以这种方式对系统的运行效率影响就比较小,一般用户在对视图使用缓冲时采用开放式的缓冲。设置缓冲的方式VFP6 中的 CURSORSETPROP()函数设置的 Buffering值决定了所采用的方式:1、缺省的情况下是没有缓冲。2、保守式记录缓冲,立即锁定记录,在指针移动或者用 TABLEUPDATE()函数后进行更新。3、开方式记录缓冲,视图或者访问远程表,一般选择这种方式。等记录指针移动后进行锁定和更新。4 、保守式表缓冲,马上锁定记录,等发出 TABLEUPDATE()函数后再更新5 、开放式表缓冲,等到函数 TABLEUPDATE ()时才锁定和更新记录,访问远程表有时也采用这中方式。

Page 224: 涪陵职业教育中心 吴玉琼    制作

10.2.2 使用事物处理机制管理更新 用缓冲技术对数据库进行更新时,有时也可能会出错,如果使用事务处理机制管理它们在出错的情况下,整段代码将被还原回来在应用程序中添加事务处理所提供的保护机制超过了缓冲技术的保护功能。它把整段代码作为一个受保护并且可以恢复的单元,另外, VFP6 事务处理系统只能用于数据库中的表和视图。它类似于一个外包装,可以用于高速缓存对内存或硬盘的数据库更新操作,并不直接对数据库进行更新,其实对数据库的更新是在操作完成之后。 VFP6 提供了如下的命令和函数来控制事物处理 :命 令 功 能 BEGIN TRANSACTION 对一个事务处理进行初始化,或者取消

最近的一条TXNLEVEL() 确定现在处理事务的等级ROLLBACK 取消全部所做的修改

Page 225: 涪陵职业教育中心 吴玉琼    制作

10.2.3 通过视图管理更新数据VFP6 视图具有更新冲突管理技术,用户可以通过它来管理多用户对数据的访问,通过Where Type属性来控制发送到基于视图的基表的内容,WhereType设置了四种属性:1、 B _KEY &&关键字段2、 B_KEYANDUPDATABLE &&关键字和可更新字段3、 DB_KEYANDMODIFIED &&关键字和已修改字段4 、 DB_KEYANDTIMESTAMP &&关键字和时间戳用户可以通过下面的办法来改变该属性的设置。■ 用“视图设计器”的“更新条件”选项来选择设置■ 用 DBSETPROPC()设置一个视图定义的 Where Type 属性。■ 用 Cursorsetprop ()来改变一个活动视图临时表的 Where Type设置。

Page 226: 涪陵职业教育中心 吴玉琼    制作

10.3 10.3 对访问冲突的处理对访问冲突的处理

对于多用户环境中,用户之间需要进行数据共享,就不可避免的出现冲突,不管用户采取的是缓冲、事务处理、还是视图,冲突都是存在的,所以检测和处理冲突是非常重要的。10.3.1 管理缓存冲突两个用户不能够同时锁定一个表或记录。如果一个用户要锁定一个另一个用户已经锁定的记录或表就容易产生冲突。在多用户环境下更高效进行数据更新操作,必须合理选择打开、缓冲和锁定数据的时间和方法,减少访问表或记录发生冲突的时间。用户开发的应用程序应包含管理冲突的例程,这样可以防止死锁。死锁通常在这种情况下发生:第一个用户已经锁定一个记录或表,现在试图去锁定已被第二个用户锁定的记录,而第二个用户又反过来试图锁定第一个用户锁定的记录。尽管这种情况很少发生,但记录或表被锁定的时间越长,这种死锁的可能性就越大。在对表和记录锁定的时候,用户应该尽量在操作完成后马上释放,尽量减少对象被锁定的时间。这样也可以较好的避免死锁现象。

Page 227: 涪陵职业教育中心 吴玉琼    制作

10.3.2 检测并避免冲突在共享环境下,用户可以通过某些函数知道在数据更新过程中哪些字段的值发生更改,其原来的值或者更改后的值是多少等。1、检测字段中所做的修改在数据更新特别是在共享的环境下,也许希望知道那些字段的值已经更改,在 VFP6.0中可以用 GETFLDSTAGE()来实现,下面的例子说明 student.dbf在缓冲区中的内容如果被修改MULTILOCKS将被置为 ON

CLOSE DATABASESCLEARSET MULTILOCKS ON && Allow table bufferingOPEN DATABASE SYS(2004)+"samples\data\testdata"USE student && Open student table=CURSORSETPROP("Buffering",5,"student") * Get field state on original xh field and display statenState=GETFLDSTATE("xh")DO DisplayState WITH nState

Page 228: 涪陵职业教育中心 吴玉琼    制作

* Change field contents and display stateREPLACE xh WITH "***"nState=GETFLDSTATE("xh")DO DisplayState WITH nState* Discard table changes and display state= TABLEREVERT(.T.) && Discard all table changesnState=GETFLDSTATE("xh")DO DisplayState WITH nStatePROCEDURE DisplayStatePARAMETER nStateDO CASE CASE nState=1

=MESSAGEBOX("Field has not been modified",0,"Results") OTHERWISE

=MESSAGEBOX("Field has been modified",0,"Results")ENDCASE

Page 229: 涪陵职业教育中心 吴玉琼    制作

2、确定缓冲区中字段的当前值和原有值如果知道当前值、原有值和一编辑的值,将可以决定如何处理错误和冲突。函数 OLDVAL() 返回一个缓冲字段的值,而 CURVAL()它可以确定磁盘上一个缓冲字段的当前值,下面的例程将建立一个新的表 nestabel.dbf ,它通过改变 CDIGIT 的值,然后输出原有值和当前值。

CLOSE DATABASESCLEARCREATE TABLE newtable FREE (cDigit C(10)) INSERT INTO mytable (cDigit) VALUES ("you") &&给 cDigit赋初值SET MULTILOCKS ON = CURSORSETPROP("Buffering",5) REPLACE cDigit WITH "we" &&给 cDigit赋新值? "Current value: " + CURVAL("cDigit", "mytable" ) && 输出 cDigit 的当前值? "Old value: " + OLDVAL("cDigit", "mytable") && 输出 cDigit 的原值= TABLEUPDATE(.T.) && 将更新提交到表中? "Table changes committed"? "New current value: " + CURVAL("cDigit", "mytable")? "New old value: " + OLDVAL("cDigit", "mytable")

Page 230: 涪陵职业教育中心 吴玉琼    制作

10.3.3 使用备注字段检测冲突使用 CompareMemo 属性来控制何时使用备注字段检查更新冲突。这个视图和临时表属性确定了在更新的 WHERE 子句中是否包含备注字段(备注或通用型)。默认设置是“真” (.T.),即在 WHERE 子句中包含备注字段。如果这个属性设置为“假” (.F),不论 UpdateType 如何设置,在更新的 WHERE 子句中都不会包含备注字段。当 CompareMemo 属性设置为假时,备注字段上的开放式冲突检查是不可用的。如要使用备注字段的冲突检查,请将 CompareMemo 属性设置为真 (.T.)。10.3.4 处理冲突的规则有扩展和可重用的代码可以管理在多用户环境中的冲突,完整的冲突管理例程应进行如下操作:■ 查有无冲突。■然后检测冲突的性质和位置。■ 提供详细的帮助信息,帮助用户有效的解决冲突。

Page 231: 涪陵职业教育中心 吴玉琼    制作

小 结小 结

一个比较好的能在网络上运行的文件必须要解决好数据的共享和数据更新的问题。本章讲述了在多用户的环境下文件的文件共享技术。主要讲述了多用户环境中的数据共享技术、数据更新技术和对访问冲突的处理。

Page 232: 涪陵职业教育中心 吴玉琼    制作

THE END

THANKS

Page 233: 涪陵职业教育中心 吴玉琼    制作

返回上一页