Page 1

高等学校计算机教材

Visual FoxPro 实用教程 (第 2 版) 郑阿奇 王洪元

王一莉

主编

梁敬东

杨长春

编著

Publishing House of Electronics Industry 北京·BEIJING


内 容 简 介 本书以 Visual FoxPro 6.0 中文版为语言背景,通过大量实例深入浅出地介绍了 Visual FoxPro 的基础知 识、可视化编程工具与编程方法。系统介绍了创建数据库、表和索引、程序设计、表单、控件、项目管理、 类、查询与视图、选单与工具栏、报表和标签设计、网络数据共享。本书概念清楚、层次分明、例题丰富, 适合教师课堂教学和自学。 书中每章均有习题和配套使用的上机实验指导,最后有综合应用实习,适合作为大学、高职、高专及各 类培训学校的教材,也可作为初学编程人员的参考书。

未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。 版权所有,侵权必究。 图书在版编目(CIP)数据 Visual FoxPro 实用教程/郑阿奇主编.—2 版.—北京:电子工业出版社,2004.8 ISBN 7-5053-9707-9 Ⅰ. V… Ⅱ. 郑… Ⅲ. 关系数据库—数据库管理系统,Visual FoxPro—高等学校—教材 Ⅳ. TP311.138 中国版本图书馆 CIP 数据核字(2004)第 014714 号

责任编辑:张荣琴 印

特约编辑:晓 鸽

刷:北京市海淀区四季青印刷厂

出版发行:电子工业出版社 北京市海淀区万寿路 173 信箱 邮编 100036 经

销:各地新华书店

本:787×1 092 1/16 印张:22 字数:577 千字

次:2004 年 8 月第 1 次印刷

数:5 000 册

定价:27.00 元

凡购买电子工业出版社的图书,如有缺损问题,请向购买书店调换。若书店售缺,请与本社发行部联系。 联 系 电 话 :( 010 ) 68279077 。 质 量 投 诉 请 发 邮 件 至 zlts@phei.com.cn , 盗 版 侵 权 举 报 请 发 邮 件 至 dbqq@phei.com.cn。


Visual FoxPro(简称 VFP)是 Microsoft 公司推出的一种 Windows 应用程序开发工具, 由于它具有简单易学、操作方便、功能强大等特点,已经成为普通程序设计语言。在我国, VFP 6.0 中文版已相当流行,为了适应形势发展的需要,高校的计算机专业和非计算机专业 已经开设 VFP 应用程序设计课程。江苏省从 1998 年开始进行 VFP 3.0 等级考试,2000 年开 始进行 VFP 5.0 等级考试。2001 年,我们结合 VFP 教学和应用开发的经验体会,编写了《Visual FoxPro 实用教程》。推出后,得到高校师生和广大读者的广泛认同,两年来已经重印 8 次, 目前仍在热销中。在此我们对大家的信任表示由衷的感谢! 为什么要推出《Visual FoxPro 实用教程(第 2 版)》? 《Visual FoxPro 实用教程(第 2 版)》继承了《Visual FoxPro 实用教程》的成功经验,仍 以 VFP 6.0 为平台,结合近两年的教学实践,进一步方便教和方便学。 《Visual FoxPro 实用教 程(第 2 版)》进一步充实了数据库和程序设计的内容和实例,增加了项目管理、网络数据 共享、程序调试、打包发布应用程序等内容,这些都是读者比较关注的。最后还特别增加了 一个综合应用实习,把所学的主要内容串起来。经过第 2 版的修订,本教程基本覆盖了 VFP 考试和应用中的所有问题。 本教程分为 4 个部分。实用教程部分一般在讲解内容后紧跟实例;习题部分主要训练编 程和弄清基本概念;上机操作指导部分通过实例一步一步引导读者进行操作、设计界面和编 程,还提出问题思考和在原来基础上让读者自己进行操作和编程练习;实习部分构成了一个 小的应用系统,进行综合训练。 全书通过大量应用实例介绍程序设计基础、面向对象程序设计的概念与方法,使读者轻 松学会在 Windows 环境中的可视化编程。不少例题先给出设计目标,然后介绍其实现方法步 骤,更便于读者理解程序设计的思想和方法。凡标有[Ex_xxx]的实例程序均能上机调试通过。 本教程各部分内容既相互联系又相对独立,其内容介绍的顺序依据教学特点作精心编 排,方便用户根据自己需要进行选择。本书不会有突然出现的概念和内容,从前到后读下来 不会有太多的障碍。实际上,读者只要阅读本书,结合上机操作指导进行练习和实习,就能 在较短的时间内基本掌握 Visual FoxPro 及其应用技术。 为了方便教学,本书配有 Powerpoint 课件,需要者可在 http://edu.phei.com.cn 网站下载 ·III·


打开课件文件的密码为 385352。 本教程不仅适合于教学,也非常适合于 VFP 的各类培训和用 VFP 开发应用程序的用户 学习和参考。 本书由王洪元(江苏工业学院)、王一莉(南京工业大学) 、梁敬东(南京农业大学)和 杨长春(江苏工业学院)编写,郑阿奇(南京师范大学)统编、定稿。杨丹丹帮助做了一些 校对工作。 参加本套丛书编写的还有顾韵华、刘启芬、殷红先、张为民、徐文胜、曹弋、丁有和、 郑进等。 由于时间仓促,加之作者水平有限,不当之处在所难免,恳请读者批评指正。 主编电子邮件地址:zhengaqi@njnu.edu.cn。

编 者 2004 年 1 月

·IV·


《Visual FoxPro 实用教程(第 2 版)》读者意见反馈表 尊敬的读者: 感谢您购买本书。为了能为您提供更优秀的教材,请您抽出宝贵的时间,将您的意见以 下表的方式(可从http://edu.phei.com.cn下载本调查表)及时告知我们,以改进我们的服务。 对采用您的意见进行修订的教材,我们将在该书的前言中进行说明并赠送您样书。 姓名: 电话: E-mail: 职业: 邮编: 通信地址: 1.您对本书的总体看法是: □很满意 □比较满意 □尚可 □不太满意 □不满意 2.您对本书的结构(章节): □满意 □不满意 改进意见

3. 您对本书的例题

□满意

□不满意

改进意见

4.您对本书的习题

□满意

□不满意

改进意见

5.您对本书的实训

□满意

□不满意

改进意见

6. 您对本书其他的改进意见:

7.您感兴趣或希望增加的教材选题是:

请寄:100036 北京万寿路 173 信箱高等职业教育事业部 电话:010-68163538 E-mail:baiyu@phei.com.cn

白羽收

·V·


第 1 部分 实 用 教 程 第1章

Visual FoxPro 6.0 的环境 ································································································ 1

1.1 集成开发环境 ····················································································································· 1 1.2 选单系统 ···························································································································· 2 1.3 工具栏 ······························································································································· 5 1.4 选项对话框 ························································································································ 5 1.5 命令窗口 ···························································································································· 7 1.6 项目管理器 ························································································································ 7 1.7 一个简单实例 ····················································································································· 8

第 2 章 数据库、表和索引········································································································· 10 2.1 数据库 ······························································································································ 10 2.1.1 交互创建数据库 ······································································································ 10 2.1.2 命令操作数据库 ······································································································ 11 2.2 表的结构 ··························································································································· 12 2.3 表的操作 ··························································································································· 15 2.3.1 通过选单操作表 ······································································································ 16 2.3.2 命令方式操作表 ······································································································ 18 2.4 表的索引 ··························································································································· 27 2.5 工作区 ······························································································································ 31 2.6 表的关系 ··························································································································· 32 2.6.1 永久关系 ················································································································ 33 2.6.2 临时关系 ················································································································ 34 2.7 数据库和表属性 ················································································································· 35 2.7.1 数据库的属性 ·········································································································· 35 2.7.2 数据库表的属性 ······································································································ 36 2.8 多数据库操作 ···················································································································· 40 2.9 数据库表的增减 ················································································································· 41 2.10 SQL 语句操作表··············································································································· 43 2.11 一个简单界面操作表实例 ·································································································· 46

第 3 章 程序设计基础················································································································· 48 3.1 数据类型 ··························································································································· 48 3.1.1 常量 ······················································································································· 48 3.1.2 变量 ······················································································································· 49 3.1.3 数组 ······················································································································· 52

·V·


3.2 操作符和表达式 ················································································································· 55 3.2.1 操作符 ···················································································································· 55 3.2.2 常用函数 ················································································································ 56 3.2.3 表达式 ···················································································································· 58 3.3 流程控制 ··························································································································· 59 3.3.1 顺序 ······················································································································· 59 3.3.2 条件分支 ················································································································ 60 3.3.3 循环控制 ················································································································ 63 3.4 过程和自定义函数 ············································································································· 65 3.4.1 过程和自定义函数的定义 ························································································· 65 3.4.2 自定义函数和过程的调用 ························································································· 66 3.4.3 参数传递方法 ·········································································································· 68 3.5 变量的作用范围 ················································································································· 69 3.6 数据库的存储过程和触发器 ································································································ 70

第 4 章 表单 ································································································································ 73 4.1 面向对象的程序设计 ·········································································································· 73 4.2 创建表单 ··························································································································· 80 4.3 表单的属性、事件和方法 ··································································································· 83 4.4 表单应用举例 ···················································································································· 88

第 5 章 控件 ································································································································ 89 5.1 标签 ································································································································· 89 5.2 文本框和编辑框 ················································································································· 90 5.3 命令按钮和命令按钮组 ······································································································· 94 5.4 列表框和组合框 ················································································································· 97 5.5 选项按钮组 ····················································································································· 100 5.6 复选框 ···························································································································· 102 5.7 页框和页 ························································································································· 102 5.8 表格 ······························································································································· 104 5.9 图像框和图片框 ··············································································································· 108 5.10 计时器 ·························································································································· 110 5.11 微调按钮 ······················································································································· 110 5.12 Active 控件 ···················································································································· 111 5.12.1 ActiveX 控件(OLEControl) ················································································ 111 5.12.2 ActiveX 绑定控件(OLEBoundControl) ································································· 113

第 6 章 项目管理器 ·················································································································· 114 6.1 使用应用程序向导 ··········································································································· 114 6.2 项目管理器介绍 ··············································································································· 119 6.2.1 项目管理器功能 ···································································································· 120 6.2.2 项目管理器管理项目 ······························································································ 122 6.3 项目连编 ························································································································· 124

·VI·


6.4 项目信息和项目文档 ········································································································ 126

第 7 章 类的创建和使用··········································································································· 130 7.1 VFP 的类 ························································································································ 130 7.2 用类设计器交互创建类 ····································································································· 130 7.3 新定义类的使用 ··············································································································· 134 7.4 编程创建类和表单 ··········································································································· 135

第 8 章 查询和视图 ·················································································································· 139 8.1 查询的创建和使用 ··········································································································· 139 8.1.1 查询设计器 ··········································································································· 140 8.1.2 SELECT-SQL 查询语句 ·························································································· 148 8.1.3 查询的应用 ··········································································································· 153 8.1.4 交叉表查询 ··········································································································· 154 8.2 视图的创建和使用 ··········································································································· 155 8.2.1 创建本地视图 ········································································································ 155 8.2.2 视图使用 ·············································································································· 158

第 9 章 选单和工具栏··············································································································· 160 9.1 选单设计器 ····················································································································· 160 9.1.1 选单设计器 ··········································································································· 160 9.1.2 创建主选单 ··········································································································· 163 9.1.3 创建快捷选单 ········································································································ 165 9.2 在应用程序中使用选单 ····································································································· 166 9.2.1 启用和废止选单项 ································································································· 167 9.2.2 配置系统选单 ········································································································ 168 9.2.3 程序调用选单 ········································································································ 170 9.3 创建自定义工具栏 ··········································································································· 170 9.3.1 创建工具栏类 ········································································································ 170 9.3.2 将工具栏类连接到表单··························································································· 171 9.3.3 协调选单和自定义工具栏 ······················································································· 172

第 10 章 报表和标签 ················································································································ 173 10.1 创建报表 ······················································································································· 173 10.1.1 报表向导创建报表 ······························································································· 174 10.1.2 快速报表 ············································································································· 176 10.1.3 报表设计器创建报表 ···························································································· 177 10.1.4 修改报表布局 ······································································································ 181 10.1.5 报表预览和打印 ··································································································· 184 10.1.6 报表调用 ············································································································· 186 10.2 设计标签 ······················································································································· 187 10.2.1 标签向导 ············································································································· 187 10.2.2 标签设计器 ········································································································· 188

·VII·


第 11 章 网络数据共享············································································································· 190 11.1 记录锁定 ······················································································································· 190 11.2 数据会话 ······················································································································· 194 11.3 数据缓冲 ······················································································································· 194 11.4 事务处理 ······················································································································· 199

第 12 章 程序调试 ···················································································································· 201 12.1 跟踪窗口 ······················································································································· 201 12.2 监视窗口和局部窗口 ······································································································ 203 12.3 事件跟踪 ······················································································································· 204 12.4 出错处理程序 ················································································································ 204

第 13 章 系统选项设置············································································································· 206 13.1 显示选项卡 ···················································································································· 206 13.2 常规选项卡 ···················································································································· 206 13.3 数据选项卡 ···················································································································· 208 13.4 远程数据选项卡 ············································································································· 209 13.5 文件位置选项卡 ············································································································· 210 13.6 表单选项卡 ···················································································································· 211 13.7 项目选项卡 ···················································································································· 212 13.8 控件选项卡 ···················································································································· 213 13.9 区域选项卡 ···················································································································· 214 13.10 调试选项卡 ·················································································································· 215 13.11 语法着色选项卡············································································································ 216 13.12 字段映像选项卡 ··········································································································· 217

第 2 部分

习题 2 数据库 ··························································································································· 218 习题 3 程序设计 ······················································································································· 225 习题 4 表单 ······························································································································· 230 习题 5 控件 ······························································································································· 233 习题 7 类的创建和使用············································································································ 236 习题 8 查询和视图 ··················································································································· 238 习题 9 选单和工具栏················································································································ 240 习题 10 报表和标签 ················································································································· 241

第 3 部分

实验 1 Visual FoxPro 集成环境和项目 ···················································································· 242 目的和要求 ····························································································································· 242

·VIII·


实验准备 ································································································································ 242 实验内容 ································································································································ 242 思考与练习 ····························································································································· 246

实验 2 数据库、表的创建和操作 ···························································································· 247 目的和要求 ····························································································································· 247 实验准备 ································································································································ 247 实验内容 ································································································································ 247

实验 3 创建表的索引和表临时关系 ························································································ 252 目的和要求 ····························································································································· 252 实验准备 ································································································································ 252 实验内容 ································································································································ 252

实验 4 创建数据表字段属性、表的转换和 SQL ···································································· 256 目的和要求 ····························································································································· 256 实验准备 ································································································································ 256 实验内容 ································································································································ 256

实验 5 程序设计 ······················································································································· 259 目的和要求 ····························································································································· 259 实验准备 ································································································································ 259 实验内容 ································································································································ 259

实验 6 表单 ······························································································································· 265 目的和要求 ····························································································································· 265 实验准备 ································································································································ 265 实验内容 ································································································································ 265

实验 7 控件 ······························································································································· 269 目的和要求 ····························································································································· 269 实验准备 ································································································································ 269 实验内容 ································································································································ 269

实验 8 类的创建和使用············································································································ 280 目的和要求 ····························································································································· 280 实验准备 ································································································································ 280 实验内容 ································································································································ 280

实验 9 创建查询 ······················································································································· 284 目的和要求 ····························································································································· 284 实验准备 ································································································································ 284 实验内容 ································································································································ 284

实验 10 创建和使用本地视图···································································································· 291 目的和要求 ····························································································································· 291 实验准备 ································································································································ 291 实验内容 ································································································································ 291

·IX·


实验 11 创建选单 ····················································································································· 295 目的和要求 ····························································································································· 295 实验准备 ································································································································ 295 实验内容 ································································································································ 295

实验 12 创建自定义工具栏······································································································ 302 目的和要求 ····························································································································· 302 实验准备 ································································································································ 302 实验内容 ································································································································ 302

实验 13 报表设计 ····················································································································· 306 目的和要求 ····························································································································· 306 实验准备 ································································································································ 306 实验内容 ································································································································ 306

第 4 部分

VFP 综合应用实习

附录 A 本书使用的数据库 ······································································································· 323 A.1 人员信息数据库 RY ········································································································· 323 A.2 产品销售数据库 XS ········································································································· 324 A.3 学生成绩数据库 XSCJ ····································································································· 324

附录 B 创建安装程序··············································································································· 326 B.1 可发布文件 ····················································································································· 326 B.2 安装向导介绍 ················································································································· 327

附录 C 江苏省 VFP 等级考试(笔试部分)··········································································· 333 附录 D 江苏省 VFP 等级考试上机试卷 ·················································································· 338

·X·


第 1 部分 实 用 教 程 第 1 章 Visual FoxPro 6.0 的环境 1.1

集成开发环境

启动 Visual FoxPro 6.0(简称 Visual FoxPro 或 VFP)后,系统显示 Visual FoxPro 6.0 的集 成环境,如图 1.1 所示。

图 1.1

Visual FoxPro 6.0 的集成环境

Visual FoxPro 6.0 的集成环境大体上包括以下几个部分。 (1)系统窗口。系统窗口包含系统主选单、工具栏、主窗口、命令窗口、最大化、最小 化和关闭按钮。 (2)主选单栏。在主窗口的最上一列是选单栏,通过它可以完成绝大部分操作。在默认 情况下共有 8 个选单,系统会随着用户操作的不同而自动增加或减少。 (3)工具栏。在主选单的下面是“常用”工具栏,其中的按钮执行的操作对应于某个选 单命令。可以根据自己的任务创建、编辑、隐藏和定制工具栏。 (4)主窗口。在主选单栏下面的窗口区域是主窗口,在主窗口中可以显示输出结果。 (5)命令窗口。在命令窗口可以输入并执行单个的命令和函数。例如,如果想退出 VFP, 可以在命令窗口中键入 QUIT,然后按回车键。 (6)状态栏。状态栏显示了 VFP 的当前状态,包括按钮或选单的功能说明以及数据库名 和记录状态等。 ·1·


1.2

选单系统

Visual FoxPro 6.0 的选单系统提供了绝大部分的操作,Visual FoxPro 6.0 的强大功能通过 选单系统充分体现出来。系统主选单共 17 个,但在某一时刻仅显示 7~9 个。选单系统中部 分操作也可通过工具栏上的按钮完成。选单和选单中的选单项会根据用户操作的不同而有所 增减。 使用鼠标和快捷键操作选单项,熟记选单项的快捷键,可以大大加快编辑速度。 Visual FoxPro 6.0 的选单系统包括以下几个方面。 1. 文件选单 文件选单中的选单项命令用于在磁盘上建立、打开和存储文件以及对文件进行操作,还 可以设置打印机和退出 VFP,如表 1.1 所示。 表 1.1

文件选单的选单项

选 单 项

新建

使用设计器或向导创建新文件

打开

打开一个已有的文件或创建一个新文件

关闭

关闭活动窗口

保存

将修改保存到活动文件中

另存为

保存新建文件,或用一个不同的文件名保存已有文件

另存为 HTML

用一个不同的文件名以 HTML 语言保存已有文件

还原

将表单或在表单上选择控制作为一个类定义保存

导入

将其他类型的文件导入到 Visual FoxPro 表中

导出

将 Visual FoxPro 表中的数据导出到其他类型的文件中

页面设置

调整报表或标签的列宽度和页面布局

打印预览

预览打印效果,但不真正打印

打印

打印文本文件、报表、标签、命令窗口或剪贴板的内容

发送

运行电子邮件软件

退出

退出 Visual FoxPro

其中的“新键”和“打开”命令可以创建或打开各种文件。选择了不同文件类型的文件, 就会进入不同的文件的操作环境。 有时,某些选单项命令是灰色的,这表明这些命令的功能暂时还不能用。例如,只有当 编辑报表或标签时,才能选取“页面设置”和“打印预览”。 2. 编辑选单 编辑选单中的命令用于对文本或其他对象进行编辑,包括“剪切” 、 “复制”、 “粘贴”等 一般的编辑选项,也包括对象的插入和链接等高级功能。 表 1.2

编辑选单的选单项

选 单 项

·2·

撤消

撤消最后一次编辑命令所做的修改

重做

重做最后一次撤消的命令

剪切

删除选择的内容,并将它放到剪贴板上

复制

读取选择的内容,并将它放到剪贴板上

粘贴

将剪贴板上的内容放入插入点处

选择性粘贴

链接或嵌入剪贴板上的 OLE 对象


续表 选 单 项

清除

删除窗口,并且不在剪贴板上放入任何内容

全部选定

选择活动窗口中所有的对象或文本

查找

显示“查找”对话框,从中可以搜索文本

再次查找

从当前位置按“查找”条件继续找下一个

替换

搜索并替换当前文件中指定的文本

转到行

将插入点移到文本、程序文件或命令窗口的指定行

插入对象

向通用字段中链接或嵌入一个 OLE 对象

对象

在创建 OLE 对象的应用程序中打开这个对象

链接

修改或断开一个链接

3. 显示选单 在没有打开文件的情况下,显示选单只有“工具栏”一个命令,如表 1.3 所示。选单和 选单中的选单项会根据用户操作的不同而有所增减。例如,如果打开了一个表,则显示选单 会自动增加许多操作表的选单项。 表 1.3

查看选单的选单项

选 单 项 工具栏

创建、编辑、隐藏以及定制工具栏

4. 格式选单 格式选单中的命令可以控制窗口中文本或其他对象的显示效果,如表 1.4 所示。 表 1.4

格式选单的选单项

选 单 项

字体

控制字体的类型、字形和大小

放大字体

将字体增大到更大的可用尺寸

缩小字体

将字体减小到更小的可用尺寸

1 倍行距

显示文本时文本行之间加空白行

1.5 倍行距

以 1.5 倍行间距显示文本

2 倍行距

以 2 倍行间距显示文本

缩进

将选定的行缩进一个 Tab 键宽度

取消缩进

一次删除一个先前插入的缩进

5. 工具选单 工具选单中列出了系统提供的辅助工具,如表 1.5 所示。其中,向导是 VFP 提供的工具, 只要回答一系列的问题,就可以很方便地完成某些任务。例如,创建表、表单、报表,等等。 在新建某些类型的文件时,可以单击“向导”按钮,也可以在“工具”选单中选择“向导” 子选单中的各种向导。 “拼写检查”在编辑文本时才能使用。 “选项”命令将在本章稍后介绍。 表 1.5

工具选单的选单项

选 单 项

向导

显示一个子选单,其中包含了所有的向导

拼写检查

运行拼写检查器

定义可以执行一组命令的组合键

类浏览器

打开类浏览器

·3·


续表 选 单 项

组件管理器

打开组件管理器

代码范围分析器

打开代码范围分析器

修饰

打开修饰对话框

运行

运行

Active Document

Active Document

调试器

打开调试窗口,从中可以监控程序中的值

选项

设置 Visual FoxPro

6. 程序选单 程序选单用于对应用程序进行操作,如表 1.6 所示。 表 1.6

程序选单的选单项

选 单 项

运行

指定要执行的程序文件

取消

中止一个挂起的程序文件的执行

继续执行

在程序被挂起的程序行处继续执行该程序

挂起

中止程序的运行,但使该程序保持打开状态

编译

编译程序、选单或查询文件

7. 窗口选单 通过该选单,用户可以管理多个窗口,如表 1.7 所示。 表 1.7

窗口选单的选单项

选 单 项

全部重排

显示全部打开的窗口,使其不重叠

隐藏

从视野中移去活动窗口,但不将它关闭

清除

从主窗口中清除所有的文本

循环

把打开的活动窗口依次置前

命令窗口

显示命令窗口

数据工作期

打开数据工作期对话框

8. 帮助选单 在帮助选单中,可以得到对各种问题的帮助,可以通过逐渐打开目录找到有关内容,也 可以直接搜索某个主题,如表 1.8 所示。 表 1.8

帮助选单的选单项

选 单 项

Microsoft Visual FoxPro 帮助主题 目录

显示联机帮助的目录表

索引

允许使用关键字搜索帮助主题

搜索 技术支持

显示与微软产品支持服务有关的信息

Microsoft on the Web 关于 Microsoft Visual FoxPro

·4·

显示版本信息


VFP 除了上述系统主选单及其选单项外,在某个对象上单击鼠标右键可显示快捷选单。 其中的选单命令表示能对该对象所做的操作以及该对象的帮助信息。快捷选单使命令的使用 变得更加简捷。

1.3

工具栏

工具栏上的按钮对应于最经常使用的选单命令。所以使用工具栏可以加快某些任务的执 行。 1. 改变工具栏的外观 将鼠标指针指向工具栏但不要放在按钮上,按住鼠标左键,移动鼠标,将工具栏“拖” 下来,如图 1.2 所示。可以四处拖动工具栏,将它放在主窗口的各种位置。将工具栏放在窗 口四周的动作称为“停放(Dock) ” 。将鼠标放在某个按钮上停一会儿,就会出现该按钮的说 明文字,称为工具提示(Tooltip),如图 1.3 所示。 2. 打开其他工具栏 Visual FoxPro 6.0 提供了 11 个工具栏。用户可以随时打开每个工具栏,但是工具栏和某 些按钮只有在执行特定的任务时才能使用。例如,如果不是在设计报表,则“报表控件”和 “报表设计器”工具栏上的按钮呈灰色,表示不可用。 打开工具栏可在“视图”选单中选择“工具栏”选单项,在窗口中选择所需的工具栏。 也可将鼠标放在某个工具栏上,单击鼠标右键,再从快捷选单中选择。 3. 定制工具栏 工具栏上的按钮是由 VFP 系统提供的,不能删除或添加这些按钮,但是可以按任务的需 要将它们重新组合,创建满足自己需要的工具栏。 在“显示”选单选“工具栏”选单项后,系统打开“工具栏”对话框,如图 1.2 所示。

图 1.2

“工具栏”对话框

图 1.3 工具栏的窗口形式

单击“新建”按钮,在“新工具栏”对话框中输入新工具栏的名称(例如“我的工具栏” ) , 单击“确定”按钮。找到合适的按钮,将它拖动到“我的工具栏”中。最后选择“关闭”。这 样, “我的工具栏”就出现在“工具栏”对话框中。

1.4

选项对话框

VFP 提供了很多设置,VFP 启动时按系统的默认状态配置系统的初始环境。用户可以通 ·5·


过选择“工具栏”选单中“选项”对话框改变这些设置,使 VFP 系统环境配置成用户所需要 的状态。例如修改主窗口标题、默认目录、临时文件的存放位置,等等。 除了使用“选项”对话框外,也可以通过 SET 命令或给系统变量赋值,修改选项卡上显 示的大多数选项。下面只介绍常用的几项设置。 在“工具”选单中选择“选项”命令,这时会出现“选项”对话框,其中包含 12 个选项 卡,对应于不同种类的设置,如图 1.4 所示。各选项卡及其功能如表 1.9 所示。

图 1.4

“选项”对话框

表 1.9 “选项”选项卡及其功能 选 项 卡

访 问 功 能

显示

界面选项

常规

数据输入和程序设计选项

数据

表选项

远程数据

远程数据访问选项

文件位置

默认的目录、路径和文件位置选项

表单

表单设计器选项

项目

项目管理器选项

控件

在“表单控件”工具栏单击“查看类”按钮时可列出的可视类库和 Active 控件选项

区域

日期、时间、货币和数值型格式选项

调试

调试器的显示和跟踪选项

语法着色

用以区分程序元素(如关键字、注释)等的字体和颜色

字段映像

当从“数据环境设计器” 、“数据库设计器”或“项目管理器”中向表单拖放表和字 段时创建的控件类型选项

如果单击“设置为默认值”按钮,则设置在下次启动 VFP 时仍然起作用。如果只单击“确 定”按钮,则设置在下次启动 VFP 时不起作用。如果按住 Shift 键,再单击“确定”按钮, 则当前设置会显示在命令窗口中,可以将它们复制到程序中。 每一个选项卡及其各项功能请参考附录 D。 ·6·


1.5

命令窗口

命令窗口用于接受用户输入命令。因此这是与 VFP 进行交流的主要界面。另一个重要的 进行交流的界面是主选单。主选单提供的选项绝大部分都可以通过命令完成,但是命令提供 的功能却远远超过主选单,因为主选单只列出最常用的功能。 在选择主选单的选项时,所对应的命令就会显示在命令窗口中。可以在命令窗口中将光 标移动到某个命令上(不一定在命令的末尾) ,按 Enter 键,该命令就会重新执行。也可以在 命令窗口中修改某个命令,然后再执行。另外,还可以将命令窗口中的命令剪切并复制到程 序中。

1.6

项目管理器

项目管理器是 VFP 中处理数据和对象的主要的组织工具。项目是文件、数据、文档和 VFP 对象的集合,以 .PJX 扩展名文件保存。建立一个项目可以方便地组织文件和数据。在项 目管理器中只需单击几次鼠标按钮,就可以方便地组织相关的表单、报表、标签、代码、位 图和其他文件。 项目管理器为数据提供了一个组织良好的分层结构视图。若要处理项目中某一特定类型 的文件或对象,可选择相应的选项卡,如图 1.5 所示。

图 1.5 项目管理器

1. 创建一个项目 可以通过界面操作来创建项目。也可以使用 CREATE PROJECT 命令创建一个项目。步 骤如下: (1)在“文件”选单中选择“新建” 。 (2)选择“项目”,单击“新建文件”按钮。 (3)在“创建”对话框中输入项目的名称,并选择保存项目的目录。 (4)选择“创建”。

·7·


2. 查看一个项目的内容 项目管理器中的项是以类似于大纲的结构来组织的,可以将其展开或折叠,以查看不同 层次中的详细内容。 如果项目中具有一个以上某一类型的项,其类型符号旁边会出现一个“+”号。单击符号 旁边的“+”号可以显示项目中该类型项的名称,单击项名称边的“+”号可以看到该项的组 件。若要折叠已展开的列表,可单击列表旁边的“-”号。 3. 定制项目管理器 项目管理器显示为一个独立的窗口。可以移动它的位置、改变它的大小或者将它折叠起 来只显示选项卡标题。 折叠项目管理器可单击项目管理器右上角的上箭头。折叠项目管理器后,可以拖开选项 卡,并根据需要重新安排它们的位置。选定一个选项卡,拖开某一选项卡后,它可以在 Visual FoxPro 的主窗口中独立移动。还原项目管理器可单击右上角的下箭头。 当选项卡处于浮动状态时,通过在选项卡中单击鼠标右键可以访问快捷选单中的选单项。 如果希望选项卡始终显示在屏幕的最表层,可以单击选项卡上的图钉图标,这样,该选项卡 就会一直保留在其他 Visual FoxPro 窗口的上面。可以使多个选项卡都处于“顶层显示”的状 态。再次单击图钉图标可以取消选项卡的“顶层显示”设置。要还原选项卡,单击选项卡上 的“×”按钮,或者将选项卡拖回到项目管理器。 还可以“停放”项目管理器,使它像工具栏一样显示在 Visual FoxPro 主窗口的顶部。 停放项目管理器后,它就变成窗口工具栏区域的一部分。项目管理器处于停放状态时, 不能将其展开,但是可以单击每个选项卡来进行相应的操作。对于停放的项目管理器,同样 可以从中拖开选项卡。 4. 为文件添加说明 创建或添加新文件时,可以为文件加上说明。这样,当文件被选定时,说明将显示在项 目管理器的底部。为文件加上说明,可先在项目管理器中选定文件,从“项目”选单中选择 “编辑说明”,在“说明”对话框中键入对文件的说明,单击“确定”按钮。 关于项目管理器的详细介绍请参考第 6 章。

1.7

一个简单实例

创建一个简单的实例的主要步骤如下: (1)创建应用程序界面。应用程序的界面一般由选单、表单、控件对象等构成。根据程 序的功能要求和用户与程序之间的信息交流的需要来确定哪些对象,规划界面的布局。可创 建一个项目来管理这些文件和数据。 (2)设置界面上各个对象的属性。根据规划的界面要求设置各个对象的属性,比如对象 的外貌、名称、颜色、大小等。 大多数属性取值既可以在设计时通过属性窗口来设置,也可以在程序代码中通过编程在 程序运行时设置修改。 (3)编写对象响应的程序代码。界面仅仅决定了程序的外观,设计界面后就要为对象的 事件添加代码,实现一些在接受外界信息后作出的响应、信息处理等。 (4)调试程序。运行程序,当出现错误时系统会显示出错信息或运行结果不正确,用户 据此查找和排除错误。 ·8·


(5)生成可执行程序。为了使程序可以脱离 VFP 环境,在程序运行正确后对其进行编译, 生成可执行程序。再通过安装向导将所有相关文件打包,就可以作为一个软件产品在 Windows 9x/2000 环境下安装后独立运行。 【例 Ex_ CricleA】设计一个表单,计算圆面积。 (1)设计界面。文件选单→“新建”选单项→文件类型选“表单”→“新建文件”→系 统显示空白表单。 选择“表单”工具条上的“标签”控件,单击表单,表单上显示标签控件 Lable1,照此 再做 Lable2。选择“表单”工具条上的“文本框”控件,单击表单,表单上显示文本框控件 Text1,照此再做 Text2。选择“表单”工具条上的“命令按钮”控件,单击表单,表单上显 示命令按钮控件 Command1。界面如图 1.6 所示。

图 1.6

计算圆面积界面

(2)设置对象属性。对象属性如表 1.10 所示。 表 1.10 对象属性 对 象 Lable1

属 性 名 Caption

属 性 值 半径 R=

Lable2

Caption

圆的面积=

Text1

Value

0

Command1

Caption

计算

(3)编写事件代码。 “计算”命令按钮 Command1 的 Click 事件代码: R=THISFORM.TEXT1.VALUE THISFORM.TEXT2.VALUE=3.14159*R*R

其中,R=THISFORM.TEXT1.VALUE 表示将当前表单中文本框对象 TEXT1 的 VALUE 属性的值赋给变量 R;THISFORM.TEXT2.VALUE=3.14159*R*R 表示将 3.14159*R*R 的值送 入当前表单中文本框对象 TEXT2 的 VALUE 属性中,文本框对象的 VALUE 属性值就是文本 框中的值。关于表单及其包含的控件的详细内容将在第 4,5 章介绍。

·9·


第 2 章 数据库、表和索引 Visual FoxPro 是关系数据库管理系统,管理数据库是它的基本功能和目的所在。在 VFP 中,数据库(DataBase)是一个容器(Container) ,用于管理存放在其中的对象。这些对象包 括数据库表(Table) 、视图(View) 、关系(Relation) 、存储过程(Stored Procedure)和连接 等。用户管理的数据是存放在“数据库表”中的,数据库表单独作为文件的形式存在;为了 对表的数据进行分类和快速检索,需要建立表的“索引” ;通过表的“视图”可得到表中所关 心的数据;多个表之间可建立“关系” ;要操作远端数据需要进行“连接” ;用户完成特定功 能的程序可存放到“存储过程”中。下面分别一一介绍。

2.1

数据库

数据库文件的结构是固定的,它在建立数据库时由系统自动建立,并且在一般情况下数 据库文件的记录由系统自动维护。但是,用户也可以用操作表的命令对其进行浏览和其他必 要的操作。

2.1.1 交互创建数据库 交互创建数据库既可用选单也可用工具栏。 选“文件”主选单→选“新建”选单项→“新建”对话框,文件类型选“数据库” ,单击 “新建文件”命名按钮→显示“创建”对话框,如图 2.1 所示。

图 2.1

新建和创建数据库对话框

在“保存在”位置输入创建的数据库文件保存的文件夹,在“数据库名”框内输入要创 建的数据库的主文件名。这里, “保存在”选 D:\RY_mis,“数据库名”输入 RY,选择后单击 “保存”按钮。此后,系统打开数据库设计器,显示数据库设计工具栏。同时系统自动增加 “数据库”主选单,如图 2.2 所示。用户此时即可利用这个工具或系统选单做建立数据库表 ·10·


等各种数据库操作。

图 2.2

“数据库”主选单

选“×”可关闭数据库设计器。 图标,或者在“项目管理器”中选“数据”页,然后再选“新建”也可创 选工具栏 建数据库的操作。 数据库建立后形成 3 个文件,它们是基本文件 DBC、相关的数据库备份文件 DCT、相关 的索引文件 DCX。此后打开 DBC 文件即可打开该数据库,操作后 D:\RY_mis 目录中生成 了 RY.DBC 和 RY.DCT 文件。 打开数据库(文件)的操作如下:选“文件”主选单→选“打开”选单项→显示“打开” 文件对话框。在“文件类型”框中选择“数据库” ,搜索指定数据库文件所在的文件夹,选择 或输入数据库文件名后单击“确定”按钮即可。

2.1.2 命令操作数据库 在命令窗口键入相应的命令也可创建数据库。操作数据库命令如下。 (1)创建数据库。 格式: CREATE DATABASE 数据库名

执行该命令后,从界面上看不出任何反映,但数据库文件已经建立。除非在数据库名前 指定路径,否则创建的数据库文件存放在当前默认的文件夹中。默认的文件夹可通过 SET DEFAULT TO 命令设定。 (2)打开数据库。 格式: OPEN DATABASE 数据库名

(3)修改数据库。 格式: MODIFY DATABASE 数据库名

·11·


(4)关闭数据库。 格式: CLOSE DATABASE

(5)删除数据库(文件) 。 格式: DELETE DATABASE 数据库名 [RECYCLE]

带 RECYCLE 项,则将删除数据库文件放入回收站中,可在回收站中进行还原操作,恢 复删除的数据库(文件)。 【例 Ex_Cry】创建人员信息数据库,数据库名为 RY。 CREATE DATABASE RY (查看文件 RY.DBC, RY.DCT, RY.DCX) OPEN DATABASE RY

&&重新打开 RY 数据库

MODIFY DATABASE RY (数据库设计器-RY) CLOSE DATABASE

2.2

表的结构

1. 表与表结构 数据库中可包含若干个表,包含在数据库中的表为数据库表,不包含在数据库中的表为 自由表。操作数据库表与自由表的命令基本相同,但数据库表增加了许多控制功能,使用户 操作表不仅方便而且可视化。数据库中的表可以移出变成自由表,自由表又可以加入到数据 库中成为数据库表。 VFP 是关系型数据库,表是关系表。其形态与平常的表格相似。例如,基本情况表如图 2.3 所示。

图 2.3 基本情况表

从纵向讲,表由若干列组成。每一列都有一个项名称为字段,列中的数据类型一致。 从横向讲,表包含表头和表记录两部分,表头是所有字段的总体。 VFP 中,将表中各字段的数据类型和宽度等信息的总体称为表结构。建立表首先要建立 表结构,然后方可向表中输入数据记录。 ·12·


2. 表结构的创建 表结构可通过表设计器建立,也可通过 SQL 命令直接建立。下列方法均可打开表设计器。 (1)选“文件”主选单→选“新建”选单项→“新建”对话框选“表”→显示“创建” 表对话框。输入文件名,单击“保存”按钮即打开表设计器窗口。 (2)单击工具栏“新建”按钮,然后一步一步进行。 (3)在项目管理器选“数据”页→选表对应的“数据库”容器名下面的“表”→选“新 建”后即可打开表设计器窗口。 (4)打开数据库容器,在数据库设计器工具栏中单击“新建”按钮。 (5)用命令打开表设计器创建表。 CREATE 表名 需要说明的是,打开表设计器前如果没有打开数据库,则创建的是自由表。 【例 Ex_OpenRy】在人员信息数据库(数据库名为 RY)创建“基本情况”表结构。 “基 本情况”表结构见附录A。 OPEN DATABASE RY CREATE 基本情况

在表设计器中交互输入表结构,如图 2.4 所示。

图 2.4

表设计器输入表结构

表设计器包含“字段” 、 “索引”和“表”3 页。其中“字段”页用于建立表结构。“字段” 页包含 4 个部分,上面部分用于建立表结构;显示” 、“字段有效性”部分用于设置字段属性, 而“匹配字段类型到类”用于设置字段显示时使用的类库和类;“字段”注释是用户对字段的 附加说明,它对字段功能没有任何影响。建自由表结构时只有建立表结构部分,如果当前建 立的是数据库表,才有下面 4 个框。关于字段属性和类在后面将进行专门叙述。 建立表结构部分一行为一个字段,每个字段由以下字段名、类型、宽度等项目组成。 ① 字段名。字段名由若干个字符(字母、汉字、 “_”和数字)组成,但不能以数字打头。 对于数据库表字段名最多为 128 个字符,对于自由表字段名最多为 10 个字符。不能使用系统 ·13·


的保留字。 字段名取名只要符合上述规则就是正确的字段名。但是字段名取名要尽量有意义、简单 明了。如以汉字作为字段名看上去比较直观,但在需经常输入字段名时就显得比较麻烦。用 英文(缩写)或汉语拼音(缩写)输入字段名时比较方便,但又不太直观(可设置字段的标 题为汉字说明,在有些场合可弥补一些) 。用户应根据情况权衡利弊。本书教程为了便于读者 阅读和理解,人员信息数据库中的表的字段名用汉字,主要在本书教程中使用,而附录A中 的另外 2 个数据库和表使用代号作为字段名,主要在本书习题、上机操作指导中使用。 ② 字段类型、宽度。字段类型应根据当前字段的存放的数据和将要对它进行的操作而定。 例如,姓名字段存放的就是符号,只能确定为字符型;工资存放的是数值数据,需要对它进 行加减、累加等运算,应该将它指定为数值型;出生日期字段需要对它进行日期运算(例如 计算年龄) ,应该将它指定为日期型。对于编号字段,尽管存放的内容也是数字,但不会对它 进行数值运算,相反地,却能对它进行字符运算。例如编号的前 2 位代表部门代号,当需要 通过该人的编号得到他所属的部门时,就需要取编号的前 2 位。所以编号字段选字符型更方 便。 字段宽度对于字符型和二进制字符型是字段最大允许存放的字符个数,对于数值型和浮 点型是数值的最大位数。其他类型是系统固定的。表 2.1 是 VFP 字段类型和宽度的有关说明。 表 2.1 字段类型

类型代号

字段类型和宽度

宽 度

字符型

C

1~254

二进制字符型*

C

1~254 宽度=1(正负

存放字符数据 任意不经过代码页修改而维护 的字符数据 存放数值数据,数值可包含小数

N

任意字符 -0.9999999999×1019~ 0.9999999999×1020

号)+整数部分 数值型

范 任意字符

位 数 +1 ( 小 数 点)+小数部分 位数

整型

I

4

浮点型*

F

同数值型

存放整型值数据

-2 147 483 647~147 483 647

同数值型

同数值型

双精度浮点数

+/-4.940 656 458 412 47×10-324~

存放货币数据

+/-8.988 465 674 311 5×10-307 -922 337 203 685 477.580 8~

双精度型*

B

8

货币型

Y

8

日期型

D

8

日期时间型

T

8

逻辑型

L

1

存放逻辑数据

真-T 假-F

备注型*

M

4

存放内容在 .FPT 文件中的位置

仅受内存空间的限制

二进制备注型*

M

通用型*

G

4

922 337 203 685 477.580 7 存放日期数据

00/01/1000~12/31/9999

存放日期时间型数据

00/01/1000~12/31/9999 00:00:00a.m.~11:59:59p.m.

任意不经过代码页修改而维护

仅受内存空间的限制

的备注数据 4

OLE 对象数据

仅受内存空间的限制

注:*为不能用于内存变量的数据类型。

③ 小数位数。对于字段指定的数值型,还可指定小数位数。此时,字段宽度=整数位数 +小数位数+1(小数点)。 ④ 索引。如果以当前字段作为索引关键字建立索引则可选择该项,这里选择创建的初始 ·14·


索引类型为普通索引,向上箭头为从大到小排列,向下箭头为从小到大排列。这里选择后, 在“索引”页中就会出现该索引行,字段名就是该索引的索引标识名。反之,如果在“索引” 页中以某字段作为索引关键字的索引,则在“字段”页中的对应该字段行的索引栏就会出现 箭头。关于索引将在本章后面介绍。 ⑤ NULL。本字段是否可为 NULL。 字段名栏最前面的栏用于改变已定义的字段的顺序。在需移动的字段前按住鼠标并拖动 到指定位置后放开即可。 3. 表文件 表结构建立后,单击“确定”按钮即保存到表文件中。生成的对应表的文件一般有 3 个。 (1)表文件:存放表结构和表记录数据,文件的默认扩展名为 .DBF。 (2)表备注文件:存放表中备注型字段的内容,文件的默认扩展名为 .FPT。包含备注字 段的表文件中仅存放其保存实际内容的 FPT 文件的位置。如果表中没有备注字段,则 FPT 文 件不存在。 (3)表索引文件:存放表结构化复合索引的文件,文件的默认扩展名为 .CDX。只有在 “索引”页建立索引后才会产生这个文件。 例如,对于基本情况表,上述表结构建立后,在当前目录中产生了“基本情况.DBF”和 “基本情况.FPT”(因为有 M, G 型字段)文件。如果设置了索引,还会产生“基本情况.CDX” 文件。 4. 修改表结构 数据库表结构建立后,打开数据库容器后表就会在数据库中以可视化的形式显示出来。 要修改数据库表结构,有下列几种方法。 (1)打开数据库容器,在数据库设计器工具栏中单击“修改表”按钮。 (2)通过文件选单中“打开”选单项或在常用工具栏单击文件按钮打开表文件或使用下 列命令打开表文件: USE 表文件名

再使用下列命令打开表设计器,修改打开的表文件: MODIFY STRUCTURE

表结构修改后要使用下列命令关闭表文件: USE

2.3

表的操作

表的结构建立后,就可向表中输入数据了。VFP 中的表就好像平常见到的表格一样。表 格中的一行在表中为一条记录。一个表有很多条记录组成,但在任何时间,操作的只有一条 记录,例如,向表中输入记录、修改已在表中的某记录等。当前进行操作的记录称为当前记 录。VFP 中有一个记录指针指示当前记录。当表打开时,当前记录为 1 号记录,记录指针值 为 1。当改变当前记录时,记录指针同时指向相应的记录。 操作表记录,可以用系统界面提供的选单,更多的是用系统命令,但最终还是落实到应 用程序上。

·15·


2.3.1 通过选单操作表 要操作表,首先要打开表。在数据库容器中选择操作的表,选择数据库选单 “浏览” 或 按右键后选择“浏览” ,或者在项目管理器“数据库”页选择操作的表后选择“浏览”,系统 均会以表格形式显示数据库表的记录内容。 现在,打开 RY 数据库后选择“基本情况”表,选择“浏览”即以表格形式浏览基本情 况表的内容。 在“浏览”表的状态,系统自动产生一个“表”主选单,选择选单中的选单项就可对表 进行常用操作,如图 2.5 所示。需要注意的是,当用户选择了一个选单项时,在命令窗口中 会出现一条相应的命令,这实际上是选择选单项操作相当于发出的 VFP 操作表的命令。关于 使用命令操作表将在随后讲解。

图 2.5

“表”主选单的选单项

下面分别说明“表”主选单的选单项的功能。 1.追加新记录 在表的末尾追加一条空记录,并使该记录变成当前记录。用户即可向该空记录中填入数 据。例如,一开始“基本情况”表中没有任何记录,用此方法向库中追加部分记录。 顺便说明,还有一个追加记录选单项,其作用是将别的表(文件)中的记录加入当前表 中。 2.转到记录 用于改变当前记录。在子选单中除了可转到“第一个”记录、 “最后一个”记录、 “上一 个”记录、“下一个”记录外,选择“记录号”项,就会出现一个小对话框让用户选择要转到 的记录号。选择“定位记录”项,可按用户指定的条件进行记录定位,系统显示如图 2.6 所 示。 ·16·


图 2.6

“定位记录”对话框

(1)作用范围。 All:在表的所有记录中定位。 Next n:在当前记录向后的 n 条记录中定位。n 的值在后面的第 2 个框中指定。 Record n:在 n 号记录定位。 Rest:从当前记录开始到文件的末尾中定位。 在命名格式中用[范围]来表示记录作用范围。 (2)FOR 条件。 “For”后面的框提供用户输入记录定位的条件。定位的条件的描述必须 符合逻辑表达式的规则(详见第 3 章) 。记录定位的条件也可单击其后的“…”按钮由系统帮 助生成。 在命名格式中用[FOR 条件]来表示按这种方法定位记录。 (3)WHILE 条件。“While”后面的框也是提供用户输入记录定位的条件。它与 For 的区 别是,在作用范围内只要遇到一条不符合条件的记录就不再向下定位,而 For 在作用范围内 都要定位。举例来说,作用范围为 All,如 For 编号="01003",则只要表中存在这条记录,则 一定能定位到该记录。但如换成 While 编号="01003",则一定查不到。因为系统从第 1 条记 录开始查找,而第 1 条记录的编号肯定不是 01003,则系统就不再向下查找,而回答没有找 到。 在命名格式中用[WHILE 条件]来表示按这种方法定位记录。 尽管我们主要使用 For 描述定位条件,但 While 功能有时也很有用,For 和 While 也可配 合使用。例如,作用范围为 All,For 编号="01003",While 编号="01",则可提高查找速度。 其意思是编号为 01 打头的肯定在表的前面,While 为编号="01"用于控制只在编号为 01 打头 的人员中查找,For 控制查找的具体条件。 3.删除记录 删除记录下用于删除表中不需要的记录。系统显示的界面与定位时相同。 需要说明的是,VFP 删除记录分两步进行,这里的删除记录仅是在库中做删除标记。做 过删除标记的记录在“浏览”窗口最前面一个小栏会显示一个小黑方块,如再单击这个方块 就可将删除标记去掉。同样,没有删除标记的记录,单击这个方块也会加入删除标记。要使 做过删除标记的记录不显示,可在命令窗口输入 SET DELETE ON 命令。要从表中彻底删除 具有“删除标记”的记录,选择“彻底删除”选单项。 4.恢复记录 恢复记录是用于恢复做过删除标记的记录。系统显示的界面与定位时相同,也就是将具 有删除标记的记录中符合恢复条件的记录的删除标记去掉。 5.替换字段数据 替换字段就是自动修改记录的内容。系统显示的界面如图 2.7 所示。 ·17·


图 2.7

“替换字段”对话框

其功能是将职称为工程师的人员的工资加 100。 6.追加记录 追加记录就是将另一个 DBF 或其他格式的表的数据加入当前打开(指定)的表中,如图 2.8 所示。

图 2.8 追加记录

“类型”框为被加进来的表的格式,默认为 DBF。“来源于”框指定文件名。 “到”框中 显示的是当前打开的表。

2.3.2 命令方式操作表 命令方式操作表就是在命令窗口中键入命令来操作表。一般是先打开数据库再打开表, 也可直接打开表。如果是自由表当然不需要打开数据库,而直接打开数据库中的数据库表, 其所在的数据库系统会自动打开。在操作表结束后,要使用 USE 命令关闭表才会将修改的内 容保存到表文件中。 选单中操作表的选单项和功能仅是最常见的。比较复杂的操作一般只能通过命令进行。 1.打开表 格式: USE [数据库名!]表名 | ?

“[]”中的内容表示可选择,例如,打开数据库的表时在表名前可加“数据库名!”作为前 缀,也可不加前缀,从命令格式上都允许。 “|”表示或者的意思,也就是说既可打开前面一项也可打开后面一项。对上面的命令也 ·18·


可打开 USE ?命令。 “?”表示执行该命令时会出现一个对话框。对上面的命令表示打开表的文件名可通过对 话框进行选择。 注意:打开的表文件如不在当前文件夹中,应指定文件路径。或输入“SET DEFAULT TO 路径”命令设置该文件夹为当前文件夹。 2.追加新空记录 格式: APPEND [BLANK]

选择 BLANK 项,则直接在表的末尾加一条空记录。否则,系统就会以窗口形式让用户 以交互方式输入记录数据,一个字段一行。 3.浏览表记录 格式: BROWSE [FIELDS 字段名表] [FOR 条件 [REST]] […]

说明:FIELDS 字段名表项指定浏览窗口中出现字段名表。字段名之间用“,”分隔。 FOR 条件 [REST]指定浏览窗口中出现的记录条件,同时还可用 REST 指定范围。 【例 Ex_Browse】浏览表记录。 USE RY!基本情况 BROWSE

(如图 2.9 所示) USE

图 2.9 浏览窗口

说明:在上述表浏览状态,要输入数据,首先要用选单(按 Ctrl+Y 键)或命令方式追加 空记录,然后在空记录中填入数据。通用字段(照片)输入可用鼠标双击照片字段区域中的 “gen” ,打开通用字段的编辑窗口,此时可以插入图像、波形声音、MIDI 音乐、视频剪辑等 多媒体数据。这里插入图像数据有两种方法。 (1)先激活通用字段的编辑窗口,选择“编辑”选单中的“插入对象…” ,打开“插入对 象”对话框,选择对象类型为“BMP 图像” ,单击“确定”按钮,即可在通用字段编辑窗口 中编辑图片。 ·19·


(2)可先把要插入的图像数据在图像编辑程序中(如 Windows 的画图程序)复制到剪贴 板上,然后将图片数据粘贴进来。 单击窗口“关闭”按钮,退出编辑状态。此时可以看到字段中的“gen”变成了“Gen” 。 第 1 个字母大写表示通用字段中已包含内容。 4.显示表记录 格式 1: LIST OFF [字段名表] [范围] [ FOR 条件] [WHILE 条件] [TO PRINTER [PROMPT] | TO FILE 文件名]

格式 2: DISPLAY OFF [字段名表] [范围] [ FOR 条件] [WHILE 条件] [TO PRINTER [PROMPT] | TO FILE 文件名]

不选任选项,LIST 为显示所有记录,DISPLAY 为显示当前记录。DISPLAY ALL 满一屏 暂停显示,按任意键继续。 TO PRINTER:显示记录送打印机打印。带 PROMPT 项,打印前打开“打印”对话框, 用户可在该对话框中对打印机进行设置。 TO FILE 文件名:显示记录送到指定的文件中保存。 顺便介绍以下两条显示表结构的命令。 格式 1: LIST STRUCTURE [TO PRINTER [PROMPT] | TO FILE 文件名]

格式 2: DISPLAY STRUCTURE [TO PRINTER [PROMPT] | TO FILE 文件名]

5.交互修改记录 格式: EDIT [字段名表] [范围] [ FOR 条件] [WHILE 条件]

【例 Ex_Edit】交互修改记录,如图 2.10 所示。

图 2.10 OPEN DATABASE TO RY USE 基本情况 EDIT RECORD 1

·20·

Edit 交互修改


USE

说明:字段值直接输入,备注字段数据的输入只要用鼠标双击字段区域中的“memo”, 打开备注字段的编辑窗口,在该窗口中可以输入任意长度一段文字。输完后单击该窗口的 “关闭” 按钮, 或按 Ctrl+W 键结束并保存。此时, 可以看到备注字段中的 “memo” 变为 “Memo”。 第一个字母大写,表示备注字段中已包含内容。 6. 自动修改记录 格式: REPLACE 字段名 WITH 内容…[范围] [ FOR 条件] [WHILE 条件]

【例 Ex_Replace】替换字段。 USE 基本情况

&&基本情况为数据库 RY 的表,所以打开表 &&就自动打开了 RY 数据库

REPLACE 工资 WITH 工资+100 FOR 职称="工程师" BROWSE FIELDS 编号,姓名,工资 FOR 职称="工程师" USE

注:&&为注释。 7. 删除恢复记录 (1)删除记录。 格式: DELETE [范围] [ FOR 条件] [WHILE 条件]

(2)恢复删除。 格式: RECALL [范围] [FOR 条件] [WHILE 条件]

(3)彻底删除。 格式: PACK

【例 Ex_Delete】删除记录。 USE 基本情况 DELETE FOR 编号="01006" BROWSE

&&观察到 01006 记录最前面栏有黑块,这是删除标记

SET DELETE ON BROWSE

&&观察不到 01006 记录行,因为该状态不显示有删除&&

标记的记录 RECALL FOR 编号="01006" BROWSE

&&观察到 01006 记录最前面栏删除标记没有了

SET DELETE OFF DELETE FOR 编号="01006" PACK BROWSE

&&观察不到 01006 记录行,因为该记录已彻底删除了

USE

·21·


8. 转到记录 格式 1: GO TOP | BOTTOM |n

格式 2: SKIP [n]

格式 1 为绝对记录定位。TOP 为表中最前面的一条记录;BOTTOM 为表中最后一条记 录;“n”为定位的记录号。 格式 2 为相对记录定位。相对记录定位是相对于当前记录移动 n 条记录。n >0 为向下移, n <0 为向上移。省略 n,则默认为 1。 【例 Ex_Go】记录定位。 USE 基本情况 ? RECNO()

&&显示 1,“?”为显示命令,RECNO()为得到当前记录号的函数

SKIP ? RECNO() GO BOTTOM ? RECNO() SKIP ? EOF()

&&显示.T.,EOF()为判断是否超过表的最后一条记录的函数

9. 记录定位 格式 1: LOCATE [范围] [FOR 条件]

格式 2: COUNTINUE

LOCATE 命令定位到符合条件的第一条记录,如果定位不到,EOF()为.T.。CONTINUE 命令按 LOCATE 条件定位下一个。 【例 Ex_Locate】定位符合条件记录。 USE 基本情况 LOCATE FOR 姓名="杨" DISPLAY CONTINUE DISPLAY USE

10. 条件记录过滤 格式: SET FILTER TO [过滤条件]

设置记录过滤后,只有满足过滤条件的记录才会显示。但是这里设置的记录过滤在 SQL 语句操作表时不产生作用。该命令不带任何选项,则清除过滤条件,不再对记录过滤。 【例 Ex_Filter】记录过滤。 USE RY!基本情况 SET FILTER TO 性别="女"

·22·


&& 只有性别="女"的记录显示

BROWSE SET FILTER TO

&& 浏览所有记录

BROWSE USE

11. 追加记录 追加记录的步骤如下。 (1)从其他文件中追加记录。 格式: APPEND FROM 文件名 | ? [FIELDS 字段名表] [FOR 条件] [[DELIMITED [WITH 限定符] | 文件格式] [AS 代码页]

说明:加入当前表记录的字段由 FIELDS 字段名表指定,FOR 选项指定加入的记录符合 的条件。后面分别用于描述加入文件的格式。限定符可为 Delimiter,BLANK,TAB 或具体 符号。文件格式可为 DIF,FW2,MOD,PDOX,RPD,SDF,SYLK,WK1,WK3,WKS, WR1,WRK,XLS 和 XL5。 通过 AS 代码页指定被加入的文件的编码系统。Windows 系统和 VFP 不仅支持中文,而 且支持许多国家或地区的不同的语言编码系统。在 VFP 中,不同的编码系统用代码页表示。 通过代码页,就可实现跨平台数据共享。用?GETCP()可进入“代码页”对话框,如图 2.11 所示。

图 2.11

“代码页”

(2)向备注型字段中追加。 格式: APPEND MEMO <备注型字段名> FROM <文件名> [OVERWRITE] [AS 代码页]

【例 Ex_AMemo】向备注型字段中追加。 USE 基本情况 LOCATE FOR 姓名="肖文红" ?基本情况.备注 APPEND MEMO 备注

FROM 肖文红.TXT OVERWRITE

? 基本情况.备注

·23·


USE

(3)向通用型字段中追加。 格式: APPEND GENERAL<通用型字段名> FROM <文件名> […] [DATA 字符串] [LINK] [CLASS OLE 类名]

【例 Ex_AGen】追加通用型字段。 USE 基本情况 LOCATE FOR 姓名="肖文红" APPE GENERAL 照片 FROM 肖文红.BMP BROWSE USE

(4)在数组中追加记录。 格式: APPEND FROM ARRAY 数组名 [FOR 条件] [FIELDS 字段名表]

(5)复制表记录。与此相反也可将当前数据表的记录复制出去,并转换成指定的文件格 式。 格式: COPY TO 文件名 [DATABASE 数据库名 [NAME 表名]] [FIELDS 字段名表 | LIKE 字段名描述框架 | EXCEPT 字段名描述框架] [范围] [FOR 条件] [WHILE 条件] [[TYPE] 文件格式 | [DELIMITED [WITH 限定符] ] [AS 代码页]

说明:复制的目的地可以是数据库或 TYPE 指定格式的文件,被复制出去的记录须在指 定范围内符合 FOR 和 WHILE 指定的条件,复制出去的字段由 FIELDS 或 LIKE 或 EXCEPT 描述框架指定。DATABASE 数据库名 [NAME 表名]项表示复制得到的表放到的数据库同时 起别名。 (6)复制表结构。 COPY STRUCTURE TO 表备 [FIELDS 字段名表] [[WITH] CDX] [DATABASE 数据库名 [NAME 表名]]

说明:该命令仅复制表结构,选 WITH CDX,则同时复制复合索引。 【例 Ex_CExcel】用 EXCEL 修改表数据。 OPEN DATABASE RY USE 基本情况 COPY STRUCTURE TO backup COPY TO JBQK.XLS TYPE XLS

(用 EXCEL 修改 JBQK.XLS) USE backup

·24·


APPEND FROM JBQK.XLS TYPE XLS BROWSE USE

12. 记录计算 记录计算有如下项目。 (1)记录统计。 格式: COUNT [范围] [FOR 条件] [WHILE 条件] [TO 变量名]

说明:统计符合条件的记录数。无任何选项,统计当前表的所有记录。 例如: SET TALK OFF

&&统计的过程不显示

USE RY!工资情况 COUNT TO n ? "人数=",n

(2)数据累加。 格式: SUM [表达式表] [TO 变量名表

| TO ARRAY 数组名]

[范围] [FOR 条件] [WHILE 条件]

说明:累加符合条件的表达式表值。无[表达式表]项,累加所有数值型字段;无任何选 项,累加当前表的所有记录。 例如: SET TALK ON USE RY!工资情况 SUM SUM 技能工资, (岗位工资+浮动工资)*1.2

运行结果:

(3)数据求均值。 格式: AVERAGE [表达式表] [TO 变量名表 | TO ARRAY 数组名] [范围] [FOR 条件] [WHILE 条件]

说明:对符合条件的表达式表值求均值。无[表达式表]项,对所有数值型字段求均值; 无任何选项,当前表的所有记录求均值。 例如: USE RY!工资情况 SET TALK OFF AVERAGE 技能工资,(岗位工资+浮动工资)*1.2 TO JN,GWFD

·25·


? JN,GWFD

(4)统计计算。 CALCULATE [表达式表] [TO 变量名表

| TO ARRAY 数组名]

[范围] [FOR 条件] [WHILE 条件]

说明:该命令需计算的表达式表进行统计计算。 【例 Ex_Cal】统计计算。 OPEN DATABASE RY USE 工资情况 SET TALK ON CLEAR CALCULATE AVG(技能工资),MIN(技能工资),MAX(技能工资),STD(技能工资)

计算结果:

其中,统计函数的功能如下: MIN():求最小值。 MAX() :求最大值。 AVG():求均值。 STD() :计算标准偏差。 另外,还有 CNT(),NPV()等统计函数的功能请查手册。 (5)数据汇总。 格式: TOTAL TO 表名 ON 分组字段名 [FIELDS 字段名表] [范围] [FOR 条件] [WHILE 条件]

说明:对当前表中数值字段进行汇总,分组字段名值相同的汇总在一起,表名指定汇总 的结果的存放表。FIELDS 字段名表项为存放结果的表包含的字段,不选该项,则为当前表所 有字段。 【例 Ex_Total】汇总分组字段。 USE RY!工资情况 TOTAL ON LEFT(编号,2)TO MYGZ USE MYGZ BROWSE

汇总的结果如图 2.12 所示。 13. 记录排序 格式: SORT TO 表名 ON 字段 1 [/A | /D] [/C] [,字段 2 [/A | /D] [/C] …]

·26·


[ASCENDING | DESCENDING] [范围] [FOR 条件] [WHILE 条件] [FIELDS 字段名表 | FIELDS LIKE 字段名框架 | FIELDS EXCEPT 字段名框架]

图 2.12 汇总的结果

说明:按当前表中的字段 1、字段 2、……进行排序,将排序结果放在表名指定的表中。 包含多个排序字段,则先按第一个字段排,在第一个字段的值相同时再按第二个字段排,依 次类推。选/A(默认)升序,选/D 降序。均未选/A 和/D,则选 ASCENDING 整个升序,选 DESCENDING 整个降序。 【例 Ex_Sort】记录排序。 USE RY!基本情况 SORT TO MYGZ1 ON 职称,工资/D USE MYGZ1 BROWSE

BROWSE 窗口结果如图 2.13 所示。

图 2.13

2.4

BROWSE 窗口

表的索引

在数据库的表中,数据记录在表文件中的存储顺序称为物理顺序,记录号就是物理顺序 号。当在表中查找满足某个条件的记录时,必须从头开始在整个表记录中进行查找。这种查 找方法速度慢、效率低。对于经常查找的数据项,如果事先对它们进行排序,并将排序结果 和对应物理顺序的记录号的对照表保存到相应的文件(称为索引文件)中。那么,在对这个 ·27·


数据项查找时仅需在索引文件中进行,因为索引文件是按该数据项的大小顺序存放的,所以 很快就能定位。然后,系统通过索引文件中的对照表就可得到该数据项在表文件中的实现位 置,这就是索引技术,这个过程称为索引。 索引的数据项是经常进行查询的字段或由字段组成的表达式,称为索引关键字。例如, 在基本情况表中经常按编号查找,那么“编号”字段可作为索引关键字,我们也经常按姓名 和性别连在一起查找,“姓名+性别”也可作为索引关键字。一个表可建多个索引,为了区分 它们,每一个索引都要起一个名称,称为索引标识。在 VFP 中,如果一个索引存放在一个索 引文件中,这种索引文件为独立索引文件,扩展名为 .IDX。如果若干个索引存放在同一个索 引文件中,这种索引文件为复合索引文件,扩展名为 .CDX。复合索引文件又分为结构化复合 索引和非结构化复合索引。结构化复合索引文件的主文件名与表的主文件名相同。 在 VFP 中,索引可分为下列几种类型: (1)主索引。作为主索引的索引关键字,其表中所有记录的值必须是惟一的。例如,基 本情况表的“编号”字段可作为主索引的索引关键字,而“姓名”字段就不可作为主索引的 索引关键字。只有数据库表才可建立主索引,一个数据库表只能建立一个主索引。 (2)候选索引。作为候选索引的索引关键字,其表中所有记录的值必须是惟一的。一个 表可以建立多个候选索引,数据库表和自由表均可建立候选索引。 (3)普通索引。作为普通索引的索引关键字,其表中记录的值可重复。一个表可以建立 多个普通索引,数据库表和自由表均可建立普通索引。 (4)惟一索引。作为惟一索引的索引关键字,其表中记录的值可重复。但在索引文件中 仅保存重复值记录的第一个。一个表可以建立多个惟一索引,数据库表和自由表均可建立惟 一索引。例如,对于基本情况表,用“LEFT(编号,2) ”作为惟一索引的索引关键字,那么 只会显示每个部门的第一个人的记录。因为编号左边的 2 个字符为部门代号,所有该部门的 人员都相同。 索引可通过表设计器和命令方式建立。 1. 通过表设计器建立索引 打开表设计器→选“索引”页,如图 2.14 所示。

图 2.14

·28·

表设计器“索引”页


一行描述一个索引,一个索引描述包含下列几项。 (1)排序:指定索引中的排列顺序。向上箭头为从小到大排序,向下箭头为从大到小排 序。排序时根据表达式(索引关键字)值的类型确定大小。 ① 数值型:按其数值论大小。 ② 字符型:西文字符按其 ASCII 值论大小;汉字按其内码论大小,汉字内码从小到大的 顺序一般与国标 GB2312.80 的排列顺序一致。在国标 GB2312.80 中的汉字,常用的一级汉字 按汉语拼音从前到后排列,排在一级汉字后面的二级汉字按部首偏旁笔画多少排列。也就是 说,就汉字内码而言,“陈”小于“王”。汉字与 ASCII 码比较,汉字大于 ASCII 码。 ③ 日期型:按其日期论大小,在当前的日期之前的越早,日期值越小。 ④ 逻辑型:假(F)小于真(T) 。 (2)索引名:索引标识名,即引用该索引的名字。 (3)类型:可选上述介绍的四种索引类型之一。注意,只可在一行中选择主索引,因为 一个数据库表只能建一个主索引。 (4)表达式:索引关键字。多个字段组合时要求描述的表达式要符合 VFP 表达式规则。 例如,将职称和出生时间组成表达式时,因为两个字段的数据类型不同不能直接连接,而应 用 DTOC()函数将出生时间从日期型转换成字符型,然后与字符型的职称字段用字符运算 符“+”进行连接方可。关于表达式的规则详见第 3 章。注意,备注型、通用型不能作为索引 关键字。 (5)筛选:索引中包含符合条件记录的条件表达式。筛选条件的描述必须符合 VFP 逻辑 表达式的规则,详见第 3 章。不包含筛选,则对所有记录进行索引。 这里,一个表可建多个索引,用多行表示。索引在行中的顺序就是后面引用索引的序号。 例如:SET ORDER TO 2 就是将当前表的显示顺序设定为第 2 个索引顺序。2 就是指这里的 第 2 行对应的索引。另外,在这里建立的索引一定是结构化的复合索引。建立索引后,系统 生成一个主文件名相同、扩展名为 .CDX 的文件。例如,对于基本情况表建立索引后,系统 生成了“基本情况.CDX”文件。 2. 通过命令建立和删除索引文件 可用下列命令建立索引。 格式: INDEX ON 索引表达式 TAG 索引标识名[OF CDX 文件名] | TO 索引文件名 [FOR 条件] [ASCENDING | DESCENDING] [UNIQE | CANDIDATE]

其中, ON 索引表达式:指定索引关键字。 TAG 索引标识名:指定索引标识名。选 OF CDX 文件名,表示创建非结构化复合索引, OF 后指定的是存放该索引的文件名。不选 OF CDX 文件名,表示创建结构化复合索引。选 TO 索引文件名,则创建独立的索引文件。 FOR 条件:指定索引过滤条件。 ASCENDING:索引顺序为升序。 DESCENDING:索引顺序为降序。 UNIQE:指定惟一索引。 ·29·


CANDIDATE:指定候选索引。 已经建立的复合索引可用下列命令删除。 格式 1: DELETE TAG 索引标识名 [OF CDX 文件名] …

格式 2: DELETE TAG ALL [OF CDX 文件名]

说明:DELETE TAG 命令删除复合索引文件中的索引;DELETE TAG ALL 命令删除复 合索引文件中的所有索引。用 DELETE TAG 命令删除了所有的复合索引后,复合索引文件自 动被删除。 对于结构化复合索引,当在表设计器中删除所有索引后,结构化复合索引文件也就不存 在了。 独立索引文件用删除文件的方法删除。 3. 打开索引 在 VFP 中,在打开表的同时系统自动地打开结构化复合索引。要使索引产生作用,必须 指定主控索引。主控索引就是控制当前显示顺序的索引。例如,执行下列命令后,浏览窗口 看到的记录顺序仍是物理顺序。 USE 基本情况 BROWSE

要指定主控索引,可有下列几种方法。 (1)打开表的同时打开索引并指定主控索引。 格式: USE [[数据库名!]表名 | ?] [INDEX 索引文件表 | ? [ORDER [顺序号| [TAG] 索引标识名 [OF CDX 文件名] [ASCENDING | DESCENDING]]]]

其中,INDEX 项用于指定打开独立索引文件名;ORDER 指定主控索引;顺序号对于复 合索引是对应加入复合索引文件的先后顺序索引。结构复合索引就是表设计器在“索引页” 中看到的对应索引的先后顺序。对于独立索引,就是 INDEX 索引文件表项中的排列顺序, 略去顺序号,则索引文件表中的第 1 个作为主控索引。 略去 ORDER 项,则在没有 INDEX 项时,系统虽然也打开了复合索引,但却没有指定主 控索引。显示的顺序仍为物理顺序。 例如: USE 基本情况 ORDER TAG 工资 && 窗口记录按工资从大到小排列

BROWSE

(2)打开表后打开索引。 格式: SET INDEX TO [INDEX 索引文件表 | ? ] [ORDER 顺序号 |

索引文件名

| [TAG] 索引标识名 [OF CDX 文件名] [ASCENDING | DESCENDING]] [ADDITIVE]

·30·


【例 Ex_SIndex】打开表后打开索引。 USE 基本情况 && 显示物理顺序

BROWSE SET ORDER TO TAG 性别

&& 显示按姓名排列,姓名相同再按性别

BROWSE SET ORDER TO 1

&& 按编号顺序显示

BROWSE USE

4. 索引查找 建立索引的目的是为了进行快速查找。快速查找命令如下。 格式: SEEK 表达式 [ORDER 顺序号 |

索引文件名

| [TAG] 索引标识名 [OF CDX 文件名] [ASCENDING | DESCENDING]]

说明:SEEK 命令按表达式的值进行查找。在索引查找前应打开相应的表和索引,查找 内容就是与其后指定的索引标识的关键字匹配的内容。如 SEEK 命令无任何选项,则此前必 须指定主控索引,SEEK 查找的是与主控索引关键字相匹配的第一个位置。 如果 SEEK 查找到相匹配的内容,则 FOUND()为.T.,EOF()为.F.。如找不到,则 FOUND()为.F.,EOF()为.T.。 SEEK 命令只能查找相匹配的第一个记录,如有相同内容的值,则一定是紧跟在其后。 系统的 SEEK()函数功能相当于执行 SEEK 命令后再将 FOUND()值返回。 【例 Ex_Seek】索引查找。 USE 基本情况 ORDER 性别 SEEK "杨

华"

DISPLAY

&& 显示杨华记录

USE

2.5

工作区

1. 工作区的概念 工作区就是表可打开的区域。每个工作区有一个编号,在工作区中打开的表都有一个别 名。一个工作区任何时候只能打开一个表,如果工作区中已经打开了一个表,则在该工作区 中打开另一个表时先前打开的表被自动关闭。系统启动后用户如果没有选择工作区,则系统 默认的当前工作区为 1 号工作区。这就是说,我们此前进行的表操作都是在 1 号工作区进行 的。既可以先选择工作区,然后打开表,也可以在打开表的同时选择工作区。 格式: USE [数据库名!]表名 IN 工作区

在工作区中打开的表的文件名就是表的别名,但也可以在打开表的同时命名表别名。在 工作区中打开了表后,表的别名可用于选择工作区。 格式: ·31·


USE [数据库名!]表名 ALIAS 别名

2. 工作区选择 格式: SELECT 别名 | 工作区号

工作区号可以是 A~J,W11~W255 的数值。如果工作区号为 0,则系统自动选择一个 当前未用的最小工作区。 【例 Ex_Sele】工作区选择。 SELECT A USE 基本情况 ALIAS JB SELECT B USE 工资情况 ALIAS GZ SELECT JB BROWSE SELECT 工资情况 BROWSE CLOSE DATABASES

实际上,有很多命令中包含选择工作区的选项,例如: USE [[数据库名.]表名 IN [别名 | 工作区号] APPEND [BLANK] [别名 | 工作区号] DELETE [范围] [FOR 条件] [WHILE 条件] [别名 | 工作区号] RECALL [范围] [FOR 条件] [WHILE 条件] [别名 | 工作区号] SEEK 表达式 [ORDER 顺序号 | 索引文件名 | [TAG] 索引标识名 [OF CDX 文件名] [ASCENDING | DESCENDING]] [别名 | 工作区号] 它们的差别是:命令中包含选择工作区的选项,命令执行后当前工作区并没有变化。

2.6

表的关系

在 VFP 中,每张表既相互独立,互相之间又存在联系。一般将有联系的表放在同一个数 据库中。建立关系的目的是把独立存在的表连接起来,以获得有联系的信息。 表与表之间有下列关系,以下举例中使用的数据库和表的结构请参见附录。 (1)一对一关系。有两张表:A 表和 B 表。A 表中的一条记录在 B 表中有一条记录与之 对应。反过来,B 表中的一条记录在 A 表中也有一条记录与之对应。具有这种关系的两张表 存在一对一的关系。例如,人员信息数据库中的基本情况表和工资情况表记录之间就是一对 一的关系。有基本情况必有工资情况,有工资情况也必有基本情况。 (2)一对多关系。有两张表:A 表和 B 表。A 表中的一条记录在 B 表中有多条记录与之 对应。反过来,B 表中的一条记录在 A 表中仅有一条记录与之对应。具有这种关系的两张表 存在一对多的关系。例如,人员信息数据库中的部门工资表和工资情况表记录之间就是一对 多的关系,一个部门对应该部门的所有人员。 ·32·


(3)多对多关系。有两张表:A 表和 B 表。A 表中的一条记录在 B 表中有多条记录与之 对应。反过来,B 表中的一条记录在 A 表中也有多条记录与之对应。但是 A 表和 B 表之间的 这种多对多关系必须通过中间表 C 表来连接方可实现。例如产品表和销售商表之间存在着多 对多关系。即一个产品可有多个销售商,而一个销售商又可销售多个产品。它们之间通过产 品销售表实现了多对多的关系。 表之间的关系可通过界面和命令两种方式建立。表之间可建立永久关系,也可建立临时 关系。但仅有数据库表可建立永久关系。在建立表之间的关系时,被关联的表为子表,发起 关联的表为主表。

2.6.1 永久关系 打开数据库设计器,该数据库中的数据库表就会被可视化地显示出来。数据库中的可视 化数据库表除了显示字段名外,还显示它的结构化复合索引的索引标识名。 索引是建立永久关系的前提。在一对一关系表中,主表和子表均应按相同的关键字建立 主索引或候选索引。而对于一对多关系表,主表应建立了主索引或候选索引,而子表建立了 普通索引。下面以在数据库设计器中创建人员信息数据库的永久关系为例加以说明。 基本情况表与工资情况表之间的一对一关系:拖动基本情况表的“编号”索引标识到工 资情况表的“编号”索引上,这时在数据库设计器的基本情况表与工资情况表的编号标识上 就会出现一条连线,表示在它们之间建立了一对一的关系。 部门工资表分别与基本情况表、工资情况表之间的一对多关系:先拖动部门工资表的“部 门编号”索引标识到基本情况表“部门编号” (索引关键字为 LEFT(编号,2))索引上,再 拖动部门工资表的“部门编号”索引标识到工资情况表“部门编号”索引(索引关键字为 LEFT (编号,2) )上。这时在数据库设计器中部门工资表与基本情况表、部门工资表与工资情况 表的部门编号标识上分别出现一条连线。连线与一对一关系不同的是,一对一关系两头均为 单线,而一对多关系在基本情况和工资情况这一头连线出现了 3 个分叉线,表示在它们之间 建立了一对多关系,3 个分叉线这一头对应的表为多方。建立后的结果如图 2.15 所示。

图 2.15

数据库设计器建立永久关系

已经建立的永久关系可进行编辑。先选择要编辑关系的连线,按右键在快捷选单中选择 “编辑关系”,如图 2.16 所示。 ·33·


在建立关系的表中选择已经建立的索引标识。

图 2.16

“编辑关系”对话框

要删除已经建立的永久关系,先选择要编辑关系的连线,按 Delete 键或按右键在快捷选 单中选择“删除关系”。

2.6.2 临时关系 创建和解除临时关系有以下几种方法。 (1)用命令创建临时关系。 格式: SET RELATION TO [字段表达式 INTO 工作区 | 表别名 … [ADDITIVE]]

在当前表中,以字段表达式与 INTO 指定的工作区中的主控索引建立关联。 (2)在数据环境中创建临时关系。在用表单设计界面时,可在表单中加入数据环境对象, 在数据环境中可视化地建立临时关系。首先,向数据环境中加入有关的数据库表或临时表。 然后,在数据环境中建立表之间的临时关系。除了上述所讲的建立永久关系的方法外,还可 以在主表的字段与子表的主控索引之间建立临时关系。 表单启动时,数据环境中的临时关系被建立。表单释放时,数据环境中的临时关系被撤 消。 在用表单设计界面时可在表单中加入数据环境对象,系统将永久关系预置为临时关系。 用户可根据情况修改成自已所需要的临时关系。 【例 Ex_ Relation】人员信息数据库三表联动浏览。 SET DEFAULT TO D:\RY_MIS OPEN DATABASE RY USE 基本情况 IN 0 ORDER 1 USE 工资情况 IN 0 ORDER 1 USE 部门工资 IN 0 ORDER 1 SELECT 基本情况 SET RELATION TO 编号 INTO 工资情况 SET RELATION TO LEFT(编号,2)INTO 部门工资 ADDITIVE BROWSE FIELD 基本情况.姓名,部门工资.部门名称,工资情况.实发工资 CLOSE DATABASE

运行结果如图 2.17 所示。 ·34·


(3)解除临时关系。解除临时关系命令如下。 格式 1: SET RELATION TO

格式 2: SET RELATION OFF

图 2.17

人员信息数据库三表联动浏览表

使用此命令前先要进入建立关联时主表所在的工作区。另外,在关闭数据库和表时,表 临时关系同时解除。

2.7

数据库和表属性

2.7.1 数据库的属性 数据库是一个容器,在数据库容器中存放数据库对象的信息,这些对象包括数据表、结 构化复合索引、永久关系、存储过程等。数据库设计器中可以可视化地显示有关的对象,如 图 2.18 所示。

图 2.18 数据库容器

要操作数据库,可选择主选单中“数据库”中的选单项,或数据库设计器的工具栏进行。 ·35·


要改变当前数据库设计器中显示的对象,只要选择数据库的“属性”项,即出现如图 2.19 所 示的对话框。

图 2.19

数据库的“属性”项

要操作哪一个对象,只要单击该对象,然后按右键,选择相应的操作选单即可。

2.7.2 数据库表的属性 数据库表的属性分为字段属性和表的属性。 1.数据库表的字段属性 在表设计器设计表结构时,如果是数据库表,则在字段名列表的下方还有若干项,用于 控制字段的属性。例如,产品销售数据库的产品销售字段属性表如图 2.20 所示。

图 2.20

产品销售表字段属性

字段的属性包含下列几个方面。 (1)字段的显示属性。 格式:控制字段在浏览窗口、表单、报表等显示时的大小写和样式。格式字符及功能如 表 2.2 所示。

·36·


表 2.2 字段的显示属性格式字符 字符

字符

A

字母字符,不允许空格和标点符号

D

使用当前的 SET DATE 格式

E

英国日期格式

K

光标移至该字段选择所有内容

L

显示数值字段前导 0

M

允许多个预设置选择项。参见文本框 InputMask 属性

R

显示文本框的格式掩码,但不保存到字段中

T

删除前导空格和结尾空格

!

字母字符转换为大写

^

用科学计数法表示数值数据

$

显示货币符号

例如,上面的 yf(月份)字段“格式”设置为 L,表示显示前导 0。一般情况下,对于 数值字段前导 0 是不显示的。 输入掩码:控制向字段输入数据的格式。掩码字符及功能如表 2.3 所示。 表 2.3 字段的显示属性掩码字符 字符

字符

x

任意字符

*

左侧显示*

9

数字字符和+-号

.

指定小数点位置

#

数字字符、+-号和空格

用逗号分隔整数部分

$

指定位置显示货币符号

$$

货币符号与数字不分开显示

例如,对于一个字符型字段仅允许输入 5 位数字字符,则输入掩码为 99999。 标题:浏览表时字段显示列标题,没有标题则用字段名。一般情况下,经常用代号作为 字段名,这样编程操作可少输入汉字。但在使用系统的浏览表和选择字段等操作时显得不太 直观。给字段加标题属性可弥补这方面的不足。例如,上面的 yf 字段,标题用“月份” 。 (2)字段有效性。 规则:是指定字段数据的有效范围。满足该条件,数据才能放入该字段。向该字段中输 入数据,输入的数据格式要受“输入掩码”的控制,同时还要满足字段“规则”中指定的条 件。例如,上面的 yf 字段,表示的是月份,如果用户向该字段输入“00”或“13”显示是错 误的。 信息:是当企图向字段输入不符合“规则”的数据时,显示给用户的提示内容。 默认值:是在向表中添加记录而未向该字段输入数据前,系统向该字段预置的值。例如, 上面的 yf 字段,在添加记录时,预置一个当前月的数据。 字段注释:是对本字段的说明。 (3)匹配字段类型到类。将字段与用户定义的类库中的类联系起来。关于类请参考后面 “类”的有关内容。 2. 数据库表的记录属性 字段属性用于控制字段的输入和显示,此外系统还可通过数据库表的记录属性对数据库 表的记录数据进行控制。在表设计器设计表结构时,选择“表”页即可设置数据库表的记录 属性。例如,“人员信息数据库的工资情况表”页,如图 2.21 所示。 (1)记录有效性。 规则:是指定数据记录的有效条件。满足该条件,数据才能从当前记录移出。满足字段 “规则”中指定的条件仅可移出该字段。对于人员信息数据库的工资情况表,各工资项字段 ·37·


仅控制本字段数据的合法性,但当需移出该记录时还要看总体数据关系是否有错。

图 2.21

数据库表的记录属性

例如,可在记录有效性中设置比较累加收入与扣款小计,从而进一步避免输入错误的数 据到记录中。 信息:是当不符合记录有效性“规则”时,显示给用户的提示内容。 (2)触发器。触发器是系统提供的记录级事件。事件触发时可执行的条件表达式或用户 自定义函数在相应的触发器框中设定。函数返回值为.T.,操作被认可,否则操作将被拒绝。 用户自定义函数可放在数据库所在的存储过程中。触发器在记录的验证规则之后运行,在采 用缓冲更新时只有在发布 TABLEUPDATE()命令后才运行。即使记录的验证规则通过,仍 要看触发器的条件。记录验证时只能使用当前记录中的信息,而触发器可跳到当前记录外。 可触发的事件包含下列几种。 ① 插入触发器:当向该表插入或追加记录时触发,执行插入触发器框中指定的条件表达 式或用户自定义函数。用下列命令也可创建插入触发器。 格式:CREATE TRIGGER ON 表名 FOR INSERT AS 触发条件表达式 ② 更新触发器:当修改表记录时产生。执行更新触发器框中指定的条件表达式或用户自 定义函数。用下列命令也可创建更新触发器。 格式: CREATE TRIGGER ON 表名 FOR UPDATE AS 触发条件表达式

③ 删除触发器:当删除表记录时产生。执行删除触发器框中指定的条件表达式或用户自 定义函数。用下列命令也可创建删除触发器。 格式: CREATE TRIGGER ON 表名 FOR DETELE AS 触发条件表达式

例如: OPEN DATABASE RY CREATE TRIGGER ON 基本情况 FOR UPDATE AS UF_UPDATE()

用户可在用户自定义函数 UF_UPDATE 中安排判别允许更新记录的程序。条件满足,则 函数返回真(.T.),否则返回假(.F.)。 ·38·


已经建立的触发器用下列命令删除。 格式: DELETE TRIGGER ON 表名 FOR INSET | UPDATE | DELETE

(3)表名。表名是数据库表在打开和操作时的名称,也可认为是表的别名。系统默认表 的主文件名为表名。表名最长为 128 个字符。使用表名打开表要求在此之前数据库必须打开。 例如,我们将上述工资表的表名命名为 GZ,这样: OPEN DATABASE RY USE GZ

(4)表注释。对该数据库表的附加说明。 3. 命令查看和设置数据库的属性 命令查看和设置数据库的属性有如下几种。 (1)查看数据库的属性。 格式: DBGETPROP(名称,类型,属性)

(2)设置数据库的属性。 格式: DBSETPROP(名称,类型,属性,属性值)

名称可以是数据库名、字段名、表名或视图名,类型和属性说明如表 2.4、表 2.5 所示。 表 2.4 类

类型说明

DATABASE

名称为数据库名

FIELD

名称为字段名

TABLE

名称为表名

VIEW

名称为视图

表 2.5 属

属性说明

Caption

字段标题

Comment

数据库、字段、表或视图的注释文本

DefaultValue

字段默认值

DeleteTrigger

删除触发器表达式

InsertTrigger

插入触发器表达式

Path

表的路径

PrimaryKey

主关键字标识名

RuleExpression

规则表达式

RuleText

规则出错显示文本

SQL

打开视图时执行的 SQL 语句

UpdateTrigger

更新触发器表达式

Version

数据库的版本号

例如: OPEN DATABASE RY ? DBGETPROP("工资情况","TABLE","RuleExpression")

·39·


4. 数据库表数据的完整性 数据库表数据的完整性有以下几方面。 (1)字段数据的完整性。字段数据的完整性是指输入到字段中的数据的类型和值必须符 合指定的要求。字段属性中的字段有效性规则用于控制字段数据的完整性。 (2)记录数据的完整性。记录数据的完整性是指输入到记录中有关字段中的数据的值必 须符合指定的要求。表属性中的记录有效性规则用于控制记录数据的完整性。 (3)参照完整性。参照完整性是指相关表之间的数据一致性。主要表现在:子表中的每 一条记录在父表中必须有一条记录与之对应;在主表中修改了主关键字字段的值,则子表中 相关记录的外部关键字对应的字段的值必须同步修改;在主表中删除记录时,则子表中相关 记录必须同步全部删除。 相关表之间参照完整性的规则的建立是以相关表之间建立了永久关系为前提。在相关表 之间建立了永久关系后,右击表永久关联线,在快捷选单中选择“参照完整性”,出现“参照 完整性生成器”对话框,如图 2.22 所示。

图 2.22

“参照完整性生成器”对话框

用户可通过相关表之间“参照完整性”对话框设置当父表记录修改时子表的操作规则。 选项包括级联、限制和忽略 3 项。设置分更新、插入和删除 3 个方面分别设定。 设置后单击“确定”按钮,系统询问是否保存改变和生成参照完整性代码。回答“是”, 系统自动生成为了实现参照完整性的程序放在当前数据库的存储过程中。并将程序的函数名 自动放入参照完整性关联的主表的删除触发器和更新触发器中。用户此前已经设定了触发器, 则系统与用户触发器相与。

2.8

多数据库操作

在 VFP 中,可同时打开多个数据库,但只有一个为当前数据库。在打开多个数据库时, 最后一个打开的数据库为当前数据库。 “常用”工具栏中的数据库名列表框显示的是当前数据 库的名称。用户可使其他已经打开的数据库成为当前数据库。也可使用下列命令设置当前数 据库。 格式: SET DATABASE TO 数据库名

已经打开的数据库可用下列命令关闭。 ·40·


格式1: CLOSE DATABASES

关闭当前数据库。在数据库关闭后,与此数据库相关的均被同时关闭。若没有当前数据 库,则关闭所有工作区中的所有打开的自由表及与此表相关的内容。 格式 2: CLOSE DATABASES ALL

关闭所有打开的数据库以及与数据库相关的内容。关闭所有工作区中的所有打开的自由 表及与此表相关的内容。 格式 3: CLOSE ALL

关闭除“命令窗口”、“调试窗口”、“跟踪窗口”和“帮助窗口”以外的所有内容。 例如: OPEN DATABASE RY OPEN DATABASE XS SET DATABASE TO RY … CLOSE DATABASE ALL

2.9

数据库表的增减

1. 数据库表与自由表 数据库表是存放在数据库中的表,不存放在数据库中的表称为自由表。数据库表除了有 相应的文件外,在数据库容器中存放对该表进行管理的所有信息,其中包含表的属性。数据 库表在数据库设计器“索引”页中可视化地显示,包括表名、字段名、结构化复合索引、永 久关系等,如图 2.14 所示。 选择表,按右键即可出现操作表的选单。选择“修改”即可修改数据库表结构。注意, 在“字段”页的下方可设定字段属性,如图 2.23 所示。在“表”页中可设定表的属性,如图 2.24 所示。

图 2.23

表设计器“字段”页

·41·


图 2.24

表设计器“表”页

数据库表可移出数据库成为自由表,原数据库表的特性将失去。自由表的字段名长度为 10,不能设置字段属性。自由表设计器界面,如图 2.25 所示。也不能设置表属性,如图 2.26 所示为自由表设计器“表”页。

图 2.25

图 2.26

·42·

自由表设计器界面

自由表设计器“表”页


自由表可移入数据库成为数据库表。 表移入、移出数据库可在数据库设计选择工具栏中进行,也可用命令进行。 2. 命令方式增减表 将表移入、移出数据库命令如下。 格式: ADD TABLE 表名

格式: DELETE TABLE 表名

在数据库打开状态下建立的表自动成为该数据库的数据表。 例如: OPEN DATABASE RY ,姓名 C(10) ,出生时间 D(8) ,工资 N(6,2) ) CREATE TABLE 基本情况 1 (编号 C(5) MODIFY DATABASE DELETE TABLE 基本情况 1 MODIFY DATABASE

2.10 SQL 语句操作表 为什么要用 SQL 语句操作表? 1. SQL 命令创建表结构 用 SQL 命令建立表结构,命令如下。 格式: CREATE TABLE | DBF 表文件名 [NAME 表名 ] [FREE] 字段名 1 类型 [ (宽度 [,小数位])] [NULL | NOT NULL] [CHECK 字段规则 [ERROR 不符合字段规则的显示信息 ]] [DEFAULT 字段默认值] [PRIMARY KEY | UNIQUE] [REFERENCES 主表名 [TAG 主表索引标识]] [NOCPTRANS] [字段名 2,…] [,PRIMARY KEY 主关键字表达式 TAG 索引标识 [FOR 过滤条件] |,UNIQUE 惟一索引关键字表达式 TAG 索引标识 [FOR 过滤条件]] [,FOREIGN KEY 索引关键字 TAG 索引标识 REFERENCES 主表名 [TAG 主表索引标识]] [,CHECK 记录规则 [ERROR 记录信息]]) | FROM ARRAY 包含表结构的数组名

例如,直接创建表 JBQK,命令如下。 ,姓名 C(10),出生时间 D(8),工资 N(6,2)) CREATE TABLE JBQK (编号 C(5)

2. SQL 命令修改表结构 (1)增改字段。 ·43·


格式: ALTER TABLE 表名 ADD | ALTER [COLUMN] 字段名 [类型[(宽度 [,小数位])] ] [NULL | NOT NULL] [CHECK 字段规则 [ERROR 不符合字段规则的显示信息]] [DEFAULT 字段默认值] [PRIMARY KEY | UNIQUE [FOR 过滤条件]] [REFERENCES 主表名 [TAG 主表索引标识]] [NOCPTRANS] [NOVALIDATE]

其中,选择 ADD 为增加字段,选择 ALTER 为修改字段。 (2)增删字段属性。 格式: ALTER TABLE 表名 ALTER [COLUMN] 字段名 [NULL | NOT NULL] [SET DEFAULT 字段默认值] [SET CHECK 字段规则 [ERROR 不符合字段规则的显示信息]] [DROP DEFAULT] [DROP CHECK] [NOVALIDATE]

其中,选择 SET DEFAULT 项为设置字段默认值,SET CHECK 项为设置字段规则。 选择 DROP DEFAULT 项为删除字段默认值,DROP CHECK 项为删除字段规则。 (3)增删索引。 格式: ALTER TABLE 表名 [DROP [COLUMN]] 字段名 [SET CHECK 字段规则 [ERROR 不符合字段规则的显示信息]] [DROP CHECK] [ADD PRIMARY KEY 关键字表达式 TAG 索引标识 [FOR 过滤条件]] [DROP PRIMARY KEY] [ADD UNIQUE 关键字表达式 [TAG 索引标识 [FOR 过滤条件]]] [DROP UNIQUE TAG 索引标识] [ADD FOREIGN KEY [索引关键字] TAG 索引标识 [FOR 过滤条件] REFERENCES 主表名 [TAG 索引标识]] [DROP FOREIGN KEY TAG 索引标识 [SAVE]] [RENAME COLUMN 字段名 TO 字段名] [NOVALIDATE]

其中,选择 DROP [COLUMN] 项为删除字段。 选择 SET CHECK 项为增加字段规则和信息,DROP CHECK 项为删除字段规则。 ·44·


选择 ADD PRIMARY KEY 项为增加主控索引,其后 TAG 为主控索引标识;选择 DROP PRIMARY KEY 项为删除主控索引。 选择 ADD UNIQUE 项为增加惟一索引, 其后 TAG 为惟一索引标识; 选择 DROP UNIQUE TAG 项为删除主控索引。 选择 ADD FOREIGN KEY 项,为设置相关联表记录参照完整性。该命令在建立表结构的 同时,以索引关键字建立索引,并以 TAG 后“索引标识”作为索引名。与 REFERENCES 后 指定的主表中的索引(无“TAG 主表索引标识”项,则为主表的主索引)建立永久关系。 选择 DROP FOREIGN KEY TAG 为删除相关联表记录参照完整性。 【例 Ex_Alter】修改表结构。 * 向基本情况表中添加“附加工资”字段: ALTER TABLE 基本情况 ADD 附加工资 N(6,0)

* 创建永久关系: ALTER TABLE 基本情况 ADD FOREIGN KEY LEFT(编号,2)TAG 部门编号 REFERENCES 部门工资

3. SQL 命令操作表 SQL 命令提供了另外一种操作表的方法。SQL 命令操作表前不需要打开数据库。如系统 与远端通过 ODBC 建立了连接,SQL 命令可以操作远端数据库中的表。SQL 命令建立表结构 CREATE TABLE、修改表结构 ALTER TABLE 前面已经介绍,这里再介绍操作表记录的 SQL 命令。 (1)插入记录。 格式: INSERT INTO [数据库名!]表名 [(字段名表)] VALUES(表达式表)

向表名指定的表中插入一条记录,字段名表指定的字段值为 VALUES 后的相应的表达式 的值。 【例 Ex_SInsert】插入记录。 INSERT INTO RY!基本情况(编号,姓名,工资)VALUE("01006","周全新",1200) USE 基本情况 ? RECCOUNT()

&& RECCOUNT()函数得到当前表的记录数

USE

(2)删除记录。 格式: DELETE FROM [数据库名!]表名 WHERE 条件

删除表名指定的表中符合 WHERE 指定的条件的记录。 【例 Ex_SDele】删除记录。 DELETE FROM RY!基本情况 WHERE 编号= "01006" USE 基本情况 IN 0 ALIAS JB ? RECCOUNT("JB")

&& RECCOUNT("JB")函数得到 JB 表的记录数

USE

·45·


(3)替代字段。 格式: UPDATE [数据库名!]表名 SET 字段名=表达式…WHERE 条件

对表名指定的表中符合 WHERE 指定的条件的记录,将字段名指定的字段用表达式值替 代。 【例 Ex_SUpdate】替代字段。 UPDATE RY!基本情况 SET 基本情况.工资=基本情况.工资+100 USE 基本情况 BROWSE USE

2.11

一个简单界面操作表实例

【例 Ex_ EditGz】修改人员工资数据,计算实发工资。 (1)设计界面。修改人员工资数据库表单界面如图 2.27 所示。

图 2.27

修改人员工资数据库表单

(2)设置对象属性。对象属性如表 2.6 所示。 表 2.6 对 象 Form Label Label

对象属性

属 性 名

属 性 值

Name

From1

Caption

From1

Name

lbl 编号

Caption

编号

Name

lbl 姓名

Caption

姓名

… TextBox TextBox

·46·

Name

txt 编号

Readonly

.T.

Name

txt 姓名

Readonly

.T.


续表 对 象 TextBox

属 性 名

属 性 值

Name

Txt 技能工资

Readonly

.F.

… CommandButton CommandButton CommandButton CommandButton

Name

Command1

Caption

第一个

Name

Command2

Caption

上一个

Name

Command3

Caption

下一个

Name

Command4

Caption

最后一个

(3)编写代码。 *“第一个”按钮(Command1)的 Click 事件代码: GoTop Thisform.Refresh

*“上一个”按钮(Command2)的 Click 事件代码: If !Bof() Skip –1 Endif Thisform.Refresh

*“下一个”按钮(Command3)的 Click 事件代码: If !Eof() Skip Endif Thisform.Refresh

*“最后一个”按钮(Command4)的 Click 事件代码: Go Bottom Thisform.Refresh

*“计算实发”按钮(Command5)的 Click 事件代码: Replace All 实发工资 With 技能工资+岗位工资+浮动工资+其他工资-扣款小计 Go Top Thisform.Refresh

·47·


第 3 章 程序设计基础 3.1

数据类型

数据类型包含数据的值和取值范围以及可以进行的操作运算。 在定义表结构时,用户都要定义每个字段的数据类型。字段的数据类型就是表中该字段 存放的数据的类型,称为字段类型。例如,“姓名”字段只能定义成字符型,“工资”字段定 义成数值型, “婚否”字段定义成逻辑型。表中字段类型不同,可进行的操作也就不同。数值 型字段可进行算术运算、累加、求平均值等操作,字符型字段可进行字符运算操作。 用 VFP 编写程序,需要用到常量、变量和数组等数据元素,同样这些数据元素也都有相 应的数据类型。VFP 中定义的数据类型及其取值范围参见表 2.1,有些数据类型只能作为字段 的数据类型。 在 VFP 中,存储数据有下列方式。 (1)表的记录。表打开后,通过引用字段名就可得到对应该字段当前记录的内容(值) 。 通过交互方式和操作表的命令可修改字段在记录中的内容。 (2)对象。 (3)常量、变量和数组。在程序设计时经常要用这些数据元素存储数据。 这些记录、对象、常量、变量和数组称为存储数据的容器。本节主要介绍常量、变量和 数组存储数据的方法。

3.1.1 常量 常量是一个数据项,该数据项在程序运行过程中保持不变。常量分为一般常量和符号常 量。 1.一般常量 一般常量就是直接描述的常量。例如,下列常量都是一般常量: 数值型常量:-25,128.43,0。 字符型常量:'01002',"王 红",[128.43],' '。其中,' '表示空串。 日期型常量:{^2000.08.19},{},CTOD("06/18/99")。其中,{}表示空日期。而用字符 串表示日期型常量时需用 CTOD()函数进行转换,字符串表示日期的格式与当前系统默认 的日期格式一致。系统启动后系统默认的日期格式为“月/日/年” ,写做 MM/DD/YYYY。当 前系统默认的日期格式可通过 SET DATE [TO]命令进行设置。例如:SET DATE ANSI,则日 期格式为 YYYY.MM.DD。 逻辑型:真为.T.,.Y.;假为.F. ,.N.。 2.符号常量 符号常量就是在程序中为一个符号先定义一个值,程序中凡使用该值的地方就写上该符 号常量。编译该程序时,编译程序将程序在出现该符号常量中的地方用定义的值直接代替。 所以符号常量又称为编译常量。使用符号常量的好处是当值需要改变时只需改变符号常量定 ·48·


义的值即可。注意,程序中不能对符号常量重新赋值,符号常量不是变量。符号常量用下列 方法定义: #DEFINE 符号常量名值 例如:#DEFINE PI 3.14159

3.1.2 变量 变量是程序运行中可以变化的量。变量对应内存中的某存储单元,该存储单元存放该变 量的值。变量名是存储位置的符号标识。所以变量又称内存变量。 变量的命名规则与字段名基本相同,但变量名可以更长。变量名由字符(字母、汉字、 “_”和数字)组成,但不能以数字打头。变量名不能使用系统的保留字。 1.变量赋值 变量赋值的语句有下列两个。 格式: 变量名=值 STORE 值 TO 变量名表

【例 Ex_Store】变量赋值。 R=10 S=3.14159*R*R STORE "教授" TO S1,S2 ? R,S,S1,S2

有些命令对变量不需事先声明就可直接赋值。赋值的同时该变量就被创建,变量类型取 决于赋予的值的类型。 【例 Ex_VFPStore】变量直接赋值。 SET TALK OFF USE RY!工资情况 SUM 技能工资, (岗位工资+浮动工资)*1.2 TO JN,GWFD FOR 编号="01" ? JN,GWFD USE

运行后,结果自动产生变量 JN 和 GWFD,并存放技能工资和 (岗位工资+浮动工资) *1.2 累加值。 2.变量的引用 在程序中变量可直接用变量名引用其值。但如果当前打开的表中有与变量同名的字段名, 这时用 M.变量名引用该变量,而字段名可直接引用。 【例 Ex_Muse】变量的引用。 USE 基本情况 编号="04012"

&& 给内存变量"编号"赋值 && 给字段名为"编号"赋值使用 REPLACE 或 UPDATE 命令

? 编号

&& 显示 1 号记录编号字段的内容

? 基本情况.编号

&& 显示 1 号记录编号字段的内容

·49·


? M.编号

&& 显示 04012

除了变量、字段的引用外,还有对象的引用。为了便于对比,下面同时列出字段值的引 用和对象属性的引用方法。 变量的引用:M.内存变量名 字段值的引用:[[数据库名!]表名.]字段名 对象属性的引用:对象名.属性名 把这些引用统一起来,我们都可以认为是对象引用,可把 M 和表都视做对象。 例如: #DEFINE PI 3.14159 S=PI*8*8 THISFORM.TEXT1.VALUE=S

例如: OPEN DATABASE RY USE 工资情况 THISFORM.TEXT2.VALUE=RY!工资情况.岗位工资

3.显示变量 格式: DISPLAY MEMORY [LIKE 文件名框架] [NOCONSOLE] [TO PRINTER [PROMPT] | TO FILE 文件名]

格式: LIST MEMORY [LIKE 变量名框架] [NOCONSOLE] | TO FILE 文件名]

显示内存变量名和当前值。可用 LIKE 变量名框架限制显示的变量名。框架可用*和?进 行描述。 TO PRINTER:显示记录送打印机打印。带 PROMPT 项,打印前打开“打印”对话框, 用户可在该对话框中对打印机进行设置。 TO FILE 文件名:显示记录送到指定的文件中保存。 4. 变量的保存和恢复 (1)保存变量。 格式: SAVE TO 文件名 | MEMO 备注字段名 [ALL LIKE 变量名框架 | ALL EXCEPT 变量名框架]

该命令将当前内存变量保存到文件或备注字段中。 ALL LIKE 变量名框架:指定保存的变量范围。可使用*和?描述框架。ALL EXCEPT 指 定不保存的变量范围。 (2)恢复变量。 格式: RESTORE FROM 文件名 | MEMO 备注字段名 [ADDITIVE]

从保存变量的文件或备注字段中恢复变量到内存中。选择 ADDITIVE,则不覆盖当前已 ·50·


有的内存变量。 5. 内存变量的释放 格式: RELEASE 变量名表 | ALL [LIKE 变量名框架 | EXCEPT 变量名框架]

【例 Ex_Release】内存变量的释放。 OLDDate= CTOD("06/18/99") NAME1="肖文红" GZ1=1633 NAME2="朱 平" GZ2=1834 NAME3="杨 华" GZ3=1183 DISPLAY MEMORY

&& 显示所有内存变量

SAVE TO MFILE DISPLAY LIKE NAME*

&& 显示所有 NAME 打头的内存变量

RELEASE ALL EXCEPT GZ* DISPLAY MEMORY

&& 显示所有内存变量

CLEAR MEMORY

&& 清除所有内存变量

RESTORE FROM MFILE DISPLAY MEMORY

6. 变量和表 (1)表字段到内存变量。 格式: SCATTER [FIELDS 字段名表 | LIKE 字段名描述框架 | EXCEPT 字段名描述框架] [MEMO] TO 数组名 | TO 数组名 BLANK | MEMVAR | MEMVAR BLANK | NAME 对象名 [BLANK]

说明:将当前表的当前记录中 FILEDS 指定的字段的值放到数组、内存变量或对象中。 其中,内存变量的名字与字段名相同。选对象项,对象生成与字段名同名的属性,字段的值 放入相应的属性中。含 BLANK,值赋空值。选 MEMO,则包含备注型字段。 【例 Ex_Scatter】表字段到内存变量。 USE 工资情况 GO 3 SCATTER MEMVAR ? M.其他工资,工资情况.其他工资

&& 值不同

SCATTER NAME GZ ? GZ.其他工资,工资情况.其他工资

&& 值不同

USE DISPLAY MEMORY

·51·


(2)内存变量到表字段。 格式: GATHER FROM 数组名| MEMVAR | NAME 对象名 [FIELDS 字段名表 | LIKE 字段名描述框架 | EXCEPT 字段名描述框架] [MEMO]

该命令用数组、内存变量或对象的值更新当前表的当前记录。 【例 Ex_Gather】内存变量到表字段。 USE 工资情况 GO 3 M.其他工资=120 ? M.其他工资,工资情况.其他工资

&& 值不同

GATHER MEMVAR ? M.其他工资,工资情况.其他工资

&& 值相同

USE

3.1.3 数组 1. 数组的定义 数组就是变量名相同而下标不同的一组变量。数组用下列语句定。 格式: DIMENSION 数组名[下标最大值表]

例如,DEMINSION NAME[100],CJ[5,10] 注意:由数据库操作命令存放结果的数组系统会自动建立。 2. 表数据传送到数组 数组与表之间、变量与表之间都可交换数据,但通过数组不仅传送的数据多、速度快, 而且还具有自动定位、使用简单方便。数组与表之间的数据传送分为表数据到数组和数组数 据到表两个方向。先介绍表数据传送到数组。 格式: COPY TO ARRAY <数组名> [FIELDS <字段名>] [<范围>] [WHILE <条件 1>] [FOR <条件 2>] [NOOPTIMIZE]

用于将当前工作区中打开的表当前指针开始的若干记录的指定字段内容复制到指定数组 中。 3. 数组内容传送到表 格式 1: APPEND FROM ARRAY <数组名> [FROM <条件>] [FIELDS <字段名表>]

用于将数组中的内容加到当前表中(不包括记忆型和通用型字段)。

·52·


格式 2: INSERT INTO <表名> FROM ARRAY <数组名> | MEMVAR

用于将数组或一组与表字段同名的内存变量中的内容插入或追加到指定表中。 【例 Ex_ACopy】设计程序,复制表中最后一条记录后再修改。 USE 工资情况 GO BOTTOM COPY TO ARRAY TARR NEXT 1 APPEND FROM

ARRAY TARR

&& 表中有重复记录的索引

EDIT USE DISPLAY MEMORY LIKE TARR*

4. 操作数组的函数 使用数组的函数很多,这里仅列出常用的操作数组的函数。 (1)数组拷贝。 格式: ACOPY(<原数组名>,<目标数组名>[,<原数组起始元素> [,<拷贝个数>[,<目标数组起始元素>]]])

(2)数组删除。 格式: ADEL(<数组名>,<序号>[,2])

(3)文件名到数组。 格式: ADIR(<数组名>[,<文件名框架>[,<属性>]])

该函数能得到指定目录中文件名框架的文件的情况。返回的数组中的内容如表 3.1 所示。 属性描述的功能如表 3.2 所示。 表 3.2 属性描述的功能

表 3.1 返回的数组中的内容 数组列

数据类型

属性

1

文件名

Character

A

Archive – Read/Write

2

文件大小

Numeric

H

Hidden

3

最后修改日期

Date

R

Read-only

4

最后修改时间

Character

S

System

5

文件属性

Character

D

Directory

例如, ADIR(AA,"D:\RY_MIS\*.DBF","AD") ? AA[1,1],AA[1,2],AA[1,3],AA[1,4],AA[1,5] ? AA[2,1],AA[2,2],AA[2,3],AA[2,4],AA[2,5] ? AA[3,1],AA[3,2],AA[3,3],AA[3,4],AA[3,5] ·53·


… (4)得到元素序号。 格式: AELEMENT(<数组名>,<行号>[,<列号>])

(5)表结构到数组。 格式: AFIELDS(<数组名>)

(6)数组插入。 格式: AINS(<数组名>,<序号>[,2])

(7)得到数组大小。 格式: ALEN(<数组名>[,<数字表达式>])

(8)数组定位。 格式: ASCAN(<数组>,<待找的表达式>[,<开始位置>[,<需比较元素的个数>]])

(9)数组排序。 格式: ASORT(<数组名>[,<排序起始元素>[,<要排序元素个数或行数>[,<排序方式>]]])

(10)由序号得到下标。 格式: ASUBSCRIPT(<数组名>,<元素顺序号>,<数字表达式>)

【例 Ex_Array】数组函数应用。 DIMENSION AA[5] AA[1]=2 AA[2]=4 AA[3]=1 AA[4]=3 AA[5]=5 ? AA[1],AA[2],AA[3],AA[4],AA[5]

&& 显示 2

? ASCAN(AA,1)

&& 显示 3

4 1

3

5

2 3

4

5

3 4

5 .F.

=ASORT(AA) ? ASCAN(AA,1)

&& 显示 1

? AA[1],AA[2],AA[3],AA[4],AA[5]

&& 显示 1

=ADEL(AA,1)

·54·

? ALEN(AA)

&& 显示 4

? AA[1],AA[2],AA[3],AA[4],AA[5]

&& 显示 2


3.2

操作符和表达式

3.2.1 操作符 VFP 操作符有下列几类。 1. 数值操作符 数值操作符用于进行数值运算,数值操作符如表 3.3 所示。 表 3.3

数值操作符

操 作 符

+,-

正负号

**,^

*,/,%

乘,除,取模

+,-

加减

优先级从高到低为:+,-号→**,^→*,/,%→+,-。 例如: -12.4/3+56 2. 字符操作符 字符操作符用于进行字符运算,字符操作符如表 3.4 所示。 表 3.4

字符操作符

操作符

+

连接字符串

-

删除操作符左侧字符串尾部空格后再连接字符串

$

判左侧字符串是否包含在右侧字符串中

优先级从高到低为:+,-→$。 例如,职称+DTOC(出生时间),"王"$姓名 3.日期操作符 日期操作符用于进行日期运算,日期操作符如表 3.5 所示。 表 3.5

日期操作符

操作符 +

日期+天数得到新日期 时间+秒数得到新时间

-

日期-日期得到间隔天数 时间-时间得到间隔秒数

日期操作符没有优先级。 例如,DATE()-出生时间+1,DATETIME()-{^2000.10.1.12:00PM} 4.关系操作符 关系操作符用于进行关系运算,关系操作符如表 3.6 所示。 ·55·


表 3.6

关系操作符

操作符

<

小于

>

大于

=

等于

<>,#,!=

不等于

<=

小于等于

>=

大于等于

==

字符串精确等于比较

关系操作符没有优先级。 例如,工资>=800,编号<> " " 5.逻辑操作符 逻辑操作符用于进行逻辑运算,逻辑操作符如表 3.7 所示。 表 3.7

逻辑操作符

操作符

.NOT.,!

逻辑非

AND

逻辑与

.OR.

逻辑或

优先级从高到低为:.NOT.,!→.AND.→.OR. 例如,职称="工程师".AND.DATE()-出生时间>35 各操作符之间的优先级如下: 数值操作符,字符操作符,日期操作符→关系操作符→操作符优先级 在同一表达式中,优先级相同的运算符,则按从左到右的次序进行运算。括号()可以 改变运算的优先级,运算时总是先算括号里面的。注意,括号必须成对出现。

3.2.2 常用函数 常用函数有如下几种。 1. 数值函数 LEN(c) 得到字符串 c 的长度(字符数)。 例如: LEN("01002")=5 USE 基本情况 LEN(姓名+职称)=14

INT(n) 例如:

取数值 n 的整数部分。

INT(680.34)=680

RECNO() 例如: ·56·

得到当前记录号。


USE 基本情况 ? RECNO() 值为 1 SKIP ?RECNO()

值为 2

SQRT(n) 求 n 的算术平方根。 2. 字符函数 LEFT(c,n) 取字符串 c 左边 n 个字符。 例如,LEFT("王 红",2)="王" RIGHT(c,n) 取字符串 c 右边 n 个字符。 SUBSTR(c,n1,n2) 取字符串 c 第 n1 个字符开始的 n2 个字符。 TRIM(c), RTRIM(c), LTRIM(c), ALLTRIM(c) 去字符串 c 后面、后面、左、 左右的空格字符。 EMPTY(c) 判断字符串 c 是否为空。 3. 日期函数 DATE() 得到当前日期。 TIME() 得到当前时间字符串。 DATETIME() 得到当前日期时间。 YEAR() 得到当前年的数值。 MONTH() 得到当前月的数值。 DAY() 得到当前日的数值。 4. 数据类型转换函数 STR(n, n1, n2) 将数值转换为字符串。n1 为总长度,n2 为小数位。 例如: STR(1002)="

1002"

STR(编号, 4, 0)= "1002"

VAL(s) 例如:

将数值字符串 s 转换为数值。

VAL("01004")=1004.00 USE 基本情况 VAL(编号)=1002

DTOC(d) 将日期 d 转换为日期字符串。 CTOD(c) 将日期字符串 c 转换为日期。 TTOC(t) 将时间 t 转换为时间字符串。 CTOT(C) 将时间字符串 c 转换为时间。 CHR(n) 得到 n 的 ASCII 码字符。 ASC(c) 得到 c 字符的 ASCII 码。 5. 表操作函数 EOF() 判断是否超出表的末尾。 BOF() 判断是否超出表的首行。 RECCOUNT() 得到表的记录数。 ·57·


FCOUNT() 得到表的字段数。 6.其他函数 FILE(c) 判断 c 文件是否存在。 MESSAGEBOX(提示文本 [,对话框类型 [,对话框标题文本]]) 显示字符串 c。 说明见表 3.8 和表 3.9。 表 3.8

表 3.9

对话框类型功能

对话框类型

返回值

返 回 值

0

仅 OK 按钮

1

OK

1

OK 和 Cancel 按钮

2

Cancel

2

Abort,Retry 和 Ignore 按钮

3

Abort

3

Yes,No 和 Cancel 按钮

4

Retry

4

Yes 和 No

5

Ignore

5

Retry 和 Cancel 按钮

6

Yes

16

Stop 图标

7

No

32

? 图标

48

! 图标

64

i 图标

0

默认第 1 个按钮

256

默认第 2 个按钮

512

默认第 3 个按钮

例如: =MESSAGEBOX("工资报表已经生成!", 0+64, "人员工资情况")

显示结果如图 3.1 左所示。 yes= MESSAGEBOX("是否删除该记录", 4+32, "人员基本情况") ? yes

显示结果如图 3.1 右所示。

图 3.1

MESSAGEBOX 函数

3.2.3 表达式 表达式是由数据元素和操作符适当连接而成的式子。在 VFP 中,数据元素可以是常量、 变量、函数、字段、对象的属性。当然这些数据元素本身就是一个简单的表达式。根据表达 式返回的值的类型,VFP 表达式可分为下列类型。 1.字符串表达式 例如: USE 基本情况 ? 基本情况.姓名+"工资为"+STR(基本情况.工资, 8, 2)

·58·


? 后面的就是字符串表达式。 (1)数值表达式。 例如: #DEFINE PI=3.14159 ? PI*THISFORM.txtR.VALUE^2- PI*8^2

2.日期表达式 例如: ? DATE()+20

3.逻辑表达式 例如: USE 工资情况 LOCATE FOR(LEFT(编号,2)="01".OR. LEFT(编号,2)="04").AND.岗位工资<200

FOR 后的就是逻辑表达式。 4.名称表达式 名称表达式是由圆括号括起来的一个字符串表达式,可以用来替换命令和函数中的名称。 这些名称包括字段名、变量名、窗口名、选单名、文件名和对象名。 【例 Ex_Nexp】名称表达式。 BM="基本情况" GZ="工资" USE("RY!"+BM) REPLACE(GZ)WITH (GZ)+100

5.宏代换 宏代换和名称表达式的作用类似,但宏代换是用“&变量.”替换名称。当宏代换与其他 字符串连在一起使用时要使用"."进行分隔。 【例 Ex_&】宏代换。 KM="RY! " USE &KM.基本情况 GZ="工资" REPLACE &GZ WITH &GZ+100 M.&GZ=&GZ ? M.&GZ

3.3

流程控制

3.3.1 顺序 顺序结构由一系列语句组成,程序运行时按顺序执行语句。例如: OPEN DATABASE RY USE 基本情况 BROWSE

·59·


CLOSE DATABASE

3.3.2 条件分支 条件分支就是如果条件成立,则执行指定的语句序列。条件分支包括 IF 分支和 CASE 分 支。 1. IF 分支 格式: IF 条件 语句序列 1 [ELSE] 语句序列 2 ENDIF

功能: 如果条件成立,则执行语句序列 1,否则执行语句序列 2。 【例 Ex_Equation】 求 ax2+bx+c=0 的方程的解。 求一元二次方程的解公式如下:

x1, 2

图 3.2

(1)设计表单。表单包含下列对象:标签 Label1(Name 属性)~Label5 为信息提示;文 本框 txtA,txtB 和 txtC 分别用于输入 a,b,c 系数,文本框 txtx1,txtx2 放入方程根 x1 和 x2; 一个命令按钮 cmdStart 用于执行计算。界面安 排如图 3.2 所示。 (2)设置对象属性。对象属性如表 3.10 所示。

计算一元二次方程根界面 表 3.10 对 象

计算一元二次方程根对象属性 属 性 名

属 性 值

Form1

Caption

计算方程根

Label1

Caption

a=

Label2

Caption

b=

Label3

Caption

c=

Label4

Caption

x1 =

Label5

Caption

x2 =

txtA

Value

0

txtB

Value

0

txtC

Value

0

cmdStart

Caption

计算

(3)算法分析。方程的根有以下几种可能: a=0,不是一元二次方程。 ·60·

− b ± b 2 − 4ac = 2a


b2-4ac=0,有两个相等的实根。 b2-4ac>0,有两个不等的实根。 b2-4ac<0,没有实数根。 (4)编写代码。 * 计算按钮(cmdOK)的 Click 事件代码: a=Thisform.txtA.Value b=Thisform.txtB.Value c=Thisform.txtC.Value DT=b*b-4*a*c If a!=0.AND.DT>=0 x1=(-b+Sqrt(DT))/(2*a) x2=(-b-Sqrt(DT))/(2*a) Thisform.txtX1.Value=x1 Thisform.txtX2.Value=x2 Thisform.Refresh Else If a=0 Messagebox("a 不能为 0!") Else Messagebox("没有实数解!") Endif Endif

思考:修改上述界面和程序,使其也能计算复根。 2. CASE 分支 格式: DO CASE CASE 条件 1 语句序列 1 CASE 条件 2 语句序列 2 … OTHER 语句序列 n ENDCASE

功能: 从第一个 CASE 开始判断,若条件 i 成立,则执行语句序列 i,然后跳到 ENDCASE 后的 语句。选 OTHERWISE,则在所有 CASE 条件均不满足时,执行其后的语句序列 n。 【例 Ex_CountCJ】统计成绩分数段。 (1)设计表单。表单包含下列对象:标签 Label1~Label2 为信息提示;文本框 txtCJ 用 ·61·


于输入成绩,文本框 txt9~txt5 存放各分数段的统计结果;一个命令按钮 cmdOK 用于执行统 计,输入一个成绩统计一次。界面安排如图 3.3 所示。

图 3.3

成绩分段统计界面

(2)设置对象属性。对象属性如表 3.11 所示。 表 3.11 对 象

成绩分段统计对象属性

属 性 名

属 性 值

Form1

Caption

成绩分段统计

Label1

Caption

请输入成绩

Label2

Caption

>=90 80~89 70~79 60~69 <60

txtCJ

Value

0

Txt9

Value

0

Txt8

Value

0

Txt7

Value

0

Txt6

Value

0

Txt5

Value

0

cmdOK

Caption

确定

(3)编写代码。确定按钮(cmdOK)的 Click 事件代码: cj=Thisform.txtCJ.Value If cj<0.or.cj>100 Messagebox("输入的成绩不正确!") Else Do Case Case cj>=90 Thisform.txt9.Value=Thisform.txt9.Value+1 Case cj>=80.and.cj<90 Thisform.txt8.Value=Thisform.txt8.Value+1 Case cj>=70.and.cj<80 Thisform.txt7.Value=Thisform.txt7.Value+1 Case cj>=60.and.cj<70 Thisform.txt6.Value=Thisform.txt6.Value+1

·62·


Case cj<60 Thisform.txt5.Value=Thisform.txt5.Value+1 Endcase Endif Thisform.Refresh

3.3.3 循环控制 1. FOR 循环 格式: FOR 变量=初值 TO 终值 [STEP 步长] 语句序列 ENDFOR | NEXT 变量

只要变量的值小于等于终值,重复执行循环体中的语句序列。 具体执行步骤如下。 (1)给变量赋初值; (2)判断变量的值是否小于等于终值; (3)若不是,则循环结束; (4)若是,则执行语句序列; (5)变量=变量+步长(若省略 STEP,则步 长=1); (6)转(2)。 【例 Ex_ni】计算 n 的阶乘。 ( 1 )设计表单。表单包含下列对象:标签 Label1~Label2 为信息提示;文本框 Text1 用于输 入 n,文本框 Text2 用于存放 n!的计算结果;一个 图 3.4 计算 n 的阶乘界面 命令按钮 Command1 用于执行计算。界面安排如 图 3.4 所示。 (2)设置对象属性。对象属性如表 3.12 所示。 表 3.12 对 象

计算 n 的阶乘对象属性 属 性 名

属 性 值

Label1

Caption

n=

Label2

Caption

n!=

Tex1

Value

0

Text2

Readonly

.T.

Command1

Caption

计算

(3)编写代码。计算按钮的 Click 事件代码: n=Thisform.Text1.Value If n<=0 Return

·63·


Endif n1=1 For i=1 To n n1=n1*i Endfor Thisform.Text2.Value=n1 Thisform.Refresh

2. WHILE 循环 格式: DO WHILE 条件 语句序列 ENDDO

&& 循环起始及条件语句 && 循环体 && 循环终止语句

只要条件为真,重复执行循环体中的语句序列。 语句序列中遇到退出循环语句 EXIT,则退出循环体,执行 ENDDO 后面的语句。语句序 列中遇到跳转语句 LOOP,则跳过该语句到 ENDDO 之间的语句。 循环语句本身可以嵌套,并且可以与其他控制语句互相嵌套,但不允许有交叉。 这些规则也适用 FOR 循环和 SCAN 循环。 【例 Ex_n!_w】修改 Ex_n!程序,改用 WHILE 循环计算 n 的阶乘。 (1)设计界面(同上)。 (2)设置对象属性(同上)。 (3)编写代码。计算按钮的 Click 事件代码: n=Thisform.Text1.Value If n<=0 Return Endif n1=1 I=1 Do While I<=n n1=n1*I I=I+1 Enddo Thisform.Text2.Value=n1 Thisform.Refresh

3. SCAN 循环 格式: SCAN [范围] [FOR 条件] 语句序列 ENDSCAN

只要当前打开的表范围内满足条件,就执行语句序列。不满足条件或超出范围,退出循 ·64·


环。SCAN 循环能自动跳到下一个记录。 【例 Ex_AverGZ】计算平均技能工资。 (1)设计表单。在例 Ex_EditGZ.scx 表单文件中增加命令按钮(cmdAVER),计算当前显 示的人员所在部门的平均工资。 (2)设置对象属性(同例 Ex_EditGZ)。 (3)编写代码。 * 计算按钮(cmdAVER)的 Click 事件代码: S=0 JS=0 BH=LEFT(编号,2) Scan For 编号=BH S=S+工资情况.技能工资 Thisform.Refresh Wait "" Timeout 1

&&等待 1s

JS=JS+1 Endscan Messagebox("部门编号为"+BH+"的平均工资="+Str(S/JS))

3.4

过程和自定义函数

把经常用到的一段代码独立出来,创建一个过程和自定义函数,这样在程序中多次使用 时不必重复编写代码,直接调用即可。需要对其代码进行修改时,仅需在创建的过程和自定 义函数处进行修改即可。一般来说,一段独立代码完成某个特定功能。 在 VFP 中,过程和自定义函数(UDF)功能基本相同。

3.4.1 过程和自定义函数的定义 过程格式: PROCEDURE 过程名 [PARAMETERS 变量名表] 语句序列 RETURN [返回值]

自定义函数格式: FUNCTION 函数名 [PARAMETERS 变量名表] 语句序列 RETURN [返回值]

子程序格式: [PARAMETERS 变量名表] 语句序列 RETURN [返回值]

·65·


过程和自定义函数分别用 PROCEDURE 和 FUNCTION 语句引导。过程或自定义函数可 存放在下列位置。 (1)一个独立的程序的结束语句后面可同时存放过程或自定义函数,包含该过程或自定 义函数的程序可直接调用该过程或自定义函数。 (2)在一个过程文件中,集中存放多个过程或自定义函数,应先用下列命令打开,其后 所有程序均可调用。 格式: SET PROCEDURE TO [过程文件名表] [ADDITIVE]

系统可同时打开多个过程。选 ADDITIVE,在打开当前过程文件时原先的过程不关闭。 不再使用过程文件时用 RELEASE PROCEDURE 命令关闭指定过程文件。 (3)数据库的存储过程存放过程或自定义函数,打开数据库时这些过程或自定义函数同 时被打开,在打开该数据库后所有程序均可调用。 在 VFP 中,数据库包含的过程称做存储过程。在打开数据库时,数据库中的所有过程被 打开。在数据库的可视状态,右击按钮,选择存储过程可对其中的过程进行编辑。在“项目 管理器”中,存储过程作为数据库的一个成员列出,单击它即可对其进行编码操作。 数 据 库 中 的 过 程 用 COPY PROCEDURE 命 令 拷 出 。 过 程 文 件 也 可 用 APPEND PROCEDURE 命令加入数据库中。 (4)若一个文件存放一个自定义函数或过程的代码,则也可使用子程序格式,这时文件 名就是子程序名,并称该程序为子程序。程序的任何位置均可调用该子程序。 为方便起见,有时自定义函数或过程统称为子程序。

3.4.2 自定义函数和过程的调用 可以用下列语句调用自定义函数。 1. DO 调用 格式: DO 自定义函数名 [WITH 表达式表] WITH 表达式表用于向自定义函数传递参数

2. 函数方式调用 格式: [变量名]=函数名(表达式表)

表达式表用于向自定义函数传递参数。采用这种方式调用自定义函数,要求自定义函数 中用 RETURN 返回值,返回值就是函数的值。 【例 Ex_DoP】自定义过程。 * MAIN PROGRAM 1 num=6 JC=0 DO CAL WITH num ? "6!=",JC JC=0

·66·

&& 显示 6!=

720


=CAL(num) ? "6!= ",JC

&& 显示 6!=

720

CANCEL

PROCEDURE CAL PARAMETER n If n<=0 Return Endif JC=1 i=1 Do While i<=n JC=JC*i i=i+1 Enddo RETURN

【例 Ex_Fun】自定义函数。 * MAIN PROGRAM 2 num=6 JC=CAL(num) ? "6!=",JC

&& 显示 6!=

720

? "6!=",CAL(num)

&& 显示 6!=

720

CANCEL

FUNCTION CAL PARAMETER n If n<=0 Return -1 Endif JC=1 i=1 Do While i<=n JC=JC*i i=i+1 Enddo RETURN JC

·67·


3.4.3 参数传递方法 自定义函数要接收调用程序的参数,在自定义函数中的第一个语句应为 PARAMETERS。 格式: PARAMETERS 变量名表 LPARAMETERS 变量名表

其中“变量名表”中变量的个数和位置顺序必须与调用程序参数传递的“表达式表”的 个数和位置顺序相同。实际传递的参数个数可用 PARAMETERS()函数得到。在 VFP 中, 参数传递有下列两种方法。 (1)按引用方式传递。调用程序通过引用方式向过程传送变量和数组。如果在被调用的 过程中一个值被改变,则新的值被传送回调用程序的相关的变量或数组中。 (2)按赋值方式传递。如果要通过赋值方式向过程传送变量或数组,被调用的过程中任 何参数的改变都不会传送到调用程序相关的变量或数组中。 默认情况下,变量通过引用传送到一个过程,通过赋值传送到用户定义的函数(UDF) 。 如果通过引用把变量传送到用户定义的函数中,则使用下列命令。 格式: SET UDFPARMS TO REFERENCE

按引用

SET UDFPARMS TO VALUE

按值

但是,不管设置成何种方式,如在传递时在变量两边加“() ”则为传值方式,在变量前 加“@”则为传地址方式。 【例 Ex_UDF】参数传递演示程序。 SET UDFPARMS TO VALUE X=1 =INC(X) MESSAGEBOX("X="+STR(X))

&& 显示 X=1

X=1 =INC(@X) MESSAGEBOX("X="+STR(X))

&& 显示 X=2

SET UDFPARMS TO REFERENCE X=1 =INC(X) MESSAGEBOX("X="+STR(X))

&& 显示 X=2

X=1 =INC((X)) MESSAGEBOX("X="+STR(X)) ************** FUNCTION INC PARAMETER TEMP TEMP=TEMP+1

·68·

&& 显示 X=1


RETURN TEMP

3.5

变量的作用范围

变量的作用范围遵循下列规则。 (1)子程序使用调用程序中的变量。调用程序中使用的内存变量可以在被调用的程序中 直接引用和修改。 (2)公用变量。在所有程序中都可使用和重新赋值的变量称为公用变量。公用变量用下 列语句定义。 格式: PUBLIC 变量名表 | ARRAY 数组名表

变量名表既可以是一般内存变量,也可以是数组。若是数组,则必须同时指定它的最大 下标,并且数组名前也可加 ARRAY 说明。实际上,在定义这些变量(包括数组)为公用变 量的同时,它们本身就同时被定义(它们的初值为.F.) 。对于数组也就不要再用 DIMENSION 进行定义了。 (3)局部变量。仅本程序使用的变量称为局部变量。局部变量仅在本程序中定义,可以 与调用它的程序中使用的变量同名,但不会对其产生影响。当退出该程序后,局部变量就被 释放。局部变量用下列语句定义。 格式: PRIVATE 变量名表 | ARRAY 数组名表 | ALL LIKE 结构 | ALL EXCEPT 结构

变量名表既可以是一般内存变量,也可以是数组。若是数组,数组名前可加 ARRAY 说 明,但不必同时指定它的最大下标。不过,在定义这些变量(包括数组)为局部变量的同时, 它们本身并没有同时被定义,对于数组仍需用 DIMENSION 进行定义。 用 PRIVATE 命令定义局部变量的程序调用的子程序中仍可使用和对其进行修改。但以下 命令定义的局部内存变量在其调用的子程序中不能使用和修改。 格式: LOCAL 变量名表 | ARRAY 数组名表

局部内存变量在数组赋值之前定义,局部内存变量和数组只能在创建它们的过程和函数 内部使用和修改,而不能被调用它或它调用的程序中访问。一旦包含局部内存变量和数组的 过程或函数执行完毕,该局部内存变量和数组被释放。 局部变量可通过引用方式进行传递。 【例 Ex_EditXY】变量的作用范围。 Public X X=1 Y=1 Do EditXY Messagebox("X="+str(X))

&& 显示 X=2

Messagebox("Y="+str(y))

&& 显示 Y=1

Cancel

·69·


Procedure EditXY Local Y X=2 Y=2 Return

3.6

数据库的存储过程和触发器

1.数据库的存储过程 数据库的存储过程是数据库的一部分,存放在数据库的容器(文件)中。数据库中为什 么要用存储过程及使用很多方便的存储过程?因为存储过程随着数据库的打开而自动打开, 随着数据库的关闭而自动关闭。这样我们可以把操作本数据库有关的程序放入存储过程中, 而且不同的数据库中可用同样的名字存储过程表示不同功能。否则我们只能放在程序文件 (PRG)中或放在过程文件中。 数据库的存储过程作为数据库表触发器是存储过程的一个典型应用。 数据库的存储过程的编辑:打开数据库,右键出现操作数据库的选单,选择“编辑存储 过程” ,即打开文本编辑器,如图 3.5,图 3.6 所示。

图 3.5 数据库

图 3.6

·70·

数据库存储过程


2.数据库表触发器 编辑数据表的基本操作就是插入、修改和删除记录。如果不用数据库表触发器,那么, 凡是涉及编辑数据表的程序都要进行合法性控制,要修改原来的控制思想就很麻烦。用数据 库表触发器可以从源头抓一道必经之路,就不会遗漏修改。修改维护十分方便! 可以把编辑数据表的程序合法性控制的程序作为存储过程写在数据库中,这样操作使 用都方便,思路也清楚。图 3.6 是 RY 数据库的工资情况触发器的设置情况。其中:函数 uf_ insert()是插入触发器;函数 uf_update()是更新触发器;函数 uf_delete()是更新触发器。 它们的代码在 RY 数据库的存储过程中,如图 3.7 所示。

图 3.7

数据库的表触发器设置

下面通过对工资情况表的操作过程进一步理解数据库中的存储过程和触发器。 【例 Ex_UF】数据库的存储过程和触发器。 * 触发器测试程序 PUBLIC UNAME NAME="LIHONG" USE RY! 工资情况 BROWSE

(RY 数据库的工资情况记录内容如图 3.8 所示。) 删除最后一条记录(TEMP,则执行 UF_DELETE() ,显示是否删除对话框)。 (选择是,UF_DELETE()返回.T.,前面出现删除标记。)

APPEND BLABK (调用 UF_INSERT() ,该命令插入时能使编号为空,所以返回.F.,操作不成功!) INSERT INTO RY!工资情况 (编号,姓名)VALUE("06999","林时用") (调用 UF_INSERT() ,该命令插入时能使编号不为空,所以返回.T.,操作成功!) UPDATE RY!工资情况 SET 编号="06100" WHERE 姓名="林时用" (调用 UF_UPDATE() ,命令修改时 UNAME!= "ADMIN",所以返回.F.,操作不成功!) UNAME="ADMIN" ·71·


UPDATE RY!工资情况 SET 编号="06100" WHERE 姓名="林时用" (调用 UF_UPDATE(),命令修改时 UNAME="ADMIN",所以返回.F.,操作成功!)

图 3.8 工资情况

·72·


第4章 表 4.1

面向对象的程序设计

1. 概述 传统的结构化程序设计是自顶向下的功能设计,按照事先编排的顺序,对功能进行逐步 分解后进行程序设计。结构化程序设计通过顺序、条件分支和循环 3 种控制流程进行编程。 但是随着软件规模的扩大、功能提高和需求变化,结构化程序设计的开发效率和维护问题比 较突出。 面向对象(Object)的程序设计即 OOP(Object Oriented Program)是近年来发展起来的 一种新的程序设计方法。面向对象的设计方法是按照人们的习惯思维方式建立模型,模拟客 观世界。客观世界是由一系列具有动作的对象构成的,一个复杂的对象包含若干个简单的对 象,每个对象都具有的一些性质、执行的一些操作和对应的一些动作。例如,日常生活中的 气球这个对象,可以看到的性质有气球形状和颜色,可以有上升和下降的动作,另外气球对 充气、放气的响应是形状变大和缩小。对象所具有的性质称为对象的属性;对象所执行的一 些操作称为对象的方法;对象所对应的动作称为对象的事件。对象之间通过消息进行联系。 VFP 是面向对象的数据库程序设计语言,VFP 应用程序的用户界面一般是由表单、选单 和控件等对象构成的,各个对象之间的联系完全取决于用户所做的操作。也就是说,程序的 运行并没有固定的顺序。VFP 采用事件驱动的方式,通过编写“事件”的程序代码,为对象 规定了被某个“事件”激活时对应的动作以及所要进行处理的具体内容,由各个对象编写的 事件代码集合在一起,就构成了应用程序。 再看第 1 章的【例 Ex_CricleA】,如图 4.1 所示。

图 4.1 计算圆面积

用户界面由 1 个表单、2 个标签、2 个文本框和 1 个命令按钮组成,这些都是对象。用鼠 标单击“计算”命令按钮,就产生了该命令按钮的 Click 事件,它的 Click 事件中的程序被执 行。具体的代码如下: R=THISFORM.TEXT1.VALUE THISFORM.TEXT2.VALUE=3.14159*R*R

一般事件中的代码是由若干个语句组成的一段程序,这里仅需计算圆的面积并将结果在 ·73·


文本框中显示出来,所以仅用 2 个语句即可。VALUE 是文本框的一个属性,通过该属性可得 到用户在文本框中输入的值。将值赋给该属性,就能在该文本框中显示这个值。 2. 类、基类和子类 类(Class)是对象外观和行为的模板,对象是类的一个实例。类是一个抽象的概念,对 象是一个具体的东西。例如, “汽车”就是一个类,它包含了汽车这个类的共同特征(例如: 型号、发动机排量、外观尺寸、颜色等),而对于“桑特纳 2000”,则是汽车这个类的一个具 体实例。日常生活中会涉及到各种类,例如,房子、蔬菜、学校,等等。 在 VFP 中,为了实现常用功能,系统提供了一些类称为基类(BaseClass) ,子类是在已 有类的基础上进行修改而形成的类。子类所依托的类称为父类(ParentClass) 。用户还可根据 需要自定义类。 系统提供的基类工具栏(图标)如图 4.2 所示,在打开表单设计界面时自动打开该工具 栏。 系统提供的基类对应的基类名如表 4.1 所示。 表 4.1 基类名称 名 称

图 4.2

基类工具栏

基 类 名

表单

Form

标签

Label

文本框

TextBox

编辑框

EditBox

命令按钮

CommandButton

命令按钮组

CommandGroup

单选按钮组

OptionGroup

检查框

Check1

列表框

ListBox

复选框

ComboBox

微调框

Spinner

表格

Grid

图像

Image

定时器

Timer

页框

PageFrame

线条

Line

形状

Shap

容器

Container

是否容器 √

VFP 中提供的基类可分为容器类和控件类两大类。 (1)容器类。容器类是可以包含其他类的基类,将容器类的对象加入表单后,无论在设 计时还是在运行时,既可以将容器类的对象作为一个整体进行操作,也可以分别对其容器中 包含的对象进行处理。容器类及其可包含的对象如表 4.2 所示。 表 4.2

容器类及其包含的对象

容 器 类

·74·

可 包 含 的 对 象

容器

任意控制

工具栏

任意控制、页框、容器

表单集

表单、工具栏

表单

页框、容器或用户自定义对象、任意控制


续表 容 器 类

可 包 含 的 对 象

页框

页面

页面

任意控制、容器或用户自定义对象

表格

表格列

表格列

标头及除表单集、表单、工具栏、定时器和其他列以外的任意对象

命令

命令按钮

选项按钮组

选项按钮

(2)控件类。控件类是可以包含在容器类中的基类。控件类的封装比容器类更为严密, 但也因此丧失了一些灵活性。控件类对象不能作为其他对象的父对象。 在打开表单设计器时,表单控件工具栏同时打开,工具栏中的控件就是系统提供的基类。 用户选择控件放入自己的表单上,这个控件就变成了一个具体的对象。此后就可修改对象的 属性,编写该对象所关注事件的代码。 子类是对其他类(称为父类)经过修改而得到的类,它将继承任何对父类所做的修改。 下面分别说明 VFP 的对象、对象的属性、对象的方法和对象的事件。 3. 对象 对象通过对象名引用对象。对象名由该对象的 Name 属性指定,在创建对象时系统首先 赋给一个默认的对象名,例如,建立的第 1 个文本框对象名为 Text1,第 2 个文本框为 Text2, 依次类推。为了编程时方便阅读,用户一般应修改成有意义和一看就明白是何意思的名称。 由于容器可以包含容器类和控件类对象,这就产生了一种层次结构。VFP 在类层次结构 中对象的引用则是由上向下逐层引用的,而由下逐层向上查找事件代码。掌握了类的层次结 构,才能够准确地在容器中调用方法或使用对象的属性。所以引用对象时要在引用的对象名 前一层一层地冠以它所在的容器的对象名,就好像定位文件时指定的路径一样。引用对象有 下列两种方法。 (1)绝对引用。绝对引用就好像定位文件时指定的绝对路径一样,须从包含该对象的最 外面的容器对象名开始,一层一层进行。 格式: [表单集名.]表单名.[容器对象名…]对象名

例如: Form1.txt 编号.Value FormSet1.Form1.PageFrame1.Page1.Grid1.Column1.Text1.Value

同时包含多个表单的容器称做表单集。另外,系统还有一个屏幕对象_SCREEN, _SCREEN 对象的属性用于设置屏幕属性。_SCREEN 的方法用于在屏幕上操作。 (2)相对引用。相对引用就好像定位文件时指定的相对路径一样,仅需从当前位置开始。 系统相对引用的关键字及意义如表 4.3 所示。 表 4.3 名

相对引用名

THIS

当前操作对象

THISFORM

当前操作的表单

THISFORMSET

当前操作的表单集

Parent

当前对象的直接容器

·75·


续表 名

ActiveForm

当前活动表单

ActivePage

当前活动页

ActiveControl

当前具有焦点的控件

例如: THIS.Value THIS.Parent.Text1.Value THISFORM.txt 编号.Value

下面是几种相对引用的方法:引用本身对象的属性、方法和事件用“THIS”;使用与本 身对象处于同一容器中的对象使用“THIS.Parent.引用对象名”;引用当前表单中的对象用 “THISFORM.[容器对象名…] 引用对象名”。 应用程序对象(_VFP)的 ActiveForm,ActiveControl 属性允许在不知道表单名或控件名 的情况下处理活动的表单或控件。例如,下列代码改变活动表单的背景颜色,而不考虑其所 属的表单集。 _VFP.ActiveForm.BackColor=RGB(255,255,255)

用户只能在方法程序或事件代码中使用 THIS,THISFORM 和 THISFORMSET。 (3)连续设置多个属性。使用 WITH…ENDWITH 结构可以一次为对象设置多个属性。 With 结构如下所示。 格式: With 对象 语句块 End With

使用 With 结构可以对某个对象执行一系列的语句,而不用重复指出该对象的名称。例 如,在表单中,要设置表格列的多个属性,在 With 结构中进行属性的赋值如下。 WITH THISFORM.Grid1.Colormn1 .Width=5 .Resizable=.F. .ForeColor=RGB(0,0,0) .BackColor=RGB(255,255,255) SelectOnEntry=.T. ENDWITH

当程序一旦进入 With 块,对象就不能改变。因此不能用一个 With 语句来设置多个不同 的对象,但 With 块可以嵌套。 4. 对象的属性 属性是对象的数据,用来表示对象的状态。属性有属性值,改变对象的属性值就可以改 变对象的状态。属性的设置可以设计时在“属性”窗口中完成,也可以在运行时由代码来实 现。在运行时可设置的属性称为读写属性,只能读取的属性称为只读属性。对象属性引用方 法格式如下。

·76·


格式: 对象引用.属性名

VFP 对象的常用属性如表 4.4 所示。 表 4.4

对象的常用属性

属 性

Name

对象引用名

Caption

标题文本

Value

存放的值

ForeColor

设置对象的前景颜色和背景颜色

BackColor 指定文本显示字体名和字体大小。与字体有关的属性还有:

FontName FontSize

FontBold—黑体;FontItalic—斜体;FontStrikeThru—空心体; FontOutline—轮廓;FontShadow—阴影;FontUnderline—下划线

Enabled

是否允许用户操作

Visible

是否可见

ReadOnly

是否只读 指定对象的高度、宽度和起点位于容器左边和上边的单位距离。度量单位由 ScaleMode

Height,Width Left,Top

指定

ControlSource

确定对象的数据源。一般为表的字段名 对象在表单中 Tab 键的选取顺序或页上控件的选取顺序。TabStop 属性为假,将 TabIndex

TabIndex

设定的顺序 ToolTipText

当鼠标指针移至该对象时显示的提示信息

Comment

注释

VFP 所有容器对象都具有与之相关的集合属性和计数属性。集合属性是一个数组,可用 它引用包含的对象。计数属性值表示它包含的对象的个数。VFP 容器对象的集合属性和计数 属性如表 4.5 所示。 表 4.5 容器对象的集合属性和计数属性 容

集 合 属 性

计 数 属 性

_SCREEN

Forms

FormCount

表单集

Forms

FormCount

表单

Controls

ControlCount

页框

Pages

PageCount

页面

Controls

ControlsCount

表格

Columns

ColumnsCount

命名组

Buttons

ButtonsCount

选项组

Buttons

ButtonsCount

Controls

ControlsCount

工具栏

Controls

ControlsCount

容器

Controls

ControlsCount

控制

Controls

ControlsCount

5. 对象的方法 对象的方法决定了对象要执行的操作,方法中的代码是不可见的,可以通过调用来使用 对象的方法。对象方法的引用方法如下。

·77·


格式: 对象引用.方法属性名

或 对象引用.方法属性名([参数名表])

例如,调用 THISFORM.Release 方法用于释放当前执行的表单。有返回值的方法必须用 圆括号结尾,传递给方法的参数必须将参数放在方法名后面的括号中。例如,下列方法为在 表单上画一条线。 THISFORM.Line(n 起点 X,n 起点 Y,n 终点 X,n 终点 Y) 下列方法为激活表格 Grid1 对象的 nRow 行和 nCol 列单元: THISFORM.Grid1.ActivateCell(n 行,n 列) 系统定义的方法用户也可以自行编写代码以取代原来的功能。 VFP 对象的常用方法如表 4.6 所示。 表 4.6 事

对象的常用方法

Refresh

刷新对象的屏幕显示

SetFocus

把焦点移至该对象

SetAll(属性,值[,类])

为容器中所有(或某类)控件的属性设置值

6. 对象的事件 对象的事件是对象的动作和行为。VFP 中对象的事件可通过用户操作、程序代码或系统 触发。只有当事件发生时,事件的程序才会运行。如果没有事件发生,则整个程序就处于停 滞状态。 VFP 对象的常用事件如表 4.7 所示。 表 4.7 事

常用事件

Click

鼠标单击事件

DblClick

鼠标双击事件

RightClick

鼠标右击事件

在对象上移动鼠标时产生的事件 MouseMove

参数:鼠标状态,ShihtCtrlAlt 状态,x 坐标,y 坐标 其中,鼠标状态为鼠标与键值之和。左键值为 1,右键值为 2,中键值为 4。 ShihtCtrlAlt 状态为三键值之和:Shift 值为 1,Ctrl 值为 2 ,Alt 值为 4

MouseDown

当鼠标按下时产生的事件

MouseUp

当鼠标释放时产生的事件

DragDrop

当鼠标拖动对象到目标对象时在目标对象上产生的事件。 参数:被拖动的对象名,x 坐标,y 坐标 当鼠标拖动对象通过目标对象时在目标对象上产生的事件。

DragOver

参数:被拖动的对象名,x 坐标,y 坐标,状态 其中:状态就以 0 为进入,1 为离开,2 为经过 当单击一键时产生的事件。

KeyPress

参数:键 ACSII 码,ShihtCtrlAlt 状态 其中,ShihtCtrlAlt 状态为三键值的和。Shift 值为 1,Ctrl 值为 2,Alt 值为 4

InteractiveChange

当交互改变控件值时产生的事件

ProgrammaticChange

当程序改变控件值时产生的事件

GotFocus

当对象得到焦点时产生的事件

·78·


续表 事

LostFocus

当对象失去焦点时产生的事件

When

当对象得到焦点前产生的事件

Valid

当对象失去焦点前产生的事件

Resize

当调整对象大小时产生的事件

Activate

当激活表单、表单集、页和工具栏对象时产生的事件

DeActivate

当一个容器对象不再处于活动状态时产生的事件

Destry

当对象释放时产生的事件

VFP 编程的核心就是为每个要处理的事件编写响应事件的过程代码。对象的事件名在代 码窗口的过程列表框中单击下拉箭头进行选择。 虽然对象能识别的事件很多,但用户一般只用到几个常用的事件,例如命令按钮 (CommandButton)常用的就是单击(Click)事件。用户没有编写代码的事件,系统会以默 认的方式来处理。 在程序中也可触发事件,程序触发事件相当于调用该事件的代码执行。 格式: 对象引用.事件名

例如,THISFORM.Command1.Click 调用 Command1 对象的 Click 事件程序。下面说明几 种情况下事件的触发顺序。 (1)启动时表单及表单控件触发的顺序见表 4.8。 表 4.8 启动时表单及表单控件触发的顺序 对

数据环境

BeforeOpenTables

表单、表单集和报表中的数据环境包含的表或视图打开前触发

表单集

Load

创建表单集前触发

表单

Load

创建表单前触发

数据环境临时表

Init

创建数据环境临时表时触发

数据环境

Init

创建数据环境时触发

表单中的控件

Init

从内层的对象到外层容器创建时触发

表单集

Activate

当激活表单集对象时触发

表单

Activate

当激活表单对象时触发

对象

When

从内层的对象到外层容器,从 Tab 键次序中的第 1 个对象开始,在控 件接收焦点之前触发

表单

GotFocus

当对象接收焦点时触发

对象

GotFocus

从内层的对象到外层容器,对象接收焦点时触发

对象

Message

从内层的对象到外层容器,对象得到焦点后触发

(2)当失去焦点时的事件触发顺序: Valid 事件→LostFocus 事件→DeActivate 事件。 (3)表单释放时事件触发的顺序: →表单(Form)的 QueryUnload 事件; →表单集(FormSet)的 Destry 事件→表单的 Destry 事件→控件的 Destry 事件; →表单的 UnLoad 事件→表单集的 UnLoad 事件; →数据环境(Dataenvironment)的 AfterCloseTables 事件; ·79·


→数据环境的 Destry 事件→数据环境的临时表 Destry 事件。

4.2

创建表单

表单在 VFP 中是一个容器,它可以容纳 Visual FoxPro 的对象。在程序运行时,表单是 用户与应用程序之间进行交互的窗口。VFP 通过表单设 计用户的交互界面。选择“文件”选单→新建→选“表 单”→显示如图 4.3 所示的对话框。 选择“新建表单”则系统显示一个空白的表单。用 户即可在这个空白的表单上进行设计。 选择“表单向导”则一步一步询问数据库和表→选 择表单中显示的表字段→选择控件显示的格式→系统 自动生成表单及控件对象。 图 4.3 “新建表单”对话框 表单设计器用于交互创建表单(用户界面)。表单 设计器就像画图时提供的一张纸,画图时还需要其他工具配合方可。用表单设计器设计用户 界面时还需要系统的表单设计工具。在打开表单设计器时,表单设计器工具栏、表单控件工 具栏和属性窗口自动被打开。同时,系统自动地增加了一个“表单”选单栏,在显示选单栏 自动增加了设计表单时要用到的许多选单项。用户可根据需要选择相应的选单项打开其他工 具栏或窗口。下面分别介绍各工具栏、属性窗口和选单的作用。 也可使用“CREATE FORM 表单名”命令新建空白表单,已经建立的表单用“MODIFY FORM 表单名”打开表单进行交互修改。 1. 表单设计器工具栏 表单设计器工具栏,如图 4.4 所示,用于打开表单设计时需要用到的表单设计工具和功 能。此时显示选单栏中的选单项与表单设计器工具栏中的项目基本相同,但操作工具栏更方 便一些。 表单设计器工具栏从左到右的图形按钮功能如下。 (1)设置 Tab 键的次序:在表单中的各个对象的左上方显示用 Tab 键选择操作对象时的 顺序,这个顺序是进入表单的先后顺序,也是系统执行时初始化各对象的顺序。用户可在该 状态改变这个顺序以满足需要。对于【例 Ex_CricleA】 ,选择该键的次序显示如图 4.5 所示。

图 4.4

表单设计器工具栏

图 4.5 Tab 键的次序显示

(2)数据环境:用于设置在表单中要用到的数据库和表。 (3)属性窗口:用于设置对象的属性、选择对象的方法和事件。 (4)代码窗口:用于切换至对象的事件和方法的编辑代码窗口。 ·80·


(5)表单控件工具栏:用于显示系统内部提供的表单控件。表单控件工具栏如图 4.6 所示。

图 4.6

表单控件工具栏

(6)调色板工具栏:用于设置对象(例如文本框、标签等)的背景色。先选择对象,然 后选择调色板工具栏的指定颜色。调色板工具栏如图 4.7 所示。 (7)布局工具栏:用于以表单中的对象进行重新排列。先选择对象,然后选择排列图形 按钮。布局工具栏如图 4.8 所示。

图 4.7

调色板工具栏

图 4.8

布局工具本栏

(8)表单生成器:根据用户选择的表按当前默认的格式在当前表单中自动生成字段对象。 (9)自动格式:改变当前表单中控件对象的外观显示格式。 2. 表单中控件的布局 对表单中控件的布局改变有如下几种方式。 (1)选择表单控件。单击表单控件可选择该控件;按住 Ctrl 键不放再单击表单控件,可 同时选择多个控件。拖动鼠标,在表单上画一个区域,该区域内的所有控件被选择。 当表单中包含多层容器对象时,按右键后选择“编辑”选单项即可从外到内进入容器中, 从而可选择容器中的对象。 (2)增加表单控件。单击表单控件工具栏的控件,光标移至表单中该控件的位置,单击 或拖动鼠标画出该控件的大小后松开。 (3)移动表单控件。单击要移动的控件并拖动到指定位置,或者单击控件用方向键移动。 (4)改变表单控件大小。鼠标指针放到控件的边缘和右下角处,待鼠标指针形状变化时 进行拖动,或者单击控件,按住 Shift 键不放,用方向键移动。 (5)删除控件。选择要删除的控件,按 Del 键。 (6)从数据环境拖放对象。设置数据环境,打开数据环境,从数据环境中拖动表的字段 到表单中。 (7)控件布局。先选择对象,然后选择排列图形按钮。控件布局包括上下左右对齐、对 中、等宽、等高、放至后面、放至前面等方面。 3. 表单的数据环境(DataEnvironment) 表单中的数据环境是一个容器,用于设置表单中使用的表和视图以及表单所要求的表之 ·81·


间的关系。这些表和视图及表之间的关系都是数据环境容器中的对象,可以分别设置它们的 属性。在表单被执行时,数据环境中设置的表和视图自动被打开,表之间的关系自动被建立。 当表单被释放时,数据环境中设置的表和视图自动被关闭。 数据环境通过数据环境设计器进行设置,选择“显示”→选择“数据环境”或在表单中 按右键→选择“数据环境”即可打开数据环境设计器,如图 4.9,图 4.10 所示。

图 4.9

选单打开数据环境

图 4.10

右键打开数据环境

(1)向数据环境添加表或视图。在数据环境设计器中按右键→选择“添加”→选择表或 视图。 (2)数据环境移去表或视图。在数据环境设计器中选中要移去表或视图→按右键→选 择“移去”。 (3)在数据环境中设置关系。如果加入数据环境的表具有在数据库中设置的永久关系, 则这些关系自动带入到数据环境中。如果表中没有永久关系,则可在数据环境进行设置表之 间的临时关系。若要在数据环境设计器中设置临时关系,可在主表中拖动字段到相关表中相 匹配的索引标识上。在数据环境设计器中设置了一个关系后,在表之间就有一条连线指示这 个关系(对象) 。若要编辑这个关系的属性,先选中这条连线,按右键在快捷选单中选择“属 性”这个选单项即可,如图 4.11 所示。

图 4.11

编辑这个关系的属性

数据环境中设置的关系是临时关系,表单执行时建立,表单释放后不再存在。 ·82·


4.3

表单的属性、事件和方法

1.表单的属性 表单属性定义表单对象的特征或行为。表单及其包含的对象的属性通过“属性”窗口定 义和修改。表单的属性窗口如图 4.12 所示。 在“属性”窗口包含对象列表框和页框,页框中包含 5 个选项卡。每个选项卡由属性设 置框和属性列表和项目说明文本框几个部分组成。表单的所有属性分成数据、布局和其他 3 类,分别放入相应的选项卡中。同时表单的方法和事件放入方法程序选项卡中。表单的所有 属性、方法和事件均放在“全部”选项卡。所有项目按英文字母次序排列。 当前表单文件

对象选择列表框

对象属性分类页

对象属性设置部分

对象属性选项列表

对象属性说明框

图 4.12 表单的属性窗口

(1)对象选项。对象选项是一个下拉列表框,采用分层方式显示表单及包含在表单中的 所有对象。选择某个对象后,在属性列表框中所显示的均是对应于该对象的各种属性及方法 程序。 (2)分类页。分类页的作用是按照分类的形式显示属性、事件和方法程序。每一页及其 功能如下。 ① 全部:用于显示所选表单或其他对象的所有属性、事件和方法程序。 ② 数据:用于显示有关对象如何显示或怎样操纵数据的属性。 ③ 方法程序:用于显示有关对象的事件和方法程序。 ④ 布局:用于显示所有的布局属性。 ⑤ 其他:用于显示其他和用户自定义的属性。 ·83·


(3)属性设置部分。属性设置部分包括如下 3 个命令按钮和对象属性的设置框。 ① ×:取消属性值的修改。 ② √:确认属性值的修改。 ③ fx:自动生成属性。 ④ 属性值输入文本框。 属性值输入有下列几种情况:系统出现输入文本框,则在文本框直接输入属性值; 对于那些可被设置为表达式的属性,则在文本框先输入等号“=”标记,后面再写表达 式,系统用表达式的值作为属性值。例如 ForeColor 属性可输入"255,0,0",也可输入 "=RGB(255,0,0)"。如果该属性值可通过浏览确定,则在该文本框后会有 … 命令按 钮,用户也可单击它通过浏览选择确定属性值。例如,命令按钮的 Picture 属性,可直接 输入“D:\VFP98\FOX.BMP”,也可通过 … 浏览选择图像文件名及文件路径。对于具 有预定值的属性,则系统会出现一个组合框,用户可用右边下拉箭头进行选择,也可以在 属性列表中双击属性名遍历所有的可选项。例如,BorderStyle 属性,它共有 4 种属性值。在 此属性上双击,在遍历属性值的过程中选取所需要的值。而对于仅有两个预定值的属性(例 如 ReadOnly 只有.T.与.F.两种取值),只需在属性列表中双击属性名即可在两者间切换。 (4)属性选项列表。属性选项列表是一个包含两列的列表,它显示了所有可在设计时更 改的属性和他们的当前值。在属性框中以斜体显示的属性值表明那些属性、事件和方法程序 是只读的。当对于某些属性的属性及其他特性不明白它们的意义时,选择该属性并按 F1 键可 得到此属性的帮助信息。 需要某属性的系统默认值。可以在“属性”窗口,单击鼠标右键,然后在属性快捷选单 中选择“重置为默认”命令,就可以设置属性的默认值。表单的常用属性如表 4.9 所示。 表 4.9 属 性

表单的常用属性

默 认 值

Caption

Form1

指定表单标题栏的显示文本

Name

Form1

指定表单对象名,在程序设计中可以通过引用表单对象名来引用表单

BorderStyle

3

MaxButton MinButton

.T. .T.

WindowState

普通

AlwaysOnTop

.F.

AutoCenter

.F.

控制表单初始化时是否让表单自动在 Visual FoxPro 主窗口中居中

Movable

.T.

控制表单是否能移动到屏幕的新位置上

Visible

.T.

指定表单等对象是可见的还是隐藏的

Closable

.T.

控制用户是否能够通过双击“关闭”框来关闭表单

ScaleMode

像素

控制表单的尺寸和位置的度量单位

WindowType

无模式

0—无模式,用户不必关闭表单就可访问其他界面;

决定表单边框 0—无边框;1—单线边框;2—固定对话框;3—可调边框 控制表单是否具有最大化按钮和最小化按钮 控制表单是普通(0),最小化(1),最大化(2)。 如 WindowState 为 2,则 MaxButton,MinButton,BorderStyle 属性将不起作用 控制表单是否总是处在其他打开的窗口之上。也就是防止所引用的表单被其 他的表单所覆盖

控制表单是无模式还是模式表单 1—模式,用户必须关闭表单方可访问其他界面 CurrentX CueeentY

·84·

当前绘图 x,y 方向坐标。其值随下列方法而改变。 Cls—0,0;Box—终点坐标;Line—终点坐标;Circle—圆心;Pset—绘图点; Print—下一个打印位置


续表 属 性

默 认 值

DataSession

控制表单(集)能否在自己的数据工作期中运行。

1

1—数据工作期;2—私有数据工作期,每个表单(集)都有独立的数据环境

2.表单的事件 表单的常用事件如表 4.10 所示。 表 4.10 表单的常用事件 事

触 发 时 间

Active

当一个表单变成活动表单时触发

DeActivate

表单从活动变成不活动时触发

Init

当表单第 1 次创建时触发,一般将表单的初始化代码放在其中 创建表单前触发,事件发生在 Init 事件之前。因为此时表单中的任何控件尚未建立,所

Load

以该事件代码不能处理表单控件

UnLoad

释放表单时触发,该事件发生在 Destry 事件之后

Click

在鼠标单击表单时触发

DblClick

在鼠标双击表单时触发

Destroy

当释放对象时触发

Error

当方法中有一个运行错误时触发

3.表单的方法 表单的常用方法如表 4.11 所示。 表 4.11 表单的常用方法 方

Release

从内存中释放表单或表单集

Refresh

重新绘制表单或控件,并更新所有的值

Hide Show

设置 Visible 属性为.F.来隐藏表单(集) ,使表单(集)不可见,但未从 内存中清除 设置 Visible 属性为.T.来显示表单(集) ,使表单(集)变为活动对象。 参数:1—模式;2—无模式(默认)

Move

移动一个对象

Draw

重新绘制表单对象

AddObject

在运行时给容器对象增加一个对象

SaveAs

将对象存入 SCX 文件中

Cls

清除一个表单中的图形和文本

Pset

给表单上的一个点设置指定的颜色

Line(起点 x,起点 y,终点 x, 在指定位置绘制直线 终点 y) 在指定位置画方框。其他参数由下列属性指定: Box([起点 x,起点 y,]终点 x,终点 y)

度量单位—ScaleMode;线宽—DrawWith; 方式—DrawMode;风格—DrawStyle; 填充颜色—FillColor;填充风格—FillStyle; 略起点,则以 CurrentX,CurrentY 作为起点

Circle(半径,圆心[,纵横比])

在表单上画一个圆或一段圆弧。其他参数同 Box

Print

在表单对象上显示一个字符串

·85·


4. 表单文件的执行和关闭 表单文件的执行和关闭有如下几种。 (1)在表单设计器中直接执行表单。按右键,在快捷选单中选择“执行表单”,或者在表 单选单中选择“执行表单”选单项。 (2)在程序中调用执行。在表单设计器中直接执行表单用于系统开发阶段,组成系统时, 表单一般在程序中调用执行,调用命令如下。 格式: DO FORM 表单文件名| ? [NAME 表单名 [LINKED]] [WITH 参数表] [TO 变量名] [NOREAD]

其中,NAME 表单名是指定执行的表单的名字,以后引用该表单时使用这个名。LINKED 可用来链接表单和相关联的变量,当变量超出作用域时,释放表单。 WITH 参数表用于向表单的 INIT 事件代码传递参数。如果执行的是表单集,则表单集的 WindowType 为 0(无模式)或 1(模式),参数表用于向表单集的 INIT 事件代码传递。 TO 变 量 名 接 收 表 单 UnLoad 事 件 的 RETURN 的 语 句 的 返 回 值 。 但 要 求 表 单 的 WindowType 为 1(模式)。 NOREAD 创建并显示表单集, 在执行 READ 前不激活控制, 但要求表单集的 WindowType 为 2(读) 。 (3)激活事件处理。 格式: READ EVENTS

只有执行了 READ EVENTS 命令,VFP 才启动事件处理。当执行 CLEAR EVENTS 命令 后,系统停止事件处理。 (4)关闭表单。 格式: 表单引用名.RELEASE

5.创建新属性和新方法 创建新属性和新方法的步骤如下。 (1)创建新属性。打开表单→选择“表单”选单→选择“新建属性”选单项→系统显示 下列“新建属性”对话框,如图 4.13 所示。

图 4.13

“新建属性”对话框

在名称框中输入属性名,同时可在说明框中加上该属性的注释,选择“添加”即可。如 果新建数组属性,则在输入属性名的同时定义数组的维数和最大元素个数。例如 ·86·


TEMP_DAT[50,2],如图 4.13 所示。但新建的数组属性在设计时为只读,在执行时为可读写。 选择 Access 项和 Assign 项,则在新建表单属性的同时创建该属性对应的方法程序,其中 Access 方法程序在查询该属性时被执行,Assign 方法程序在修改该属性时被执行。 (2)创建新方法程序。打开表单→选择“表单”选单→选择“新建方法程序”选单项→ 系统显示下列“新建方法程序”对话框,如图 4.14 所示。

图 4.14

“新建方法程序”对话框

输入方法程序名称后选择“添加”即可。方法程序代码应在“属性”窗口的“方法程序” 选项卡选择方法程序名双击,在编辑器中编辑方法程序。新建方法程序的执行方法与系统提 供的方法程序相同。 顺便说明一下,若要在 “表单设计器”中为 Visual FoxPro 的原有属性创建 Access 或 Assign 方法程序,在“新建方法程序”对话框的“名称”文本框中输入其原来的属性后面接 _Access 或_Assign 即可。例如,若要创建 Left 属性的 Access 方法程序,只需在“名称”文本框中输 入“Left_Access” ,选择“添加” ,将创建原有属性的 Access 或 Assign 方法程序即可。但是, 在“表单设计器”中,只能为表单或表单集创建带有 Access 和 Assign 方法程序的属性。如果 需要为控件或对象创建带有 Access 和 Assign 方法程序的属性,则可使用类设计器。在“类设 计器”中,将带有 Access 和 Assign 方法程序的属性添加到控件或对象中,然后在“表单设计 器”中将控件或对象添加到表单中。 (3)编辑属性/方法程序。打开表单→选择“表单”选单→选择“编辑属性/方法程序” 选单项,可修改和移去新建属性和方法。 6. 创建单文档和多文档 VFP 允许创建单文档和多文档两种类型的应用程序界面。单文档界面由一个或多个独立 的窗口组成,它们在 Windows 的桌面上独立显示。多文档界面由单一的主窗口组成,应用程 序窗口包含在主窗口中或浮动在主窗口的顶端。VFP 本身就是一个多文档窗口,VFP 主窗口 中包含各种设计器窗口、编辑窗口、命令窗口等。 VFP 通过设置表单的 ShowWindow 属性和 Desktop 属性实现单文档和多文档的功能。 ShowWindow 属性和 Desktop 属性及功能如表 4.12 所示。 表 4.12 ShowWindow 属性

ShowWindow 属性和 Desktop 属性 能

Desktop 属性

0

在屏幕中

.T.

表单可放在桌面的任何位置

1

在中

.F.

表单放在 VFP 主窗口中

2

作为顶层表单

改变 ShowWindow 和 Desktop 属性,可创建下列 3 种类型的表单。 ·87·


(1)子表单。设置 ShowWindow 为 0 或1,Desktop 为.F.。该表单包含在父表单中,子 表单不能移出父表单。子表单不出现在 Windows 的任务栏中,最小化时只出现在父表单的底 部。父表单最小化时子表单同时最小化。 (2)浮动表单。设置 ShowWindow 为 0 或1,Desktop 为.T.。该表单属于父表单,但可 在整个桌面上移动。浮动表单最小化时出现在屏幕底部。父表单最小化时浮动表单同时最小 化。 (3)顶层表单。设置 ShowWindow 为 2,既可作为单文档界面,又可作为多文档界面中 的父表单。 7. 表单的多个实例 表单的多个实例是指同一个表单同时被执行了多次。这些表单虽基于同一个定义,但却 可以独立地显示和操作。 对于需拥有多个实例的表单,应将表单的 DataSession 属性设置为 2,系统自动为每个实 例建立独立的数据环境。为了方便多个实例的表单的管理,启用表单时应使用数组作为表单 对象的引用名,用下标区分不同实例。

4.4

表单应用举例

【例】在主程序 Ex_Main1 中调用表单 Ex_EditGZ 执行。 在 Ex_EditGZ 表单的 Destroy 事件中加入: THISFORM.Release CLEAR EVENTS

编辑 Ex_main1.prg 中程序,代码如下: SET DEFAULT TO D:\RY_MIS DO FORM EX_EditGZ READ EVENTS CLEAR CLOSE ALL

执行 Ex_Main1.PRG

·88·


第5章 控

控件是面向对象程序设计的基本操作单元。系统提供的控件在表单中用于获取用户的输 入,显示输出信息。只有熟练掌握控件的使用,开发 VFP 应用程序才能得心应手地面向对象 的程序设计。 在 VFP 中,为了实现常用功能,VFP 提供的标准类型 控件共有 19 个,是系统内部提供的类(称为基类) 。系统 提供的基类在“表单控件”工具栏中,在打开表单设计界 面时系统自动打开该工具栏,如图 5.1 所示。 VFP 中提供的基类可分为容器类和控件类两大类。容 器类本身有自己的属性、方法和事件。同时,容器类可以 包含其他对象,容器对象相对引用它包含的对象可用 图 5.1 表单控件工具栏 “THIS.对象名”。而被包含的对象相对引用容器类对象用 “THIS.Parent” 。 VFP 为不同的控件定义了不同的属性、方法和事件。使用控件与使用表单相似,控件的 命名规则与表单的命名规则相同,控件的很多属性、方法和事件也与表单相类似。下面分别 介绍系统提供的表单控件及其属性、方法和事件。

5.1

标签

标签用于显示文本,一般用于提示信息。显示文本的格式由标签的属性设置。常用属性 如表 5.1 所示。 表 5.1 属

标签常用属性

Caption

显示文本内容,最多允许 256 个字符

BackStyle

0—透明:可看到标签后的东西;

指定背景是否透明 1—不透明:背景由标签设置 AutoSize

指定是否可自动调整标签的大小

WordWrap

显示是否可换行

Alignment

指定文本在标签中的对齐方式: 0—左;1—右;2—中央

通过上述属性与标签的其他属性配合一般能够满足提示信息的各种要求,同时还能产生 许多特殊效果。 【例 Ex_TextMove】“欢迎”在屏幕上移动,如图 5.2 所示。 (1)设计表单设置属性。在表单上设计一个标签,属性如下: Caption=欢迎 FontName=楷体_GB2312 FontSize=48

·89·


FontBold=.T. ForeColor=255,0,0 Alignment=2

(2)编写事件代码。 * 标签的 Click 事件代码: DO WHILE .T. FOR I=1 TO THISFORM.WIDTH step 10 THIS.LEFT=I =INKEY(1)

&&延时 1s

NEXT I ENDDO

用标签产生特殊效果的办法如下。 (1)字排多行。在需换行的地方加 Chr(13)回车符。例如 Caption="欢"+Chr(13)+ "迎"。 如果要改变字的方向,设 FontName 属性为带 @ 的字体名。 (2)字从小到大。用一个循环不断改变标签的 FontSize,同时调整 Top 和 Left 的属性值, 每次增加一个值,直到最大时停止。 THIS.Top=THISFORM.HEIGHT/2-THIS. FontSize/2

(3)立体字。设计两个标签,将另一个标签的相对位置略加移动,ForeColor 设置不同的 颜色,就可产生立体字的效果,如图 5.3 所示。

图 5.2 “欢迎”在屏幕上移动

图 5.3

“欢迎”立体字

文本框和编辑框

5.2

文本框(TextBox)用于显示、输入和修改数据。常用属性如表 5.2 所示。 表 5.2 属

文本框常用属性 作

PassordWordChar

口令字符。此属性赋值后,文本框中的内容均用此内容显示,但实际内容并没有变化

ReadOnly

是否只读。设置为只读属性后,文本框只能显示 Value 内容,不能进行交互修改

Value

存放值。设计时可用此属性赋初值。初值类型决定文本框的数据类型

·90·


续表 属

控制输入数据格式和显示方式。参数及意义如下: 输入:X—任何字符;9—数字和+-号;#—数字和+-号和空格;

InputMask

显示:$—货币符号;$$—浮点货币符号;*—数值左边显示"*"; . —指示小数点位置;,—小数点左边的数字用" ,"分隔 指定 Value 属性数据输入输出数据格式。参数及意义如下: A—字符(非空格标点);D—当前日期格式;E—BRITISH 日期数据; K—光标移入选择整个内容;L—数值数据加前导 0; M—InputMask 属性中可放入输入选

Format

项表; T—去头尾空格;! —转换为大写字母; ^—用科学计数法显示数据;$—显示货币符;R—屏蔽字符不放入控制源中 ControlSource

指定与文本框绑定的数据源

SelStart

文本框中被选择的文本的起始位置

SelLength

文本框中被选择的文本的字符数

SelText

文本框中被选择的文本内容

SelectOnEntry

当文本框得到焦点时是否自动选中文本框中的内容

例如,将 Value 属性设置为{},文本框的内容将会自动转变为 VFP 系统默认的日期格式。 表 5.3 列出了文本框与处理日期有关的属性。 表 5.3 文本框与处理日期有关的属性 属

公元纪年采用 4 位还是 2 位。 Century

0—不显示世纪部分;1—显示世纪部分 ; 2—由 SET CENTURY 命令决定是否显示世纪部分

DateFormat

日期显示格式

StrictDateEntry

日期格式检查方式

DateMark

设置日期类型的分隔符号,比如“/”

编辑框(EditBox)与文本框的功能类似,也是用于显示、输入和修改数据。其区别是文 本框一般为一行,输入的内容放不下会自动向左移动。当文本框的 ControlSource 与表字段数 据源绑定时不能放内容太长的字段或备注字段。而编辑框则为若干行一个区域,当编辑框的 ScrollBars 属性设为.T.,还可包含滚动条,因此更适合编辑较多的文本内容。 另外,IntegralHeight 属性可控制编辑框的高度是否自动调整,以便其最后一项能被完整 显示。 文本框与编辑框有时会用到下列事件。 When 事件:在得到焦点之前发生; GotFocus 事件:在得到焦点时发生; Valid 事件:在失去焦点之前发生; LostFocus 事件:在失去焦点后发生。 例如,可在 When 事件代码中保存文本框的原内容,可在 Valid 事件代码中验证文本框数 据输入内容的正确性。Valid 事件中的 RETURN 返回.F.,则焦点不会移开。表单释放时忽略 RETURN 值的影响。 【例 Ex_Login】 在主程序 Ex_txt1 中先调用表单 Ex_Login 进行用户登录,如果用户名 和口令正确,调用表单 Ex_EditGZ 执行。 (1)设计表单设置属性。表单包含下列对象:标签 Label1~Label2 作为信息提示;文本 ·91·


框 txtName 用于输入登录名;文本框 txtPassWord 用于输入口令;一个命令按钮 cmdOk 用于 确定登录用户;一个命令按钮 cmdExit 用于退出登录。界面安排如图 5.4 所示。

图 5.4

用户登录界面

(2)设置属性。口令文本框(txtPassWord)属性 PasswordChar=* (3)编写代码。 *

表单的 Activate 事件代码:

THIS.txtPASSWORD.Enabled=.f.

&&输入登录名后才能输入口令

THIS.txtNAME.SetFocus

&&启动后先输入登录名

*

txtNAME 文本框 KeyPress 事件代码:

LPARAMETERS nKeyCode,nShiftAltCtrl IF nKeyCode=13.AND.!EMPTY(THIS.VALUE) &&输入登录名后按回车键即进入输入口令 THISFORM.txtPASSWORD.Enabled=.t. THISFORM.txtPASSWORD.SetFocus ENDIF * "确定(cmdOK)" 按钮的 Click 事件代码: UNAME=THIS.PARENT.txtNAME.VALUE Yes=.F. DO CASE CASE Uname="ZHANG".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="123456" Yes=.T. CASE Uname="WANG".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="681266" Yes=.T. ENDCASE IF Yes Messagebox("登录成功!") ELSE Messagebox("用户名或口令不对!") ENDIF THISFORM. Release CLEAR EVENTS * "退出(cmdExit)" 按钮的 Click 事件代码:

·92·


THISFORM.Release CLEAR EVENTS * Ex_txt1.prg 程序代码: PUBLIC YES SET DEFAULT TO D:\RY_MIS DO FORM Ex_LOGIN READ EVENTS IF YES DO FORM Ex_EditGZ READ EVENTS ENDIF CANCEL

【例 Ex_TextCopy】将左边编辑框中的选择内容复制到右边文本框中。也可在左边编辑 框自动选择与右边文本框内容相同的部分。 (1)设计表单。表单包含下列对象:左边编辑框 Edit1,右边文本框 Text1,中间一个命 令按钮 Command1,如图 5.5 所示。

图 5.5

文本框内容复制界面

(2)设置对象属性。对象属性如表 5.4 所示。 表 5.4 文本框内容复制对象属性 对 象

属 性 名

属 性 值

Edit1

Format

K

Edit1

Value

VFP 6.0 是 MicroSoft 公司的关系数据库管理系统

Command1

Caption

->

(3)编写事件代码。 * "->(Command1)" 按钮的 Click 事件代码: THIS.Parent.Text1.Value=THIS.Parent.Edit1.SelText * 编辑框 Edit1 的 GotFocus 事件代码: :GotFocus EditBox:

·93·


str1=Trim(This.parent.Text1.Value) d=At(str1,This.Value) If d>0 This.SelStart=d-1 This.SelLength=Len(str1) Else This.SelLength=0 Endif

用户可观察和操作: (1)启动后左边编辑框的内容全部被选择。 (2)用户可在左边编辑框重选部分内容后,单击“->”命令按钮,则选择的内容在右边 编辑框中出现。 (3)在右边编辑框重新输入左编辑框中包含的部分内容,单击左编辑框,看其与右边编 辑框相同的内容是否自动被选择。

5.3

命令按钮和命令按钮组

命令按钮(CommandButton)通常用来完成某些功能。例如移动表记录、数据查询操作、 打印报表、释放表单等。 当一个表单需多个命令按钮时,也可使用命令按钮组(CommandGroup) ,这样可使事件 代码更简洁、界面更整齐。命令按钮组中各命令按钮的排列方向和位置根据用户需要进行调 整。操作次序如下: (1)选择命令按钮组; (2)按右键,在快捷选单中选择“编辑”; (3)单击命令按钮后根据用户需要进行调整。 也可在属性窗口的对象选择列表框中直接选择命令按钮组中各命令按钮对象名。 命令按钮(组)常用属性如表 5.5 所示。 表 5.5 命令按钮(组)常用属性 属 性

Caption

标题文本。含“\<字符”,输入该字符可选择该命令按钮

Picture

标题图像

Default

.T.—回车键可选此命令按钮

Cancel

.T.—Esc 键可选此命令按钮

Value*

命令按钮组中被选命令按钮序号

ButtonCount*

命令按钮组中命令按钮个数

从上面属性表看出,命令按钮标题既可以是文字,内容由 Caption 属性指定,也可以是 图像,图像文件名由 Picture 属性指定。3 个命令按钮的效果如图 5.6 所示。 下面说明上述表单中 3 个命令按钮属性设置的情况。 (1)Caption="确定",单击该按钮可执行 Click 事件代码。 (2)Caption="\<C 取消",Cancel=.T.,单击该按钮、单击 C 键、Esc 键均可执行 Click 事 ·94·


件代码。

图 5.6

命令按钮标题的 3 种情况

(3)Picture="d:\vfp98\fox.bmp",单击该按钮可执行 Click 事件代码。 命令按钮中用得最多的事件为 Click,命令按钮组中也有 Click 事件。当单击命令按钮组 中的命令按钮时,如本身包含 Click 事件代码,就执行该代码。如本身不包含 Click 事件代码, 则执行命令按钮组 Click 事件代码。 【例 Ex_EditGZ_Gcmd】将 Ex_EditGZ 表单(第 2 章)中的命令按钮换成命令按钮组, 对比使用方法。 (1)修改界面。修改后的界面如图 5.7 所示。

图 5.7

命令按钮组实例

其中,CommandGroup1 命令按钮组容器包含 5 个命令按钮:Command1~Command5, 见表 5.6。 表 5.6 命令按钮组实例对象属性 对

属 性 名

属 性 值

CommandGroup1

ButtonCount

5

CommandGroup1

AutoSize

.T.

Command1

Caption

第一个

Command2

Caption

上一个

Command3

Caption

下一个

Command4

Caption

最后一个

Command5

Caption

退出

* CommandGroup1 的 Click 事件代码: sel=This.Value DO CASE

·95·


CASE sel=1 GO TOP CASE sel=2 IF !BOF() SKIP -1 ENDIF CASE sel=3 IF !EOF() SKIP ENDIF CASE sel=4 GO BOTTOM ENDCASE THISFORM.REFRESH * 退出(Command5)的 Click 事件代码 THISFORM.Release

【例 Ex_Edit1】按人员编号增、删、改基本情况数据。 (1)设计表单界面。新建表单→打开数据环境→将 RY 数据库中的工资情况表添加到数 据环境中→拖动数据环境的工资情况表的字段到表单中。 建立文本框 txtBH 用于输入定位人员的编号,建立定位(cmdLOCATE) 、追加和删除 3 个命令按钮。界面如图 5.8 所示。

图 5.8

增、删、改基本情况数据界面(1)

(2)设置对象属性。设置 TxtBH 的属性 InputMask=99999。 观察字段文本框的 ControlSource 的属性如下: txt 编号. ControlSource=基本情况.编号 txt 姓名.ControlSource=基本情况. 姓名 txt 出生时间.ControlSource=基本情况. 出生时间

·96·


(3)编写代码。 *

"定位"命令按钮的 Click 代码:

bh=Trim(This.Parent.txtBH.Value) jlh=recno() Locate For 编号=bh If Eof() Go jlh =MessageBox("没有找到该编号!") Else Thisform.Refresh Endif

*

"追加"命令按钮的 Click 代码:

Append Blank Thisform.Refresh

*

"删除"命令按钮的 Click 代码:

yn=Messagebox("是否要删除?",4+32)**未曾提过 If yn=6 Delete If Eof() Go top Else Skip Endif Thisform.Refresh Endif

(4)可进一步考虑的问题。 在 TxtBH 文本框中按回车键也可进行记录定位。 * TxtBH 文本框的 VALID 事件代码 IF !EMPTY(THIS.VALUE) THIS.PARENT.cmdLOCATE.Click

&& 按回车键启动定位事件代码

ELSE RETURN .F.

&& TxtBH 文本框为空不能离开

ENDIF

5.4

列表框和组合框

列表框(ListBox)主要用来选择一组预定的数据,当选项内容在列表区域显示不下时, 可通过滚动条浏览列表的其他选项。组合框(ComboBox)和列表框的功能类似,但使用更灵 ·97·


活。实际上,组合框是由一个文本框和下拉列表框组成的。列表框在屏幕占用一个区域,而 组合框则占用一行。 列表框(组合框)常用属性如表 5.7 所示。 表 5.7 列表框(组合框)常用属性 属 性

RowSource

列表选项内容从何处得到(来源)

RowSourceType

列表选项内容来源的类型,详见注 1

DisplayValue

选择值

BoundColumn

在列表框包含多项时指定哪一列作为 Value 属性的值

ColumnCount

行源列数

List(i)

i 行值

Selected(i)

i 行是否被选上

MultiSelect

是否可同时选多项

MoverBars

项目是否可移动

Sorted

当 RowSourceType 为 0 和 1 时,列表项是否按字母大小排序 指定组合框的类型。参数如下:

Style

0—下拉组合框,也可在文本框直接输入;2—下拉列表框,只能下拉选择 IncrementalSearch

确定在键盘操作时是否支持增量搜索。值为.T.,当用键盘选择列表项,用户按一个键, 系统将自动定位到与输入字母相应的项前

注 1(RowSourceType 可指定值): 0—无,运行时用 AddItem 和 AddListItem 方法加入。 1—值,直接写在该属性中。 2—表的别名,由 ColumnCount 确定表中选择的字段。当用户选择列表时,记录指针将自动移到相应的记录上。 3—SQL 语句,由执行的结果产生。 4—查询文件名,由执行该文件的结果产生。 5—数组名。 6—字段名表,可用“表别名.”作为字段前缀。当用户选择列表时,记录指针将自动移到相应的记录上。 7—文件名描述框架,可包含“*”, “?” 描述在列表中显示的文件名。 8—结构。 9—弹出式选单,提供向后兼容。

列表框常用方法如表 5.8 所示。 表 5.8 属 性

列表框常用方法 作

AddItem

增加数据项

RemoveItem

移去数据项

Clear

移去所有数据项

Requery

当 RowSourceType 为 3 和 4 时,根据 RowSource 中的最新数据重新刷新列表项

如列表框或组合框包含多列,则 ColumnCount 属性为列数,ColumnWidths 属性为列的宽 度,BoundColumn 属性确定被选列表的哪一列作为 Value 属性的值。 另外,IntegralHeight 属性可控制列表框的高度是否自动调整,以便其最后一项能被完整 显示。 【例 Ex_List】列表框选择多个项目练习。 (1)设计界面,如图 5.9 所示。 ·98·


图 5.9 设计界面

(2)设置对象的属性。 List1 对象的属性: MoverBars=.T. MultiSelect=.T.

(3)编写事件代码。 *

List1 对象 LostFouce 事件:

qm="" FOR I=1 TO THIS.ListCount IF THIS.Selected(I) qm=qm+Trim(This.List(I))+"," Endif Next I Messagebox(qm)

*

"加入->" 命令按钮 Click 事件:

QM=This.Parent.Text1.Value If !Empty(QM) No=.T. For I=1 To This.Parent.List1.ListCount If This.Parent.List1.List(I)=QM No=.F. Endif Next I If No This.Parent.List1.AddItem(QM) Thisform.Refresh Endif Endif *

"<-移去" 命令按钮 Click 事件:

This.Parent.List1.Clear

·99·


【例 Ex_Edit2】按人员编号增、删、改基本情况数据。 (1)设计表单界面。修改增、删、改基本情况数据界面,如图 5.10 所示。

图 5.10

增、删、改基本情况数据界面(2)

(2)设置对象属性。 “文化程度”组合框: ControlSource=基本情况.文化程度 RowSourceType=值 RowSource=研究生,本科,大专,高中,初中 Style=2

&& 只能选择列表项

“职称”组合框: ControlSource=基本情况.职称 RowSourceType=值 RowSource=政工师,工程师,助工

5.5

选项按钮组

选项按钮组是包含选项按钮的容器控件。一般一个选项按钮组可包含多个选项按钮,其 特点是组中仅有一个选项按钮被选中,当前选项按钮被选中,先前选中的被释放。圆点指示 当前被选中的选项按钮。选项按钮组中各选项按钮的排列方向和位置根据用户需要进行调整。 例如,

选择选项按钮组中选项按钮操作次序如下。 (1)选择选项按钮组; (2)按右键,在快捷选单中选择“编辑”; (3)单击选项按钮后根据用户需要进行调整。 也可在属性窗口的对象选择列表框中直接选择命令按钮组中各选项按钮对象名。选项按 钮组的常用属性如表 5.9 所示。

·100·


表 5.9 属

选项按钮组的常用属性

ButtonCount

设置选项按钮组的数目

Caption

设置选项按钮组的标题

ControlSource

确定选项按钮组的数据来源

DisableForeColor

确定选项按钮失效时的前景颜色

DisableBackColor

确定选项按钮失效时的背景颜色

选项按钮组中的 ButtonCount 属性指定选项按钮的个数,选项按钮组的 Value 属性指定哪 一个选项按钮被选中。如 ButtonCount 属性设置为 6,而 Value 属性设置为 2,则表示选项按 钮组共有 6 个选项按钮,当前选中第 2 个按钮。 选项按钮组中各选项按钮的 Caption 属性为各选项按钮的提示信息,Value 属性为选项按 钮是否被选中。Value 为 1 表示当前的选项按钮被选中,否则为 0。 选项按钮组中的 ControlSource 属性与表的字段绑定后,运行时选中选项按钮的 Caption 属性值被送入字段中。 【例 Ex_Edit2】按人员编号增、删、改基本情况数据。 (1)设计表单界面。修改增、删、改基本情况数据界面,如图 5.11 所示。

图 5.11

修改增、删、改基本情况数据界面(3)

(2)设置对象属性。 “性别”选项按钮组(OptionGroup1)有 2 个选项按钮(Option1, Option2) Option1.Caption=男 Option2.Caption=女

(3)编写代码。 *“性别”选项按钮组(OptionGroup1)的 Valid 事件: If This.Value=1 Replace 基本情况.性别 With "男" Else Replace 基本情况.性别 With "女" Endif

实际上,上述“性别”选项按钮组 Valid 事件代码的功能仅需通过设置 ControlSource=基 ·101·


本情况 .性别即可实现。

复选框

5.6

复选框通常代表独立的逻辑值。复选框由一个方框和标题说明组成。一般情况下,用空 框来表示该选项未被选定,当用户选定某一选项时,与该选项对应的方框中会出现打勾符号。 复选框的常用属性如表 5.10 所示。 表 5.10 属

复选框的常用属性

确定复选框的数据来源,一般为表的逻辑字段 字段值为.T.,则复选框被选中;字段值为.F.,则复选框未被选中;

ControlSource

字段值为.NULL.,则复选框以灰色表示 表示当前复选框的状态。0—未选中;1—选中;2—禁用。

Value

也可设置.T.为选中;.F.为未选中;.NULL.或 NULL 为禁用

Caption

指定复选框的标题

Picture

设置一个图像作为复选框的标题 确定显示风格。

Style

0—标准状态;1—图形状态

DisableForeColor

确定失效时的前景颜色

DisableBackColor

确定失效时的背景颜色

复选框 3 种显示格式如图 5.12 所示。

图 5.12 3 种显示格式

复选框可通过 ControlSource 属性与表的逻辑型字段进行绑定。例如,上例的婚否字段。 复选框是彼此独立的,在一个表单中用户可以设置多个复选框,在选择时,可以选择其 中的一个或多个、甚至全部,也可以一个都不选。

5.7

页框和页

页框(PageFrame)是页面(Page)的容器。页框定义了页面的大小、位置、边框类型和 活动页面等总体特性。一个页框可包含若干个页面,而页面本身也是一个容器。一个页面又 可包含若干个对象,通过页面,大大展宽了表单的大小,并方便分类组织对象。页框中通过 页面标题选择页面,当前被选中的页面就是活动页面。 页框常用属性如表 5.11 所示。 表 5.11 页框常用属性 属

·102·

PageCount

页数

ActivePage

指定活动页面


续表 属

Tabs TabStyle

指定页面标题是否显示,见图 5.13 中的形式 4。 指定页面标题排列方式,见图 5.13 中的形式 1, 2。 0—两端排列;1—非两端排列 页面标题内容较长时指定所有页的标题排列方式,见图

TabStretch

5.13 中的形式 3。 0—单行排列;1—多行排列

页框页标题属性的不同设置的效果如图 5.13 所示。

图 5.13

页框页标题的不同效果

对于形式 4 的页框,还可用 SpecialEffect 属性(0—凸起;1—凹下;2—平面)设置形式, 用 BorderWidth 属性设置边宽,用 BorderColor 属性设置边颜色(在 SpecialEffect=2 时有效)。 页面通过 Caption 属性设置标题文本。在每一个页面上可加入不同的对象,但只有活动 的页面对象被显示。同时还可在页面区域的表单上加入对象。但要让其显示出来,必须在属 性窗口的对象选择列表框中先选中表单中的对象,然后单击布局工具栏的“置前”图形按钮。 不管活动页面如何切换,置前操作后的表单对象都会显示。实际上,对各页面上共同的对象 可以用这种方法。 页面上加入和选择对象步骤:先选择页框→按右键→在快捷选单中选择“编辑”→选择 页面→选择页面上的对象。也可在属性窗口的对象选择列表框中直接选择。 页面中对象的完整引用层次如下: THISFORM(或表名).页框名.页名.页面对象名。 但是,有时用相对引用更方便。下面说明几个可能的引用情况。 (1)同一页面的不同对象引用: THIS.PARENT.引用对象名

(2)不同一页面的对象引用: THIS.PARENT.PARENT.引用对象名

【例 Ex_Edit3】按人员编号增、删、改基本情况数据。 (1)设计表单界面。修改增、删、改基本情况数据界面,如图 5.14 所示。 上述界面上,使 TxtBH、定位、追加、删除等对象放在表单上。 加入数据环境,如图 5.15 所示。 数据环境中两表的关联:拖动基本情况关联字段“编号”到工资情况以“编号”作为关 ·103·


键字的索引。

图 5.14

增、删、改基本情况数据界面(4)

图 5.15

两表的关联数据环境

(2)设置对象属性。 页框(PageFrame1)属性: PageCount=2 ActivePage=1

页(Page1 和 Page2)属性: Page1.Caption=基本情况 Page2.Caption=工资情况

5.8

表格

表格(Grid)类似一个浏览器,是按行和列操作和显示的容器。一个表格对象包含若干 列(Column)对象,每一个列对象包含一个表头(Header)对象和一个或多个列数据操作对 象。表头对象用于列的标题的显示内容和格式,数据操作对象是对列数据进行操作时所选用 的控件。系统一般自动加入一个文本框对象作为列数据操作对象,用户可加入其他控件对象。 例如某列对象与表中逻辑字段绑定,如在该列中以检查框的形式编辑和显示,则应在列中加 入一个检查框(Check)控件。一个列中如有一个以上的数据操作对象,则应设置列对象的 ·104·


CurrentControl 属性,确定当前使用哪一个。 表格对象常用属性如表 5.12 所示。 表 5.12 属

表格对象常用属性

ColumnCount

列数。如 ColumnCount 为-1,运行时表格将具有和记录源中字段一样多的列

DeleteMark

是否有删除标记列 表格中显示记录的类型(记录源类型)。参数如下:

RecordSourceType

0—表;1—别名;2—查询(.QPR);3—提示;4—SQL 说明 RecordSource

对应 RecordSourceType 的名称(记录源)

ChildOrder

与父表主关键字相连的子表中的外部关键字

LinkMaster

表格中显示子表的父表

表格对象常用方法如表 5.13 所示。 表 5.13 方

表格对象常用方法

ActivateCell(行,列)

激活指定单元

AddColumn(列号)

在指定位置添加一列,但 ColumnCount 属性值不变

AddObject

在列中添加对象

列对象常用属性如表 5.14 所示。 表 5.14 列对象常用属性 属

ContolsSource

列控制源

CurrentControl

列接收和显示数据使用的控件

CurrentControl 指定的控件是否影响整个列。 Sparse

.T. —只有在列中的活动单元才以 CurrentControl 指定的控件接收和显示数据,其他单元用文本框显示 .F. —列中所有单元均以 CurrentControl 指定的控件显示数据,活动单元接收数据

另外列可用 InputMask,Format 和 Alignment 等属性控制数据的输入内容、显示格式和对 齐方式。如要进行有条件的格式编排,可使用一组动态格式设置属性。例如, DynamicFontName、DynamicFontSize、DynamicForeColor 设置动态字体、字号和颜色。 表头对象常用属性如表 5.15 所示。 表 5.15 属

表头对象常用属性

Caption

列标题文本

Alignment

列标题文本的对齐方式

在表格中不仅能显示字段数据,还可以在表格的列中嵌入文本框、复选框、下拉列表框、 微调按钮和其他控件,例如,如果表中有一个逻辑字段,当运行该表单时,使用复选框显示 记录值“真”(.T.) 、“假”(.F.)更直观,修改这些值只需设置或清除复选框。 用户可以在“表单设计器”中交互地在表格中增删列和在列中交互式添加控件和删除已 加入列的控件。 ·105·


(1)表格中列的选择。 ① 选择表格对象→按右键→在快捷选单中选择“编辑”→进入表格内对象的编辑。 ② 单击表头即选择该列中的表头对象。单击列的非表头区即选择该列对象。 ③ 可设置列的 ControlSource 为相应的字段名。 (2)表格中列的增删和移动。选择表格中的列,按 Del 键即删除该列。列删除后表格的 ColumnCount 属性值会自动减一。要增加列,仅需改变 ColumnCount 属性值。要改变列的相 对位置,仅需选择列的表头拖动。 (3)在列中添加控件。 ① 选择表格中的列。 ② 选择表单控件工具栏中的控件,然后单击列对象,则该控件便加入到该列中。 ③ 设置该列的 CurrentControl 属性为新加入的控件名。此时,在该列中可看到该控件的 显示图标。 (4)删除列中控件。 ① 在“属性”窗口的“对象”框中选择要移去的控件。 ② 单击表格或表单标题,按下 Delete 键即可删除该控件。 除了交互式地向表格列添加控件外,也可以通过编写代码在运行时添加控件。使用 AddColumn 方法向表格中添加列;AddObject 方法在表格列中添加对象;RemoveObject 方法 删除表格中的对象。设置 AllowHeaderSizing 和 AllowRowSizing 属性为.T.,使运行时可改变 表头和行的高度。 表格对象包含 3 层,表格中对象的完整引用层次如下: 表格上层引用.表格名.列名.表头名 表格上层引用.表格名.列名.操作数据对象名 也可根据以上层次关系进行相对引用。 【例 Ex_Grid】按姓名和部门过滤编辑基本情况数据。 (1)设计表单界面。将基本情况表和部门工资表加入数据环境,姓名和部门过滤编辑表 单界面如图 5.16 所示。

图 5.16

·106·

姓名和部门过滤编辑表单界面


(2)设置对象属性。 Grid1.RecordSourceType=别名 Grid1. RecordSource=基本情况 Grid1.ColumuCount=8 Column1.ControlSource=基本情况.编号 Column1. Header.Caption=编号 …

部门组合框属性: Name=cboBM cboBM.RowSourceType=字段 cboBM.RowSourceT=部门工资.部门名称

姓名文本框属性: Name=txtName

确定命令按钮属性: Name=cmdOk

(3)编写代码。 *

“确定”命令按钮 Click 事件:

If !Empty(This.Parent.txtName.Value) Set filter to 基本情况.姓名=Trim(This.Parent.txtName.Value) This.Parent.grdJB.Refresh Return Endif If !Empty(This.Parent.cboBM.Value) bm=Trim(This.Parent.cboBM.Value) Select 部门工资 Locate For 部门名称=bm bmbh=部门编号 Select 基本情况 Set Filter To Left(基本情况.编号,2)=bmbh This.Parent.grdJB.Refresh Return Endif

关于表格,有下列问题需进一步说明。 1. 设置数据源 (1)设置表格记录源。选择表格,然后选择“属性”窗口的 RecordSourceType 属性。如 果让 VFP 打开一个表,那么则将 RecordSourceType 属性设置为“0—表” 。如果打算在表格中 放入打开表的所有字段,则将 RecordSourceType 属性设置为“ — 1 别名”,然后选择 RecordSource 属性,键入作为表格记录源的别名或表名。 (2)设置列数据源。如果在列中显示一个指定字段,那么可以为列单独设置其数据源。 ·107·


首先选择将要设置数据源的列,然后选择其“属性”窗口的 ControlSource 属性。设置其值为 相应的字段名。 2.添加记录 将表格的 AllowAdNew 属性设置为“真”(.T.) ,便可以允许用户向表格显示的表中添加 新的记录。当用户选中了最后一个记录,并且按下向下箭头键时,表中就会添加一个新记录。 如使用 APPEND BLANK 或 INSERT 命令来添加新的记录,应将 AllowAdNew 属性设置为默 认值( “假”) 。 3. 创建一对多表单 表格最常见的用途之一是当表单中的文本框显示父记录数据时,表格显示表的子记录; 当用户在父表中浏览记录时,表格子记录显示相应变化。 如果表单的数据环境包含两表之间的一对多关系,那么要在表单中显示这个一对多关系 非常容易。 (1)具有数据环境的一对多表单。 ① 从“数据环境”中的父表将需要的字段拖动到表单中。 ② 从“数据环境”中将相关的表拖动到表格中。 (2)没有数据环境的一对多表单。 ① 在表单中加入若干个文本框,分别设置文本框的 ControlSource 属性为主表的相应字 段。 ② 在表单中添加一个表格,将表格的 RecordSource 属性设置为相关表(子表)的名称。 ③ 设置表格的 LinkMaster 属性为主表名称。 ④ 设置表格的 ChildOrder 属性为相关表中索引标识的名称,索引标识和主表中的关系表 达式相对应。 ⑤ 将表格的 RelationalExpr 属性设置为连接相关表和主表的表达式。例如,如果 ChildOrder 标识以“KHXM”建立的索引,应将 RelationlExpr 也设置为相同的表达式。 4.表格生成器 选择“表格”控件的快捷选单的“生成器”选项,可以启动“表格生成器” 。在“数据库 和表”的列表中选择一个数据库或表,若想在其他目录中选择表,则单击“…”按钮,将启 动“打开”对话框,通过“打开”对话框,选择表打开。打开表后,VFP 会自动将其所有字 段放入表格项的“可用字段”列表中,用户可以选择所需字段添加至“选定字段”列表中。 使用双箭头按钮可将所有的可用字段一次性全部移入选定字段的列表中。 在“样式”选项卡中,VFP 提供了 5 种样式,其默认值为“保留当前样式”,另外 4 种为 专业式、标准式、浮雕式、账务式。当选择其中一项时,左侧的示例会显示出所选择的样式 范例。 在“布局”选项卡中,用户可以调整和设置行列。 拖动列标题的右边沿可调整列宽,拖动行的下左边沿可调整行高。在“抬头标题”中可 为列设置其 Caption(标题)属性。在“控件类型”中可以改变列的控件类型。

5.9

图像框和图片框

在 VFP 中有图像框(Image) 、形状(Shap)和线条(Line)控件。图像框和图形控件一 般用于修饰表单,使界面美观。 ·108·


图像框不能直接与表中存放图像的字段直接绑定,但可通过文件间接显示。图像框常用 属性如表 5.16 所示。 表 5.16 图像框常用属性 属

图像文件名

Picture

指定图像显示方式。

Stretch

0—裁剪;1—等比;2—变比 BorderStyle

确定边框。0—无;1—固定单线

BorderColor

边框线的颜色(仅 BorderStyle=1)

BackStyle

设置背景透明:0—透明;1—不透明

各属性设置效果如图 5.17 所示。

图 5.17 各属性设置效果

形状控件通过设置其属性可以基本实现表单中 BOX 和 Circle 方法完成的功能。形状控 件常用属性如表 5.17 所示。 表 5.17 属

形状控件常用属性

Curvature

曲率(0~99)

SpecialEffect

边格式。0—3 维;1—平面

BorderWidth

边宽度(仅 SpecialEffect=1 时)

BorderColor

边颜色(仅 SpecialEffect=1 时)

FillStyle

填充模式

FillColor

填充颜色

DrawMode

与底色的关系

各属性设置效果如图 5.18 所示。

图 5.18

形状控件的不同效果

线条控件通过设置其属性可部分实现表单中 Line 方法完成的功能。 ·109·


5.10 计时器 计时器(Timer)用于处理需用定时进行处理的事件。计时器常用属性如表 5.18 所示。 表 5.18 计时器常用属性 属

Interval

计时间隔(ms)。值为 0,不产生 Timer 事件

Enabled

控制计时器是否启动

计时器常用的事件为 Timer 事件,计时器常用的方法为 Reset。在设计阶段,设置 Interval 大于 0,Enabled 为.T.,则当表单启动时计时器便开始计时。若 Enabled 为.F.,则计时器不会 启动。调用 Reset 方法可使计时器重新从 0 开始计时。 一般情况下,计时器时间间隔不能太小,否则频繁产生 Timer 事件会降低系统的运行效 率。另外,计时器控件不能自动直接实现定时中断,例如若希望 8 时产生定时事件,应将 8 时与当前时间 DateTime()进行相减换成毫秒数后作为 Interval 属性值。

5.11

微调按钮

微调按钮控件(Spinner)可以在一定范围内控制数据的变化,同时又可像文本框一样输 入数值数据。微调按钮常用属性如表 5.19 所示。 表 5.19 属

微调按钮常用属性 作

Increment

设置微调控件向上和向下箭头的微调量,默认值为 1.00

InputMask

设置微调值,与 Increment 属性配合使用可设置带小数的数值

SpinnerLowValue

通过鼠标控制数值的下限值

SpinnerHightValue

通过鼠标控制数值的上限值

KeyboardLowValue

通过键盘输入数值的下限值

KeyboardHighValue

通过键盘输入数值的上限值

微调按钮常用事件如下。 DownClick 事件:在单击向下箭头时产生; UpClick 事件:在单击向上箭头时产生; InterActiveChange 事件:微调按钮数值改变时产生。 【例 Ex_Spin】显示时间,刷新时间可调。 (1)设计表单界面。设计一个文本框(Text1)显示时间,一个微调按钮(Spinner1)用 于控制刷新的时间间隔,一个命令按钮(Command1)用于启动时间显示。一个计时器(Timer1) 用于刷新时间。定时刷新界面如图 5.19 所示。 (2)设置对象属性。 Text1.Value={} Spinner1.SpinnerHighValue=60 Spinner1.SpinnerLowHighValue=1 Spinner1.KeyBoardHighHighValue=60

·110·

&& 刷新的时间间隔不大于 60s


Spinner1.KeyBoardLowHighValue=1

图 5.19 定时刷新界面

(3)编写事件代码。 * Command1 的 Click 事件: THISFORM.Timer1.Interval=THISFORM.Spinner1.Value*1000 * Timer1 的 Timer 事件 THISFORM.Text1.Value=Time()

一般情况下,微调控件值都是数值型,但是也可以将微调控件和文本框组合使用来微调 多种类型的数值,使得微调控件的功能得以充分的发挥。例如,可以将微调控件和文本框组 合起来,使它能够微调一定范围内的日期。首先把微调控件的大小作一调整,使之不显示它 本身的数值框,然后在微调按钮旁边放置一个文本框,设置文本框的 Value 属性为日期。在 微调控件的 UpClick 和 DownClick 事件中输入代码,将文本框的值加减一个数值再送到文本 框中,以实现用微调控件调整日期。

5.12 Active 控件 如果在安装 Visual FoxPro 6.0 中文版时选择了“完全安装”选项,则默认安装 ActiveX 控件。如果未选择此选项,可以在任何时候运行 Visual FoxPro 6.0 中文版安装程序,并只安 装 Activex 控件。Activex 控件被安装在 Windows 9x 的 SYSTEM 目录中,或者 Windows NT 的 SYSTEM 32 目录中。 系统提供 ActiveX 控件(OLEControl)和 ActiveX 绑定控件(OLEBoundControl)。

5.12.1

ActiveX 控件(OLEControl)

ActiveX 控件的功能是向应用程序中添加 OLE 对象,它又称为 OLE 控件。OLE 是对象 链接与嵌入的英文缩写(Object Linking and Embedding) ,即把一个对象以链接或嵌入的方式 包含在其他应用程序之中。可以通过 ActiveX 控件在自己的应用程序中使用其他的 Windows 应用程序,如 Excel,Word 等。 单击表单控件工具栏中的“OLE 容器控件”按钮,并在“表单”窗口中将其拖至所期望 的大小后松开,系统选择“插入对象”,如图 5.20 所示。 (1)新建。从当前 Windows 系统提供的对象(例如 Microsoft Excel 或 Microsoft Word 等) 进行选择后确定,可以将该 OLE 对象添加到表单。表单运行时单击该对象即可进入所选对象 ·111·


的操作。

图 5.20

“插入对象”对话框

(2)由文件创建。系统在用户选择插入对象的文件名插入该对象。Windows\SYSTEM 目 录中可能包含 ActiveX 控件(带有.OCX 扩展名的文件)。 (3)插入控件。系统列出当前系统所有的 ActiveX 控件,用户选择后插入该对象。 实际上,插入 ActiveX 控件对象可按下列步骤进行。 ① 首先选择“工具”选单→“选项” (如图 5.21 所示)→在显示的下列对话框中选择“控 件”页→选择“ActiveX 控件” 。在列出的 ActiveX 控件选择本应用系统要使用的控件后确定。

图 5.21 “选项”对话框

图 5.22

·112·

表单控件

② 单击“表单控件”中“查看类” (第 2 个)按钮。如 图 5.22 所示,系统显示下列选单。 ③ “选 ActiveX 控件” ,系统表单控件工具就变为在第 ①步中所选的 ActiveX 控件图标。 ④ 用户按系统提供的基本控件的方法进行操作。 表 5.20 列出了与 Visual FoxPro 6.0 中文版一起发布 的.OCX 文件以及每个文件所包含的 Activex 控件。


表 5.20 文

.OCX 文件及其包含的 ActiveX 控件

COMDLG32.OCX

ImageList 控件;ListView 控件;ProgressBar 控件;Slider 控件;StatusBar 控 件;TabStrip 控件;Toolbar 控件;Treeview 控件

DBLIST32.OCX

Common Dialogs 控件

DBLIST32.OCX

MSDataCombo 控件;MSDatalist 控件

FOXHWND.OCX

Visual FoxPro HWND 控件

FOXTLIB.OCX

Visual FoxPro Foxtlib 控件

GRID32.OCX

Grid 控件

MCI32.OCX

Microsoft Multimedia 控件

MSACAL70.OCX

Calendar 控件

MSCOMM32.OCX

Microsoft Comm 控件

MSMAPI32.OCX

Microsoft MAPI Message 控件;Microsoft MAPI Session 控件

MSOUTL32.OCX

Outline 控件

PICCLP32.OCX

PicClip 控件

RICHTX32.OCX

Rich Textbox 控件

SYSINFO32.OCX

SysInfo 控件

TABCTL32.OCX

SSTab 控件

THREED32.OCX

Threed Checkbos 控件;Threed Command Button 控件;Threed Frame 控件; Threed Group Push Button 控件;Threed Option Button 控件;Threed Panel 控件

注意:同 Visual FoxPro 6.0 中文版一起发布的很多 ActiveX 控件是用来与其他应用程序 一起使用的。当把一个控件放在表单上,并按下 F1 键查看该控件的帮助信息时,所显示的帮 助是原来应用程序的,而不是 Visual FoxPro 6.0 中文版的。如果将 SysInfo 控件放在表单上, 按 F1 键将得不到该控件的帮助信息。

5.12.2

ActiveX 绑定控件(OLEBoundControl)

ActiveX 绑定控件(OLEBoundControl)与 OLE 容器控件一样,可用于向应用程序中添 加 OLE 对象,它又称为 OLE 绑定控件。与 OLE 容器控件不同的是,OLE 绑定型控件可绑定 在一个通用字段上。绑定型控件是表单或报表上的一种控件,其中的内容与后端的表或查询 中的某一字段相关联。 单击表单控件工具栏中的“ActiveX 绑定型控件”按钮,并在“表单”窗口中拖动到所 期望的大小,可以在表单中创建一个绑定型 OLE 控件对象。在创建这个对象后,可以设置对 象的 ControlSource 属性,将它和表中的通用字段链接,然后便可以用这个对象显示字段中的 内容。例如,如果将 Word 文件保存在通用字段中,就可以在表中使用一个绑定型 OLE 对象 显示这些文件的内容。

·113·


第 6 章 项目管理器 为了用 Visual FoxPro 解决一个实际的应用问题,需要建立很多文件。例如,要开发一个 人事管理系统,需要创建数据库、表、索引;需要设计表单、控件并为事件编写操作代码; 需要编写程序、存储过程、触发器代码;需要建立类库;需要设计表单;需要创建报表,等 等。开发时我们需要反复打开、修改、关闭这些文件,一般通过选单、在命令窗口输入命令、 借用工具等来进行这些操作,其操作效率很低。Visual FoxPro 采用项目管理器很好地解决了 这个问题。 在 Visual FoxPro 中把解决一个实际的应用问题称为一个项目,项目管理器是 Visual FoxPro 对应用系统中的文件进行集中组织的工具。管理信息保存在以.PJX 为扩展名的文件 中。项目管理器用类似大纲的形式可视化地组织项目中的各个文件,通过文件组织数据、对 象、文档和所有操作,大大提高了开发系统的效率;可创建经过编译的.APP 文件和可在 Windows 环境下单独执行的.EXE 文件。

6.1

使用应用程序向导

Visual FoxPro 6.0 中文版提供的应用程序向导是项目管理器的一个快捷工具。 选择“工具”选单→选择“向导”子选单的“应用程序”命令,将弹出“应用程序向导” 对话框,如图 6.1 所示。选择“文件”选单→选择“新建”子选单→在“新建”对话框中单 击“项目”单选按钮→单击“向导”按钮,将弹出“应用程序向导”对话框。

图 6.1

“应用程序向导”对话框

在“项目名称”文本框键入给项目起的名字,“项目文件”文本框将自动显示项目名称和 路径名,可以修改文本框的内容,也可以单击[浏览]按钮选择其他目录。在确认后系统先生 成一个项目框架。应用程序生成器共有 6 个选项卡,分类显示各数据项,让用户加入当前项 目管理的各种文件。下面逐一介绍这 6 个选项卡。 1.常规选项卡 常规选项卡如图 6.2 所示。在[名称]和[图像]文本框中,可输入项目名称和图像文件名, 它们在项目运行时首先显示,相当于应用系统的封面。系统的封面只会在屏幕上显示几秒钟, 然后会显示出系统的主界面。 “常用对话框”选项组用于确定项目运行时系统的主界面一开始 ·114·


希望出现的内容。前 3 个选项为系统默认选项,如果选中第 4 个“用户登录”复选框,系统 将在主界面一开始希望出现用户登录对话框,让用户输入进入应用系统的用户名和口令。在 “应用程序类”中有正常、模块、顶层 3 个单选按钮,下面的“图标”指定创建的项目中一 个图标文件。

图 6.2 常规选项卡

2.信息选项卡 信息选项卡如图 6.3 所示。该对话框主要是让用户输入有关该项目的辅助信息,这些内 容在应用程序运行的系统封面中显示。可以逐一键入之后单击“确定”按钮。

图 6.3 信息选项卡

3.数据选项卡 数据选项卡如图 6.4 所示。该对话框的功能是为项目添加数据库或自由表。单击“选择” 按钮可以把已存在的数据表添加到项目中。如确认自己的表单或报表没有问题,单击“生成” 按钮,即可生成所需要的表单或报表,并自动添加到项目中。系统生成的表单样式和报表样 式可在下部选择。如需把列表框中显示的数据清除,单击“清除”按钮即可。

·115·


图 6.4 数据选项卡

4.表单选项卡 表单选项卡如图 6.5 所示。用户单击“添加”按钮,把属于该应用系统的已设计好的表 单加入项目中。右边 5 个复选框用于在系统主界面如何与列表框中包含的表单连接和调出运 行。系统主界面包含主选单、工具栏和选择某功能后会打开对话框。例如,如果在“使用定 位选单复选框”和“在打开文件对话框中显示”上打勾,则在系统主界面上单击定位选单项 或在打开文件(选单或工具栏)时就会调用该表单运行。名称文本框中是当前选中的表单的 名字,如果执行某操作要调用一个以上的表单,就会出现一个对话框进行选择,选择时列出 的表单名就是用户确定的名字。

图 6.5 表单选项卡

5.报表选项卡 报表选项卡如图 6.6 所示。用户单击“添加”按钮,把属于该应用系统的已设计好的报 表加入项目中。右边复选框“在打印报表对话框中显示” ,用于在系统主界面单击打印报表选 单项就会调用该报表单。名称文本框中是当前选中的报表的名字,如果执行单击打印报表选 单操作要调用一个以上的报表,就会出现一个对话框进行选择报表,选择时列出的报表名就 是用户确定的名字。 ·116·


图 6.6 报表选项卡

如果需要在表单设计器中编辑当前表单,单击“编辑”按钮。如果需要删除当前选中的 表单,单击“删除”按钮。 如果需要在报表设计器中编辑当前报表,单击“编辑”按钮。如果需要删除当前选中的 报表,单击“删除”按钮。 6.高级选项卡 高级选项卡如图 6.7 所示。可以设置项目中的帮助文件和系统数据存放的目录。也可以 在复选框中确定在项目的主选单中是否包含“常用工具栏”和“收藏夹选单”。单击“清理” 按钮,就会把文件从源表添加或移动到活动项目的相应位置上。

图 6.7 高级选项卡

应用程序向导生成的项目框架,已经帮助用户生成了项目运行时很多有用的事情,例如 应用程序封面、主选单、工具栏以及它们与表单和报表等连接。在上述 6 个选项卡设定后单 击“确定”按钮,则系统开始生成项目框架,并形成 PJX 项目文件保存这些信息。 打开应用程序向导生成的项目框架 PJX 项目文件,即打开项目管理器,如图 6.8 所示。 此后就可在项目管理器下创建、修改、调试项目所需的文件。如果项目所有文件都已调 试好,而且在开发环境下统调正确,即可对项目进行连编。这里就先对上面应用程序向导生 成项目 MY 进行连编,感觉一下效果,然后我们再慢慢介绍。单击项目管理器下窗口右边的 ·117·


“连编”按钮,显示“连编选项”对话框,如图 6.9 所示。

图 6.8 项目管理器

图 6.9

“连编选项”对话框

选择“连编可执行文件”项,单击“确定”按钮,系统即开始连编,最后在 D:\MY 目录 下生成了一个 my.EXE 文件。 在 Windows 操作系统状态下双击 my.EXE 即开始运行这个应用程序。系统首先显示封 面。封面上部是你在项目中设置的 TITLE.BMP 图像,下面是你在项目中设置的应用程序名 称和版本信息。过几秒钟,系统即显示应用程序窗口,并打开快速启动对话框,选择执行的 表单或报表,也可选择取消。单击“打开”图标或选单,显示如图 6.10 所示的对话框,选择 表单(这里选择“实发工资计算”)后确定,即调用该表单,如图 6.11 所示。 选择“文件”选单→选择“新建”子选单→在新建对话框中选择“项目”单选按钮→单 击“新建文件”按钮,则不会调用应用程序向导,而是让用户选择生成的项目.PJX 存放的目 录后立即生成项目空的框架。与应用程序向导项目框架相比,不包含任何文件。这里,我们 用这种方法在 D:\RY_MIS 目录建立一个 RY_DAT 的项目。 不管以什么方式建立项目框架后,对项目进行管理只需打开这个文件。

·118·


图 6.10

图 6.11

6.2

“选择表单”对话框

“实发工资计算”表单

项目管理器介绍

在打开文件时,在“打开”对话框中的文件类型选择“项目” ,然后找到项目 .PJX 文件 所在的目录,指定项目文件,即打开项目管理器,如图 6.12 所示。 6 个选项卡显示的内容如下。 (1)全部选项卡:显示项目管理器所有类型的文件。 (2)数据选项卡:显示项目管理器中的数据库、自由表和查询 3 种类型的文件。 (3)文档选项卡:显示项目管理器中的表单、报表和[标签] 3 种类型的文件。 (4)类选项卡:显示项目管理器中的所有类库文件,但当项目是空项时无显示。 (5)代码选项卡:显示项目管理器中的程序、API 库和应用程序 3 种类型的文件。 (6)其他选项卡:显示项目管理器中的选单、文本文件和其他文件 3 种类型的文件。 ·119·


图 6.12 项目管理器

在项目管理器中,以类似于大纲的形式组织各项,可以展开或折叠它们。在项目中,如 果某类型数据项有一个或多个数据项,则在其标志前有一个加号。单击标志前的加号可查看 此项的列表,单击减号可折叠展开的列表。与工具栏类似,可以将项目管理器拖动到屏幕顶 部,或双击标题栏停放项目管理器。项目管理器停放后,被自动折叠,只显示选项卡。当项 目管理器折叠时,把鼠标指针放到选项卡上,并将其从项目管理器移走,可以拖动显示选项 卡。

6.2.1 项目管理器功能 项目管理器的功能通过右侧几个按钮和“项目”选单中相应的选单项实现。 1. 项目管理器右侧按钮 项目管理器右侧有几个按钮。当编辑一个项目时,选中对应的文件类型,这些按钮将显 示高亮度。“项目”选单中也有相应的选单项对应。 (1)新建:新文件或对象的类型与当前选定项的类型相同。注意:在打开项目管理器情 况下,从“文件”选单中创建的文件不会自动包含在项目中。 (2)添加:把已有的文件添加到项目中。 (3)修改:打开相应的设计器并对选定项进行修改,比如可以在报表设计器中打开一个 报表进行修改。 (4)浏览:在浏览窗口中打开一个表,浏览表中内容。当在浏览窗口中浏览一个表时, 可以用两种方式查看记录:浏览和编辑。可以从“显示”选单中选择“浏览”或“编辑”命 令切换查看方式。 浏览窗口要把一个列移到新位置,可单击字段名,把列拖动到希望的位置,然后放开鼠 标键。要在可接受 NULL 值的字段中输入 NULL,按 Ctrl+O 组合键。当激活包含 NULL 值的 字段时,不显示任何值。当激活其他字段时,包含 NULL 值的字段显示 NULL。如果从“显 示”选单中选择“追加方式”命令,浏览窗口将添加一个新的空记录。当填满这个新记录之 后,浏览窗口自动添加另一个新记录。 (5)关闭:关闭一个打开的数据库。当且仅当选定一个表时可应用。如果选定的数据库 已关闭,此按钮变为“打开”。 ·120·


(6)打开:打开一个数据库。如果选定的数据库已打开,此按钮变为“关闭”。 (7)移去:从项目中移去选定文件或对象。Visual FoxPro 会询问是仅从项目中移去此文 件,还是同时将其从磁盘中删除。 (8)连编:连编一个项目或应用程序,在专业版中,还可以连编一个可执行文件。该功 能相当于其他语言中的编译和连接。 (9)预览:在打印预览方式下显示选定的报表或标签。当选定项目管理器中的一个报表 或标签时可用。 (10)运行:执行选定的查询、表单或程序。当选定项目管理器中的一个查询、表单或程 序时可用。主要是用它测试程序的正确性。 注意:关闭、打开、运行和预览共用一个按钮,由所选择的数据类型决定。 2. 项目选单选项的其他功能 (1)重命名文件:对话框中的“重命名”文本框将显示选定文件的当前名称。 “到”文本 框显示当前文件名,键入新的名称时可以更改此文件名。 重命名文件时要特别小心。如果改变了表单 DataEnvironmem 属性中引用的表的名称, 表单将找不到这个表。如果更改了一个已经添加到表单中的类的名称,表单将不能定位到这 个类。 (2)包含:文件在项目管理器中有两种状态存在,即包含和排除。所谓包含文件,就是 连编项目后,指定文件不能再被用户修改。在一个项目中包含以前排除在外的文件。仅当选 定一个排除文件时,该选项才可用。所有的包含文件都以只读方式被编译进.APP 或.EXE 文 件中。如果希望在运行时写入一个文件,应把它们标记为排除文件。 (3)排除:所谓排除文件,就是连编项目后,指定文件允许被用户修改。 排除文件并不编译进应用程序。仅在“项目管理器”中选定一个包含文件时,该命令才 可用。项目管理器在排除的文件名称前显示一个中间带斜杠的圆。排除文件列在项目管理器 中供参考,但如果应用程序需要它们时,必须人工发布它们。 (4)设置主文件:在每一个项目中必须指定一个主文件,且只能设置一个主文件。主文 件是应用程序的起始执行过程或程序。把所选定的程序或表单指定为系统主程序,该程序在 编译后的应用程序中首先执行。必须在项目管理器中选择一个程序、表单或选单,此命令才 可用。在选定主文件后,每当在项目管理器中选择该文件时,此命令的旁边将显示一个对号。 (5)编辑说明:是显示“说明”对话框。可在框中修改文本,该文本作为文件说明出现 在项目管理器窗口的底部。说明对话框提供一个文本框,可以键入程序文件的简短说明。 (6)将项目加到源代码管理器中:是显示源代码管理器的一个对话框,它允许用户把打 开的项目添加到源代码管理器中。如果在“选项”对话框内“项目”选项卡上选定了一个源 代码管理器,该选单选项出现。 (7)源代码管理:显示源代码管理子选单,它允许用户访问与源代码管理有关的对话框。 仅当打开一个源代码管理项目时选单命令可用。 “源代码管理”子选单用来管理一个源代码管 理项目中的项目文件。“源代码管理”子选单包含下列命令。 ① 获取最近的版本:允许用户把选定的源代码管理文件的最新只读复本放置在项目管理 器中。 ② 签出:允许用户从源代码管理器中签出选定文件的一个复本,并在开发环境相应的工 作目录中放置一个可以写入的复本。 ·121·


③ 签入:允许用户签入在开发环境工作目录中对源代码管理数据库所做的更改。 ④ 撤消签出:允许用户忽略对一个文件所做的更改,并把该文件的最新签入版本复制到 用户开发环境工作目录中。 ⑤ 显示历史记录:允许用户查看对选定文件所做更改的历史记录。 ⑥ 显示差别:允许用户查看一个文件的本地版本和源代码管理器中最新签入版本之间的 不同。 ⑦ 源代码管理器属性:允许查看选定文件的详细信息。 ⑧ 往源代码管理器中加入文件:允许用户把项目中选定的文件添加到源代码管理器中。 ⑨ 从源代码管理器中删除文件:允许用户从源代码管理器中移去项目中选定的文件。 ⑩ 共享文件:允许用户在多个项目之间共享特定的文件。 更新项目列表:把用户的更改与核心项目列表文件(.PJM 文件)合并,然后在更新 项目列表对话框中显示结果。该过程结束时,将更新本地的项目文件,以反映其他开发者添 加的文件。如果用户添加了文件,也应该更新项目列表,这样其他开发者也可以更新他们的 项目列表,并能看到用户添加的列表。 显示项目列表历史记录:允许显示有关选定项目的版本号、创建日期以及其他信息。 显示项目列表的差别:允许用户查看他的项目复本与该项目的源代码管理器版本之间 的不同。 项目属性:允许用户查看选定项目的详细信息。 从源代码管理器中分离项目:允许把用户的项目从源代码管理器中分离出来。 (8)项目信息:显示项目信息对话框,从中可以查看和编辑有关的项目及其文件的信息。 快捷键为 Ctrl+J。 (9)错误:显示编译应用程序期间生成的错误日志文件。 (10)连编:显示[连编选项]对话框,从而可以创建自定义应用程序并更新已有的项目。 (11)刷新:刷新项目。 (12)清理项目:通过运行 PACK 命令删除带有删除标记的文件,来减小项目.PJX 文件 的大小。当使用“移去文件”命令从项目中移去一个文件时,相关记录仍保留在.PJX 项目文 件中,但带有删除标记。可以选择清理项目命令来删除带有删除标记的记录。

6.2.2 项目管理器管理项目 前面已创建了一个空项目文件 RY_DAT,需要在项目文件中创建新文件,添加各种已建 好的文件。下面仍分类说明。 1.数据选项卡 数据选项卡用于管理项目中的数据,主要包括数据库、自由表和查询。数据库包括数据 表、视图、存储过程和连接。视图分本地视图和远程视图,如图 6.13 所示。由于所有对象都 是树状结构,所以对象之间的关系清楚明了,操作起来非常方便。 下面说明一下“新建功能” 。例如新建数据库,先单击“数据库”,然后单击“新建”按 钮。此后即打开新建数据库对话框。 已经建立的对象,先选中该操作的对象,右边会出现操作该对象的按钮。选择不同的操 作对象,右边出现操作对象的按钮可能不一样。例如,选择数据库,会有修改按钮;选择表, 会有修改按钮,还有浏览按钮,因为浏览表是表的主要操作。 ·122·


图 6.13 数据选项卡

自由表可直接拉入数据库中,查询将在后面介绍。 2. 文档选项卡 文档选项卡是主要管理表单、报表和标签 3 种类型的文件,如图 6.8 所示。报表和标签 将在后面介绍。 3. 类选项卡 类选项卡是用于管理项目中的所有类库文件,当项目是空项时无显示,如图 6.14 所示。 类库文件将在后面介绍。

图 6.14

类选项卡

4. 代码选项卡 代码选项卡是管理项目中的程序、API 库和应用程序 3 种类型的文件,如图 6.15 所示。 API 库是项目中需要调用系统中 API 函数时使用的。 5. 其他选项卡 管理项目中的选单、文本文件和其他文件 3 种类型的文件,如图 6.16 所示。其他文件可 以是图像文件、声音文件等不能归入上面其他部分的文件。选单将在后面介绍。 在项目管理器中,可以为列表框中的每个项编一个说明,包括表中的每个字段或索引。 它将出现在项目管理器下部的“说明”/“路径”文本框中。 ·123·


图 6.15 代码选项卡

图 6.16 其他选项卡

如果想在两个项目中共享一个文件,可以分别打开要共享文件的两个项目管理器,然后 在已经包含该文件的项目管理器中选定该文件,用鼠标拖动到另一项目中。在项目管理器中 设计报表或表单,同样可以把表或字段直接从项目管理器中拖动到表单设计器或报表设计器 中。 还要说明,项目管理器只是为了操作文件方便,文件之间的关系,譬如文件之间如何调 用跟它无关。这是编程序的人自己考虑的。

6.3

项目连编

如果项目所有文件都已调试好,而且在开发环境下统调正确,即可对项目进行连编。连 编前须先设置项目的主文件。 1. 设置主文件 每一个项目中必须指定一个主文件,而且只能设置一个主文件。只有把所选定的程序或 表单指定为系统主文件,该程序才能在编译后的应用程序中执行。 实际上,在通过应用程序向导构造项目时,Visual FoxPro 会默认指定一个主文件,用户 也可以手工设置一个主文件,没有通过应用程序向导构造权的项目必须手工设置一个主文件。 ·124·


手工设置主文件时先选择一个程序文件、表单文件或选单文件,然后在项目主选单或按右键 出现的选单项选择“设置主文件”。 一般来说,主文件有一些特殊要求。例如可以在项目管理器代码选项卡中建立一个程序 文件 MAIN.PRG。 可以在编辑窗口中输入下列程序: CLEAR

&&清屏

SET DEFAULT TO D:\RY_MIS

&&设置默认数据文件搜索路径 &&也可通过 home()设置动态路径

DO

MENU_MAIN.MPR

READ EVENTS

&&执行主控选单 &&启动事件循环

CLEAR CLOSE ALL

&&关闭所有文件

RETURN

与“MAIN.PRG”文件中的启动时间循环选项相对应,需要一个结束事件循环的命令。 只要在系统的“退出”选单的“结果”命令改为“过程”命令,在过程代码中输入: SET SYSMENU TO DEFAULT CLEAR EVENTS

当设置一个程序文件为主文件时,系统会自动把原来的主文件设置为非主文件。在项目 管理器中,单击项目的主文件并单击“运行”按钮,即可运行这个项目的应用程序,开始在 开发环境下测试整个系统的程序。 2. 项目连编 当在“项目管理器”中,从项目的主文件开始运行,在开发环境下测试整个系统的程序 成功之后,就可以进行项目连编。在 Visual FoxPro 6.0 中文版中,连编就是把一个项目文件 管理器的各个文件连接成一个可运行的应用软件的过程。连编生成的可执行文件是.APP 文件 或.EXE 文件。.APP 文件的运行环境只能在 Visual FoxPro 6.0 中文版下,而.EXE 文件可以在 Windows 9x 环境中单独执行。当然,.EXE 文件的运行速度明显比.APP 文件快。 连编一个项目,只要在项目管理器中单击“连编”按钮即可打开“连编选项”对话框, 如图 6.9 所示。 “连编选项”对话框包括“操作”单选按钮组和“选项”检查框组。 “操作”单选按钮组 包括下列几项。 (1)重新连编项目:创建和连编项目文件,将根据项目管理器中各组件的设计重新创建 和连编项目文件,生成扩展名为.PJX 和.PJT 的项目文件。该选项对应于 BUILD PROJECT 命 令。 (2)连编应用程序:连编项目,编译过时的文件,并创建单个扩展名为 .APP 的文件。 该选项对应于 BUILD APP 命令。 (3)连编可执行程序:将编译项目文件创建一个扩展名为.EXE 的可执行文件,该选项对 应于 BUILD EXE 命令。 (4)连编 COM DLL:使用项目文件中的类信息,创建一个具有.DLL 文件的动态链接库。 它的主要作用是把 Visual FoxPro 类库文件编译成其他应用程序也能够使用的.COM 文件。这 是 Visual FoxPro 6.0 中文版新增的功能。 ·125·


“选项”检查框组包括下列几项。 ① 重新编译全部文件:重新编译项目中的所有文件,并对每个源文件创建其目标文件。 ② 显示错误:连编完成后,在一个编辑窗口中显示编译时的错误。 ③ 连编后运行:连编应用程序之后,立即运行所编译的应用程序或可执行文件。 ④ 重新生成组件 ID:安装并注册包含在项目中的 OLE 服务程序。 “版本”按钮显示“EXE 版本”对话框,允许指定版本号以及版本类型。当选择“连编 可执行文件”或“连编 COM DLL”选项时,该按钮高亮显示。单击该按钮,屏幕将弹出“EXE 版本”对话框。

6.4

项目信息和项目文档

1. 项目信息 项目信息是允许查看和编辑有关项目和项目中文件的信息。可以打开“项目”选单,选 择“项目信息”命令或者按快捷键 Ctrl+J,屏幕将弹出“项目信息”对话框,如图 6.17 所示。

图 6.17

“项目信息”对话框

在该对话框中,左上角有 3 个选项卡:项目选项卡、文件选项卡和服务程序选项卡。 (1)[项目]选项卡显示项目当前的状态信息,它包括以下 14 个选项。除了前面几个,还 要注意以下几个选项。 ① 调试信息:选中它,则指定的已编译项目文件中包含调试信息。否则不可调试,即不 能在调试器中查看程序的执行情况。 ② 加密:选中它,则可以对已编译的文件进行加密。 ③ 附加图标:选中它,可以为所运行的应用程序指定一个图标。 ④ 图标:该按钮只有在选中“附加图标”复选框时才高亮显示,单击该按钮可以为运行 的应用程序选定一个图标,被选定的图标将自动代替原来的图标。 (2)文件选项卡的功能是在列表框中显示项目中的文件信息,如图 6.18 所示。 显示的文件信息包括文件类型、文件名称、上次修改的日期和时间、包含/排除状态和代 ·126·


码页信息等。

图 6.18 文件选项卡

① 类型:该列显示代表文件类型的图标,这些图标与项目管理器中所显示的是一致的。 ② 名称:在列表框中,该列显示了项目中所有的文件名和扩展名。文件名按首字母顺序 排序。 ③ 上次修改:该列显示的是最近一次修改的日期和时间。时间按先后顺序排列。 ④ 包含:该列显示文件的当前状态为包含,即选中小方框。如果不选中小方框,则为排 除状态。单击包含列后,列表框中排除状态的文件在前,包含状态的文件在后排列。 ⑤ 代码页:该列显示的是文件的代码页的编号文件代码页按由小到大排列。 ⑥ 更新本地代码页:单击该按扭可以更新本地代码页。 (3)服务程序选项卡的功能是显示服务程序类以及类所在的类库、类名、实例、说明和 帮助信息等,如图 6.19 所示。

图 6.19 服务程序选项卡

·127·


2. 项目文档 在 Visual FoxPro 6.0 中文版中提供了制作文档的文档向导。文档向导能够分析项目中源 代码文件中的代码并整理代码文件的格式,使代码成为规范的文档,引导用户为项目或程序 文件制作出一份全面、细致、有条理的项目文档。在 Visual FoxPro 中,制作文档并没有一个 文档设计器,而是文档制作工具。操作步骤:打开“工具”选单,在“向导”子选单中选择 “文档”命令,即可弹出“文档向导”对话框,如图 6.20 所示。

图 6.20

“文档向导”对话框

文档向导制作一个项目的文档过程如下。 (1)选择源文件:在“源文件”文本框中输入项目文件或者指定的程序文件的名称。单 击“浏览”按扭打开“打开”对话框,选择项目或程序文件。如果选择了一个项目文件,文 档向导会将项目中所有的源代码文件放入文档。 (2)设置大写允许:使用文档向导设置代码中的关键字大小写方式。关键字是 Visual FoxPro 程序语言内部的所有保留字,而符号是在代码中定义的变量和名称。不允许把保留字 命名为变量的名称,否则将会发生错误。符号则是指在源代码文件中自定义变量、过程或函 数的名称。其中各选项解释如下。 ① 大写:关键字和符号全部用大写显示。例如:ADDOBJECT 和 OMYFORM。 ② 小写:关键字和符号全部用小写显示。例如:addobject 和 omyform。 ③ 大小写混合:关键字的词头使用大写。例如:AddObject。 ④ 匹配首次出现的值:符号在文件中第一次出现时大写。 ⑤ 不改变:关键字和符号不改变。 (3)缩进指定文档可以缩进程序行的方式:该向导可以缩进特定类型的行,并可以调整 缩进的空格数。显示内容介绍如下。 ① 缩进类型:使用制表符还是空格进行缩进。如果选择下拉列表框中的“空格”选项时, 可设置每级缩进的空格数。如果不需要缩进处理,可选择“不改变”选项。 ② 缩进文本:是要缩进的行类型。可用的选择有注释、控制结构(例如循环、IP 结构 或 DO CASE 结构),以及用分号继续的各行语句。 (4)加入标题:是否在程序中插入标题。标题是对它后面代码的说明,它们可以放在文 件、过程、类定义和方法程序的开始处,以增强代码的可读性。 (5)选择报表:产生的报表类型,它们都是文本文件。 ·128·


(6)完成:选择是否允许改写源文件和文档输出的目录。默认情况下,向导不能改写已 存在的文件。各个选项如下。 ① 改写当前文件:用向导保存的文件代码改写已存在的代码文件。 ② 将文件放到单个目录中:将提示选择一个目录来存储建立的文件。 ③ 将文件放到新目录树中:将提示选择一个目录来建立项目资源树的备份,并在新树的 适当目录中存储新建的格式化的程序。 (4)交叉引用关键字:创建或者向名称为 FDXREF.DBF 的关键字表添加记录。向导运行 完成后,可以使用这个表来创建关于使用应用程序关键字的报表。对应于程序代码中 Visual FoxPro 关键字的每个实例,向导向 FDXREF.DBF 文件中添加一条记录。 (5)运行分析器:选定该选项并单击“完成”按钮,进入“代码分析器”对话框。代码 分析器可以动态跟踪 Visual FoxPro 6.0 中文版应用程序文件中的结构和符号,还可以通过使 用文档向导的输出,提供一些可视化的控件、选单及键盘选项来查看应用程序文件的代码。

·129·


第 7 章 类的创建和使用 7.1

VFP 的类

在面向对象程序设计中,类可由已存在的类派生,类与派生类之间是一种层次结构。在 这个层次结构中,处于上层的类称为父类,处于下层的类称为子类。父类、子类之间具有继 承性,子类可继承父类的全部数据和方法,而这种继承具有传递性,任何一个类都继承了层 次结构中所有上层类的全部特性。因此,子类具有父类的全部特性,而且自己还可增加新数 据和新方法。 在 VFP 中,VFP 系统定义的类称为基类,用户不能对其修改。用户可以根据基类直接创 建对象,从而实现基类的实例化。VFP 将其所定义的基类分为容器类(Container)和控件类 (Control)。容器类可以包含其他对象,并且允许访问这些对象。控件类是单一的对象,不能 容纳任何其他对象。比如表单类就属于容器类,设计时用户可将诸如文本框、命令按钮、线 条等对象放入其中。 VFP 包含下列容器类: 表单集(FormSet) 、表单(Form) 、容器(Container) 、页框(PageFrame) 、页面(Page) 表格(Grid) 、列(Column)、选项按钮组(Command Button)、命令按钮组(Command Button) 和工具(Tool) 。 VFP 包含下列控件类: 标签(Label)、文本框(TextBox)、编辑框(EditBox)、列表框(ListBox)、组合框 (ComboBox) 、命令按钮(Command Button) 、复选框(CheckBox)、控件(Control) 、图像 (Image)、微调(Spinner) 、计时器(Timer) 、标头(Header) 、OLE 绑定型控件(OLE Bound Control) 、OLE 容器控件(OLE Container Control) 、自定义(Custom)、形状(Shape) 、线条 (Line)和分隔符(Separator) 。

7.2

用类设计器交互创建类

在 VFP 中,可以使用类设计器交互修改扩展基类和创建新类。新生成的类存储在类库文 件(.VCX)中。利用类设计器可以创建可视类和非可视类,其中可视类是指基于可视容器和 控件的类,非可视类是指基于 Custom 类的类。在应用程序中可视类一般用于控制程序和输 入、输出的作用。非可视类则用于定义一种特殊的对象或数据单元。 使用类设计器来扩展、创建类,启动类设计器有下列 3 种方法。 (1)在项目管理器中,选择“类”选项卡,单击“新建”按钮。 (2)在 VFP 的“文件”选单中选择“新建”命令,再选择“类” ,然后,单击“新建文 件”按钮。 (3)在命名窗口中输入 CREATE CLASS 命令。 上述操作后首先出现下列“新建类”对话框,如图 7.1 所示。

·130·


图 7.1

“新建类”对话框

在“新建类”对话框中的“派生于”栏内选择“Custom”,将创建一个自定义类,选择其 他基类名,则用于扩展基类。当单击“确定”按钮后,系统打开“类设计器”,并根据在“派 生于”栏内选择基类名自动建立一个默认的新类。在“类设计器”中创建的新类,用户在设 计阶段所看到的外观将是由这个类所创建的对象的外观。 1.添加对象 如果新类基于容器类,则可以向它添加控件。在“表单控件”工具栏中单击所要添加的 控件的按钮,将它拖动到“类设计器”中,再调整它的大小。具体操作方法与表单中设计相 同。基于新类建立的对象的下列属性及意义如表 7.1 所示。 表 7.1 属

新类建立的属性及意义 说

Class

新类名称

BaseClass

新类的基类

ClassLibrary

新类的类库文件名

ParentClass

对象所基于的父类。若该类直接由 VFP 基类派生而来,则 ParentClass 属性值与 BaseClass 属性值相同

不仅可以修改已有属性和重新编写已有方法程序的代码,也可以创建新的属性和方法程 序。没有修改的属性和方法,则继承了父类的属性和方法。 2.添加新属性 不论新类是基于什么类,不仅可以对已有属性进行修改,也可以创建新的属性。没有修 改的属性,则继承了父类的属性。尽管 VFP 对一个类所拥有的属性数量不作限制,但如果通 过方法程序没有利用该属性做什么事,那么这个属性实际上就没有存在的必要。添加新属性 包括添加属性和指定属性的默认值。 单击 VFP“类”主选单,选择“新建属性” ,弹出“新建属性”对话框,如图 7.2 所示。

图 7.2

“新建属性”对话框

在“新建属性”对话框中, “名称”栏输入要添加的属性的名称。 “可视性”栏指定该属性在什么层面进行操作。可视性分为公共、保护或隐藏 3 种。其中, ·131·


“公共”是默认值,表示可在对象的设计时进行修改。若属性设置为“保护” ,则只能被该类 定义内的方法程序或该类的子类所访问,类实例化后无法对其进行修改,该属性的值显示为 斜体字。若属性设置为“隐藏”,则只能被该类内定义的成员所访问,该类的子类不能“看到” 和引用,该类实例化后这个属性也不会显示。 “说明”栏:用户还可以加入有关属性的说明。 单击“添加”按钮后,新的属性就会添加到类中。 创建了一个新属性后,VFP 默认其设置为“假” (.F.) 。用户可使用“属性”窗口为属性 指定一个希望的默认值。在“类设计器”中,打开“属性”窗口,在“其他”选项卡中,单 击刚加入的这个属性并将它设置为需要的值。这样,在把类添加到表单或表单集时,该值将 作为初始的属性值。如要使属性的默认设置为空字符串,可选择“属性编辑”框,然后按 BackSpace 键。 3.添加方法程序 与创建类中添加新的属性一样,用户也可以向创建类中添加新的方法程序。方法程序所 保存的是调用时可以运行的过程代码。 添加新方法程序与添加新属性的操作是相似的。选择 VFP 主选单中的“类”选单下的“新 方法程序” ,将弹出“新方法程序”对话框。在“新方法程序”对话框中“名称”栏内,输入 方法程序的名称。在“可视性”栏内指定可视性为公共、保护或隐藏。为确保类的正确功能, 防止用户编程从类外调用方法程序,添加新方法可设置为保护或隐藏。 在“说明”栏内,用户可以加入有关方法程序的说明。 单击“添加”按钮后,新的方法程序将被添加到类中。 在实际操作中要注意类的属性和方法不能同名。 4.为类指定图标 当用户要为一个类指定显示外观时,可以通过“类信息”对话框为类指定工具栏图标和 容器图标。 在“类设计器”中,从 VFP“类”主选单中选择“类信息”选单项后,将会显示“类信 息”对话框,如图 7.3 所示。

图 7.3

“类信息”对话框

在“工具栏图标”和“容器图标”框中分别输入 BMP 文件的名称和路径。 ·132·


工具栏图标的 BMP 文件必须是 15*16 像素点大小。如果图片过大或过小,它将被调整到 15*16 像素点,但图形可能变形。 把类和工具栏一起放入类库后,工具栏图标将显示在“表单控件”工具栏中。当设置容 器图标后,类在“项目管理器”和“类浏览器”中所显示的图标将是用户所设置的图标。 另外,在“新类”对话框中的“派生于”栏内选择“Custom”,系统将创建一个自定义类。 当单击“确定”按钮后,在“类设计器”中将显示自定义类。在运行期间,基于自定义类(Custom) 的子类属于非可视类也就是说,通过自定义类所创建的对象在运行期间不可见。但它同样具 有属性和方法程序,使用“类设计器” ,用户可以为自定义类设置外观,通过“类”选单栏中 的“新建属性”和“新建方法程序”选单项,为自定义类创建新的属性和方法程序。 自定义类属于非可视类(计时器控件也是非可视类),在设计阶段“表单设计器”中是可 见的,当用户把自定义类添加到表单时,如果想在“表单设计器”中显示它,需要将自定义 类的 Picture 属性设置为一个 BMP 文件,如果没有设置图片属性,那么在设计阶段所见到的 将是 VFP 默认的自定义类图片。 【例 Ex_CRecmove】建立记录移动命令按钮组类。 (1)启动“类设计器”。系统显示“新建类”对话框,如图 7.4 所示。

图 7.4

“新建类”对话框

通过“新建类”对话框, “类名”栏中指定新类的名称 My_RecordMove, “派生于”栏中 为新类指定基类 CommandGroup。 “存储于”栏中指定保存新类的类库名为 RY_Class.VCX。 类库是存放类的文件,一个类库可存放若干个类的定义。单击“确定”按钮,系统打开“类 设计器” 。 因为在上例中选择的是命令按钮组,所以系统开始时以默认状态产生了两个命令按钮, 用户即可像在表单中建立命令按钮组一样在“类设计器”开始设计新类。在“类设计器”中 命令按钮的布局、设置属性、编写对象的事件代码的方法与在表单设计器中一样。 (2)命令按钮布局、属性设置。 设置 My_RecordMove.ButtonCount=4 重新横向排列 4 个命令按钮;使 4 个命令按钮的 Caption 属性为空;使 4 个命令按钮的 Picture 的属性分别为 4 个(BMP)图标文件名。设置后的界面如图 7.5 所示。

图 7.5

类设计器实例

·133·


(3)编写事件代码。 *

My_RecordMove 的 Click 事件代码:

sel=THIS.Value DO CASE CASE sel=1 GO TOP CASE sel=2 IF !BOF() SKIP - 1 ENDIF CASE sel=3 IF !EOF() SKIP ENDIF CASE sel=4 GO BOTTOM ENDCASE

(4)关闭类设计器,系统询问是否将 My_RecordMove 类保存到 RY_Class.VCX 库中,回 答是即可完成新类的创建。 以上所介绍的是使用“类设计器”扩展和创建类的步骤。VFP 还提供了另外一种比较简 捷适用的扩展和创建类的方法,它可以使用户在程序设计的过程当中,将其所设计的表单及 控件作为一个新类保存在类库中。 比如说,用户创建一个表单,并且其上面分布有各种控件。将表单及其所包含的控件进 行合理的布局,并将属性、方法和事件代码一一设置后,选择 VFP“文件”主选单下“另存 为类”项。它的功能就是将用户所设计的表单或控件作为一个新类保存在用户所指定的类库 中。

7.3

新定义类的使用

创建了类后,就可使用这些类来进行应用程序的设计与开发。 1.添加到表单 要使用存储于类库之中的类,首先应将其打开或注册。至少有 3 种方法可以将类库打开 或注册。 (1)使用“项目管理器”。在“项目管理器”中选择“类”选项卡,单击“添加”按钮, 将会弹出“打开”对话框。在“打开”对话框中,选择一个类库并打开。 所打开的类库将被添加到项目之中,用户就可以将类从“项目管理器”拖动到“表单设 计器”或“类设计器”中。也可在“表单设计器”或“类设计器”的表单控件工具栏上直接 显示它们,然后用与添加标准控件同样的方法将它们添加到表单或其他容器之中。 (2)利用“选项”对话框。在“工具”主选单中选择“选项”选单项,启动“选项”对 话框,并选择“控件”选项卡。如果想在以后的 VFP 工作期中让类库出现在“控件”工具栏 ·134·


上,则选择“设置为默认值”。 可以单击“表单控件”工具栏的“查看类”按钮来注册一个类库,在出现的快捷选单中 选择“添加”,将类库添加到“表单控件”工具栏。 2.覆盖默认属性设置 将基于新创建的类的对象添加到表单后,用户可以修改所创建对象中所有未被保护的属 性,覆盖其默认的属性设置。此后即使在“类设计器”中该属性的值被修改,被覆盖的属性 的值也不会改变。但是,如果用户没有修改表单中对象的属性设置,则在“类设计器”中修 改了类中的属性后,由这个类所创建的对象的相关属性将会同时改变。 例如,用户将一个新建类的对象添加到表单,并且将其 BackColor 属性从白色修改为红 色,此时如果再将类的 BackClolor 属性改成绿色,用户表单上的对象的 BackColor 属性仍然 是红色。但如果用户没有修改对象的 BaclColor 属性,而将类的 BaclColor 属性改为绿色,那 么表单上的对象继承这一修改,也变为绿色。 3.调用父类方法程序代码 对象和子类自动继承基类的功能。但同时用户也可以用新的功能替代这些继承来的功 能。比如,用户由某个基类派生出子类,或把基于这个类的对象加入到一个容器中时,重新 为相应的 Click 事件编程。那么,在运行时,基类的代码不会运行,而运行新的代码。而有 时用户希望向新类或对象中添加新功能的同时,保留父类的功能。事实上,在面向对象的程 序设计中很关键的一点就是决定哪些功能应包含在基类中,哪些功能应包含在子类中,哪些 功能应包含在对象中。用户可以在类或容器层次的各级代码中使用函数 DODEFAULT()或 作用域操作符(::)来调用父类中的程序代码。

7.4

编程创建类和表单

采用表单设计器创建表单是用户利用系统提供的工具交互创建表单。有时需要创建的表 单事先无法确定,而需在应用程序运行时根据情况动态建立,这时只能通过编程创建表单。 【例 Ex_CForm】编程创建表单,单击表单后显示如图 7.6 所示的界面。

图 7.6

编程创建表单界面

* Ex_CForm 程序 PUBLIC MyForm MyForm = CREATEOBJECT ("Form1")

&& 根据定义表单类建立对象

MyForm.Show

·135·


MyForm.Circle(60,100,150,1)

&& 在表单上画圆

READ EVENTS DEFINE CLASS Form1 AS Form ADD OBJECT COMM1 AS CommandButton;

&& 定义表单类 && 定义表单中的命令按钮

WITH Caption='终止',BackColor=2,Left=40 ADD OBJECT TEXT1 AS TextBox;

&& 定义表单中的文本框

WITH Top=60,Left=40 PROCEDURE Click

&& 表单的 Click 事件代码

=MESSAGEBOX("Form 的 Click!") THISFORM.TEXT1.VALUE="测试数据" ENDPROC PROCEDURE Comm1.Click

&& 命令按钮的 Click 事件代码

=MESSAGEBOX("终止的 Click!") THISFORM.Release CLEAR EVENTS ENDPROC ENDDEFINE

说明: 以上程序中用到的 DEFINE CLASS 语句创建一个用户定义的类或子类,且指定类和子类 的属性、事件和方法。 格式: DEFINE CLASS 类名 1 AS 基类名 [[Protected 属性名表] 属性名=表达式 …] [ADD OBJECT [Protected] 对象名 AS 类名 2 [NOINIT] [WITH 属性名=表达式,…]…] [[Protected] FUNCTION | PROCEDURE 对象引用.事件名 语句序列 [ENDFUNC | ENDPROC] …] ENDDEFINE

参数“类名 1”指定要创建的类的名称。 “基类名”指出一个类或子类的父类。父类可以 是一个 Visual FoxPro 的基类或另一个用户定义的子类。一个不可视的用户定义类可用基类名 指定为“Custom”创建。 Protected 属性名表阻止从类或子类定义的外部访问或改变对象的属性。属性名=表达式 为属性赋值。未赋值的属性使用该属性的默认值。例如: DEFINE CLASS MyClass AS Custom PROTECTED Version

·136·


Name='' Version='V1.0'

&& Version 属性被保护

ENDDEFINE

ADD OBJECT 从一个 Visual FoxPro 基类、用户定义类、子类及 OLE 定制控件向类或子 类定义中添加一个对象。PROTECTED 阻止从类或子类定义的外部访问或改变对象的特性。 PROTECTED 关键字必须放在 ObjcetName 的前面,否则,FoxPro 生成一个语法错误。 ObjectName 指出一个对象名,并用来从类或子类来定义内部引用对象。 “AS 类名 2”指出包 含加入类定义中的对象的类或子类名。参数 NOINIT 指出当一个对象被添加时,INIT 方法不 被执行。WITH 属性名=表达式指出要加到类或子类定义中去的对象的属性和属性值的列表。 FUNCTION 或 PROCEDURE 可在类或子类定义内创建一个事件和方法程序。函数或过 程程序以 ENDFUNC 或 ENDPROC 结束。 用 DEFINE CLASS 定义的类是一组命令,像一个程序中的过程一样,一般放在程序的后 面。要使用 DEFINE CLASS 定义的类或子类定义创建一个对象,可使用 CREATEOBJECT() 函数。 【例 Ex_CGrid】编程创建表单及其网格,界面显示如图 7.7 所示。

图 7.7 *

编程创建表单及其网格界面

Ex_Cgrid 程序

Set Default to d:\RY_Mis USE 基本情况 MyForm = CREATEOBJECT('Form') MyForm.Width=480 MyForm.Closable = .f. MyForm.AddObject('cmdCommand1','cmdMyCmdBtn') MyForm.AddObject('grdGrid1','Grid') WITH MyForm.grdGrid1 .columnCount=5 .Left = 25 .width=400 .Visible = .T.

·137·


ENDWITH MyForm.grdGrid1.SetAll("DynamicBackColor","IIF(性别='女',RGB(0,255,0); ,RGB(255,255,255))","Column")

&& 性别为女的记录底色为绿色

MyForm.cmdCommand1.Visible =.T. WITH MyForm.grdGrid1 .Column1.Header1 .Caption = Field(1)

&& 指定字段名作标题

.Column2.Header1 .Caption = Field(2) .Column3.Header1 .Caption = Field(3) .Column4.Header1 .Caption = Field(4) .Column5.Header1 .Caption = Field(5) ENDWITH MyForm.SHOW READ EVENTS

DEFINE CLASS cmdMyCmdBtn AS CommandButton Caption = '退出' Cancel = .T. Left = 125 Top = 210 Height = 25

PROCEDURE Click CLEAR EVENTS CLOSE ALL ENDDEFINE

本例仅定义了一个命令按钮类,在建立了一个表单实例后再用 AddObject 方法向其中加 入其他对象。

·138·


第 8 章 查询和视图 将数据保存在数据库中的目的之一是能够对数据进行快速分析。在 VFP 中,数据分析是 通过查询(Query)实现的。利用 VFP 的查询功能,可以从一个或多个表中选择所需的数据。 其中,基于多表进行关联查询更有意义。 查询只能从表中提取数据,但不能对这些数据进行修改。如果既要查询数据,又要修改 数据,可以使用视图(View)。 在设计表时,一般按主题把数据分解到不同的表中,这样便于管理和提高操作效率。但 有时又需把分散在相关表中的数据通过连接条件收集到一起,构成一张“虚表”(也就是视 图) 。之所以称为“虚表” ,是因为视图中并不保存数据,数据仍存放在导出视图的源数据表 中。所以,又把导出视图的源数据表称做“基表”(Base Table)。 视图是数据库的一个组成部分,它兼有查询和表的双重特点。像查询一样,可以用来 从一张或多张相关联的表中提取有用数据,但视图并不等同于查询,查询不能修改表中的 数据,而视图可以修改表中的数据。在很多情况下,视图的作用就等同于表,用视图中的 条件查询得到的数据组成视图的记录。例如,可以像打开表一样打开视图,对视图进行定 位、移动、编辑;可作为查询的数据源;给字段设置标题、设置字段的有效性规则、添加 注释等。

8.1

查询的创建和使用

在 VFP 中,数据保存在表中。数据库将多个表组织起来,并在表之间建立关系,使这些 表在逻辑上成为一个整体。保存数据的目的是为了使用数据和快速查询数据。使用查询功能, 可以方便地实现对各种数据的查询。 创建查询可以有 3 种方法:一是使用查询向导;二是使用查询设计器;三是直接编写 SELECT-SQL 语句。 使用查询向导,可以按序交互创建一个查询。通过引导用户回答一系列的问题逐步建立 查询。VFP 查询提供了 3 种向导:查询向导、交叉表向导、图形向导。各种向导的功能如表 8.1 所示。 使用查询设计器可以很方便地交互创建查询和修改已经建立的查询。 不管是用查询向导还是用查询设计器创建查询, 其结果都是生成一条 SELECT-SQL 语句, 在本质上是 SELECT-SQL 命令的可视化设计方法。 表 8.1 3 种查询向导的功能 查询向导类型

功 能 说 明

查询向导

创建一个标准的查询,在浏览窗口中显示查询结果

交叉表向导

按电子表格的形式显示查询结果

图形向导

以图形的形式显示查询结果

·139·


8.1.1 查询设计器 打开查询设计器有下列方法。 (1)“项目管理器”→选择“数据”选项卡→选择“查询”。 (2) “文件”选单→“新建”→选择“查询” 。或者单击“常用”工具栏的“新建”按钮。 (3)使用 CREATE QUERY 命令。 打开查询设计器后,查询设计器界面如图 8.1 所示。同时打开查询设计器工具栏。系统 还自动增加了一个查询主选单,如图 8.2 所示。另外,单击鼠标右键,还可弹出快捷选单。 系统提供的这些手段的功能基本相同,都是为了方便查询操作。

图 8.1 查询设计器

图 8.2 查询主选单

查询设计器对话框的上半部分为数据环境显示区,可看到所选择的两个表,两个表之间 有一条表示关系的连线。下半部分包括 6 个选项卡,各个选项卡的功能见表 8.2。 表 8.2

查询设计器的选项卡

选项卡

字段

设置查询输出的字段或表达式

连接

设置表之间的连接条件

筛选

设置筛选记录的条件

排序依据

设置查询结果排序的条件

分组依据

设置查询结果分组的条件

杂项

设置是否对重复记录进行检索,同时是否对返回的记录个数做限制

查询设计器工具栏的按钮说明如表 8.3 所示。 表 8.3 查询设计器工具栏的按钮说明 按 钮 名 称

·140·

添加表

为查询添加表或视图

移去表

从查询设计器中移去指定的表

添加连接

为查询中的两个表创建连接


续表 按 钮 名 称

显示/隐藏 SQL 窗口

显示/隐藏当前查询语句的窗口

最大化/最小化上部窗口

放大/缩小查询设计器的数据环境窗口

查询去向

指定查询结果的输出对象

1.查询设计器介绍 现对查询设计器进行介绍。 (1)数据环境。查询设计器对话框的上半部分为数据环境显示区,用来显示所选择的表 或视图,可以用“添加表( ) ”或“移去表( ) ”功能向数据环境添加或移去表。如果是 多表查询,可在表之间可视化连线建立关系。 (2)字段。在“查询设计器”中,选择“字段”选项卡,在“可用字段”框中列出了查 询数据环境中选择的数据表的所有字段;在“选定字段”框中设置在查询结果中要输出的字 段或表达式;“函数和表达式”框用来建立查询结果中输出的表达式。“选定字段”框中行的 顺序就是查询结果中列的顺序。 在“可用字段”框和“选定字段”框之间有 4 个按钮:“添加” 、 “全部添加” 、 “移去”和 “全部移去”按钮,用于选择或取消选定字段。 在“函数和表达式”框中,可以用来输入一个表达式,或单击“…”按钮,打开“表达 式生成器”对话框,生成一个表达式,单击“添加”按钮,表达式就出现在“选定字段”框 中。还可以给选定的字段或表达式起一个别名,方法是在“函数和表达式”框中字段名或表 达式后输入“AS 别名”,查询结果中就以别名作为该列的标题。 例如,在基本情况表中有出生时间字段,为了输出年龄,可以在“选定字段”框中加入 下列表达式: YEAR(DATE())-YEAR(ry!出生时间)+1 AS 年龄

在表达式中,用当前系统日期的年份减去出生时间的年份,得到职工的年龄,并给表达 式起一个别名为“年龄”。 (3)连接。进行多表查询时,需要把所有有关的表或视图添加到查询设计器的数据环境 中,并为这些表建立连接。这些表可以是数据表、自由表或视图的任意组合。 当向查询设计器中添加多张表时,如果新添加的表与已存在的表之间在数据库中已经建 立永久性关系,则系统将以该永久性关系作为默认的连接条件。否则,系统会打开“连接条 件”对话框,并以两张表的同名字段作为默认的连接条件,如图 8.3 所示。

图 8.3

“连接条件”对话框

·141·


在该对话框中有 4 种连接类型:内部连接(Inner Join) 、左连接(Left Outer Join) 、右连 接(Right Outer Join)和完全连接(Full Join) ,其意义见表 8.4 所示。系统默认的连接类型是 “内部连接”,可以在“连接条件”对话框中更改表之间的连接类型。 表 8.4

连接类型

连接类型 内部连接 左连接 右连接 完全连接

两个表中的字段都满足连接条件,记录才选入查询结果 连接条件左边表中的记录都包含在查询结果中,而右边表中的记录只有满 足连接条件时,才选入查询结果 连接条件右边表中的记录都包含在查询结果中,而左边表中的记录只有满 足连接条件时,才选入查询结果 两个表中的记录不论是否满足连接条件,都选入查询结果中

两表之间的连接条件也可以通过查询设计器的“连接”选项卡来设置和修改,如图 8.4 所示。

图 8.4

查询设计器的“连接”选项卡

(4)筛选。查询既可以查询所有记录,也可以查询满足某个条件的记录。指定选取记录 的条件可以使用查询设计器的“筛选”选项卡,如图 8.5 所示。

图 8.5

查询设计器的“筛选”选项卡

其中, “字段名”框用于选择要比较的字段;“条件”框用于设置比较的类型(见表 8.5) ; “实例”框用于指定比较的值;“大小写”框用于指定比较字符值时,是否区分大小写;“逻 辑”框用于指定多个条件之间的逻辑运算关系。如果用逻辑与运算符“AND”连接两个条件 组成筛选条件,则只有同时满足这两个条件的记录才能出现在查询结果中;如果用逻辑或运 算符“OR”连接两个条件组成筛选条件,则满足这两个条件中的任何一个记录就能出现在查 询结果中。“筛选”卡中的一行就是一个关系表达式,所有的行构成一个逻辑表达式。

·142·


表 8.5

条件类型和意义

条件类型

=

字段值等于实例值

Like

字段值与实例值匹配

==

字段值与实例值严格匹配

>(>=)

字段值大于(大于或等于)实例的值

<(<=)

字段值小于(小于或等于)实例的值

Is NULL

字段值为“空值”

Between

字段值在某个值域内。值域由实例给出,实例中给出两个值,两个值之间用逗号分开

In

字段值在某个值表中,值表由实例给出,实例中给出若干值,值与值之间用逗号分开

(5)排序依据。使用查询设计器,可以对查询结果中输出的记录排序。例如,使查询结 果按“出生时间”的先后顺序输出,或按“工资”的高低顺序输出。还可以使输出结果按多 个字段排序输出。例如,查询结果先按部门排序,同部门的职工再按工资高低排序。 “排序条 件”列表框中的顺序决定了排序的优先权。排序可以是升序,也可以是降序。在图 8.6 中设 置的排序条件就是先按“性别”升序排序,同性别者按工资降序排序。

图 8.6

查询设计器的“排序依据”选项卡

(6)分组依据。在查询设计器中还有一个“分组依据”选项卡。所谓分组就是将一组类 似的记录压缩成一个结果记录,以便完成对这一组记录的计算。例如,在“基本情况”表中 查询男女职工的工资总额,就可以按性别对表中的记录分组,然后求每一组记录中的工资总 额。下面来看一下“分组依据”的使用。 【例 Ex_QueryGroup】查询男女职工人数、工资总额和平均工资,并按平均工资的降序 排序。查询输出必须包含性别、人数、工资总额和平均工资。 本例按照性别进行分组,也就是说,把所有性别相同的记录压缩成一个记录,利用 COUNT() ,SUM()和 AVG()函数可以对每一组 记录进行计数、求和及求平均计算。另外,MAX() 是求最大值函数,MIN()是求最小值函数。 新建一个查询,选择“基本情况”表,在“查询设 计器”的“字段”选项卡中,将下列字段和表达式设置 到“选定字段”列表框中,如图 8.7 所示。 基本情况.性别 COUNT(*)AS 人数

图 8.7 查询设计器的“字段”选项卡

SUM(基本情况.工资)

·143·


AVG(基本情况.工资)

这里,给表达式 COUNT(*)起了别名“人数” 。 在“排序依据”选项卡中,选择 AVG(基本情况.工资)作为排序条件,设置为降序排 序。 在“分组依据”选项卡中,把“可用字段”中的“基本情况. 性别”字段添加到“分组 字段”中,如图 8.8 所示。

图 8.8

查询设计器的“分组字段”选项卡

这样就完成了本例的查询要求。查询结果如图 8.9 所示。

图 8.9 查询结果

如果在分组的基础上,还要对查询结果记录进行筛选,可以单击在“分组依据”选项卡 中的“满足条件”按钮,打开“满足条件”对话框,如图 8.10 所示。

图 8.10

图 8.11 查询设计器“杂项”选项卡

·144·

“满足条件”对话框

这里是对查询结果记录进行筛选,“筛选”选 项卡的筛选的记录才会作为查询操作的记录。 例如,加入 AVG(基本情况.工资)<1000,则 上述查询结果中只会显示“女”的一条记录。 (7)杂项。在“查询设计器”的“杂项”选项 卡中,可以设置一些特殊的查询条件,如图 8.11 所 示。 ① 如果选择复选框“无重复记录”,则查询结 果中将排除所有相同的记录;否则,将允许重复记


录的存在。 ② 如果选择复选框“交叉数据表”,将把查询结果以交叉表格式传送给 Microsoft Graph、 报表或表。只有当“选定字段”刚好为 3 项时,才可以选择“交叉数据表”复选框,选定的 3 项代表 X 轴、Y 轴和图形的单元值。 ③ 如果选择复选框“全部” ,则满足查询条件的所有记录都包括在查询结果中。这是查 询设计器的默认设置。只有在取消对“全部”复选框的选择的情况下,才可以设置“记录个 数”和“百分比”。 “记录个数”用于指定查询结果中包含多少条记录。当没有选定“百分比” 复选框时,“记录个数”微调框中的整数表示只将满足条件的前多少条记录包括到查询结果 中;当选定“百分比”复选框时, “记录个数”微调框中的整数表示只将最先满足条件的百分 之多少个记录包括到查询结果中。 (8)选择查询结果的输出去向。查询结果可以输出到不同的目的地。在“查询去向”对 话框中,根据需要可以把查询结果输出到如表 8.6 所示的不同的目的地。如果没有选定输出 目的地,系统默认值为查询结果显示在浏览窗口中。 表 8.6

输出去向

输出去向

浏览

将查询结果显示在“浏览”窗口

临时表

将查询结果存储在一张命名的只读临时表中

将查询结果保存在一张表中

图形

将查询结果用于 Microsoft Graph 应用程序

屏幕

将查询结果显示在 VFP 主窗口或当前活动窗口

报表

将查询结果输出到一个报表文件

标签

将查询结果输出到一个标签文件

从“查询”选单中选择“查询去向”,或在“查询设计器”工具栏中单击“查询去向”按 钮,屏幕上将出现“查询去向”对话框,如图 8.12 所示,在其中可以选择一个去向。

图 8.12

“查询去向”对话框

2.生成 SQL 语句 前面曾提到,不管是用查询向导还是用查询设计器创建查询,其结果都是生成一条 SELECT-SQL 语句。可以通过选择“查询”选单(或者快捷选单)中的“查看 SQL”项或单 击查询设计器的工具栏上的“SQL”按钮( )即可看到所生成的 SELECT-SQL 语句。例如: SELECT 基本情况.编号,基本情况.姓名,基本情况.文化程度,基本情况.职称; 基本情况.工资; FROM

ry!基本情况;

WHERE 基本情况.性别="女";

·145·


ORDER BY 基本情况.工资 DESC

一般情况下,用查询设计器创建查询的目的是通过交互设置,生成 SQL 命令。然后复制 下来,粘贴到自己的应用程序中或保存到查询文件中。 3.生成查询文件 查询创建完成以后,单击常用工具栏上的“保存”按钮或文件“选单”中的“保存”命 令,输入文件名,例如 Query1,系统自动为该文件加上扩展名“.QPR” ,即生成了查询文件 Query1.QPR。该文件中保存的就是 SQL 语句。 4.运行查询 运行查询的方法有多种。 (1)在项目管理器打开的情况下,选择要运行的查询文件,单击项目管理器上的“运行” 按钮,即可运行查询。 (2)在查询文件打开的情况下,单击“常用”工具栏上的“运行”按钮( )或“查询” 选单(或者快捷选单)中的“运行查询”项即可运行查询。 (3)在命令窗口或应用程序中用 DO 命令运行查询。例如:DO Query1.QPR。 【例 Ex_FSQL】查询出每个职工的编号、所在部门名称、姓名、职称、实发工资,并先 按部门名称的降序排序,再按编号的升序排序。 一般来说,对于一个查询要求,首先分析要查询哪些字段?有没有需要计算的表达式和 计算涉及哪些字段?然后,找出这些字段分别在哪个表或视图中?如果涉及多个表,就需要 找出表之间的连接关系。至此,查询所需要的数据环境、连接条件、输出字段或表达式已经 确定。最后,看一看查询结果是否需要排序?是否需要分组?等等。 本例中,职工的编号、姓名、职称来自“基本情况”表,实发工资来自“工资情况”表, 部门名称来自“部门工资”表,因此查询涉及 3 张表。其中“基本情况”表和“工资情况” 表可以通过职工的编号字段进行连接;而职工编号字段的前两位就是部门的编号,据此,可 以通过设置筛选条件,连接“基本情况”表和“部门工资”表。这样,3 张表有效地连接起 来了。 最后,根据要求设置查询结果的排序条件:先按部门名称降序排列,再按编号的升序排 列。 创建查询步骤如下: 首先,打开查询设计器,将“基本情况”表、 “工资情况”表及“部门工资”表添加到数 据环境中,用连接选项卡设置“基本情况”表和“工资情况”表,其连接条件如图 8.13 所示。 然后,通过用筛选选项卡设置如下筛选条件连接“基本情况”表和“部门工资”表:部 门工资.部门编号=LEFT(基本情况.编号,2) ,如图 8.14 所示。 接着,用字段选项卡设置要输出的字段,最后,选择排序依据选项卡设置查询结果的输 出顺序,如图 8.15 所示。 将创建的查询用 Ex_FSQL 文件名保存起来,则生成查询文件 Ex_FSQL.qpr。 运行此查询,输出结果如图 8.16 所示。

·146·


图 8.13 连接选项卡

图 8.14 设置筛选条件

图 8.15 设置输出字段

图 8.16

输出结果

·147·


8.1.2

SELECT-SQL 查询语句

VFP 提供了一些功能强大的结构化查询语言(SQL)命令。VFP 的 SQL 命令采用 Rushmore 技 术 来 优 化 系 统 性 能 。 一 个 SQL 命 令 可 以 用 来 代 替 多 个 VFP 命 令 。 这 里 主要 介 绍 SELECT-SQL 命令。 前面用查询设计器和视图设计器所做的工作,实质上都是生成一个 SELECT-SQL 命令。 单击“查询设计器”中的 SQL 按钮,就可以随时查看 VFP 在后台建立的 SQL 命令。这个按 钮可以交替地显示或隐藏 SQL 窗口。 1. SQL 语言概述 SQL(Structure Query Language,结构化查询语言)是美国国家标准局 ANSI 确认的关系 数据库语言的标准,用于对关系型数据库中的数据进行存储、查询、更新等操作。正是由于 SQL 语言的标准化,所以绝大多数关系数据库系统都支持 SQL 语言,它已经发展成为多种平 台进行交互操作的底层会话语言。 SQL 为用户提供了以下功能:数据定义、数据检索、数据操纵和数据控制。 SQL 语言是一种交互式的计算机操作语言,也是一种数据库编程语言,它不仅能够在单 机的环境下提供对数据库的各种访问操作,而且还作为一种分布式数据库语言用于客户-服务 器(Client/Server)模式数据库应用的开发。 VFP 支持如下 SQL 命令。 (1)SELECT-SQL。指定查询条件并执行查询命令,VFP 解释该查询,并且从表中检索 出指定的数据。 (2)ALTER TABLE-SQL。用于修改自由表的结构,可以对表中每一个字段的字段名、 字段类型、精度、比例、是否允许空值和引用完整性规则进行修改。 (3)CREATE CURSOR-SQL。用于创建一个临时表。临时表中的每一个字段由字段名、 字段类型、精度、比例、是否允许空值和引用完整性规则来定义。这些定义可从命令本身或 从数组获得。 (4)CREATE TABLE-SQL。用于创建一张表。新表的每一个字段由字段名、字段类型、 精度、比例、是否允许空值和引用完整性规则来定义。这些定义可从命令本身或从数组获得。 (5)DELETE-SQL。用于将表中的记录打上删除标记。 (6)INSERT-SQL。用于在已经存在的表的尾部追加一条新的记录。新增记录中的数据 可以是 INSERT 命令自带的,也可以来自一个数组。 (7)UPDATE-SQL。用于更新表中的记录,可以基于 SELECT-SQL 语句结果来更新记录。 2. SELECT-SQL 命令 数据库中的数据查询最终总是通过 SELECT-SQL 命令进行。SELECT-SQL 命令格式如下: SELECT [ALL | DISTINCT] [TOP n

[PERCENT]] 列名 [,列名…]

FROM 表名 [,表名…] | [INNER | LEFT | RIGHT | FULL JOIN 表名 ON 连接条件] [[INTO ARRAY 数组名 | CURSOR 临时表名 | DBF 表名 | TABLE 表名] | [TO FILE 文件名 [ADDITIVE] | TO PRINT [PROMPT] | TO SCREEN]] [WHERE 条件表达式] [GROUP BY 列名 [,列名…][HAVING 条件]]

·148·


[ORDER BY 表达式 [ASC/DESC]…]

SQL 查询语句的格式主要有 SELECT 子句、FROM 子句、INTO 和 TO 子句、WHERE 子 句、GROUP BY 子句和 ORDER BY 子句,其与查询设计器各选项卡的对比见表 8.7。 表 8.7 SELECT-SQL 命令与查询设计器各选项卡的对比 功

SQL 查询语句

查询设计器

设置数据源表

FROM 子句

定义数据环境

设置表间的连接条件

…JOIN…ON…子句

连接选项卡

设置输出字段

SELECT 子句

字段选项卡

筛选源表记录

WHERE 子句

筛选选项卡

设置结果顺序

ORDER BY 子句

排序依据选项卡

设置记录的分组和筛选分组

GROUP BY 子句

分组依据选项卡

指定有无重复记录

ALL/DISTINCT

杂项选项卡

指定结果的范围

TOP n [PERCENT]

杂项选项卡

设置输出类型

INTO 和 TO 子句

设置查询去向

SELECT 子句指明查询输出的项目(称为列)也可以是表达式。利用表达式可以查询表 中未存储但可以计算出的结果。为了构造表达式,SQL 提供了加(+) 、减(-) 、乘(*)、除 (/)4 种运算符和一些函数。若以*代替列名,则表示查询表的所有列。 FROM 子句指明被查询的表或视图名。 INTO 子句指明查询结果保存在何处,可以是数组、临时表或表。 TO 子句也是指明查询结果输出到何处。可以是文件、打印机或 VFP 主窗口。如果在同 一个查询语句中同时包括了 INTO 子句和 TO 子句,则 TO 子句不起作用。 SELECT 和 FROM 子句是每个 SQL 查询语句所必须的,其他子句是任选的。 WHERE 子句说明查询的条件。满足条件的查询结果可能不止一个,在 SELECT 子句中 有 DISTINCT 任选项,加了这个任选项,则要求消除查询结果中的重复项。 GROUP BY 子句将表按列的值分组,列的值相同的分在一组,HAVING 后的条件是选择 组的条件,符合条件的组才能输出。 ORDER BY 子句可对查询结果按子句中指定的列的值排序,ASC 表示升序,DESC 表示 降序。 【例 Ex_SELECT】下面的 SELECT-SQL 语句就是在【例 Ex_FSQL】中用查询设计器创 建查询时所生成的。 SELECT 基本情况.编号,部门工资.部门名称,基本情况.姓名,基本情况.职称; 工资情况.实发工资; ; FROM ry!部门工资, ry!基本情况 INNER JOIN ry!工资情况 ON 基本情况.编号 = 工资情况.编号; WHERE 部门工资.部门编号 = LEFT(基本情况.编号,2); ORDER BY 部门工资.部门名称 DESC,基本情况.编号

其中,SELECT 子句中所选择的各个字段,就是在查询设计器的字段选项卡中所选定的 字段;FROM 子句中指出的 3 张表就是数据环境中所设置的,其中, “基本情况”表和“工资 情况”表设置的按编号字段相等的内连接由 JOIN…ON…子句给出;WHERE 子句给出的条 件就是筛选选项卡中设置的条件,本例中作为“基本情况”表和“部门工资”表的连接条件; ·149·


ORDER BY 子句对查询结果按要求进行排序,也就是排序依据选项卡中所设置的排序条件, 先按部门名称的降序排序,同部门的职工再按编号排序。 3. SELECT-SQL 应用举例 SELECT,FROM,WHERE 3 个子句构成最常用、最基本的 SQL 查询语句。以下将举例 说明其应用方法。比较复杂的查询在稍后介绍。例子涉及的是前面多次用到的 3 张表:基本 情况.DBF、工资情况.DBF 和部门工资.DBF。 (1)简单查询。SQL 可以实现一张表上的任何查询。以下举例说明这种简单查询。 ① 查询全部信息。 【例 Ex_SQL1】查询基本情况表的全部信息。 SELECT *; FROM 基本情况 其中,* 表示全部的列。

② 不包含重复信息。 【例 Ex_SQL2】查询职工的姓名,对于重名的职工只显示一次。 SELECT DISTINCT 姓名; FROM 基本情况

使用 DISTINCT 可消除重复的值,这里表示去掉重复的姓名。 ③ 输出字段表达式。 【例 Ex_SQL3】查询职工的编号、姓名和年龄。 )-YEAR(出生日期)AS 年龄; SELECT 编号,姓名,YEAR(DATE() FROM 基本情况

SELECT 语句后面是列名。列可以是字段、字段组成的表达式或常数,AS 用来指定查 询结果中列的标题。这里表达式 YEAR(DATE() )-YEAR(出生日期)以“年龄”作为列 名显示。 ④ 排序查询结果。 【例 Ex_SQL4】查询工资在 800 元以上的职工的编号、姓名和工资,并按工资由高到低 列出。 SELECT 编号,姓名,工资; FROM 基本情况; WHERE 工资>1000; ORDER BY 工资 DESC

ORDER BY 子句中的 DESC 是用来指明显示结果的顺序,即工资由高到低输出。默认情 况下,是以升序排序(ASC)。WHERE 子句用来指定筛选记录的条件,有多个条件时,可用 AND 或 OR 连接。 SQL 的查询方式很丰富,它提供了 3 种谓词,它们分别是 BETWEEN,IN 和 LIKE。以 下举例说明这 3 种谓词的使用。 ⑤ 数据区间查询。 【例 Ex_SQL5】查询工资在 1000 到 1500 之间的职工的编号、姓名和职称和工资。 SELECT 编号,姓名,职称,工资; FROM 基本情况;

·150·


WHERE 工资 BETWEEN 1000 AND 1500

在查找中,如果要求某列的数值在某个区间内,可用 BETWEEN … AND;而如果要求 某列的数值不在某个区间内,可用 NOT BETWEEN … AND。 例如,查询工资不在 1000 到 1500 之间的职工的编号、姓名、职称和工资。 SELECT 编号,姓名,职称,工资; FROM 基本情况; WHERE 工资 NOT BETWEEN 1000 AND 1500

⑥ 数据包含查询。 【例 Ex_SQL6】使用 IN 的查询。查询具有本科和大专文化程度的职工的编号和姓名。 SELECT 编号,姓名; FROM 基本情况; WHERE 文化程度 IN ('本科','大专')

在查询中,经常会遇到要求表的列值是某几个值中的一个,这时可用 IN。同样可以使用 NOT IN 来表示与 IN 完全相反的含义。 ⑦ 数据匹配查询。 【例 Ex_SQL7】利用 LIKE 的查询。查询部门编号为“01”的职工的工资情况。 SELECT *; FROM 工资情况; WHERE 编号 LIKE '01___'

(或者 WHERE 编号 LIKE '01%')

在查找中,有时需要对字符串比较。LIKE 提供两种字符串匹配方式,一种是使用下划线 符'_' 匹配任意一个字符;另一种是用百分号 '%' 匹配 0 个或多个字符的字符串。同样可以使 用 NOT LIKE 表示与 LIKE 相反的含义。 (2)连接查询。在日常事务中往往要涉及到多个表之间的关系查询。SQL 语言也提供了 连接多个表的操作,可以在两个表之间按指定列的相同值将一个表中的行与另一个表中的行 连接起来,从而大大增强了其查询能力。 【例 Ex_SQL8】查询职工的编号、姓名、职称、工资和实发工资。 SELECT 基本情况.编号,基本情况.姓名,职称,工资,实发工资; FROM 基本情况,工资情况; WHERE 基本情况.编号=工资情况.编号

大家知道,编号、姓名、职称、工资在“基本情况”表中可以查到,实发工资在“工资 情况”表中可以查到,按照编号字段相等连接两张表。由于编号和姓名两个字段在两个表中 都出现,所以为了防止二义性,在其列名前加上表名作为前缀,以示区别。如果列名是惟一 的,则不必加前缀,例如,职称、工资和实发工资 3 个字段就不必加前缀。另外,为了减少 输入时的麻烦,可以在 FROM 子句中给表起一个别名。 SELECT RS.编号,RS.姓名,职称,工资,实发工资; FROM 基本情况 RS,工资情况 GZ; WHERE RS.编号=GZ.编号

这里,“基本情况”表用“RS”作为别名, “工资情况”表用“GZ”作为别名。 ·151·


(3)联合查询。在 SQL 语言中可以将 2 个或多个查询结果进行并操作(UNION) 。需要 注意的是,2 个查询结果进行并操作时,它们必须具有相同的列数,并且对应的列有着相同 的数据类型和长度(对应的列名可以不同)。UNION 运算自动去掉重复记录。 【例 Ex_SQL9】查询具有工程师职称和政工师职称的职工的编号和姓名。 SELECT 编号,姓名; FROM 基本情况; WHERE 职称='工程师'; UNION; SELECT 编号,姓名; FROM 基本情况; WHERE 职称='政工师'

【例 Ex_SQL10】查询具有工程师职称和实发工资高于 1000 元的职工的编号。 SELECT 编号; FROM 基本情况; WHERE 职称='工程师'; UNION; SELECT 编号; FROM 工资情况; WHERE 实发工资>1000

(4)嵌套查询。在一个 SELECT 命令的 WHERE 子句中出现另一个 SELECT 命令,则 称为嵌套查询或子查询,必须用括号括起来。在 WHERE 子句中最多可以有 2 个同级(不是 嵌套的)子查询。 【例 Ex_SQL11】查询实发工资高于 1000 的职工的编号、姓名和职称。 SELECT 编号,姓名,职称; FROM 基本情况; WHERE 编号 IN (SELECT 编号; FROM 工资情况; WHERE 实发工资>1000)

上述 SQL 语句执行的是两个过程,首先在“工资情况”表中找出实发工资高于 1000 的 职工的编号,然后再根据此编号在“基本情况”表中查出姓名和职称。 (5)库函数。SELECT 语句不仅可以通过 WHERE 子句查找满足条件的数据,还可以通 过函数对满足条件的数据进行统计、计数等运算。下列 5 种函数可以在 FROM 子句中与选定 的列一起使用。 MIN

求(字符、日期、数值)列的最小值

MAX

求(字符、日期、数值)列的最大值

COUNT(*)计算记录个数

·152·

COUNT

对一列中的值计算个数

SUM

计算数值列的总和

AVG

计算数值列的平均值


这些函数一般是从一组值中计算出一个汇总信息。GROUP BY 子句用来定义或者划分进 行统计与求和的组。 【例 Ex_SQL12】查询男女职工人数、最高工资、最低工资、工资总额和平均工资。 ,MAX(工资),MIN(工资),SUM(工资),AVG(工资); SELECT 性别,COUNT(*) FROM 基本情况; GROUP BY 性别

【例 Ex_SQL13】查出有 3 人以上具有相同职称的职称名称。 SELECT 职称; FROM 基本情况; GROUP BY 职称; HAVING COUNT(*)>=3

要特别注意 HAVING 子句和 WHERE 子句的区别。WHERE 子句用于指定表中元组所应 满足的条件,而 HAVING 子句用于指定每一分组所应满足的条件,只有满足 HAVING 子句 的条件的那些组才能在结果中被显示。即 HAVING 用于去掉不符合条件的若干组,如同 WHERE 用于去掉不符合条件的若干行一样。 在上例中,在表中按职称进行分组,然后在每个分组中检测其记录个数是否大于等于 3, 如果满足条件,则该组的职称才被输出。

8.1.3 查询的应用 在实际应用中,可以将查询结果用表单中的列表框控件显示出来。例如,显示职工的编 号、姓名、工资信息,如图 8.17 所示。 首先,创建一个表单 ApplySQL.scx,插入一个标签控件,Caption 属性设置为“编号 姓 名 工资” ,再插入一个列表框控件,如图 8.18 所示。

图 8.17

查询结果

图 8.18

创建表单

在列表框控件中有两个重要属性:RowSource 和 RowSourceType。这两个属性可以控制 在列表中显示的数据。当 RowSourceType 设置为 3 时,可以用 SQL 语句选择数据项。这时, RowSource 属性中应输入一条 SQL 命令;当 RowSourceType 设置为 4 时,RowSource 属性中 应为查询文件的文件名,例如 Query1.QPR。 ·153·


这里,将 RowSourceType 属性设置为 3,RowSource 属性设置为“SELECT 编号,姓名, 工资 FROM 基本情况”,如图 8.19 所示。另外,ColumnCount 属性设置为 3。

图 8.19

设置 RowSourceType 和 RowSource 属性

保存表单,运行可得到如图 8.17 所示的结果。

8.1.4 交叉表查询 交叉表查询是查询的一种,这种查询能以电子表格的形式显示出总结性的数据。例如, 在产品销售表中,一个客户所销售的各种产品的数量分布在多个记录中,因而,不能清楚地 表达每个客户所销售的各种产品的数量情况。最好是将一个客户所销售的各种产品的数量放 在一行中。这个要求可以通过交叉表查询来实现。 例如,根据产品销售表,建立产品销售交叉表。在“项目管理器”中新建一个查询,在 “新建查询”对话框中选择“查询向导” ,在“向导选取”中选择“交叉表向导”。 1. 字段选取 “交叉表向导”的第 1 个步骤是字段选取,选择“XS”表的 3 个字段:Khmc,Cpmc 和 Sl。 2. 布局 “交叉表向导”的第 2 个步骤是布局,可以用鼠标把“Khmc”字段拖动到“行”框中, 把“Cpmc”字段拖动到“列”框中,把“Sl”字段拖动到“数据”框。这样,在产品销售表 中有多少个客户,则在交叉表中就会有多少行;有多少种产品,则在交叉表中就会有多少列。 3. 加入总和信息 “交叉表向导”的第 3 个步骤是加入总和信息。在这里,可以为查询结果指定一个“总 计”列,这个“总计”列将会被加入到查询结果的最右侧。我们选择了系统的默认值。 4. 完成 “交叉表向导”的第 4 个步骤是完成。在这里,单击“预览”按钮可以查看查询的结果, 如果对结果满意,就可以单击“完成”按钮,结束交叉表向导的运行。如果对查询的结果不 满意,还可以单击“上一步”按钮,返回到向导的前几步重新选择数据。

·154·


8.2

视图的创建和使用

前面所介绍的查询可以很方便地从表中检索出所需要的数据,但不能修改所查出的数据。 如果既要查询数据,又要修改数据,可以使用视图。 因为视图是数据库的一部分,与数据库表有很多相似的地方。在很多场合下,它的作用 就等同于表,数据库提供给表的一些特性,例如,给字段设置标题、添加注释、设置字段的 有效性规则等,对视图同样适用。 在 VFP 中,可以创建两种类型的视图:本地视图和远程视图。本地视图能够更新存放在 本地计算机上的表,远程视图能够更新存放在远程服务器上的表。使用视图向导和视图设计 器都可以交互创建视图。也可以用命令方式直接创建视图。

8.2.1 创建本地视图 1.视图设计器 创建视图的过程与创建查询的过程非常相似。如图 8.20 所示为“视图设计器”对话框, 同查询设计器一样,上方用来设置数据环境;下方有 7 个选项卡,用来设定视图选择数据的 条件。其中 6 个选项卡(字段、连接、筛选、排序依据、分组依据、杂项)的作用和查询设 计器的一样,但多了一个更新条件选项卡,用于设置更新数据的条件。

图 8.20

“视图设计器”对话框

视图设计好后,可在项目管理器中运行或在视图设计器中运行。 在项目管理器中运行视图:首先,打开视图所在的项目文件,进入项目管理器;然后, 在项目管理器中选择要运行的视图,再单击“浏览”按钮,就可看到运行视图后的结果。 在视图设计器中运行视图有两种方法:在视图设计器中打开视图后,在“查询”选单中 选择“运行查询”命令;或在视图设计器中单击鼠标右键,在弹出的快捷选单中选择“运行 查询”命令。 2.命令方式 可以用以下的命令直接创建视图。 ·155·


格式: CREATE SQL VIEW ViewName AS SELECT_SQL 语句

例如,创建视图 XSS_View ,选择销售商表的全部信息,命令如下: CREATE SQL VIEW XSS_View AS SELECT * FROM 销售商

也可以使用已有的 SELECT-SQL 语句来创建视图,只要把 SELECT-SQL 语句存入一个变 量,然后用宏替换在 CREATE SQL VIEW 命令中调用即可。 例如,以上创建视图的命令,可以改成下列形式: v_SQL = "SELECT * FROM 销售商" CREATE SQL VIEW XSS_View AS & v_SQL

3. 使用视图更新基表数据 视图不仅可以显示数据,而且可以更新数据。在视图中更新数据与在表中更新数据相似。 并且,使用视图还可以对其基表进行更新。为此,需要在视图设计器的“更新条件”选项卡 中设置关键字段和设置“发送 SQL 更新”选项。下面举例说明如何使用视图的这个功能。 【例 Ex_EditView】建立职工的基本情况视图,包含下列信息:编号、姓名、出生时间、 文化程度、职称、工资及婚否字段,并使“职称”和“工资”字段可以更新,其他字段为不 可更新(这里的更新是指对基表的更新) 。 由于在视图设计器中,除更新条件选项卡是查询设计器所没有的,其余的设置与查询设 计器完全一样,所以,这里主要介绍更新条件选项卡的使用。 在视图设计器中,单击“更新条件”选项卡,设置更新条件。 其中, “表”框用于选择可更新的表; “字段名”框用于设置关键字段和可更新的字段, 字段名左边钥匙图标列按钮用于设置关键字段,铅笔图标列按钮用于设置可以更新的字段, 必须先设置关键字段,才能选取可修改的字段。视图根据关键字段的值来定位需要更新的记 录; “发送 SQL 更新”复选框用来设置是否把视图中修改的结果传回到基表中。 本例中,要更新的表是“基本情况” ,关键字段是编号,要更新的字段是职称和工资。选 择“发送 SQL 更新”复选框,设置表为可更新的,如图 8.21 所示。

图 8.21

设置“更新条件”

将视图存为 EditView,运行视图,结果如图 8.22 所示。 为了验证视图更新基表数据的效果,可做如下试验。 在项目管理器中选择视图 EditView,单击“浏览”按钮,然后修改一个职工的编号、姓 名、职称、工资字段,在视图中可看到这些字段的值都已被改掉。关闭视图浏览窗口,选择 “基本情况”表,单击“浏览”按钮,这时,可以看到视图中对编号和姓名字段的修改并没 有影响基表,因为,没有设定它们为可更新字段;而视图中对职称和工资字段的修改更新了 基表的数据,表示设定的可更新字段是有效的。这也说明了如果视图中的某个字段没有设置 ·156·


为可更新的,运行视图时,虽然也可以在浏览窗口中修改这个字段,但修改的结果不会送到 它所引用的基表中。

图 8.22 视图 EditView 的运行结果

更新字段也可以用下列命令来进行设置。 (1)设置关键字段。 =DBSETPROP("视图名.字段名","Field","KeyField",.T.)

(2)设置可更新字段。 =DBSETPROP("视图名.字段名","Field","UpdateName","基表.字段名")

(3)设置“发送 SQL 更新”。 =DBSETPROP("视图名","View","SendUpdates",.T.)

4. 创建参数化视图 为了使视图更加灵活,可以给视图的筛选条件设置参数,以避免每取一部分记录就创建 一个视图的情况。这种带有参数的视图称为“参数化视图” 。以后,运行视图时,VFP 将提示 输入参数值,系统根据所输入的正确的参数值,找出符合条件的记录。 【例 Ex_Para_View】建立一个视图,可以根据提供的职称,找出给定职称的职工的基本 情况。 首先,在项目管理器中,选择“本地视图” ,单击“新建”按钮,选择“基本情况”表后, 进入视图设计器。接着,选择“字段”选项卡,单击“全部添加”按钮,将所有字段添加到 “选定字段”框。然后,选择“筛选”选项卡,单击“字段名”框,选择用于筛选记录的字 段名为“职称” ,在“条件”框中选择比较的类型“=” ,在“实例”框中输入一个问号和参数 名“?职称”,如图 8.23 所示。

图 8.23 设置视图参数

·157·


保存视图,取视图名为 Para_View,关闭视图设计器,返回项目管理器。选择本地视图 Para_View,单击“浏览”按钮,这时会出现“输入视图参数”对话框,如图 8.24 所示。在该 对话框中输入“工程师”后,单击“确定”按钮,视图就显示职称为工程师的职工的基本情 况,如图 8.25 所示;如果输入“政工师”,则显示职称为政工师的职工的基本情况。

图 8.24

图 8.25

“输入视图参数”对话框

视图 Para_View 的运行结果

也可以用 CREATE SQL VIEW 命令带上“?”和一个参数来创建参数化视图。对于上例 可用下列命令: CREATE SQL VIEW Para_View ; AS SELECT * FROM 基本情况; WHERE 基本情况.职称=?职称

8.2.2 视图使用 因为视图是数据库的一部分,所以,视图也可设置为数据库表的一些特性。例如,可以 给字段设置标题、添加注释、设置字段的有效性规则等。 1.视图的打开 视图不作为单独文件保存,它只作为数据库的一部分而存在,因此,要打开视图必须先 打开数据库。 在“项目管理器”中先选择一个数据库,再选择视图名,然后单击“浏览”按钮,即可 在浏览窗口中显示视图。 也可以用 USE 命令打开视图。 OPEN DATABASE DataBaseName USE ViewName BROWSE

2.显示视图结构 如果只要打开视图并显示结构,而不必下载数据时,可以使用带 NODATA 子句的 USE 命令。对于远程视图,这个选项更为有用。另一种方法是设置视图的 MaxRecords 属性为 0。 但这种方法不如前一种方法有效。 USE ViewName NODATA BROWSE

·158·


在使用视图时,自动打开的本地基表并不在关闭视图时自动关闭,而必须另外发出命令 关闭基表。 3.关闭视图 仅关闭视图,用下列命令: SELECT ViewSell USE

关闭数据库中的所有视图和表,用下列命令: CLOSE TABLE

关闭数据库,则库中的表和视图也一起关闭: CLOSE DATABASES

4.设置视图字段的属性 同表一样,可以给视图字段设置标题、注释、默认值和规则。 若要设置视图字段属性,可在视图设计器对话框的字段选项卡中,选定要设置属性的一 个字段,并选择“属性” ,即可打开“视图字段属性”对话框,如图 8.26 所示,这时,可以 为该字段设置一些属性。 例如,前面曾给销售商表用命令方式建立了一个视图 XSS_View,在此视图中,字段名 都是用英文字母作为代号,很不直观,给 khmc 字段设置一个标题“客户名称” ,如图 8.26 所 示。

图 8.26

“视图字段属性”对话框

也可以用 DBSETPROP()函数来设置字段属性。例如,用 DefaultValue 属性为视图字 段指定默认值;用 RuleExpression 和 RuleText 属性为视图创建规则。

·159·


第 9 章 选单和工具栏 选单是应用系统一个非常重要的组成部分。所谓选单就是一系列选单项,每一个选单项 都对应一个命令或程序,选择选单项就可执行这些命令或程序,从而实现特定的功能。具有 良好风格的快捷、简单的选单系统对于实现应用系统的功能、方便用户操作至关重要。必须 花费一定的时间规划应用系统选单。 为了提高操作效率,可将那些频繁使用的选单项和功能定义工具栏按钮。使用类设计器 可创建用户自定义工具栏。 本章主要介绍创建选单、设计工具栏以及选单和工具栏协调等。

9.1

选单设计器

Visual FoxPro 6.0 中的选单分为(主)选单和快捷选单。主选单一般在运行时取代系统选 单,具有选单名和选单项列表。快捷选单是当用户在选定的对象上单击鼠标右键时出现的选 单,快捷选单列出了与选定的对象有关的操作命令,从这个快捷选单中选择选单项后可以执 行相应功能的命令。 在 Visual FoxPro 6.0 中,创建选单有两种方式:选单设计器和直接编程。使用选单设计 器创建选单更容易、更快捷。这里主要介绍用选单设计器创建选单。打开选单设计器的方法 有 3 种:使用“新建”命令;使用项目管理器;使用 CREATE MENU 命令。

9.1.1 选单设计器 打开选单设计器前系统显示“新建选单”对话框,如 图 9.1 所示。 根据需要选择选单和快捷选单后,系统即打开选单设 计器。选单和快捷选单的选单设计器基本相同。 1. “选单”选单 当选单设计器被打开后,在系统选单栏中增加了一个 图 9.1 “新建选单”对话框 “选单”选项。这个选项中包含一些与自定义选单有关的 选单命令。表 9.1 介绍了“选单”选单中包含的一些选单项。 表 9.1 选单项名称

快捷键

·160·

单内容进行增添、删除或修改,从而可以快速建立一个用户自定义的选单 Ctrl+I

在选单设计器窗口中,在当前以高亮度显示的选单项前添加一个选单或者子选单项。在选单 设计器中的“插入”按钮也可以完成相同的功能 打开“插入系统选单栏”对话框。使用这个对话框中列出的选单项内容,可以将系统选单栏

插入栏 删除选单项

使用这个命令可以将 VFP 的默认系统选单的内容显示在选单设计器中,允许用户对这些选

快速选单 插入选单项

“选单”选单的选单项

中的选单项插入到当前的选单项前,在选单设计器中的“插入栏”按钮也可以完成相同的功能 Ctrl+E

使用这个选单命令可以将当前选中的选单项从选单栏中删除。在选单设计器中的“删除”按 钮具有与这个选单命令相同的功能


续表 选单项名称

快捷键

定义好自己的选单栏后,可以使用这个选单命令生成带有.MPR 扩展名的一个程序,这个程

生成

序能创建所设计的用户选单

预览

预览用户自定义选单,与选单设计器中的“预览”按钮功能相同

2. 选单定义 选单设计器可以创建选单中的主选单、选单项、子选单和分隔相关选单项组的线条等。 选单设计器可分为 4 个部分:左侧是一个选单定义列表框;右上角为多层选单“选单级” 下拉式列表框;右侧中部是建立选单项命令区,包括 3 个按钮(插入、插入栏和删除) ;右下 角是一个预览按钮,如图 9.2 所示。

图 9.2 选单设计器

(1)选单定义列表框。所设计的选单的内容都显示在这个列表框中。图 9.2 列出了人员 信息管理系统的选单内容。这个列表框包含 4 列,表 9.2 对这 4 列的功能进行了总结。 表 9.2 选单定义列表框功能的总结 列

在这列中用户可以输入选单名称。选单或选单项名称应该能够表达这个选单的功能。如果用户在选单名称 选单名称

的文字中的某个字母前使用符号“\<” ,则用户可以使用 Alt 键与这个字母的组合键来访问这个选单或选单项, 称为热键 结果列是一个带有 4 个选项的下拉式列表。这个列表中的项可以确定当前设定选单的类别。这 4 个列表项 是:命令、填充名称、子选单和过程。 “命令” :可以为当前选单定义一个命令,当用户选中这个选单项后

结果

就会执行这个指定的命令。 “填充名称” :表示当前定义的这个选单是个选单项。“子选单” :表示当前定义的 选单项还包括一个下一级选单。“过程” :用户可以定义一个过程与当前的选单项联系在一起,当用户单击这 个选单项后,就会执行这个过程 功能区并没有标题。这个功能区显示的内容与“结果”列表的选择有关。如果在“结果”列表中选择“命 令” ,功能区是一个文本框,可以在这个文本框中输入一个命令;如果在“结果”列表中选择“填充名称” ,

功能区

可以在功能区中填写一个覆盖选单项的填充名称;如果在“结果”列表中选择子选单,功能区是“创建”按 钮,单击这个按钮后,可以为当前的选单定义子选单;如果在“结果”列表中选择“过程” ,功能区是“创 建”按钮,单击这个按钮,屏幕中将会显示出窗口,在窗口中可以为这个选单项编制过程代码

选项

选项列是一个按钮。单击“选项”按钮后,可以在屏幕中央显示出“提示选项”对话框。用户可以在这个 对话框中为当前的选单项设定快捷键、信息以及注释等信息

(2)多层选单下拉式列表框。这个下拉式列表位于对话框的右上角,被称为“选单级” 。 当用户定义了多层选单后,在这个下拉式列表中列出了选单名。用户可以在列表中选择选单 ·161·


名,从而访问不同层次的选单内容,然后在选单定义列表框中对选单的内容进行修改。 (3)选单项。在“选单项”区中有 3 个按钮,这 3 个按钮与设计选单项有着密切的关系。 插入:使用这个按钮,可以在当前选中的选 单项前添加一个新的选单项。这个新选单项的选 单标题为“新选单项” ,用户可以修改为合适的标 题。 插入栏:在子选单的当前选单项前插入一个 系统选单项。这个系统选单项列在“插入系统选 单栏”对话框中,如图 9.3 所示,可从中选择需 要的选单项。 删除:将当前选中的选单项删除。 (4)预览按钮。使用“预览”按钮可以暂时 屏蔽当前使用的系统选单,然后将用户自定义的 选单显示在系统选单条的位置,同时在屏幕中显 图 9.3 “插入系统选单栏”对话框 示出“预览”对话框。每当用户选择了一个选单 项后,在“预览”对话框中都会显示出当前正在预览的选单的选单名、提示以及命令等信息。 3. 设置快捷键 在选单设计器的列表框中, “选项”按钮可以用来定义对应选单项的快捷键、定义激活该 选单时的提示信息、确定废止选单或选单项的时间等。快捷键在任何时候输入都能激活该项 功能,而热键必须打开其所在的主选单后才起作用。 先选择相应的选单项,单击“选项”下的小方块按钮,弹出“提示选项”对话框,如图 9.4 所示。

图 9.4

“提示选项”对话框

该对话框中各选项功能如下。 (1)快捷方式:可在其中定义快捷键。 (2)位置:可在其中指定当用户在应用程序中编辑一个 OLE 对象时选单标题的位置。 (3)跳过:显示“表达式生成器”。在“表达式生成器”的“跳过”框中,键入表达式来 ·162·


确定选单或选单项是否可用。在运行时,如果表达式的值为“真” (.T.),则该选单或选单项 就将被禁止。 (4)信息:显示“表达式生成器” 。在“表达式生成器”的信息框中,可以键入用于说明 选单选择的信息,说明信息将出现在 Visual Foxpro 6.0 状态栏中。 (5)主选单名:可在其中指定可选的选单标题。 (6)备注:提供输入个人使用的备注的空间。在任何情况下备注都不影响所生成的代码, 运行选单程序时 Visual Foxpro 6.0 将忽略备注。 如果要为选单项指定快捷键,可以先在“键标签”文本框中单击鼠标,然后按下所需的 快捷键,比如 Ctrl+C 键,则在框中显示所按下的快捷键。 其中, “键标签”中显示的是按键的名称, “键说明”中显示的是希望在选单项中出现的 提示信息,可以对该内容进行手工修改。 4. 设置选单项分界线 在选单中通常会把不同的功能项进行分组。只要在“选单名称”中输入“\-” ,则在选单 中的该选单项的位置处将出现一条分界线。

9.1.2 创建主选单 1. 定义选单 在刚进入选单设计器时,选单设计器是空的,此时可以设计自己的选单。 【例 Ex_Menu】设计一个简易人员信息管理系统的选单,主选单有 4 项:建立、查询、 报表和帮助。每一项下面都有子选单。其中“建立”选单的选单项为“数据表直接编辑”和 “视图更新编辑”;“查询”的选单项为“常规查询”和“SQL 查询” 。 在“选单名称”列中输入每一个选单的名称。“结果”列都选择子选单,如图 9.2 所示定 义了 4 个选单选项:建立、查询、报表、帮助,同时为每一个选单设定热键分别为 C,Q,R, H。这是出现在屏幕顶部系统选单栏位置上的选单。下面定义子级选单,也就是选择主选单 项后,下拉出的该选单的各个选单项。 先为“建立”设置子选单数据表直接编辑和视图更新编辑。单击“创建”按钮,将显示 二级选单的编辑界面,可以按照上面同样的方法,在“选单名称”中输入子选单的名称, “结 果 列 ” 都 选 择 命 令 , 所 执 行 的 命 令 分 别 为 DO FORM EX_EDIT.SCX 和 DO FORM EX_VIEW.SCX。注意,这时“选单级”中显示的是“建立 C” ,如图 9.5 所示。

图 9.5

建立的二级选单

·163·


同样为“查询”建立二级选单。常规查询执行命令 DO FORM EX_QUERY.SCX,SQL 查 询执行命令 DO EX_FSQL.QPX。 各级选单定义完成以后,回到设计器的主界面,选择系统选单栏的“选单”,单击“生成” 命令,这时,会出现“生成选单”对话框,如图 9.6 所示。在此对话框中单击“生成”按钮, 系统自动生成这个选单的程序代码,并以扩展名.MPR 保存代码。这时,可以单击选单设计器 上的“预览”按钮,预览设计好的选单。

图 9.6

“生成选单”对话框

2. 执行自定义的选单 上面通过选单设计器设计选单最终生成了一个选单文件 EX_Menu.mpr,现在,可以执行 这个选单文件,观察一下效果。 执行一个选单通常都使用 DO 命令,当然,Visual FoxPro 6.0 系统中也可以使用其他的可 视化的方式执行选单文件。例如,在命令窗口中输入“DO”命令可以执行 EX_Menu.mpr 选 单文件。在项目管理器中,选择要运行的选单,单击“运行”按钮,即可运行选单。 执行选单之后,新的选单将替换系统选单,如图 9.7 所示。

图 9.7

执行自定义选单

如果要恢复系统选单,可以在命令窗口中输入下列命令。 格式: SET SYSMENU TO DEFAULT

3. 在系统选单中插入一个选单 在 Visual FoxPro 6.0 中,每当打开设计器时,系统选单栏中会发生一些变化。比如使用 查询设计器时,系统选单栏中就添加了一个“查询”选单,“查询”选单中所有的选单项都与 查询设计工作有关,这就是 VFP 插入系统选单功能。下面介绍如何设置自定义选单的执行方 式,例如,是插入系统选单栏中,还是替换系统选单栏。 在选单设计器中打开 EX_Menu,选择系统选单栏中“显示”选单的“常规选项”命令, 弹出“常规选项”对话框,如图 9.8 所示。 在“位置”区域有 4 个单选按钮: 选择“替换”,则生成的选单在执行时将会替换系统选单显示在选单栏中,这是系统默认 值; 选择“追加” ,则生成的选单在执行时将会被放置在系统选单栏的最后一项的后面; 选择“在…之前”,则生成的选单在执行时将会被插入指定的系统选单栏的某一项的前面; 选择“在…之后”,则生成的选单在执行时将会被插入指定的系统选单栏的某一项的后面。 现在做如下设置:单击“在…之前”单选按钮,在这个单选按钮的右侧显示一个下拉式 列表,其中列出了所有的系统选单名。选择“帮助”选单,单击“确定”按钮,则这个选单 在执行时将会显示在“帮助”选单之前。 ·164·


图 9.8

“常规选项”对话框

选择“选单”中的“生成”命令,重新生成该选单的程序代码。在命令窗口输入命令 DO EX_Menu.MPR,在系统选单栏中“帮助”选单之前就出现了 EX_Menu.MPR 自定义选单。 利用“常规选项”对话框除了可以设置选单的执行方式,还可以为整个选单系统指定代 码,包括设置代码和清理代码。 4. 建立表单选单 建立表单选单与前面介绍的用户自定义选单不同,当表单选单设计完成以后,必须将其 设置为“顶层选单”,选单才能在表单中得以执行。 设置为“顶层选单”的步骤如下。 (1)在选单设计器打开时,选择系统选单栏中的“显示”选单下的“常规选项”命令, 弹出“常规选项”对话框,选择右下角的“顶层表单”复选按钮,表示这个选单是结合表单 的顶层选单,重新生成选单。 (2)修改表单的属性。打开要添加顶层选单的表单,在表单的属性窗口中,选择“布局” 选项卡,将“ShowWindow”属性设置为“2—作为顶层表单” ;再选择“方法程序”选项卡, 为“Init Event”属性添加如下代码: DO 选单文件名 WITH THIS,.T. 则运行表单时,“选单文件名”指定的选单将加载在表单中。

9.1.3 创建快捷选单 为了快速操作选定的对象,在 VFP 中可创建快捷选单。将这些作为快捷选单项操作功 能。程序运行时,单击鼠标右键时出现这个快捷选单,从这个快捷选单中选择选单项后可以 执行相应功能的命令。 选择“新建”→“选单”→系统显示“新建选单”对话框,选择快捷选单后,系统即打 开快捷选单设计器。 在一个空的选单设计器中,选择“选单”中的“快捷选单”命令,在选单设计器中就显 示出系统默认选单的内容,如图 9.9 所示。对之进行适当地修改,例如,增加或删除一些选 单项,然后生成代码,选单的制作就完成了。 快捷选单设计器和选单设计器功能基本相同,只是在“选单级”列表中显示的是“快捷 选单”4 个字,表示当前设计的选单是快捷选单。因为一个快捷选单没有选单标题,所以, 系统使用“快捷选单”这 4 个字作为快捷选单的标题。这时,在列表框中设计的选单内容都 ·165·


是快捷选单的选单项,只是这些选单项的设计方式与设计选单栏中的选单项没有区别。

图 9.9

使用“快捷选单”生成的选单

创建并生成快捷选单以后,可以将其 附加到对象中,这样,当用户在对象上单 击鼠标右键时,能显示指定的快捷选单。 将快捷选单附加到对象中的步骤如 下: (1)选择要附加快捷选单的对象(例 如,表单或表单上的某个控件)。 (2)在对象的属性窗口中选择“方法 程序”选项卡,并选择“RightClick Event” 项,如图 9.10 所示。 (3)双击“RightClick Event”项,在 代码窗口中输入“DO QuickMenuFile.mpr” 命令,如图 9.11 所示。

图 9.10 设置对象属性

图 9.11

9.2

设置代码

在应用程序中使用选单

在许多应用程序选单中,设计某些选单项可随程序运行状态启用或废止,VFP 6.0 选单设 计器提供了设置启用和废止条件的手段。 在 VFP 6.0 应用程序中可以控制用户对系统选单栏的访问,也可以对系统选单进行重新 ·166·


配置。 使用程序调用选单命令,既可以在应用程序启动时装入系统选单,又可以在应用程序运 行过程中更换系统选单。

9.2.1 启用和废止选单项 熟悉 Windows 的用户都知道,在系统选单中,每个选单下都有若干选单项,但并不是任 何时候,这些选单项都是可用的。例如,“编辑”选单中的“剪切”选单项,当没有选中某个 对象(例如一段文字)时,这个选单项是灰的,即此选单项是不可用的;当选中某个对象后, 这个选单项又变为黑的,即此选单项已被激活变为可用。 对于自己所设计的选单系统,同样可以根据不同的场合、不同的要求来设置某个选单项 是可用的还是不可用的。 例如,前面创建了一个选单 EX_Menu,现在,对其中的查询选单下的 2 个选单项做如下 改动,当选中其中一项进行查询时,该项就不能再选用;退出后又恢复为可用状态。 设置启用或废止选单项,操作步骤如下。 (1)在选单设计器中打开 EX_Menu.mpr。 (2)选择“选单名称”为“常规查询”,将“结果”栏选择为“过程” ,系统会提示“删 除命令?” ,回答“是” ,单击“创建”按钮,进入选单设计器过程编辑窗口,如图 9.12 所示, 输入下列命令。

图 9.12 过程编辑窗口

关闭编辑窗口,回到选单设计器。 (3)仿照第(2)步,修改“SQL 查询”选单栏,过程代码如下: SET SKIP OF BAR 2 OF 查询 q .T. DO EX_FSQL.qpr SET SKIP OF BAR 2 OF 查询 q .F.

(4)保存选单,重新生成选单。 运行修改后的 EX_Menu 选单,可以看到在没有执行任何查询时,“查询”选单下的 2 个 选单项都是可用的。当执行某个查询时,例如“SQL 查询” ,这时, “SQL 查询”选单栏是不 可用的,如图 9.13 所示。退出“SQL 查询”后,该选单栏又恢复为可用状态。

图 9.13

选单栏的废止和启用

·167·


9.2.2 配置系统选单 在程序执行过程中,Visual FoxPro 6.0 系统还允许使用 SET SYSMENU 命令启动或关闭 对系统选单栏的访问,也可以用这个命令移去 VFP 主选单系统中的选单标题和选单,对其重 新配置,当然也可以将其恢复。 格式: SET SYSMENU ON | OFF | AUTOMATIC | TO [选单列表] | TO [选单标题列表] | TO [DEFAULT] | SAVE|NOSAVE

说明如下。 (1)ON | OFF | AUTOMATIC 子句。当设置为 ON,且 VFP 等待键盘输入 BROWSE, READ,MODIFY COMMAND 等命令时,使得 VFP 主选单栏是可用的。如果设置为 OFF, 则在程序执行过程中关闭 VFP 主选单栏。如果设置为 AUTOMATIC,则使 VFP 的主选单栏 在程序执行过程中可见。可以访问选单栏,但选单项是否可用取决于当前正在执行的命令。 AUTOMATIC 是系统的默认设置。 (2)TO [选单列表] 子句和 TO [选单标题列表]子句。用来指定 VFP 主选单栏中选单或 选单标题的子集。这些选单或选单标题可以是主选单中的选单或选单标题的任意组合,相互 之间用逗号分开。 例如,下列命令仅保留了 VFP 系统的主选单栏中“文件”和“窗口”选单: SET SYSMENU TO _MFILE,_MWINDO

注意,要用 RELEASE BAR 命令指定选单中的可用选单项。 在 Visual FoxPro 6.0 中系统选单栏的内部名称是_MSYSMENU。其他各选单和选单标题 的内部名称分别见表 9.3~表 9.10。 表 9.3 选单标题

系统选单内部名称 内部名称

表 9.4 “程序”选单内部名称 选单和选单项

内部名称

_MSM_FILE

程序选单

_MPROG

编辑

_MSM_EDIT

运行

_MPR_DO

显示

_MSM_VIEW

取消

_MPR_CANCL

工具

_MSM_TOOLS

继续执行

_MPR_RESUM

程序

_MSM_PROG

挂起

_MPR_SUSPEND

窗口

_MSM_WINDO

第 1 个分隔线

_MPR_SP100

_MSM_SYSTM

编译

_MPR_COMPL

文件

帮助

(3)TO [DEFAULT]子句。如果 SET SYSMENU 设置为 TO DEFAULT,则将主选单栏恢 复为默认设置,可以用 SET SYSMENU SAVE 命令指定一个默认设置。 如果发出 SET SYSMENU TO 命令而不带任何其他参数,则关闭 VFP 主选单栏。 (4)SAVE | NOSAVE 子句。发出 SET SYSMENU SAVE 命令,可使当前选单系统成为默 认配置。如果在执行这个命令后修改选单系统,可通过发出 SET SYSMENU TO DEFAULT 命 令来恢复原来的配置。选择 NOSAVE 子句,重置选单系统为默认的 VFP 系统选单。但是, 只有在发出 SET SYSMENU TO DEFAULT 命令后才显示默认的 VFP 选单系统。 ·168·


表 9.5 “窗口”选单内部名称 选单和选单项

表 9.8 “工具”选单内部名称

内部名称

选单和选单项

内部名称

窗口选单

_MWINDOW

向导

_MTOOLS

全部重排

_MWI_ARRAN

第 1 个分隔线

_MTL_SP100

第 1 个分隔线

_MWI_SP100

拼写检查

_MTL_SPELL

隐藏

_MWI_HIDE

_MST_MACRO

全部隐藏

_MWI_HIDEA

类浏览器

_MTL_BROWSER

全部显示

_MWI_SHOWA

组件管理库

_MTL_GALLERY

清除

_MWI_CLEAR

代码范围分析器

_MTL_COVERAGE

循环

_MWI_ROTAT

运行

_MTL_RUNACTIVEDOC

第 2 个分隔线

_MWI_SP200

第 2 个分隔线

_MTL_SP200

命令窗口

_MWI_CMD

调试器

_MTL_DEBUGGER

数据工作期

_MWI_VIEW

第 3 个分隔线

_MTL_SP300

选项

_MTL_OPTNS

表 9.9 “文件”选单内部名称 选单和选单项

表 9.6 “显示”选单内部名称 选单和选单项 工具栏

内部名称 _MVI_TOOLB

表 9.7 “编辑”选单内部名称 选单和选单项 编辑选单

内部名称 _MEDIT

撤消

_MED_UNDO

重做

_MED_REDO

第 1 个分隔线

_MED_SP100

剪切

_MED_CUT

复制

_MED_COPY

内部名称

文件选单

_MFILE

新建

_ MFI_ NEW

打开

_ MFI_ OPEN

关闭

_ MFI_ CLOSE

全部关闭

_ MFI_ CLALL

第 1 个分隔线

_ MFI_ SP100

保存

_ MFI_ SAVE

另存为

_ MFI_ SAVAS

另存为 HTML

_ MFI_ SAVASHTML

还原

_ MFI_ REVRT

第 2 个分隔线

_ MFI_ SP200

导入

_ MFI_ IMPORT

导出

_ MFI_ EXPORT

第 3 个分隔线

_ MFI_ SP300

页面设置

_ MFI_ PGSET

打印预览

_ MFI_ PREVU

打印

_ MFI_ SYSPRINT

发送

_ MFI_ SEND

第 4 个分隔线

_ MFI_ SP400

退出

_ MFI_ QUIT

粘贴

_MED_PASTE

选择性粘贴

_MED_PSTLK

清除

_MED_CLEAR

第 2 个分隔线

_MED_SP200

全部选定

_MED_SLCTA

第 3 个分隔线

_MED_SP300

查找

_MED_FIND

再次查找

_MED_FINDA

帮助选单

_MSYSTEM

替换

_MED_REPL

目录

_MST_MSDNC

第 4 个分隔线

_MED_SP400

索引

_MST_MSDNI

插入对象

_MED_INSOB

搜索

_MST_MSDNS

对象

_MED_OBJ

第 1 个分隔线

_MST_SP100

链接

_MED_LINK

技术支持

_MST_TECHS

第 5 个分隔线

_MED_SP500

MICROSOFT ON THE WEB

_HELPWEBVFPFREESTUFF

属性

_MED_PREF

第 2 个分隔线

_MST_SP200

修饰

_MED_BEAUT

关于 VFP

_MST_ABOUT

表 9.10 “帮助”选单内部名称 选单和选单项

内部名称

·169·


9.2.3 程序调用选单 通过各章的学习,前面已经介绍创建选单、创建表单、建立查询。现在可以此为基础构 造一个简易的应用系统了。 设计 EX_Menu 时,在建立和查询子选单中用 DO 命令分别调用了表单和查询程序。现在 进一步完善这个选单系统,使它的功能更完备。 首先,对选单 EX_Menu.mpr 稍做修改,在主选单中加入一个“返回”选单项,使得在应 用程序使用完毕以后,可以返回 VFP 的系统画面。 在选单设计器中打开 EX_Menu.mpr,在选单名称这一列输入“返回”,结果这一列选择 “命令”,在功能区中输入命令 SET SYSMENU TO DEFAULT,如图 9.14 所示。

图 9.14 增加一个选单项

在这里将新增的选单项加在最后一项。如果要插入到中间,则可用鼠标选中要插入的选 单项位置,然后单击选单设计器中的“插入”按钮。如果要从选单设计器中删除某个选单项, 则可用鼠标选中要插入的选单项位置,然后单击选单设计器中的“删除”按钮。也可以在子 选单的当前选单项前插入一个系统选单项。这个系统选单项列在“插入系统选单栏”对话框 中,可从中选择需要的选单项。 现在,以 EX_MAIN.PRG 作为应用系统的主程序,则主程序中可以用 DO EX_Menu.MPR 命令调用选单。这样一个简单的应用系统就构成了。

9.3

创建自定义工具栏

选单中经常执行选单项对应的任务,可以创建自定义工具栏,以方便用户的操作。工具 栏是一组图形小按钮,单击后可以执行指定的命令。工具栏可以浮动在窗口中,也可以停放 在 Visual FoxPro 6.0 主窗口的上部、下部或两边。可以定制 Visual FoxPro 6.0 提供的工具栏, 也可以用 Visual FoxPro 6.0 提供的工具栏基类创建自己的工具栏。

9.3.1 创建工具栏类 要创建自定义工具栏,可先为它定义一个类。Visual FoxPro 6.0 提供了一个工具栏基类, 在此基础上再创建所需工具栏类。 ·170·


要创建一个自定义的工具栏类,需要经过以下几个步骤。 (1)在项目管理器中选择“类”选项卡,单击“新建”按钮,弹出“新建类”对话框, 如图 9.15 所示。

图 9.15

“新建类”对话框

(2)在“类名”中输入所建新类的名称,例如 EX_ToolBar;在“派生于”列表框中选择 “Toolbar”基类,以使用工具栏基类;在“存储于”栏中输入存储所建新类的类库名,例如 EX_ToolBar.vcx。 单击“确定”按钮,进入类设计器,如图 9.16 所示。 (3)在类设计器中,使用表单控件工具栏向新建的工具栏类添加所需的对象。先从“表 单控件”工具栏中单击要添加的对象(例如命令按钮) ,再单击自定义工具栏,将对象放置在 自定义工具栏上。重复上述操作将所需的全部对象都放置到自定义工具栏上。另外,可以在 对象之间添加“分隔符”对象,使它们之间有一定的间隔。 (4)在“属性”对话框中,一一设置自定义工具栏上的每个对象的属性。例如,可以设 置 Picture 属性,为命令按钮添加位图或图标,如图 9.17 所示。

图 9.16

类设计器

图 9.17

设置对象属性

(5)为每个对象编写事件代码程序,这与为表单中的控件编写事件代码程序的方法一样。 (6)保存自定义工具栏。

9.3.2 将工具栏类连接到表单 在创建了工具栏类并保存在指定类库(例如 EX_ToolBar.vcx)后,就可把自定义工具栏 连接到表单中,使得在打开表单的同时,也打开自定义工具栏。步骤如下。 (1)进入表单设计器。 ·171·


(2)在表单控件工具栏中单击“查看类”按钮,在弹出的下拉列表中选择“添加”,显示 “打开”对话框。 (3)从中选择自定义工具栏类库文件名(例如 EX_ToolBar.vcx) ,单击“打开”按钮,这 时,表单控件工具栏的第 3 个按钮即为所加的新类,如图 9.18 所示。 (4)先单击 Ex_ToolBar 控件,然后单击表单中的某个地方。如果打开的表单是单个表单, 而非表单集,则系统给出如图 9.20 所示的提示,单击“是”按钮,则系统首先创建一个含有 被打开表单的表单集,然后将新的工具栏加入到表单中,如图 9.19 所示。

图 9.18 表单控件工具栏

图 9.20

图 9.19

自定义工具栏

创建表单集对话框

(5)保存对表单的修改,执行表单,可看到新的工具栏出现在表单中。 有一点值得注意,只能在表单集中添加工具栏,让工具栏与表单集中的各个表单一起打 开,而不能直接在某个表单中添加工具栏。 另外,工具栏具有以下特点: ① 工具栏可以停放在表单窗口的任意位置; ② 关闭表单窗口的同时将自动关闭工具栏; ③ 工具栏的外观(包括长、宽、高度等)可以任意定制。

9.3.3 协调选单和自定义工具栏 在创建包含选单和工具栏的应用程序时,某些工具栏按钮与选单项的功能可能会相同。 使用工具栏可以快速地实现某个功能或进行某种操作,这常常可以靠图标来描述;选单则可 以提供键盘快捷键、易读的文字标题,并且对于习惯使用选单的用户来说,它提供了一种熟 悉的访问方式。 为了协调选单和自定义工具栏,在设计应用程序时应注意以下两点。 (1)不论使用选单项还是使用与选单项相关联的工具栏按钮,它们都要执行同样的操作、 相同的功能,否则,可能会带来误操作或误解。 (2)相关的工具栏按钮和选单项具有相同的可用或不可用性,即使属性设置保持一致。

·172·


第 10 章 报表和标签 前面已介绍了用“查询设计器”和“视图设计器”在“浏览”窗口中显示表中的数据。 在 VFP 中,还可以将这些数据组织成报表和标签格式,这就是 VFP 的报表和标签的功能。 报表和标签包括两个基本组成部分:数据源和数据布局。数据源指定了报表和标签中数 据的来源,可以是表、视图、查询、临时表等;数据布局指定了报表和标签中各个输出内容 的位置和格式。报表和标签从数据源中提取数据,并按照布局定义的位置和格式输出数据。 Visual FoxPro 6.0 中的“报表设计器(Report Designer) ”和“标签设计器(Label Designer) ” 为报表和标签的设计提供了灵活方便的编辑环境,可以设置数据环境,完成数据的布局和输 出。创建的报表或标签保存在相应的文件中,说明见表 10.1。 表 10.1

报表和标签文件的扩展名及说明

扩 展 名

存 储 内 容

.FRT

报表备注

.FRX

报表的定义,包括数据源、要打印的文本及数据布局

.LBT

标签备注

.LBX

标签的定义

报表和标签文件并不存储数据源中每个数据的值,只存储数据的位置和格式信息,所以, 每次打印时,打印出来的报表内容随数据库内容的改变而改变。 常用的报表类型有列报表、行报表、一对多报表、多栏报表等,说明见表 10.2。 表 10.2 报表的布局类型 布局类型

列报表

报表中每行打印一条记录,字段按从左到右的顺序排列,类似于在浏览窗口浏览数据

行报表

报表中多行打印一条记录,字段按从上到下的顺序排列,类似于在浏览窗口编辑数据

一对多报表 多栏报表

用于打印具有一对多关系的多表数据。报表中每打印一条主表记录,子表中就打印多条 记录,类似于一对多表单显示数据 报表中每行打印多条记录的数据

10.1 创建报表 创建报表就是定义报表的数据源和数据布局。Visual FoxPro 6.0 提供了下面 3 种可视化的 方法来创建报表。 (1)利用报表向导创建报表。 (2)利用报表设计器创建和修改报表。 (3)利用快速报表功能创建报表。 报表向导使创建报表的工作程式化;用快速报表功能建立报表最为迅速,但格式简单; 而通过报表设计器则可以任意定制报表。因此,经常先使用报表向导或快速报表功能创建一 个简单的报表,然后,再利用报表设计器对这个报表进行修改,使它更美观,这样,可以使 ·173·


创建报表的过程更方便、快捷。

10.1.1 报表向导创建报表 “报表向导”是创建报表的最简单的途径。可以通过回答一系列的问题来进行报表的设 计,使设计工作变得省时省力、轻松有趣。在应用“报表向导”进行设计后,还可以打开“报 表设计器”对报表进行进一步的补充和修改完善。 利用“报表向导”创建报表可以分为以下几个步骤。 1. 打开“报表向导” 在“项目管理器”的“文档”选项卡中选择“报表”项目,单击“新建”按钮,进入“新 建报表”对话框。在“新建报表”对话框中单击“报表向导”按钮,进入“向导选取”对话 框。 在 Visual FoxPro 6.0 中,提供了两种不同的报表向导。一是“报表向导” ,针对单一表或 视图进行操作;二是“一对多报表向导”,针对多表或视图操作。 2. 字段选取 “报表向导”步骤 1—字段选取,在这个对话框中,选择要在报表中输出的字段。首先, 在“数据库和表”框选择报表的数据源,然后选择所需的字段。 3. 分组记录 “报表向导”步骤 2—分组记录,如图 10.1 所示。在这个对话框中,如果需要,可以设置 分组控制,最多进行三级分组。

图 10.1

报表向导的分组设置

在选定一个字段后,单击“分组选项”按钮,打开“分组间隔”对话框,设置分组是根 据整个字段内容还是字段的前几个字符。例如,职工编号的前两位数字代表部门的编号,因 此,可设置按职工编号的前两位进行分组,如图 10.2 所示。 4. 选择报表样式 “报表向导”步骤 3—选择报表样式,在这个对话框中,可以设置报表的样式,有经营式、 账务式、简报式、带区式和随意式 5 种,如图 10.3 所示。

·174·


图 10.2 分组间隔设置

图 10.3

报表向导的选择报表样式

5. 定义报表布局 “报表向导”步骤 4—定义报表布局,在这个对话框中,可以通过对“列数”、字段布局、 “方向”的设置来定义报表的布局。其中,“列数”定义报表的分栏数; “字段布局”定义报 表是列报表还是行报表; “方向”定义报表在打印纸上的打印方向是横向还是纵向,如图 10.4 所示。

图 10.4

报表向导的定义报表布局

·175·


需要注意的是,如果在向导的步骤 2 设置了记录分组,则这里的“列数”和“字段布局” 是不可用的。 6. 排序记录 “报表向导”步骤 5—排序记录,在这个对话框中,可以设置排序的字段,最多设置 3 个。 7. 完成 “报表向导”步骤 6—完成,这一步可以设置报表的标题;在离开向导之前预览报表;可 以选择退出向导的方式。 如果在“向导选取”对话框中,选择“一对多报表向导”,则操作步骤如下。 步骤 1:从父表选择字段,只能从单个的表或视图中选取字段; 步骤 2:从子表选择字段,只能从单个的表或视图中选取字段; 步骤 3:为表建立关系,可以从字段列表中选择决定表之间关系的字段; 步骤 4:排序记录; 步骤 5:选择报表样式; 步骤 6:完成。 如果用报表向导创建的报表不满足要求,可以使用报表设计器修改和完善这个报表。

10.1.2 快速报表 使用“报表向导”可以直观、方便地创建报表,使用“快速报表”功能则可以迅速地创 建报表。创建报表时常常先使用“快速报表”功能把一张表的所有字段或部分字段快速添加 到报表中,创建一张简单报表,再利用“报表设计器”进一步修改完善。 利用“快速报表”设计时,操作步骤如下。 1. 打开“报表设计器” 在“项目管理器”选择“文档”选项卡,选择“报表”项目,单击“新建”按钮,进入 “新建报表”对话框。在“新建报表”对话框中,单击“新建报表”按钮,打开“报表设计 器” 。 2. 进入“快速报表” 选择“报表”选单下的“快速报表”命令,出现“打开”对话框,选择要使用的表,单 击“确定”按钮后,出现“快速报表”对话框,如图 10.5 所示。

图 10.5

“快速报表”对话框

其中, “字段布局”按钮有 2 个,可以设置字段布局是列布局还是行布局。左边的是列布 局,它使字段在页面上从左到右排列;右边的是行布局,它使字段在页面上从上到下排列。 ·176·


“标题”复选框决定是否将字段名作为标签控件的标题置于相应字段的上面或左边。 “添加别名”复选框指定是否为字段添加别名。 “将表添加到数据环境中”复选框指定是否将表添加到报表的数据环境中。 “字段”按钮用于打开“字段选择器”对话框。如果选择表的所有字段制作报表,可以直 接在“快速报表”对话框中单击“确定”按钮,返回报表设计器,而不必进入“选择字段” 对话框。 3. 选择字段 设置了报表布局后,单击“字段”按钮,进入“字段选择器”对话框,为报表选择所需 的字段,如图 10.6 所示。字段选择好后,返回“快速报表”对话框。在“快速报表”对话框 中,单击“确定”按钮,返回“报表设计器”。此时,“报表设计器”中显示报表的布局。 4. 预览并保存报表 选择“显示”选单中的“预览”命令,可以预览报表的结果。 预览了报表的输出结果后,关闭预览窗口,回到报表设计器,然后保存报表文件,最后, 关闭报表设计器。

图 10.6

“字段选择器”对话框

10.1.3 报表设计器创建报表 打开“报表设计器”后,系统自动增加了一个“报表”选单,同时打开“报表设计器” 工具栏和“报表控件”工具栏。下面首先介绍“报表”选单及“报表设计器”工具栏和“报 表控件”工具栏的功能,然后再介绍报表设计器创建报表的方法。 1.“报表”选单 “报表”选单中包含创建和修改报表的命令。 “报表”选单中各选项及其说明见表 10.3。 表 10.3

“报表”选单中各选项的说明

选单选项

标题/总结

指定是否将“标题”和(或)“总结”带区包括在报表中

数据分组

创建数据分组并指定其属性

变量

创建报表中的变量

默认字体

指定标签和字段控件的永久字体、字体式样和字体大小

私有数据工作期

在私有工作期中打开报表使用的表

快速报表

自动将选定字段放入一个空的“报表设计器”窗口中

运行报表

显示“打印”对话框,将报表传送给打印机

·177·


2.“报表设计器”工具栏和“报表控件”工具栏 在报表的设计环境中,最常用的控件工具是“报表设计器”工具栏和“报表控件”工具 栏。如果在启动“报表设计器”时没有出现如图 10.7 所示的两个小窗体,可通过“显示”选 单下的“工具栏”选项来打开“工具栏”窗口。 “报表设计器”工具栏和“报表控件”工具栏所包括的按钮及其说明分别见表 10.4 和表 10.5。

图 10.7

“报表控件”和“报表设计器”工具栏

表 10.4 按

“报表设计器”工具栏的按钮说明

数据分组

显示“数据分组”对话框,创建数据分组并指定其属性

数据环境

显示“数据环境”窗口,创建或修改报表的数据环境

“报表控件”工具栏

显示或隐藏“报表控件”工具栏

“调色板”工具栏

显示或隐藏“调色板”工具栏

“布局”工具栏

显示或隐藏“布局”工具栏

表 10.5 按

“报表控件”工具栏的按钮说明

选定对象

移动或更改控件的大小。在创建了一个控件后,会自动选定“选定对象”按 钮,除非单击了“按钮锁定”按钮

标签

创建一个标签控件,用于显示字符串

字段(域控件)

创建一个字段控件,用于显示表字段、内存变量或其他表达式的内容

线条

创建一个线条控件,用于在设计报表时画直线

矩形

创建一个矩形控件,用于在报表上画矩形

圆角矩形

创建一个圆角矩形控件,用于在报表上画椭圆和圆角矩形

图片/OLE 绑定控件

创建一个图片控件,用于显示图片或通用型字段的内容

按钮锁定

允许在添加多个同类的控件时,不需多次单击此控件的按钮

3. 用报表设计器创建报表 下面以一个实例说明报表设计器创建报表的过程。 【例 Ex_ReportGZ】用报表设计器设计一张简单的工资情况报表,并按编号排序、按部 门分组。 (1)打开“报表设计器” 。在“项目管理器”中打开“工资情况”表所在的 RY 数据库, 选择“报表”项目,单击“新建”按钮,进入“新建报表”对话框,在“新建报表”对话框 中,单击“新建报表”按钮,进入“报表设计器”窗口,如图 10.8 所示。 在默认情况下, “报表设计器”显示 3 个带区:页标头、细节和页脚注。报表带区(report band)是指报表中的一块区域,可以包含文本、来自表字段中的数据、计算值、用户自定义 函数、图片、线条等。 报表上可以有各种不同类型的带区,每一个带区的底部有一个分隔栏。带区名称显示在 ·178·


靠近蓝箭头的栏上,蓝箭头指示该带区位于栏之上,而不是之下。

图 10.8

“报表设计器”窗口

利用不同的报表带区,可以控制数据在报表页面上的打印位置。各种报表带区的说明见 表 10.6。 表 10.6 报表的带区说明 带 区

打印次数

使 用 方 法

标题

每报表一次

从“报表”选单中选择“标题/总结”带区

页标头

每页面一次

默认可用

列标头

每列一次

从“文件”选单中选择“页面设置”,从中设置“列数>1”

组标头

每组一次

从“报表”选单中选择“数据分组”

细节

每记录一次

默认可用

组脚注

每组一次

从“报表”选单中选择“数据分组”

列脚注

每列一次

从“文件”选单中选择“页面设置”,从中设置“列数>1”

页脚注

每页面一次

默认可用

总结

每报表一次

从“报表”选单中选择“标题/总结”带区

(2)向报表中添加数据源。单击“报表设计器”工具 栏的“数据环境”按钮,出现“数据环境设计器”对话框, 在该窗口中任意区域单击鼠标右键,出现快捷选单,如图 10.9 所示。在快捷选单中选择“添加”,出现“添加表或视 图”对话框,选择所需的数据库后,将“工资情况”表添 加到“数据环境设计器”对话框中,然后,用鼠标拖动选 取的字段到“报表设计器”的细节带区,如图 10.10 所示。 在“数据环境设计器”中单击鼠标右键,设置“编号”字 段的 Order 属性,如图 10.11 所示。这样报表输出记录时可 按编号排序。

图 10.10

将字段添加到报表中

图 10.9

“数据环境设计器” 对话框

图 10.11

设置字段属性

单击“报表设计器”工具栏的“数据分组”按钮,出现“数据分组”对话框,设置分组 表达式为 LEFT(工资情况.编号,2) ,即按编号的前两位(部门)分组,如图 10.12 所示。在 ·179·


“报表设计器”中加入组标头带区和组注脚带区,如图 10.13 所示。报表在输出时,按部门 分组输出数据。

图 10.12

图 10.13

设置“数据分组”

添加“数据分组”后的报表带区

(3)合理安排报表布局。可以用手动调整或用“布局”工具栏,如图 10.14 所示。将所 选字段排列成所需的格式。手动调整时,可先将“显示”选单下的“网格线”和“显示位置” 打开,便于准确地调整字段位置。用鼠标单击所选字段后,即可对其进行大小和位置的调整。 如果没有特殊要求,使用“布局”工具栏进行排列会更加快捷、方便和准确,“布局”工具栏 各按钮的说明如表 10.7 所示。

图 10.14

“布局”工具栏

经过这 3 个步骤,一张简单的工资情况报表就设计出来了,可以在“显示”选单下选择 “预览”命令,浏览一下设计的结果,如图 10.15 所示。

·180·


表 10.7 按

布局工具栏按钮说明

左边对齐

使选定的多个控件与其中最左边的控件对齐

右边对齐

使选定的多个控件与其中最右边的控件对齐

顶边对齐

使选定的多个控件与其中最上边的控件对齐

底边对齐

使选定的多个控件与其中最下边的控件对齐

垂直居中对齐

使选定的多个控件按照垂直轴线对齐

水平居中对齐

使选定的多个控件按照水平轴线对齐

相同宽度

使选定的多个控件的宽度与其中最宽的控件对齐

相同高度

使选定的多个控件的宽度与其中最高的控件对齐

相同大小

使选定的多个控件的宽度与其中最大的控件对齐

水平居中

使选定的多个控件按照其垂直线排列

垂直居中

使选定的多个控件按照其水平线排列

置前

使选定的控件放置到其他所有控件的前面

置后

使选定的控件放置到其他所有控件的后面

单击常用工具栏上的“保存”按钮,将所设计的报表以 ReportGZ 作为文件名保存起来。

图 10.15 浏览报表

这只是一张非常简单的报表,后面将介绍如何美化报表。

10.1.4 修改报表布局 一张设计完美的报表应保证重点突出、易于查阅,同时给人赏心悦目的感觉。下面,结 合前面的例子利用报表控件对报表进行美化,形成如图 10.16 所示的正式报表。

图 10.16

工资发放明细表

打开项目管理器,在“文档”选项卡中选择要修改的报表 ReportGZ,单击“修改”按钮, 进入报表设计器即可对其进行修改。 ·181·


1. 修改页标头带区 在页标头带区添加一个标签控件,用鼠标单击“报表控件”工具栏上的“标签”控件, 再单击页标头带区中放置标题的地方,相应位置处将出现光标,在光标处输入“金城石化公 司热电厂工资发放明细表” ;单击“格式”选单下的“字体”选项,出现“字体”对话框,设 置字体为“宋体”、字体样式为“规则”和字体大小为“小三” ,如图 10.17 所示。修改完成 后的页标头带区如图 10.18 所示。

图 10.17

设置标题的字体

图 10.18

修改页标头带区

注意,如果要修改标签控件中的文字,必须先删除该标签,然后再添加。标签控件是报 表中的说明性文字,是一个字符串,用于说明其他数据的意义。 2. 修改组标头带区 修改组标头带区的步骤如下。 (1)添加标签控件。在组标头带区的适当位置添加标签控件:“部门编号:”、“部门”、 “姓名” 、 “岗位技能工资”、 “技能工资” 、“岗位工资”、 “浮动工资” 、 “保留工资” 、 “应发工 资” 、“扣款小计”、 “实发工资”以及“签字”。方法同上。 (2)添加域控件。域控件可以是报表数据环境中的表或视图的字段、变量或表达式。运 行报表时,报表的数据环境将从表中获取字段值、变量值或计算表达式的值,并用这些值填 充域控件。报表中添加了域控件的地方最后显示的是与域控件对应的字段、变量或表达式的 值。 在报表设计器中添加域控件时,可以直接将数据环境中表的字段用鼠标拖动到报表设计 器中所需要的地方;也可以用“报表控件”工具栏上的域控件按钮来添加数据环境中表的字 段。使用“报表控件”工具栏上的域控件按钮还可以向报表添加表达式。 现在,用域控件按钮添加两个域控件,一个用于从“编号”字段得到部门编号,一个用 ·182·


于得到输出报表时的年份和月份。 单击域控件按钮,再单击要加入域控件的区域,则出现“报表表达式”对话框,设置为 left(工资情况.编号,2) ,如图 10.19 所示。

图 10.19

“报表表达式”对话框

用同样的方法添加一个域控件,在“报表表达式”对话框中设置表达式为:str(year(date () ),4)+"年"+str(month(date()) ,2)+"月" (3)添加线条控件。在报表中加入直线可以使报表更为美观,数据的分隔更为直观。在 报表设计器中,可以方便地添加和修改直线。 ① 单击“报表控件”工具栏中的“直线”按钮,在适当位置处用鼠标绘制直线。 ② 如果所画直线的长短、位置不满足要求,选择直线并拖动直线两头的黑色小方块,可 以改变直线的长度。 ③ 选择直线并拖动直线,可以移动直线的位置。 ④ 选择直线并选择“格式”选单中的“绘画笔”命令,可以在下一级子选单中选择直线 的类型、粗细。 用上述方法将组标头上部的所有直线添加上去,注意直线的粗细有所不同。设计完成以 后的组标头带区如图 10.20 所示。

图 10.20

修改组标头带区

3. 修改细节带区 添加由其他字段计算得到的“应发工资”列,先单击域控件按钮,再单击要加入域控件 的区域,则出现“报表表达式”对话框,设置为“工资情况.技能工资 + 工资情况.岗位工资 + 工资情况.浮动工资 + 工资情况.其他工资” 。修改完成后的细节带区如图 10.21 所示。 4. 设置组脚注带区 将细节带区除编号、姓名以外的所有域控件复制到组脚注带区中,在与细节带区除编号、 ·183·


姓名域控件的下面加入标签控件,设置为“合计”,如图 10.22 所示。

图 10.21 修改细节带区

图 10.22

修改组脚注带区

5. 设置页脚注带区 在页脚注带区用标签控件加入“主管”和“制表”两项。 至此,这张报表的修改已经完成,如果需要还可以在报表中添加其他的控件,例如,加 入矩形、圆角矩形,还可以添加图形和 OLE 对象的通用字段。另外,还可以用调色板工具栏 改变控件的颜色。 例如,要添加一个图片控件,可单击报表控件工具栏上的标签控件按钮,在页标头带区 适当的位置,用鼠标拖动画出一个矩形,指定显示图片的位置,进入报表图片对话框,选择 图片来源为文件,输入图片文件名,如图 10.23 所示。

图 10.23

为报表添加图片

10.1.5 报表预览和打印 在完成了报表设计工作以后,就可以准备进行报表的打印输出。在打印报表文件之前, 最好先利用报表的打印预览功能看一下设计布局的效果。Visual FoxPro 6.0 中的打印预览工 具栏可使用户方便地对报表进行缩放、浏览。如果有不符合要求的地方,可以再返回修改, 直至满意为止。 ·184·


为了得到一份美观的报表打印文档,在报表设计器中设计了报表后,还常常需要设置报 表的页面,例如,文档的页边距、纸张类型和布局等。 1. 设置报表页面 打开报表设计器,在“文件”选单中选择“页面设置”命令,可以进入页面设置对话框, 在此,可以设置打印的列数、打印的区域、打印的顺序和左页边距等,以定义报表页面的外 貌。在页面设置对话框中,单击“打印设置”按钮,进入“打印设置”对话框,可以设置纸 张的大小和打印的方向。在打印设置对话框中,单击“属性”按钮,进入“属性”对话框, 可以进行高级页面设置和纸张大小的设置。 2. 打印报表 在报表设计器打开的情况下,报表的打印可以通过选择“文件”选单下的“打印”命令、 “报表”选单下的“运行报表”命令或者单击鼠标右键,在快捷选单中选择“打印”命令来 实现,也可以用快捷键 Ctrl+P 实现。这时,屏幕上出现“打印”对话框,如图 10.24 所示。 其中,有 3 个区域。

图 10.24

“打印”对话框

打印机区域:显示打印机的信息,单击“属性”按钮,可以进入“打印机属性”对话框, 设置打印机。 打印范围区域:设置报表的打印范围。 可以打印所有页面,也可以打印所设置的 那些页面。 打印份数区域:设置打印报表的份数。 在“打印”对话框中,如果单击“选 项”按钮,则进入“打印选项”对话框, 如图 10.25 所示,可以进一步设置打印的选 项。 在“打印选项”对话框中,单击“选 项”按钮,进入“报表和标签打印选项” 图 10.25 “打印选项”对话框 对话框,如图 10.26 所示,可以设置报表打 印记录的筛选条件。

·185·


图 10.26

“报表和标签打印选项”对话框

10.1.6 报表调用 在命令窗口也可以打印或预览报表,命令格式如下。 REPORT FORM 报表文件名 [范围] [FOR 条件] [WHILE 条件] [HEADING 表头文本] [NOCONSOLE] [PLAIN] [RANGE 开始页 [,结束页]] [PREVIEW [WINDOW 窗口名] [NOWAIT]] [TO PRINTER [PROMPT] | TO FILE 文本文件 [ASCII]] [NAME 对象名] [SUMMARY]

参数:打印的报表文件的名如果不处于默认驱动器或者目录中,就必须在文件名中指定 路径名。 范围:指定要包含在报表中的记录范围。默认的范围是“全部”(ALL)记录。 FOR 条件:如果包含了 FOR 子句,只有条件为真时,才会打印记录中的数据。利用 FOR 可以有条件地打印记录中的内容,而过滤掉不需要的记录。 WHILE 条件:使用 WHILE 子句后,只要条件为真时,就不会中断打印记录中的数据, 直到条件为假的记录为止。 HEADING 表头文本:使用 HEADING 指定一个附加在每页报表上的页眉。如果同时使 用了 HEADING 和 PLAIN 子句,将优先执行 PLAIN。 NOCONSOLE:当正在打印报表或者将报表写入一个文件的时候,利用 NOCONSOLE 可以禁止在 Visual FoxPro 的主窗口或者用户自定义窗口中回显任何信息。 PLAIN:如果包含了 PLAIN,指定只在报表开始位置出现的页标题。 RANGE 开始页 [,结束页]:指定要打印的报表的页的范围。如果不给出结束页,则默 认为 9999。 PREVIEW [NOWAIT]]:表示用页面预览的模式在屏幕上显示报表,而不是通过打印机 打印出来。如果要打印出来,必须使用带 TO PRINTER 子句的 REPORT 命令。注意使用 PREVIEW 时将忽略系统内存变量。NOWAIT 选项可以使程序在预览窗口打开时仍能继续向 下运行,而不必等待预览窗口关闭。 ·186·


TO PRINTER[PROMPT] :把报表输出到打印机。PROMPT 选项用于在打印开始之前显 示设置打印机的对话框,从而可以调整当前安装的打印机驱动程序。PROMPT 选项应紧跟在 TO PRINT 子句之后。 TO FILE 文本文件名 [ASCII]:指定报表输出到文本文件中。文本文件的默认扩展名 为.txt。ASCII 选项用于创建一个 ASCII 码文本文件。报表中任何图像、线条、矩形以及圆角 矩形都不出现在 ASCII 码文件中。 NAME 对象名:为报表的数据环境指定一个对象变量名。 SUMMARY:省略细节的打印,只打印出总计和小计信息。

10.2 设计标签 Visual FoxPro 6.0 的标签属于报表的一种,是多列布局的报表,是打印在特定标签纸张上 的报表,是数据库输出的重要形式之一。 标签的设计生成步骤与报表非常类似,使用的各类控件工具也完全相同。可以用标签向 导创建标签,也可以用标签设计器创建和修改标签。 Visual FoxPro 6.0 提供了 86 种标准标签类型,其中英制尺寸有 58 种,公制尺寸有 28 种。 不同类型的标签的大小、列数各不相同。还可以使用\VFP\TOOLS 目录下的 AddLabel.APP 应 用程序创建任意标签。

10.2.1 标签向导 使用标签向导创建标签步骤如下。 (1)选择表:选择一张表或视图。 (2)选择标签类型:从列出的标准标签类型中选择所需的标签类型,如图 10.27 所示。 如果没有找到需要的标签类型,可以单击“新建标签”按钮,自定义新的标签类型。

图 10.27

标签向导的选择标签类型

(3)定义布局:按照在标签中出现的顺序添加字段,如图 10.28 所示。可以使用空格、 标点符号、回车按钮格式化标签;使用文本框输入文本;可以单击“字体”按钮,设置字体、 ·187·


字体样式和大小。当向标签中添加各项时,向导窗口中的图片会随之更新,以显示标签的外 观。查看这个图片,看选择的字段在自己的标签上是否合适。如果文本行过多,则文本行有 可能超出标签的底边。

图 10.28

标签向导的定义布局

(4)排序记录:按照选择字段或索引标识对记录排序。最多可选 3 个。 (5)完成:可以选择 3 种保存标签的方式中的一种,还可以预览所设计的标签。 从以上介绍可以看出,使用标签向导创建标签的过程与使用报表向导创建报表非常相似。 并且,使用标签向导创建的标签,还可以使用标签设计器做进一步的修改。

10.2.2

标签设计器

标签向导和报表向导相似,标签设计器和报表设计器也相似。它们只是在默认页面和纸 张大小的规定上略有不同,报表设计器使用标准纸张的整页;而标签设计器使用的是标准的 标签纸的大小。 使用标签设计器创建标签时,当在项目管理器的“文档”选项卡中选择“标签”项目, 再单击项目管理器的“新建”按钮,出现“新建标签”对话框,单击“新建标签”按钮后, 首先出现新建标签的选择标签布局对话框,如图 10.29 所示。选择好布局后,才进入标签设 计器,如图 10.30 所示。 在标签设计器窗口活动时,系统会显示“报表”选单和报表控件工具栏。也就是说,标 签设计器和报表设计器使用相同的选单和工具栏。 若要快速创建一个简单的标签布局,可以在“报表”选单中选择“快速报表”命令。 “快 速报表”提示输入创建标签所需的字段和布局。 标签设计、修改、预览、打印等操作,与报表非常相似,这里不再赘述。

·188·


图 10.29 选择标签布局

图 10.30 标签设计器

·189·


第 11 章 网络数据共享 现代办公已经进入网络时代,这就要求应用程序是能够多用户,并可同时进行操作网络 化的数据库应用程序。 (1)共享。在 Visual FoxPro 中,数据库及其表是存放数据的主要容器,另外,还有操作 这些数据库的程序和其他各种文件。在多用户环境下,这些文件由多个用户共享。实现共享 的方法有两种:一种常用的方法就是将数据从本地硬盘移到网络中一台文件服务器计算机中, 这样,每个用户都可以访问它。另一个方法是使本地硬盘或存放这些文件的文件夹共享。 (2)冲突。开发基于网络的数据库应用程序,数据处理中的一个基本问题就是如何解决 两个以上用户同时试图修改数据时所产生的冲突。可以认为最后保存修改的用户才能真正地 修改数据,而此前所有的修改均无效。 (3)锁定。Visual FoxPro 提供了在多用户环境中记录和表锁定函数、命令以及新的数据 缓冲方案。当有多个用户要求访问表和记录时,锁就会禁止其他用户进入该数据区域,直到 当前占用数据的用户完成他的编辑活动并安全地退出操作区域为止。而使用缓冲可以保存原 始记录,这样在必要时可以恢复这些记录。在 Visual FoxPro 的文件共享环境中,数据库必须 存储在网络驱动器中以便用户共享。 (4)死锁。当一个用户锁定了一条记录或一个表,同时又试图锁定另一条记录或另一个 表时,这一记录或表格已经为另一个用户锁定,而这个用户也在试图锁定第 1 个用户已锁定 的记录。结果两个用户均被“挂起”以等待对方释放锁定的记录。很明显,谁都不会获得所 需的全部资源从而完成自己的任务,所以谁也不可能释放锁定的记录。这就是共享环境中经 常发生的死锁。

11.1

记录锁定

1. 记录锁定和文件锁定 在多用户访问的应用程序中,只有那些真正需要它的用户才能获得访问权限。当正确地 使用了记录锁定时,它便只允许执行记录锁定操作的用户写该记录。而对于文件锁定来说, 它将锁定整个表,禁止其他所有用户向表中写入数据,而只允许编辑表格中的任何记录。注 意,记录锁定和文件锁定并不禁止其他用户从被锁定的记录和表中读取数据。一般情况下, 应尽力使用记录锁定,因为记录锁定只会禁止对单个记录的访问,而不会影响整个表格。因 此,当一个用户在编辑 XSCJ 数据库的 XS 表中的第 30 条记录时,另一个用户可以同时编辑 该表中的第 20 条记录,而这两个用户可以各自保存自己的修改而不会影响对方。 当加锁用户解锁,从锁定状态释放锁时,其他用户才能对加锁表或记录进行修改操作或 再锁定。 2. 自动锁定与手工锁定 记录锁定和文件锁定既可以自动锁定,也可以手工锁定。当使用特定的数据更新命令时, VFP 会试图自动锁定记录,这些命令如表 11.1 所示。

·190·


表 11.1 命

自动锁定数据库记录和表的一些命令

自 动 锁 定 范 围

ALTERTABLE

自动锁定整个表格

APPEND

自动锁定整个表格

APPEND BLANK

自动锁定表头

APPEND FROM

自动锁定整个表格

APPEND FROM ARRAY

自动锁定表头

APPENDMEMO

自动锁定当前记录

BLANK

自动锁定当前记录

BROWSE CHANGE

自动锁定当前记录以及相关的表格中别名字段所确定的记录。一旦开始编辑 字段,锁定便会生效 自动锁定记录以及相关表格中别名字段所确定的记录。一旦开始编辑字段, 锁定便会生效

DELETE

自动锁定当前字段

DELETE NEXT l

自动锁定当前字段

DELETE <n>

当 n>1 时,自动锁定文件

DELETE SQL

自动锁定当前记录

EDIT

自动锁定当前记录,以及相关表格中别名字段所确定的记录。一旦开始编辑 字段,锁定便会生效

GATHER

自动锁定当前记录

INSERT

自动锁定整个表格

INSERTSQL

自动锁定表头

MODIPYMEMO

当开始编辑当前记录时,自动将其锁定

READ

自动锁定当前记录以及由别名字段所确定的所有记录

RECALL

自动锁定当前记录

RECALLNEXTl

自动锁定指定记录

RECALL <n>

当 n>1 时,自动锁定整个表格

REPLACE

自动锁定当前记录以及由别名字段所确定的所有记录

REPLACENEXT<n>

自动锁定当前记录以及由别名字段所确定的所有记录

REPLACE(n)

自动锁定整个表格以及由别名字段所确定的所有记录

SHOWGETS

自动锁定当前记录以及由别名字段所确定的所有记录

TABLEUPDATE()

自动锁定整个表格

UPDATE

自动锁定整个表格

UPDATESQL

自动锁定整个表格

当这些命令执行结束后,系统将自动释放所建立的锁定。例如,下列程序: SET EXCLUSIVE OFF OPEN DATABASE XSCJ USE XS1 APPEND FROM XS FOR XH="02"

其中,APPEND FORM 命令会自动锁定整个 XS1 表,这条命令将另一个文件中的数据加 入表格试图锁定整个表格。当添加任务结束后,APPEND 命令将释放所建立的锁定。设置 SET EXCLUSIVE OFF,允许网络上的任何用户共享和修改网络上打开的表;如设置 SET EXCLUSIVE ON,以后以独占方式打开表,此前打开的表的状态不变,USE 命令打开表时, 带 EXCLUSIVE 参数也是以独占方式打开表。以下的命令只有在独占方式打开时执行,这些 命令有 INSERT,INSERT BLANK,MODIFY STRUCTURE,PACK,REINDEX 和 ZAP。 ·191·


VFP 除了自动进行记录和文件锁定的命令外,还提供了一系列锁定函数用于手工锁定记 录。手工锁定函数将测试记录或表的锁定状态。如果发现记录(或表)未被锁定,那么便将它 锁定。手工锁定函数为 LOCK() ,RLOCK()和 FLOCK()函数。RLOCK()和 LOCK() 函数等价,都用于锁定单个记录或一组记录。 格式: LOCK([工作区号| 表别名] | [记录号表,工作区号| 表别名])

格式: RLOCK([工作区号| 表别名] | [记录号表,工作区号 | 表别名])

选择[工作区号| 表别名]为锁定指定工作区或表的当前记录。无参数,则锁定当前表的当 前记录。选[记录号表,工作区号| 表别名],则可以锁定多条记录,锁定的多条记录由记录号 表指定,此时工作区号| 表别名不能省略。但是,用 LOCK()或 RLOCK()同时锁定多条 记录,还必须用 SET MULTILOCKS ON。 函数锁定成功返回.T.,否则返回.F.。 FLOCK()函数用于锁定整个文件。 格式: FLOCK([工作区号| 表别名])

选[工作区号| 表别名]为锁定指定工作区的表或表别名指定的表。无参数,则锁定当前 表。函数锁定成功返回.T.,否则返回.F.。 可用下列命令设定 LOCK() ,RLOCK()和 FLOCK()函数尝试加锁的次数和时间, 不致于当加锁不成功时就立即返回(返回值为.F.)。 格式: SET REPROCESS TO n [SECONDS] | TO AUTOMATIC

选择 SECONDS,则 n 的单位为 s。选择 TO AUTOMATIC 或 n=0(默认值) ,则系统会 无限次对表或记录加锁。此前如设置 SET STATUS ON,系统在尝试对表或记录加锁时系统会 显示提示信息,此时用户可按 ESC 键取消加锁尝试。若 n=1,则用户不可按 Esc 键取消加锁 尝试。还可参考 SYS(3051)和 SYS(3052)函数。 如果用 LOCK() ,RLOCK()和 FLOCK()函数锁定一条记录或一个表,那么在完成 任务后应立即用 UNLOCK 命令释放锁定。 格式: UNLOCK [RECORD 记录号] [IN 工作区号 | 表别名] [ALL]

记录号>0,则解除该记录的锁定;记录号=0,则解除由 RLOCK(0)或 LOCK(0)锁 定的表头。在 UNLOCK RECORD 记录号时会解除表的文件锁。不带任何参数的 UNLOCK 命令,将解除当前表的所有锁,UNLOCK ALL 将解除当前所有打开的表的所有锁, 只有开锁后,其他用户才可能操作这些锁定的记录和表。 【例 Ex_Lock】手工加锁执行 REPLACE…FOR 命令操作 XSCJ 数据库 XS 表。 SET EXCLUSIVE OFF SET REPROCESS TO 0 OPEN DATABASE XSCJ USE XS

·192·


IF FLOCK() REPLACE JSJ WITH 200 FOR ZXF>30 UNLOCK ElSE WAIT "表已经被别人上锁!" WINDOW NOWAIT ENDIF

【例 Ex_LReplace】手工加锁执行 REPLACE 命令操作 XSCJ 数据库 XS 表的 3 个记录。 SET EXCLUSIVE OFF SET REPROCESS TO 0 SET MULTILOCKS ON USE XS IF RLOCK("2,10,16","XS") GOTO 2 REPLACE JSJ WITH 200 GOTO 10 REPLACE JSJ WITH 200 GOTO 16 REPLACE JSJ WITH 200 UNLOCK ELSE WAIT "表已经被别人上锁! " WINDOW NOWAIT NOWAIT ENDIF

如果无法获得列表中的任何记录,那么任何记录都不会被锁定。 注意:VFP 文档中建议,如果要更新一个表格中的多条记录,锁定整个表格要比锁定多 条记录方便得多。当然,这一锁定必须在更新过程中均有效,但不是编辑会话的整个过程。 如果可能的话,最好使用只锁定单个记录的命令,而不要过多地使用试图锁定整个表格 的命令。这是因为:由文件锁定而带来的网络开销以及其他用户不能锁定该文件的可能性。 在 Visual FoxPro 中,只有当文件中的所有记录均未被任何用户锁定时,该文件才能被锁定。 而在多用户应用程序中,这可能要等待很久。 在许多情况下,从一条记录或表向另一条记录或另一个表的物理移动会促使 FoxPro 自动 释放临时锁定的项目。然而,如果显式地锁定了一个表或一条记录,那么其他用户只有等待 该表格的锁定被释放后才能使用它。执行表 11.1 的命令后,将释放记录和表格锁定。 表 11.2 命

释放记录和表格锁定的命令

CLOSE ALL

释放所有记录和表格文件锁定

END TRANSACTION

释放所有自动锁定

QUIT

释放所有记录和表格文件锁定

UNLOCK

释放当前工作区中的记录和文件锁定

UNLOCK ALL

释放所有工作区中的记录和文件锁定

USE

释放所有记录和表格文件锁定

SET MULTILOCKS OFF

当建立新的锁定时,自动释放当前锁定

FLOCK()

在锁定文件之前释放该文件中的所有记录锁定

·193·


如果 SET MULTILOCKS OFF,在用户自定义的函数(UDF)中锁定了一条记录,则将 记录指针移开后再将指针移回当前记录,那么该记录上的锁定将被自动释放。 当编辑表的字段时,相关的记录会被锁定以防止双重编辑。然而,如果当前记录或者任 何一个相关的记录已经被另一个用户锁定,那么锁定操作会失败。只有当成功地锁定记录时, FoxPro 才会允许用户编辑记录。当用户转换到下一条记录,或者激活另一窗口,或者执行其 他任务时,锁定被系统释放。 如果使用 Browse,Change,Edit 或者 ModifyMemo 等命令来编辑记录时,将会发现只有 当开始进行编辑时,这些命令才会锁定记录。

11.2

数据会话

Visual FoxPro 数据会话(DataSession)是附属于表单上的数据环境,这就是说可以把表 附着到一个使用这些表的表单上。数据会话分为两类:私有的和默认的。数据会话允许对一 个表单建立多个实例。例如,当用户希望一次看见多个客户的记录时,用户可以不必关闭当 前打开的表单,而只需请求客户表单的另一个实例。 Form.DataSession 属性可以被设置为 1 或 2。使用默认值 1 时,对表单的修改将可以反映 到表单的所有其他打开的实例中。当将属性设置为 2(私有数据会话)时,在表单中的任何 修改将不会自动反映到同一表单的其他实例中。用户能够打开的会话个数仅仅由系统内存大 小及磁盘空间大小决定。 如果要从表单设计器中开始多个数据会话,可以将 DataSession 属性设置为 2,或者也可 以在命令窗口输入命令 SET DataSession TO 2。当将 DataSession 属性设置为 2 时,Visual FoxPro 为表单的每个实例建立一个新的数据会话,表单的每个实例维持单独的一些数据,其 中包括一系列单独的锁定。 由于能否打开数据会话主要取决于 RAM 的大小及硬盘空间,因此可以通过 LoadEvent 代码中的命令来修改会话说明,而用户可以从 View 窗口中观察到数据会话的内容。每个数据 会话都被顺序编号,并且用名为 DataSessionlD 的数据会话标号来标识。表单的 DataSessionID 属性可被显示出来: DO FORM Form1 ? Form1.DataSessionID DO FORM2 Form1 Name one ? one.DataSessionID

用户尽量避免改动表单的数据会话标号,因为一旦修改了数据会话标号,与数据绑定的 控件便会失去它们的数据源。如果用户希望表单的数据环境(DataEnvironment)一直有效且 保持不变,那么可以使用表单设计器(FormDesigner)中的数据环境对话框。 虽然表单的所有实例均可访问同一数据,并且将对其修改立即反映到所有表单的公用数 据中,但可以用数据环境(DataEnvironment)属性表格中的重构属性改变自动数据会话分配。

11.3

数据缓冲

VFP 引入的数据缓冲使在网络中对数据的保护比显式锁定更加容易。缓冲数据的使用有 ·194·


利于更好地使用本地资源,从而限制了对网络及服务器资源的竞争。缓冲数据在工作站的内 存中保存了用户对数据所做的一切修改。只有当应用程序要求 VFP 进行更新时,服务器中的 数据才会更新。 实现数据缓冲思想的显式锁定方案实现步骤如下。 (1)当要修改记录时,执行 SCATTER MEMVAR 命令将所有字段存入内存变量。 (2)修改内存变量中的数据,而不是表中的数据。 (3)如果对所做的修改感到满意,可以用 GATHER MEMVAR 命令保存修改。如果希望 恢复数据,则可以再次执行 SCATTER MEMVAR 命令来覆盖内存变量中的数据。 现在,VFP 中的数据缓冲可以完成这一系列操作。VFP 提供了以下两种缓冲方案:记录 缓冲和表格缓冲。 (1)记录缓冲。记录缓冲(record buffering)对单个记录的编辑进行缓冲。一旦完成对单 个记录的修改后,数据便立即写入磁盘。这一写入动作发生在记录指针移动时,或者执行 TABLEUPDATE()函数时。 (2)表格缓冲。表格缓冲(table buffering)把对表的多处修改存入内存。当关闭表格时 或者使用了 ROWS 参数设为.T.的 TABLEUPDATE()函数时,数据便会写入磁盘。该方法 适用于一个表格中的记录或者一对多关系中的子记录。 在多用户环境中,当编辑、删除及修改单条记录或者多条记录时,这种缓冲方式提供了 数据更新和数据维护方面的安全保证。利用 VFP 的缓冲技术,用户不必再将数据赋给内存变 量,用户可以直接编辑字段,因为只要不执行 TABLEUPDATE() ,原始数据总是安全的。 利用缓冲技术可以检测和消除数据更新操作的冲突。在编辑过程中,当前记录被复制到 已由 VFP 标识并管理的内存或者磁盘中,当前用户操作的数据被安全地隔离开,所以其他用 户依然可以访问原始记录。当记录被写回表格时,FoxPro 便试图锁定该记录,并检查是否有 其他用户做的修改,其最终的修改将被写入硬盘。 1. 锁定缓冲区 记录缓冲和表格缓冲可以用于两种不同的锁定模式。这些模式决定了在何种条件下锁定 一条或多条记录,以及如何和何时释放这些记录。这两种模式称为悲观锁定(pessimistic locking)和乐观锁定(optimistic locking)。悲观锁定告诉 FoxPro,当编辑工作开始时便锁定 记录。这就是说,一旦用户修改了某个被缓冲的字段中的值,这条记录便会被锁定。锁定后 的记录将禁止其他用户进行修改,直到占用记录的用户完成更新任务。乐观锁定是当数据被 写入磁盘时才锁定记录,这样就允许多个用户编辑同一条记录。 CURSORSETPROP()函数设置缓冲方式。 格式: CURSORSETPROP(c 属性 [,e 值] [,n 工作区号 | c 表别名])

设置表缓冲方式时,属性为"Buffering",值可为 1~5。值为 0(默认) ,则无缓冲。不指 定表,则为当前表。例如以下对表 XS 设置表缓冲。 (1)实现悲观的记录锁定。 =CURSORSETPROP("Buffering", 2, "XS")

执行该语句时,FoxPro 首先试图锁定当前指针位置处的记录。如果锁定成功,FoxPro 便 将记录写入缓冲,并允许用户编辑记录。当记录指针从当前位置移开,或者遇到 TABLEUPDATE()命令,程序便将缓冲的记录写回原来的表。 ·195·


(2)实现乐观的记录锁定。 =CURSORSETPROP("Buffering", 3, "XS")

执行该语句时,FoxPro 将当前记录写入缓冲区,当记录写入缓冲区后才允许用户编辑该 记录。如果记录指针从当前位置移开或者遇到 TABLEUPDATE()命令,FoxPro 则试图将记 录锁定。如果锁定成功,系统对原始缓冲区的值与磁盘中该记录的当前值进行比较。若两个 值相等,则将记录的修改写入表。如果两个值不相等,则不保存修改,并产生一个出错信息 警告用户。 (3)实现悲观的多条记录锁定。 =CURSORSETPROP("Buffering", 4, "XS")

该命令试图锁定指针位置处的记录。如果锁定成功,便将记录写入缓冲区。然后允许用 户编辑该记录。 (4)实现乐观的多条记录锁定。 =CURSORSETPROP("Buffering", 5, "XS")

该命令将多条记录写入缓冲区,然后允许用户编辑该记录,直到遇到 TABLEUPDATE (.T.)命令。当执行该命令后,FoxPro 会完成以下顺序动作。 ① 试图锁定每个已编辑的记录。 ② 如果锁定成功,FoxPro 将比较原始缓冲区中的值和磁盘中记录的当前值。 ③ 如果比较结果一致,FoxPro 便将记录写回磁盘。 ④ 如果比较结果不同,便产生一个出错信息。 注意:为了能够运行各种缓冲方法,需要执行 SET MULTILOCKS ON 命令。 如果使用表单,那么可以利用表单 BufferMode 属性设置缓冲类型。当在表单中设置缓冲 类型时,只需指定使用乐观的锁定还是悲观的锁定。基于表单的缓冲默认情况下使用记录缓 冲,除非是正在使用网格(Grid)控件。在这种情况下 RecordSource 使用表缓冲。该方法比 较合理,因为用户往往利用 Grid 控件来显示子记录或者细节记录。利用表缓冲,用户可以在 Grid 控件中添加记录,并同时保存所有记录,而不必一个一个地保存。如果表单使用数据环 境,则可以用所选定表格的 BufferModeOverride 属性来覆盖 BufferMode 属性。 注意:当使用表格缓冲时,在执行 TABLEUPDATE(.T.)命令之前添加到表格中的任何 记录的记录号都是负的。 2. 更新记录 在更新数据之前,用户必须决定使用哪种缓冲方法和锁定机制。一旦确定了缓冲和锁定 方法,便可以用代码,或者在表单的数据环境中使用记录缓冲和表缓冲。TABLEUPDATE() 函数用于将所做的修改写入原始表,TABLEREVERT()函数可取消这些修改。 在下列程序清单中使用了悲观的记录缓冲。移动记录指针前,逐个检查每个字段来确定 它是否被修改。如果发现记录被修改,则提供给用户把数据还原成原始的选项。 OPEN DATABASE XSCJ USE XS =CURSORSETPROP("Buffering",3) YES=.F. FOR i=1 TO FCOUNT () IF GETFLDSTATE(i)=2

·196·

&& FCOUNT()得到当前记录的字段数 && 判断得到第 i 个字段是否被修改


YES=.T. EXIT ENDIF ENDFOR IF YES R=MESSAGEBOX("记录已被修改,是否强行保存? ",'4+32+256',"保存") IF R=7 =TABLEREVERT (.F.)

&& 放弃修改

=TABLEUPDATE(.T.,.T.)

&& 强行保存修改

ELSE

ENDIF ENDIF

程序中使用了 GETFLDSTATE()函数检测字段是否被修改。GETFLDSTATE()函数 只操作被缓冲的数据。如果只是检查记录是否被修改,而不管哪一个字段是否变化,那么可 以用 IF '2'$ str(GETFLDSTATE(-1) )来判断。 GETFLDSTATE()函数返回表格中所有字段的变化状态。表 11.3 显示了 GETFLDSTATE 可能返回的值。 表 11.3 GETFLDSTATE()函数返回值 返 回 值

GETFLDSTATE() 1

已存在的记录字段中的数据未被修改

2

已存在的记录字段中的数据被修改,或者删除标志被改变

3

被附加的记录字段中的数据未被修改

4

被附加的记录字段中的数据被修改,或者删除标志被改变

GETNEXTMODIFIED()函数用于返回被缓冲表格中第 1 个被修改的记录的记录号。这 是一种根据原始数据文件控制记录更新的好方法。当与 CURVAL()函数及 OLDVAL()函 数结合使用时,可以用来编写“协商”子程序,以解决两个用户同时要求更新同一数据的问 题。CURVAL()和 OLDVAL()只能用在乐观的锁定中。一个乐观锁定表中的日期字段, 原始值为 01/01/2000,如果一个用户将其改为 08/01/2002 并保存,同时自己已将该值改成 01/31/2003,这时 CURVAL()等于 01/31/2003,OLDVAL 等于 01/01/2000,编辑控件值为 08/01/2002。用户的可选项包括:用现在的值覆盖数据修改,恢复原来的值,或者让系统警告 用户发生冲突并要求用户决定解决办法。例如可将程序代码用在 SAVE 命令按钮中。 IF CURVAL(DateField)<>OLDVAL(DateField) nOption=MESSAGEBOX("数量已被别的一个用户修改,是否覆盖?", 4+48+0,"更新冲突") IF nOption=7

&& 不覆盖

=TABLEREVERT() RETURN ENDIF ENDIF

·197·


=TABLEUPDATE(.T.,.T.)

其中,TABLEUPDATEU()函数的第 2 个.T. 告诉 VFP 不论冲突与否,强行更新数据。 如果不这样,那么用户会一直收到出错信息。 3. 检测冲突和错误处理 在设计一个多用户应用程序时,或者在单用户系统加入网络支持时,FoxPro 的记录和表 格缓冲系统可以简化这些工作。 如果试图锁定一条已被其他用户锁定的记录或表格,FoxPro 便返回一个出错信息,警告 用户发生的错误。如果将锁定与 SET REPROCESS 命令、ON ERROR 子程序或者 RETRY 命 令一起使用,那么便可以自动处理不成功的锁定动作。 格式: ON ERROR [<命令>]

功能是当出现错误时执行<命令>,无任选项,关闭出现错误时执行<命令>功能。 下列程序一旦发生错误,便会执行 ERRPRO 子程序。 * ERRPRO.PRG ON ERROR DO errfix WITH ERROR(),MESSAGE() SET EXCLUSIVE OFF SET REPROCESS TO AUTOMATIC OPEN DATABASE TO RY USE 工资情况 REPLACE ALL 其他工资 WITH 200 GO TOP EDIT ON ERROR CANCEL

PROCEDURE ERRPRO PARAMETERS ErrLn,MsgStr WAIT WINDOW "错误"+ MsgStr +"在"+STR(ErrLn)+"行" RETURN

在共享环境中,当执行数据更新操作时,可能要确定哪个字段被修改,字段中的原始值 是什么,以及随后它被修改成什么。而找出被修改的字段以及在决定如何处理错误或冲突之 前,分别比较当前值、原始值、新编辑的值等问题要容易些。 在网络环境中使用缓冲将会带来一些新的错误。VFP 提供了 AERROR()函数用来解释 从缓冲机制、数据库容器以及(如果用户使用客户-服务器方式)ODBC 驱动器中返回的消息。 AERROR()使用数组作为它的参数,将出错信息写入数组。表 11.4 列出了 AERROR 的返 回值。

·198·


表 11.4 元素

AERROR 返回值

1

数值型

错误号

2

字符型

出错信息

3

字符型

出错参数

4

字符型或数值型

工作区或者 NULL

5

字符型或数值型

触发器失败(1—插入;2—更新;3—删除或者 NULL)

6

字符型或数值型

NULL(用于 OLE 和 ODBC 错误)

7

数值型

NULL(用于 OLE 错误)

11.4

事务处理

1. 事务处理概念 在应用程序中,即使最精心设计的计划也难免出错。因此,Visual FoxPro 中使用事务处 理帮助用户在更新和恢复记录的过程中保护用户的数据。事务处理也可以嵌套并且用于保护 缓冲的数据更新。 事务处理像是在内存或硬盘临时保存数据更新的保存层,它使程序不能将更新直接写入 表,只有在事务处理后才会真正地进行更新。但是,如果由于某种原因使更新操作不能完成, 那么整个事件处理便会放弃,数据的更新也被取消,并且不会对原有数据做任何修改,因此 防止了数据的意外写覆盖。 事务处理中使用了 3 条 命 令: BEGIN TRANSACTION , END TRANSACTION 和 ROLLBACK。BEGIN TRANSACTION 为初始化事务处理。END TRANSACTION 先锁定记 录,然后将最近一次执行 BEGIN TRANSACTION 命令后用户所做的修改写入硬盘,最后释 放记录锁定。ROLLBACK 恢复自从最近一次执行 BEGIN TRANSACTION 命令后所做的所有 修改。 注意:事务处理不考虑使用内存变量的操作,任何改变了内存变量内容的事务处理都是 不可恢复的。 (1)事务处理的限制。事务处理应该与记录缓冲配合使用,但不能用于表缓冲操作。事 务处理中当使用 TABLEUPDATE()函数时,可以恢复那些失败的更新。 (2)恢复事务处理。事务处理并不是想像中的那么简单,系统并不保证不发生错误。当 系统关闭,或者发生其他异常情况时,例如在处理 END TRANSACTION 命令的过程中系统 掉电,这时数据更新就会失败,从而导致数据崩溃。 2. 事务处理规则 事务处理规则如下。 (1)使用时必须把所有事务动作放在 BEGIN TRANSACTION 和 END TRANSACTION 之间。如果只使用了其中之一,便会产生出错信息。当一条命令直接或者间接地调用某些数 据时,程序将锁定它们。因此,当结束事务处理前,系统或者用户直接或间接释放锁定的命 令都将被高速缓存起来,直到遇到 END TRANSACTION 或 ROLLBACK 命令,表示事务处 理结束。 (2)如果使用 FLOCK()或 RLOCK()命令,那么执行 END TRANSACTION 命令并 不释放锁定,必须在事务处理释放数据之前明确地释放锁定。 ·199·


(3)如果在 ROLLBACK 之前没有使用 BEGIN TRANSACTION 命令,那么 ROLLBACK 语句就会产生一个错误。 (4)一旦进入事务处理,它便一直有效,直到遇到对应的 END TRANSACTION 或者 ROLLBACK 命令。这一处理过程可以贯穿程序及函数,直到应用程序结束。 (5)对于事务处理中涉及的查询,Visual FoxPro 往往先使用事务处理缓冲区中的数据, 然后再考虑磁盘中的数据。这一方式保证了首先使用最新的数据。 (6)在执行过程中一旦事务处理失败,那么所有操作都将失败,并且在失败原因确定并 纠正之前,所有数据均无法操作。 (7)事务处理只用于数据库容器中。不能使用 INDEX 命令来重建一个已存在的索引文 件,也不能在任何索引文件已被打开时使用这个命令。 (8)事务处理可以嵌套。

·200·


第 12 章 程 序 调 试 一般来说,没有一个人编写应用程序不出错误。如果是语法错误,那么 Visual FoxPro 在 编译程序时就会显示出来;如果是逻辑错误(例如,运行结果不正确) ,Visual FoxPro 的编译 器就无能为力了。产生逻辑错误可能的情况包括:程序对一个没有预见到的变量的值错误地 进行了处理、计算的顺序不对、选择了错误的工作区或主索引、在使用了一系列的不同的表 之后没有恢复先前的环境,等等。 编写应用程序是为了解决实际问题,运行结果不正确,所有的事情都无从谈起。程序调 试是解决程序中所有问题的惟一途径。所以,程序调试是每一个编程人员所必须掌握的,是 基本功之一。 Visual FoxPro 提供了丰富的调试工具,帮助逐步发现代码中的错误,有效地解决问题。 下面介绍调试工具的使用方法。

12.1 跟踪窗口 1. 跟踪程序执行 在调试中,跟踪代码是一个最有用的方法,可以观察每一行代码的运行,同时检查所有 的变量、属性和环境设置的值。具体操作方法如下。 (1)单击主选单的“工具”选单,选择“调试器”选单项,打开“调试器”窗口,如图 12.1 所示。

图 12.1 “调试器”窗口

“调试器”窗口内有自己的选单系统、工具栏。在其中可同时打开多个文档窗口, (后面 不特别说明)都在该窗口进行操作。 ·201·


(2)单击调试器选单栏“窗口”选单的“跟踪”选单项,系统打开“跟踪”窗口,如图 12.2 所示。 (3)单击“调试”选单“运行”选单项,系统打开程序对话框,用户选择所需调试的程 序文件名,例如 D:|\RY_mis\ex_main.prg。

图 12.2 “跟踪”窗口

跟踪代码方式下工具栏提供了下列运行程序的方法。 ① 跟踪:每次执行程序的一个代码行,执行后程序暂停。如果被跟踪的程序调用了一个 函数或过程,则跟踪进入调用过程或函数的内部。 ② 单步:每次执行程序的一个代码行,执行后程序暂停,但不跟踪被调用的过程或函数。 ③ 跳出:执行完当前过程或函数中的其余代码,然后回到调用程序。 ④ 运行到光标处:运行当前程序到包含光标的行。 ⑤ 继续执行:停止追踪代码,继续执行程序直到遇到一个断点或程序的结束。 ⑥ 取消:终止程序。 2. 设置断点 断点就是调试时程序暂停执行的位置。设置断点可逐步缩小错误的范围。设置断点方法 如下。 (1)直接设置。若要为某个特定的代码行设置断点,直接在跟踪窗口下双击该行旁边的 阴影页边,或者把光标放在行中并按下空格键或回车键,该代码行左边的灰色区域中会显示 一个红色的实心圆点,这表明该行已经设置了一个断点。 (2)利用“断点”对话框。单击“工具”选单,选择“断点”选单项,出现如图 12.3 所 示的对话框。 可选择断点的类型,包括在定位处中断、如果表达式值为真则在定位处中断、当表达式 值为真时中断、当表达式值改变时中断。还可设置断点所需的定位、文件、运行次数、表达 式等内容。最后单击“确定”按钮即可。 ·202·


图 12.3

设置断点

12.2 监视窗口和局部窗口 使用调试器的一个好处是在程序暂停运行时能够很容易看到变量、数组元素、属性和表 达式的当前值,以便分析确定代码是否正确。在“跟踪”窗口中,将光标定位到任何一个变 量、数组或属性上,就可以在提示条中显示它的当前值。此外,调试器还提供了另外两个窗 口来完成这一功能。 1. 监视窗口 有时并不想查看所有的变量,而只是观察少数几个变量值。此时可以使用“监视”窗口。 在“监视”窗口的“监视”框中,键入任意一个有效的 Visual FoxPro 表达式,然后按回 车键,这时,该表达式的值和类型就会出现在“监视”窗口的列表中。另外,也可以在“跟 踪”窗口或其他的“调试程序”窗口中,选择变量或者表达式,然后将它们拖动至“监视” 窗口中。在“监视”窗口中,已经改变的值会显示为红色。在“监视”窗口中,双击一个监 视项,还可以对其进行编辑。 2. 局部窗口 “局部”窗口会显示调用堆栈上任意程序、过程或方法程序中的所有的变量、数组、对象 和对象元素。默认情况下,在“局部”窗口中所显示的是当前执行程序中的值,通过在“局 部变量的位置”列表中选择程序或过程,也可以查看其他程序或过程的值。 3.监视窗口与局部窗口 “监视”窗口只能查看当前过程和函数的变量, “局部”窗口可查看任何例程在什么地方 定义了什么变量。在“局部”窗口和“监视”窗口中,单击数组或对象名称旁边的加号(+) , 可以查看数组或对象的下一级内容。当进入下一级时,就能够看到数组中所有的数组元素值, 以及对象的所有属性设置。通过选择所需的变量、数组元素或属性,然后单击“值”列,同 时键入一个新值,即可改变这些变量、数组元素或属性的值。

·203·


12.3 事件跟踪 面向对象编程中当程序不能正常工作时,确定方法中代码是否正确的有效方法就是打开 “事件跟踪”窗口。打开“事件跟踪”窗口的过程如下。 在“工具”选单选择“事件跟踪”选单项,出现如图 12.4 所示的对话框。

图 12.4

“事件跟踪”对话框

在对话框中可以选择需要跟踪的事件。默认时,所有的事件都是预选定的。由于 Mouse Move 和 Paint 事件发生次数频繁,很难看到其他的事件序列,所以一般应把这两个事件从“跟 踪事件”列表中移去。 选中“开启事件跟踪”复选框即可激活事件跟踪,此后每当“跟踪事件”列表中的一个 系统事件发生时,该事件名字就会显示在“调试输出”窗口中,单击工具栏中的“输出窗口” 按钮即可打开或者写到一个文件里,然后单击“确定”按钮即可。

12.4 出错处理程序 程序即使进行了调试也不能保证程序正常运行时不出错。道理很简单,对于一个具有一 定规模的程序,我们不可能在调试时模仿实际运行时所有可能出现的情况,那么没有模仿到 的那一种情况如有错误就不可能被发现。还有一些情况,我们无法避免出错,等等。所有程 序事先没有考虑到的错误,都可用 VFP 的出现处理程序来处理。 当程序发生错误时,Visual FoxPro 将检查与 ON ERROR 例程相关的错误处理代码,如有 就输到相应的出错处理程序;如果 ON ERROR 例程不存在,Visual FoxPro 就显示默认的错误 信息。ON ERROR 命令如下。 格式: ON ERROR 命令

说明:ON ERROR 后面的命令一般是调用一个错误处理过程或程序。

·204·


例如: ON ERROR ? ERROR()

例如: * MAIN PROGRAM ,LINENO() ,MESSAGE(),PROGRAM() ON ERROR DO EX_ERRPROC WITH ERROR()

Μ 出错处理程序可以是一个过程或函数。 PROCEDURE EX_ERRPROC LPARAMETER errNO,errLINE,errMSG,errPROC <显示错误信息> <修正错误方法> ENDPROC

<显示错误信息>最简单的就是用 MessageBox()显示出错的号、出错的行、出错信息和 出错所在的程序。这些信息是由程序将系统函数通过调用参数传递过来的。 <修正错误方法>可包含程序可能产生的错误及处理方法,还包含其他没有预计的错误的 处理办法。例如: DO CASE CASE errNO=错误号 1 <错误号 1 的处理程序> CASE errNO=错误号 2 <错误号 2 的处理程序>

Μ OTHERWISE <没有预计错误处理程序> ENDCASE

<没有预计错误处理程序>的最简单的办法是让用户通过上面显示的出错信息进行常规的 处理方法。例如忽略、继续运行出错语句和停止程序运行。从出现语句的下一语句运行要用 RETURN 返回,继续尝试运行出错语句用 RETRY 返回。

·205·


第 13 章 系统选项设置 系统选项对话框中几乎列出了 Visual FoxPro 的所有系统设置项。选择位于工具选单下的 “选项”将激活该对话框。当使用这个对话框时,除非单击“设置为默认值”按钮,否则所 有对设置的改变都是临时的,一旦退出 Visual FoxPro 6.0,这些改变就丢掉了。Visual FoxPro 6.0 将这些设置信息存放在登录数据库中。 该对话框共包括 12 个选项卡,下面详细介绍这些选项卡中各个选项的作用和功能。

13.1 显示选项卡 显示选项卡用于控制 Visual FoxPro 的显示特性,如图 13.1 所示,它控制 Visual FoxPro 开发环境下的有些信息是否显示。

图 13.1 显示选项卡

13.2 常规选项卡 常规选项卡用于设置声音、编程环境、文件处理及其他一些选项,如图 13.2 所示,其各 项功能如下。 (1)警告声音。 关闭:用于关掉 Visual FoxPro 在发生错误时的声音提示。 默认:将 Visual FoxPro 的错误提示声音作为系统的默认设置。 ·206·


播放:设置错误提示信息为一个.WAV 文件。

图 13.2 常规选项卡

(2)一般选项组。 与 dBASE 兼容:用于设定 Visual FoxPro 与 FoxBase+和其他 XBASE 语言的兼容性。该 项对应于命令 SET COMPATIBLE。 使用 Visual FoxPro 调色板:指定使用默认的 Visual FoxPro 调色板,它对应于 SET PALETTE 命令。 文件替换时加以确认:指定当新文件与已有文件重名时是否给出一个提示,以便确认这 个文件的覆盖操作。 浏览 IME 控件:指定当用户在浏览窗口激活一文本框时是否显示一输入方法编辑框。 (3)编程选项组。 按 ESC 键取消程序运行:设置是否允许在运行程序时按 Esc 键中止程序。它对应于命令 SET ESCAPE。 记录编译错误:允许或禁止登录编译错误。如果选中该项,则 Visual FoxPro 将记录被编 译文件中的每一个语法错误,并将这些错误信息存储到.ERR 文件中。.ERR 文件可用 MODIFY COMMAND 命令打开查看。 SET DEVELOPMENT:允许或禁止 Visual FoxPro 在运行程序时比较源文件与编译后的 目标文件的生成日期。打开这一项可确保 Visual FoxPro 所执行的是该程序的最新版本。 (4)数据输入选项组。 定位键:确定光标移动的方式是采用 Windows 兼容方式还是 MS-DOS 兼容方式。 用当前值填充新记录:允许或禁止使用当前定义的值填充新记录。 用 Enter 或 Tab 键离开一字段:输入或跳转到已有字段。

·207·


13.3 数据选项卡 数据选项卡用于操纵数据和表,如图 13.3 所示,其各选项功能如下。

图 13.3 数据选项卡

(1)数据选项组。 以独占方式打开:指定所有表是否都以独占方式打开。它对应于 SET EXCLUSIVE 命令。 显示字段名:设定在使用 AVERAGE,ALCULATE,DISPLAY,LIST 及 SUM 命令输出 时是否使用字段名作为每一列的题头。它对应于命令 SET HEADING。 提示代码页:当选中该项时,每当打开一个没有附加代码表的页时,Visual FoxPro 都会 提示要求加入一个代码表。该选项对应于命令 SET CPDIALOG。 忽略已删除记录:告诉 Visual FoxPro 是否处理被标记为删除的记录。该选项对应命令 SET DELETED。 Rushmore 优化:允许或禁止使用 Rushmore 优化技术。它对应于 SETOPTIMIZE 命令。 在索引中不出现重复记录:确定是否在索引文件中全部保留具有相同索引键值的记录。 它对应命令 SET UNIQUE。 排序序列:确定在进行索引及排序操作时对字符型字段的排列顺序。如果使用语言不同, 索引及排序结果就不同。它对应命令 SET COLLATE。 记录计数器间隔:设定系统报告某命令已处理记录数的间隔。其范围从 1 条记录到 32 767 条记录。默认设置为 100,即记录计数器在某命令每处理 100 条记录时在状态条上报告一次。 如果将这个间隔设为 1,则每处理一条记录都将在状态条上报告一次。它对应命令 SET ODOMETER。 备注块大小:指定用于存储备注字段的磁盘块的大小,以字节为单位。它对应命令 SET BLOCKSIZE。 浏览窗口刷新时间间隔:设定隔多长时间(s)刷新一次处于活动状态的浏览窗口。它对 ·208·


应命令 SET REFRESH。 表刷新时间间隔:设定隔多长时间(s)刷新一次处于活动状态的表。这一选项对于在网 络上共享文件时是非常有用的。它对应命令 SET REFRESH。 (2)字符串比较选项组。 SET NEAR on:当这一项被选中时,如果一个查找未找到匹配记录,那么 Visual FoxPro 就将记录指针定位到一个最接近的记录上。它对应命令 SET NEAR。 SET EXACT on:设定当比较不同长度的串时,两串的每个字符是否都必须相同,尾部空 格被忽略。它对应命令 SET EXACT。 SET ANSI on:设定当在 FoxPro 的 SQL 命令中用等号(=)比较两个不同长度的字符串 时,在较短的字符串后面加空格以使其长度与较长的字符串一致。它对应命令 SET ANSI。 (3)锁定和缓冲选项组。 文件自动锁定:允许或禁止自动文件加锁。它对应命令 SET LOCK。 多个记录锁定:允许或禁止锁定多条记录。它对应命令 SET MULTILOCKS。 缓冲:设定在多用户环境下数据的更新与维护是否处于保护状态。该选项只有在选中了 多个记录锁定后才可用。它对应 CURSETPROP()函数。 重新处理:设置当 Visual FoxPro 在锁定文件或记录失败时,再重复试几次,都不成功后 放弃。它对应命令 SET REPROCESS。

13.4 远程数据选项卡 远程数据选项卡仅适用于处理远程(ODBC)数据,在 VFP 中通过 ODBC 操作远程数据 使用,如图 13.4 所示,其各选项功能如下。

图 13.4 远程数据选项卡

·209·


(1)远程视图默认值。 共享连接:设定对新的视图是否使用当前连接。 取备注字段:选中这一项,如果在视图的输出中有一个备注字段被激活,则备注字段内 容将从数据源取回。 SQL 更新条件:用于当试图更新一个视图中正在使用的数据时,系统根据这个标准来确 定是否在用户打算更新这些数据之前已经被其他用户修改过了。如果远程表中这个选中的条 件被改变的话,则更新操作失败。 SQL 更新方法:决定了当记录中的关键字段被更新时,发送到服务器或源表的更新语句 使用什么样的 SQL 命令。 每次取的记录数:用于控制一次从远地数据源取回多少条记录。 要取的最大记录数:指定在一个视图中可使用的记录数。 使用备注字段的长度:确定何时在视图的输出中将长字符型字段转换为备注型字段。 成批更新的记录数:指定单条命令可更新的记录数。 (2)连接默认值。 异步执行:允许或禁止异步处理。 显示警告信息:允许或禁止显示警告信息。 批处理:允许或禁止批处理。如果选中的话,则只有在所有的单个操作都完成后才给 SQLEXEC()的调用返回一个值。 自动事务处理:用来决定连接如何管理远地表的事务处理,选中时,相当于将 SQLSETPROP()函数的 Transactions 属性值设为 1,未选中相当于将 Transactions 属性的值 设为 2。 显示登录信息:当在连接或视图定义中指定登录信息时显示登录提示。 连接超时设定(s) :在这个时间段内进行与远程服务器的连接。如果超出这个时间范围 仍不能建立连接的话,Visual FoxPro 就给出一个错误提示。 空闲超时设定(min) :如果在该时间内没有向服务器发出任何请求,则将终止连接。但 是如果在连接被超时终止后向服务器发出了一个请求,那么会试图自动重新建立连接。 查询超时设定(s) :用于确定服务器响应查询的时间。如果服务器处理查询的时间比这 个限制长,Visual FoxPro 就会给出一个错误信息。 等待时间(ms):每隔这个时间系统检查一下是否一个请求已经完成了。

13.5 文件位置选项卡 文件位置选项卡设置 FoxPro 所要用到的不同文件的路径。用户既可以直接在文本框中输 入文件的路径及文件名,也可单击每个文本框右侧的按钮调出对话框进行选择,如图 13.5 所 示,其各选项功能如下。 (1)默认目录:设置 FoxPro 的默认工作目录。它对应于 SET DEFAULT 命令。 (2)搜索路径:告诉 FoxPro 到哪些目录中去寻找在默认工作目录下搜集不到的文件。各 路径间必须以逗号或分号隔开。该设置对应于 SET PATH 命令。 (3)临时文件:设置 Visual FoxPro 存放临时文件的目录。 (4)帮助文件:指定 Visual FoxPro 显示帮助文件的方式,左侧的复选框用于打开或关闭 帮助文件。如果帮助文件的扩展名是.HLP,则 FoxPro 将使用 Windows 风格的帮助系统。 ·210·


若帮助文件的扩展名是.DBF,则 FoxPro 将使用数据库风格的帮助系统。如果不加扩展名, Visual FoxPro 默认为.HLP。对应于 SET HELP 命令。 (5)资源文件:为 Visual FoxPro 指定一个存储各种资源设置的文件,左边的复选框用于 打开或关闭资源文件。该设置对应于 SET RESOURCE 命令。如果没有选择一个资源文件, 那么在选项对话框中的某些选项将不可用。

图 13.5 文件位置选项卡

(6)转换器:指定一个用做转换应用程序的文件。它对应于_CONVERTER 系统内存变 量。 (7)选单生成器:指定用做选单生成器的程序的文件名。它对应于_GENMENU 系统内 存变量。 (8)拼写检查器:指定用做拼写检查器的文件名。它对应于_SPELLCHK 系统内存变量。 (9)生成器:指定用做生成应用程序的文件。它对应于_BUILDER 系统内存变量。 (10)向导:指定用做向导的文件。它对应于_WIZARD 系统内存变量。

13.6 表单选项卡 表单选项卡用于给表单生成器设定各种选项,如图 13.6 所示,其各选项功能如下。 (1)网格线:选中该项将在表单生成器主窗口上显示网格线,用以帮助各对象在表单上 的定位和对齐。 (2)对齐格线:用于设置是否自动将对象对齐网格线放置。 (3)水平间距:用于设置网格线水平宽度,其单位由度量单位区设置。 (4)垂直间距:用于设置网格线垂直宽度,其单位为像素。 (5)显示位置:打开将在 Visual FoxPro 主表单的状态条的右侧,显示当前选中对象的位 置及尺寸信息,用户也可在查看选单中设置显示位置。 ·211·


图 13.6 表单选项卡

(6)Tab 键次序:指定改变对象的 Tab 次序的方式。可使用“Shift+单击”的交互式鼠标 方式或者使用“对象次序”对话框来设置 Tab 键次序。Tab 键次序是指运行表单时按 Tab 键 后焦点在各对象间的转移顺序。 (7)度量单位:为表单生成器和类生成器设定默认的度量单位,可以指定以像素为基本 度量单位或以字符为基本度量单位。 (8)最大设计区:设定在设计时表单的最大尺寸。 模板类选项组:指定类库和类作为新表单和表单集的基类。如果什么都不指定,FoxPro 将使用默认基类,指定类可以使用户设计的表单保持一致的风格。 表单集:在已注册类库下拉表中包含了所有的已经注册了的类库。可在选项对话框的控 件表注册类库,类名下拉表中包括所有在被选中的已注册类库中的表单集类。 表单:在已注册类库下拉列表中包括所有已经注册了的类库,类名下拉列表中包括所有 在被选中的已注册类库中的表单类。 (9)生成器锁定:当生成器被锁定后,每放一个控件到表单都将自动调出该控件所对应 的向导来修改这个控件的各种属性等。 (10)提示在运行之前保存更改:在运行表单之前询问用户是否保存表单。

13.7 项目选项卡 项目选项卡用于为项目管理器设置选项,如图 13.7 所示,其各选项功能如下。 (1)项目双击操作选项组。设置当在项目管理器中双击一文件时是运行它还是修改它。 运行选定文件:选中时,如果用鼠标双击在项目管理器中的一个文件,将运行该文件。

·212·


图 13.7 项目选项卡

修改选定文件:选中时,如果用鼠标双击在项目管理器中的一个文件,则对该文件进行 编辑。 (2)向导提示。当选中这一项时,Visual FoxPro 将自动提示用户是否使用程序向导。

13.8 控件选项卡 控件选项卡用于注册可视类库以便在设计表单时指定模板类,如图 13.8 所示。该选项卡 也有其他用途,比如通过表单控制工具条上的查看类按钮可以指定哪些控件出现在表单控件 工具条上。这样做是为了更方便地向表单中添加用户控件。本选项卡各选项功能如下。 (1)可视类库:这一项与“OLE 控制”选项是互斥选项,选中可视类库将更新“选定” 列表框中的内容,使其只显示类库名称。 (2)ActiveX 控件:选中该按钮时,系统将打开显示选择区(位于窗口右下方)并更新 选定列表框使其只显示 ActiveX 控件。 (3)显示选择区。 可插入对象:选中该项将在选定列表框中显示那些可插入对象。 控件:选中该项将在选定列表框中显示属于可插入对象的 OLE 控件。 (4)选定列表框:指定哪些类库将被加入到表单控制工具条上。 (5)标签:当单击了可视类库按钮时,将在这里显示当前类库的标签名。 (6)库:当单击了可视类库单按钮时,将在这里显示当前可视类库的路径。 (7)添加按钮:当单击了可视类库单按钮时,可增加类库到选定列表框中。 (8)移去按钮:当单击了可视类库按钮时,可从选定列表框中移去一个类库。

·213·


图 13.8 控件选项卡

13.9 区域选项卡 区域选项卡可以设置日期、时间及数字的格式,可以临时或永久性地修改 Visual FoxPro 的系统设置。该选项卡的设置效果将反映在日期、时间及货币的输出上,如图 13.9 所示,其 各选项功能如下。

图 13.9 区域选项卡

(1)使用系统设置:如果选中该项,则所有选项的设置都将从系统读出。在这种模式下, 大部分选项是只读的。如果不选中这一项,那么就可以用自己指定的设置覆盖系统设置。 (2)日期和时间选项组。所做的修改都可直接在右上角的文本框中看到结果。 日期格式:尽管可选日期格式很多,但基本上只有 3 种形式:月/日/年、年/月/日、日/ ·214·


月/年,其他仅是分隔符不同。 日期分隔符:指定一个不同的日期分隔符,例如短划线。默认时日期分隔符为右斜线“/” 。 年份:选中时,表示年的数字有 4 位长(如 1999),不选中时表示年的数字只有 2 位 (如 99)。 12 小时制:将时间显示设为 12 小时制,用“am”和“pm”区分上下午。 24 小时制:将时间显示设为 24 小时制。 秒:选中时将显示秒数。 (3)货币和数字选项组。所做的修改可直接在右上角的文本框中看到结果。 货币格式:设置货币符号是出现在数字串的前面还是后面。 货币符号:改变货币符号的设置。 千位分隔符:如果指定了一个分隔符,FoxPro 系统将在大数字的小数分隔符向左每 3 位 数字插入一个千位分隔字符。这样可更清晰地阅读大数字。常用的千位分隔符是逗号。 小数分隔符:指定一字符用做小数位开始的标记。 小数位数:指定在小数分隔符右边的数字位数。 星期开始于:指定一周是从哪一天开始。 一年的第一周:指定一年日历的开始。

13.10

调试选项卡

调试选项卡用于指定调试器窗口的显示和跟踪选项,如图 13.10 所示,其各选项的功能 如下。

图 13.10 调试选项卡

(1)环境:用于定义调试环境。 ① Debug Frame:设置所有调试窗口均出现在 Visual FoxPro 主窗口以外,它们带有自己 的选单和工具条,这使得应用程序能较少受应用程序运行环境的影响。可通过选择“工具” 选单中的“调试器”项打开调试窗口。 ·215·


② FoxPro Frame:设置调试窗口出现在 Visual FoxPro 主窗口中。 (2)指定窗口:用于指定所设置的窗口。 ① 调用堆栈:选择该选项后,将在其右下部位置显示有关窗口的下列选项。 显示堆栈调用顺序:它在调用堆栈窗口程序列表附近显示一个数,通过高亮显示该数来 指示当前执行程序的情况。 显示当前行的指示器:它决定是否在调用堆栈窗口显示行指示器“→”。 显示堆栈调用指示器:它决定是否在调用堆栈窗口显示“>” ,以指示在跟踪窗口显示 的过程。如果当前行和调用堆栈指示器相同,Visual FoxPro 仅显示当前行指示器。 ② 局部变量:该窗口无附加选项。 ③ 输出:系统将显示记录调试输出区,它包括如下选项。 记录调试输出:选择该项后,系统将复制调试窗口中的值到一个文本文件。如果选 择该项,则必须指定一个具体的文件名(其扩展名为.LOG) 。 追加:将调试输出内容追加至指定文件已有的内容之后。 改写:将调试输出内容取代指定文件已有的内容。 跟踪:它显示下列几个选项。 显示行号:系统将在跟踪窗口代码行的左侧显示行号。 跟踪断点之间的部分:以慢速执行断点之间的代码。 在两代码行之间暂停:指定两代码行之间延迟的秒数。 ⑤ 监视:该窗口无附加选项。 (2)所有调试窗口的通用选项。包括字体、区域选择以及选定区域的前景和背景颜色设置。

13.11

语法着色选项卡

语法着色选项卡用于指定命令窗口和所有编辑窗口中 Visual FoxPro 程序元素的颜色和字 体,如图 13.11 所示,其中“区域”选项用于选择要设置颜色的程序元素类型,如注释、关 键字、数字等,字体、前景和背景选项用于设置选定区域的显示。

图 13.11

·216·

语法着色选项卡


13.12

字段映像选项卡

字段映像选项卡用于指定当从数据环境设计器、数据库设计器和项目管理器拖动字段至 表单时将创建的控件类型,如图 13.12 所示。用户可通过“修改”按钮,在显示字段类型映 像对话框,该对话框修改指定字段的映像类型。其他 4 项是数据库拖放时的选项。

图 13.12

字段映像选项卡

·217·


第 2 部分 习

习题 2 数 据 库 一、选择题 1.在 VFP 系统中,“.DBF”文件被称为 。 A.数据库文件 B.表文件 C.程序文件 D.项目文件 2.执行 USE KCCJ!XS ALIAS 学生 IN B 命令后,被打开的表的别名是 。 A.XS B.学生 C.B D.ALIAS 命令显示所有女同学的记录。 3.对于 XS 表,下面 A.LIST FOR !XB B.LIST FOR XB C.LIST FOR XB="女" D.LIST FOR XB="女" 4.若要显示 KC 表中第 4 学期开设的课程,可使用____________命令。 A.LIST FOR XQ=4 B.LIST WHILE XQ=4 C.SET FILTER TO XQ=4(回车)LIST(回车) D.LOCATE FOR XQ=4(回车)LIST(回车) 5.若 XS 表包含 50 条记录,在执行 GO TOP 命令后,________命令能显示所有记录。 A.LIST ALL B.LIST REST C.LIST NEXT 50 D.LIST RECORD 50 6.执行 USE XS(回车)SKIP –1 后,下列显示值一定为.T.的命令是 。 A.?BOF() B.?EOF() C.?.T. D.? RECNO()=1 7.XS 数据库表的全部备注字段的内容存储在 文件中。 A.XS.DBF B.XS.TXT C.XS.FPT D.XSCJ.DBC 8.若 VFP 的命令中同时含有 FOR,WHILE 和范围子句,则 3 个子句执行时的优先级顺 序为 。 A.FOR,WHILE,范围 B.WHILE,范围,FOR C.范围,WHILE,FOR D.无优先级,按子句出现的顺序执行 9.对于数据库表的索引,____________说法是不正确。 A.当数据库表被打开时,其对应的结构复合索引文件不能被自动打开 B.主索引和候选索引能控制表中字段重复值的输入 C.一个表可建立多个候选索引 D.主索引只适用于数据库表 10.对于表索引操作,____________说法是正确的。 A.一个独立索引文件中可以存储一个表的多个索引 ·218·


B.主索引不适用于自由表 C.表文件打开时,所有复合索引文件都自动打开 D.在 INDEX 命令中选用 CANDIDATE 子句后,建立的是候选索引 11.建立索引时, 字段不能作为索引字段。 A.字符型 B.数值型 C.备注型 D.日期型 12.对于表索引操作,__________说法是错误的。 A.组成主索引的关键字或表达式在表中不能有重复的值 B.候选索引可用于自由表和数据库表 C.惟一索引表示参加索引的关键字或表达式的值在表中只能出现一次 D.在表设计器中只能创建结构复合索引文件 13. 若 XS 表已按 XH 字段建立了结构复合索引, 索引名为 NUM。 为了显示学号为"001806" 的记录,________________能实现上述操作。 A.USE XS ORDER NUM C.USE XS SEEK "001806" DISPLAY B.USE XS

LOCATE FOR XH="001806" DISPLAY D.USE XS

SET ORDER TO NUM LIST FOR XH="001806" XH="0018" SEEK M.XH+"06" DISPLAY 14.对于数据库, 说法是错误的。 A.数据库是一个容器 B.自由表和数据库表的扩展名都为 .DBF C.自由表的表设计器和数据库表的表设计器是不一样的 D.数据库表的记录数据保存在数据库中 15.对于向数据库添加表,__________说法是不正确的。 A.可以将一个自由表添加到数据库中 B.可以将一个数据库表直接添加到另一个数据库中 C.可以在项目管理器中将自由表拖放到数据库中使它成为数据库表 D.将一个数据库表从一个数据库移至另一个数据库,则必须先使其成为自由表 16.对于数据库的操作,____________说法是正确的。 A.数据库被删除后,则它所包含的数据库表也随着删除 B.打开了新的数据库,则原来已打开的数据库被关闭 C.数据库被关闭后,则它所包含的已打开的数据库表被关闭 D.数据库被删除后,则它所包含的表变为自由表 17.要在两个数据库表之间建立永久关系,则至少要求在父表的结构复合索引文件中创 建一个 ,在子表的结构复合索引文件中也要创建索引。 A.主索引 B.候选索引 C.主索引或候选索引 D.惟一索引

·219·


18.数据库表间创建的永久关系保存在 中。 A.数据库表 B.数据库 C.表设计器 D.数据环境 19.对于表之间的永久关系和临时关系,__________说法是错误的。 A.只要打开数据库表,两数据库表之间的永久关系就起作用 B.永久关系只能建立于数据库表之间,而临时关系可以建立于各种表之间 C.表关闭之后临时关系消失 D.临时关系不保存在数据库中 20.对于表的索引描述中,__________说法是错误的。 A.复合索引文件的扩展名为 .CDX B.结构复合索引文件在表打开的同时自动打开 C.当前显示的顺序为主控索引的大小顺序 D.每张表只能创建一个主索引和一个候选索引 21.要在两张相关的表之间建立永久关系,这两张表应该是 。 A.同一数据库内的两张表 B.两张自由表 C.一个自由表和一个数据库表 D.任意两个数据库表或自由表 22.数据库表字段的默认值保存在 文件中。 A.表 B.数据库 C.项目 D.表的索引 23.当数据库表移出数据库后,仍然有效的是 。 A.字段的默认值 B.表的触发器 C.结构复合索引 D.记录的验证规则 24.以下 操作将造成相关表之间数据的不一致。 A.在主表中插入记录的主关键字的值是子表中所没有的 B.在主表中删除了记录,而子表中没有删除相关记录 C.在子表中删除了记录,而在主表中没有删除相关记录 D.用主表的主关键字字段的值修改了子表中的一个记录 25.以下 操作不会损坏相关表之间的数据一致性。 A.删除了子表中的记录而没有删除主表中的相关记录 B.删除了主表中的记录而没有删除子表中的相关记录 C.在子表中插入记录的外部关键字值是主表关键字中所没有的 D.在主表中修改了主关键字值而没有同时修改子表中相关记录的外部关键字的值 26.以下 操作不会激活记录的有效性规则的检验。 A.修改表结构并保存时 B.修改表的某一记录时 C.修改了记录值并执行 SKIP 命令时 D.修改表记录数据并关闭表时 27.建立两个表之间的临时关系时,必须设置的是 。 A.主表的主索引 B.主表的主索引和子表的主控索引 C.子表的主控索引 D.主表的主控索引和子表的主索引 28.表之间的“一对多”关系是指 。 A.一个表与多个表之间的关系 B.一个表中的一个记录对应另一个表中的多个记录 ·220·


C.一个表中的一个记录对应另一个表中的一个记录 D.一个表中的一个记录对应多个表中的多个记录 29.设学生成绩表 XS_KC 包含学号 XH 字段和课程号 KCH 字段,如果设置记录有效性 规则为 XH!= " " .AND.EMPTY(KCH) ),则执行下列 命令时,不会违反该记 录的有效性规则。 A.USE XS_KC APPEND BLANK REPLACE XH WTTH "001801", KCH WITH "301" B.USE XS_KC APPEND BLANK UPDATE XS_KC SET CJ=85 WHERE XH="001801" C.INSERT INTO XS_KC(xh, kch) VALUES("001801", "310") D.INSERT INTO XS_KC(xh, cj) VALUES("001801", 85) 30.彻底删除学号为 001806 的同学的记录,使用________。 A.USE XS DELETE FOR XH="001806" PACK B.USE XS SET FILTER TO XH="001806" ZAP C.DELETE FROM XSCJ!XS ; WHILE XH="001806" PACK D.USE XS LOCATE FOR XH="001806" DELETE FROM XSCJ!XS PACK 31.下列_______________命令可在 XSCJ 数据库中建立一个数据库表 JS。 A.OPEN DATABASE XSCJ CREATE JS (交互输入) B.CREATE JS (交互输入) OPEN DATABASE XSCJ ADD TABLE JS C.OPEN DATABASE XSCJ CREATE TABLE JS (BH C(5), XM; D.CREATE TABLE JS (BH C(5), XM;

C(10), GZ N(7, 2)) C(10), GZ N(7, 2))

CLOSE TABLE OPEN DATABASE XSCJ ·221·


ADD TABLE JS 32.删除 XS_KC 表中的 XF 字段,可使用__________________。 A.USE XSCJ!XS_KC MODIFY STRUCTURE (交互删除 XF 字段) B.MODIFY DATABASE XSCJ (选择 XS_KC 表交互删除 XF 字段) C.ALTER TABLE XSCJ!XS_KC DROP COLUMN XF D.USE XSCJ!XS_KC EDIT (交互删除 XF 字段) 33.表移出数据库后,仍然有效的是_________。 A.记录的验证规则 B.表的验证规则 C.字段的默认值 D.结构复合索引中的候选索引 34.VFP 的文件选单中的 CLOSE 命令是用来关闭_________。 A.当前工作区中已打开的数据库 B.所有已打开的数据库 C.所有窗口 D.当前活动的窗口 35.字段的默认值保存在_________。 A.表的索引文件中 B.数据库文件中 C.项目文件中 D.表文件中 36.下列叙述中含有错误的是_________。 A.一个数据库表只能设置一个主索引 B.惟一索引不允许索引表达式有重复值 C.候选索引既可以用于数据库表,也可以用于自由表 D.候选索引不允许索引表达式有重复值 37.有关表的索引,下面说法中不正确的是__________。 A.当一张表被打开时,其对应的结构复合索引被自动打开 B.结构复合索引能控制表中字段重复值的输入 C.一张表可建立多个候选索引 D.主索引适用于数据表和自由表 38.一个表的主关键字被包含到另一个表中时,在另一个表中称该关键字为_______。 A.外关键字 B.主关键字 C.超关键字 D.候选关键字 39.下列叙述中含有错误的是___________。 A.一个表可以有多个外部关键字 B.数据库表可以设置记录级的有效性规则 C.永久性关系建立后,主表记录指针移动将使子表记录指针相应移动 D.对于临时性关系,一个表不允许有多个主表 40.对于自由表而言,不能创建的索引类型是_________。 A.主索引 B.候选索引 C.普通索引 D.惟一索引 41.建立两个表之间的临时关系时,必须设置________。 A.主表的主索引 B.主表的主控索引 C.子表的主索引 D.子表的主控索引 ·222·


42.创建数据库后,系统自动生成的 3 个文件的扩展名分别为____________。 A..PJX,.PJT,.PRG B..DBC,.DCT,.DCX C..FPT,.FRX,.FXP D..DBC,.SCT,.SCX 二、判断题 1.在设计表结构时自由表没有字段属性,数据库表才有字段属性。 2.自由表的字段名最多 10 个字符,数据库表的字段名可大于 10 个字符。 3.数据库表的 INSERT 触发器在表中增加记录时触发该规则。 4.参照完整性的作用是控制相关表之间的数据一致性。 三、填空题 1.在表的浏览窗口中,向一个允许 Null 的值的字段中输入 Null 值的方法是 。 2.创建数据库 RY 后,系统自动生成的 3 个文件为 、________和_________。 3.如果一个数据库表的 DELETE 触发器设置为.F.,则不允许对该表做 记录 的操作。 4.在当前数据库 XSCJ.dbc 中,要获得表 KC.dbf 的字段 XQ 的标题,使用函数 DBGETPROP( ,"Field,Caption")。 5.在参照完整性的设置中,如果要求在主表中删除记录的同时删除子表中的相关记录, 则应将“删除”规则设置为 。 6.当打开 RY 数据库后再打开 XS 数据库,则表达式 DBUSED("RY")AND DBUSED ("XS")的值为__________。 7.对数据库表添加新记录时,为某一字段自动给定一个初始值,这个值称为 。 8.数据库表可以设置长表名,但存储在磁盘上的文件名是_________。 9.数据库文件 MYDB1,MYDB2 存放在 D 盘的 DB1,DB2 目录。执行下列程序以后, DBC()函数的值为________。 OPEN DATABASE D:\DB1\MYDBl OPEN DATABASE D:\DB2\MYDB2 SET DATABASE TO MYDB2 ? DBC () 10.用浏览窗口对表进行输入或更新操作时,若要输入或更新备注字段的值,应按 ________键以打开相应的编辑窗口。 11.在 VFP 系统中,在同一个表上,可以打开多个索引,但其中只有一个索引对表逻辑 顺序起作用,这个索引称为_________。 12.表文件中的记录的存放顺序,称为________顺序。 13.数据库表的字段属性有标题、_______、有效性规则和有效性说明。 14.表的有效性规则是用于对_________的有效性验证。 15.同一张表可以同时在_______个工作区中打开。 16.对于表 XS.DBF,执行下述程序后,X1=_______,X3=_________。 USE XS LOCATE NEXT 5 FOR XB="女" X1=RECNO() X2=FOUND() ·223·


LOCATE NEXT 4 FOR XB="男" X3=RECNO() X4=FOUND() X5=EOF() ? Xl,X2,X3,X4,X5 CLOSE DATA RETURN 17.在数据库系统中,数据的不一致性是指___________。 18.在 VFP 中,表示范围的短语 REST 的含义为___________。 19. VFP 设置默认文件夹的命令为__________。 20.在 Visual FoxPro 系统中,表的触发器是绑定在表上的________。当表中的任何记录 被指定的操作命令修改时,触发器被激活。 21.如果数据库表的插入触发器设置为.F.,则当向该表中插入一条空记录时,屏幕显示 ____________。 22.不能用__________和通用型字段构造索引表达式来创建索引。 23.表之间的永久性关系保存在_________文件中。 24.用 SEEK 命令查找后,如果一个表中有两条满足条件的记录,则记录指针指向第一 条满足条件的记录,如果再执行一次 SEEK 命令,则记录指针指向第________条满足条件的 记录。 25.一个 OLE 对象可以链接或嵌入到表的________型字段中。 26.使用 SET FILTER TO 命令所设置的过滤器,对 DELETE-SQL 命令、UPDATE-SQL 命令及_________命令不起作用。 27.若当前数据库中有一个名为 XS 的表,且表中有一个 XM 的字段,则利用函数设置 该字段的标题属性为“姓名”的命令为=DBSETPROP("XS.xm",_____,"姓名")。 28.已知自由表 XS1 中含有 20 条记录,执行下列程序段后,N 的值为= _________。 程序清单如下: USE XS1 DELETE NEXT4 SET DELETED ON N=RECCOUNT() 29.执行下列命令后: SELECT 0 USE XS ALIAS ST USE JS IN 0 函数 USED("JS")的值是________,函数 SELECT()的值是________,函数 ALIAS()的值 是____________。

·224·


习题 3 程 序 设 计 一、选择题 1.对于日期型数据,____________说法是正确的。 A.两个日期型数据可以进行加法运算 B.两个日期型数据可以进行减法运算 C.一个日期型数据可以加一个整数 D.一个日期型数据可以减一个整数 2.以下___________数据类型不能用于内存变量。 A.日期型、日期时间型、逻辑型、备注型 B.货币型、浮点型、双精度型、整形、通用型 C.浮点型、双精度型、整形、备注型、通用型 D.货币型、数值型、字符型、逻辑型、备注型 3.均为 VFP 常量的是____________。 A.68,"68",_68、.T. B.{^2000.12.26},"2000.12.26",{}," " C.[],"AA"、0,_AA D..T.,T,"T",_T 4.下面赋值语句中错误的是___________ 。 A.MyV1="23"+456 B.MyV2=DATE()-4 C.MyV3=.T..OR.3>4 D.MyV4="今天是"-DTOC(DATE()) 5.VFP 中的 DTOC()函数返回值的类型是 。 A.字符型 B.日期型 C.数值型 D.逻辑型 6.在 DO WHILE/ENDDO 循环中,若循环条件设置为.T.,则下列说法中正确的是 。 A.程序无法跳出循环 B.程序不会出现死循环 C.用 EXIT 可跳出循环 D.用 LOOP 可跳出循环 7.下列________函数返回的值的数据类型是相同的。 A.STR(1234,6,1),LEFT("1234ABCD",4),SPACE(8), B.ASC("A"),SUBSTR("1234",3,2),ALLTRIM("1234") C.DTOC(DATE()),YEAR(DATE()),{} D.RECNO(),EOF(),RECCOUNT() 8.表达式的值的数据类型相同的有__________。 A."23">"4","王"$"王平" B.VAL("24")+1.8,{01/18/00}-{01/15/00} C.DATE(),CTOD("01/18/00") D."1",1 9.用户自定义函数或过程中接受参数,应使用____________命令。 A.PROCEDURE B.FUNCTION C.WITH D.PARAMETERS 10.用户自定义函数或过程可以定义在__________________。 A.独立的程序文件、过程文件 ·225·


B.对象的事件代码、方法代码中 C.数据库的存储过程中 D.可以编写代码的地方都可以定义函数和过程 11.函数 EMPTY(0)和 ISNULL(0)的返回值分别是__________。 A..T.和.T. B..T.和.E. C..F.和.T. D..F.和.F. 12.在命令窗口赋值的变量默认的作用域是_____________。 A.全局 B.局部 C.私有 D.不一定 13.已知 RY 数据库的基本情况表包含 “姓名” 字段, 当执行了 USE RY! 基本情况 ALIAS JB 命令打开该表后,要显示当前记录的“姓名”字段的值,应用__________。 A.? 姓名 B.? "姓名" C.? M.姓名 D.? M."姓名" 14.设 XB 为表中的字符型字段,其宽度为 2,则 XB="男".OR.XB="女"=___________。 A.XB="男" B..XB="女" C..T. D..F. 15.表达式 STR(YEAR(DATE()+10))的值的数据类型为__________。 A.字符型 B.数值型 C.日期型 D.逻辑型 二、完善整个程序 1.下列程序是用来求长方形的面积,请将它写完整。 X=3 Y=5 S=AREA(X,Y) ?S FUNCTION AREA S1=X*Y RETURN 2.下列程序计算 P=1!+2!+3!+4!+5!的值,请将程序补充完整。 SET TALK OFF X=1 P=0 S=1 DO WHILE___________ DO jc WITH X P=P________ X=X+1 ENDDO ? P CANCEL PROCEDURE jc _________________ S=1 FOR N=1 TO J ·226·


S=S*N ENDFOR RETURN 3.已知教师表(JS.DBF)已经按姓名(XM)字段建立索引(索引名为 XM),阅读下列程序: USE JS SET ORDER TO XM SEEK "王一平" IF FOUND() DISPLAY ELSE WAIT WINDOW "查无此人" ENDIF 如果要用 SEEK 函数完成上述相同的功能,可将程序改成: USE JS SET ORDER TO XM IF _______ DISPLAY ELSE WAIT WINDOW "查无此人" ENDIF 4.下列程序用来求 0~100 偶数之和,请将它写完整。 STORE 0 TO N,S DO WHILE .T. IF N>100 ________ ELSE S=S+N ENDIF N=N+2 ENDDO 5.运行下列程序段以后,显示内容的前两行为:(29) ,(30)。 SET TALK OFF S="ABCDEF" N=LEN(S) K=1 DO WHILE K<=N ? SUBS(S,K,N-K) K=K+1 ENDDO

·227·


6.下列程序用来计算长方形的面积,请将它写完整: X=3 Y=5 S=0 DO_____WITH X,Y,S ?S PROCEDURE AREA __________ S1=X*Y RETURN 7.下列程序: N=0 M=0 USE JS SCAN WHILE XB="男" N=N+1 ENDSCAN M=RECCOUNT()-N 执行上述程序后,N=_______,M=_________。 8.完善以下程序段: LOCAL n n=MessageBox("删除吗?",4+____,"删除确认") IF n=6 SELECT js DELETE ENDIF 9.已知学生成绩表(XS.DBF)中含有学号(XH,C,6)、课程代号(KCDH,C,2)和成绩(CJ, N,3)字段。评定成绩等级(优、良、中、及格、不及格)自定义函数 GETCJ5 代码如下: USE XS DO WHILE !EOF() CJ5=GETCJ5(XS.CJ) ? XH,CJ5 _______ ENDDO CANCEL FUNCTION GETCJ5 PARAMETERS nCj LOCAL dj DO CASE CASE nCj>=90 ·228·


dj="优" CASE BETWEEN(nCJ,80,89) dj="良" CASE BETWEEN(nCJ,70,79) dj="中" CASE BETWEEN(nCj,60,69) dj="及格" CASE nCj<60 dj="不及格" ENDCASE RETURN ___________ 三、综合题 1.以下符号名中哪些是合法的符号常量和变量名。 CmdV1,25a,LngNum,name&2,Year%,a>b,M.John,王 2.已知 a = 0,b = -1,c = .T.,写出以下逻辑表达式的值。 (a+b)*100>0 .AND.NOT.c

a-1=b .OR.c .NOT.(a > b-1) .AND.c .OR..F. 3.写出判别 Y 中的年份是否是闰年的条件表达式。闰年的条件符合以下二者之一: (1)能被 4 整除但不能被 100 整除。 (2)能被 4 整除又能被 400 整除。 4.将以下的条件关系用 VFP 的表达式来表示: (1)文本框 Text1 的 Value 属性中的数值大于 0,小于 100。 (2)数值型变量 X,Y 的符号相反。 (3)字符变量 X 为小写字母之一。 (4)字符串变量 String1 中含有"THE"。 5.某航空公司规定在 7~9 月份,如果订票数超过 20 张,则票价优惠 15%;如果超过 10 张,则票价优惠 5%;在 1~5 月份、10 月份和 11 月份,如果订票数超过 20 张,则票价优 惠 25%;如果超过 10 张,则票价优惠 15%。从表单中输入票价、月份以及订票数,并显示 出所需金额。 6.使用 For 循环,计算以下算式的值。 S = 11+22+33+44+55+… 使用一个文本框输入需要计算的次数,使用另一个文本框显示计算的结果。 7.根据以下步骤求两个自然数的最大公约数。 (1)在两个文本框中输入两个自然数 M,N。 (2)计算 M 除以 N 的余数 R。 (3)用 N 替换 M,M=N;用 R 替换 N,N=R。 (4)若 R<0,R>0 则重复上述过程(2)、(3)。 (5)输出 R。 8.编程实现将二进制整数转换成 n 进制的整数。 ·229·


习题 4 表

一、选择题 1.在面向对象程序设计中,考虑的问题包括_________。 A.创建什么样的对象 B.对象中的属性 C.产生的事件 D.全部代码的流程 2.关于事件,________说法是不正确的。 A.事件是由对象识别的一个动作 B.事件可以由用户的操作产生 C.事件可以由系统产生 D.事件代码可由程序调用 3.所有基类均能识别的事件是_________。 A.Click B.Load C.InteractiveChange D.Init 4.下列__________对象中不能以表单作为直接容器。 A.页框 B.页面 C.命令按钮组 D.命令按钮 5.下列________对象中能以页框作为直接容器。 A.FORM B.Grid C.Column D.Header 6.以下__________属于非可视容器类。 A.PageFrame B.FORM C.Timer D.OptionGroup 7.设表单 FORM1 包含命令按钮组 G1 和文本框 T1,G1 中包含命令按钮 C1 和 C2,在 C2 的 Click 事件代码中要引用 T1 的 VALUE 属性,则正确引用是___________。 A.THSFORM.T1.VALUE B.THIS.Parent.T1.VALUE C.THIS.Parent .Parent.T1.VALUE D.T1.VALUE 8.当调用一个表单的 Show 方法时,可能激发表单的____________。 A.Load 事件 B.Init 事件 C.Activate 事件 D.Click 事件 9.下列__________属于方法名。 A.GotFocus B.SetFocus C.LosFocus D.Activate 10.容器类对象______________。 A.只能是表单或表单集 B.必须由基类 Container 派生得到 C.能包容其他对象,并且可以分别处理这些对象 D.能包容其他对象,但不可以分别处理这些对象 11.在对象的“相对引用”中,可使用的关键字有__________。 A.THIS,THISFORM,Parent B.THIS,THISFORMSET,PageFrame C.THIS,THISFORM,THISFORMSET D.THIS,FORM,FORMSET 12.下列组中全是容器类的是_______。 A.FORM,PageFrame,Columm B.Grid,Column,TextBox C.CommandButton,OptionGroup,ListBox D.CommandGroup,DataEnvironment,Header 13.创建对象时发生__________事件。 A.Init B.Load C.InteractiveChange D.Activate ·230·


14.用表单设计器设计表单,下列叙述中错误的是______。 A.可以创建表单集 B.可以向表单添加新属性和方法 C.可以对表单添加新事件 D.数据环境对象可以加到表单中 15.表单的 Name 属性用于__________。 A.作为保存表单时的文件名 B.引用表单对象 C.显示在表单标题栏中 D.作为运行表单时的表单名 16.可以在表单的数据环境中添加的是____________。 A.表 B.表之间的临时关系 C.查询 D.视图 17.可改写计数属性的容器是__________。 A.表单集、表格、页框、页面 B.命令按钮组、选项按钮组、表格、页框 C.表单、列、页面、容器 D.页面、表单、工具栏、_SCREEN 18.如果要在运行表单时向表单中传递参数,则应在表单的_____事件代码中包含 PARAMETERS 语句。 A.Init B.Load C.Activate D.数据环境的 BeforeOpenTables 19.在 Visual FoxPro 系统中,用户不能自定义________。 A.对象的属性 B.对象的方法 C.对象的事件 D.对象所基于的类 20.如果要引用一个控件所在的直接容器对象,则可以使用________。 A.THIS B.THISFORM C.PARENT D.都可以 21.表单的 Name 属性是_________。 A.显示在表单标题栏中的名称 B.运行表单程序时的程序名 C.保存表单时的文件名 D.引用表单对象时的名称 二、填空题 1.在“________设计器”窗口活动时,Visual FoxPro 显示处理数据环境对象的数据环境 选单、属性窗口和代码窗门。 2.对象引用分为绝对引用和相对引用,THISFORMSET 表示引用________、PARENT 表示引用________。 3.要修改表单,要用________设计器修改。 4.当_________,表单的 Error 事件被触发。 5.建立事件循环的命令是____________。 6.打开表单(SCX)的命令是__________。 7.在表单的 Load,Activate 和 Init 这 3 个事件中,________事件不能引用表单及表单中 的对象,__________事件最后一个被触发。 8.有一表单 Form1,该表单中包含一个页框 PageF,下列为刷新表单的程序段,请完善 如下代码: FOR i=1 to This.__________ This.Pages(i).Refresh ENDFOR 9.要使表单中各个控制的 ToolTipText 属性的值在表单运行中起作用,必须设置表单的 ShowTips 属性的值为________。 ·231·


10.标签控件的 AutoSize 属性的作用_________, Caption 属性的作用________。 11.已知某表单子类 cFrmA 含有一个命令按钮,且命令按钮的 Click 事件代码为: Thisform.Backcolor=RGB(255,255,0)。基于该子类创建并运行表单 FormA,则单击表单上 的命令按钮后,表单的背景色为_________ 。如果在表单 FormA 中重新为命令按钮设置了 Click 事件代码:Thisform.Backcolor=RGB(0,255,255),则运行该表单后单击命令按钮,表 单的背景色为_________。 三、问答题 1.如何理解 Visual FoxPro 中的对象?使用面向对象的方法有哪些好处? 2.什么是对象的“属性”和“方法”? 3.对象的引用方法有哪些?绝对引用和相对引用各有什么不同? 4.容器类和非容器类有何区别? 5.如何调用对象的方法? 6.Visual FoxPro 中事件的发生顺序是怎样的? 7.在 VFP 中,创建表单有哪几种方法? 8.在属性窗口中,如何区分某属性值是系统默认的,还是由用户设置的或是只读的? 9.在“属性”窗口中,由用户新建的方法,除了在“全部”选项卡中显示,还显示在哪 个选项卡中? 10.在 VFP 中,用户是否可以为某控件创建新的属性或事件? 11.在“表单设计器”中,同时选择多个控件有哪几种方法? 12.在 VFP 中,系统提供的控件生成器有哪几种方法? 13.对于数据库、数据库表、视图、自由表、查询来说,哪些可以添加到表单的数据环 境中? 14.为了使某表单在运行时不可改变其大小,用户应修改表单的哪些属性? 15.顶层表单、浮动表单和子表单有何不同?其 ShowWindows 属性和 Desktop 属性应分 别如何设置?

·232·


习题 5 控

一、选择题 1.如果在表单中要为一个逻辑型字段创建一个对象,较为合适的控件类型是______。 A.TextBox B.CheckBox C.OptionGroup D.ComboBox 2.下列控件中,______在运行时一定不可见。 A.OptionButton B.Page C.OptionGroup D.Timer 3.单击表单中一个未被禁用的文本框,发生的 3 个事件的顺序是______。 A.GotFocus,When,Click B.When,GotFocus,Click C.Click,GotFocus,When D.Click,When,GotFocus 4.Grid 的集合属性和计数属性是_______。 A.Columns 和 ColumnCount B.Forms 和 FormCount C.Pages 和 PageCount D.Controls 和 ControlCount 5.对列表框的内容进行一次新的选择,一定会发生______事件。 A.Click B.When C.InteractiveChange D.GotFocus 6.如果要在列表中一次选择多个项(行),必须设置_______ 属性为.T.。 A.MultiSelect B.LisItem C.ListItemID D.Enabled 7.Timer 控件的 Interval 属性值设置为 100,表示________ 。 A.Timer 事件在 100s 后失效 B.100s 后,时钟控件的 Enabled 属性自动为.F. C.Timer 事件发生的频率为 10 次/秒 D.Timer 事件发生的时间间隔为 100s 8.Grid 能包容的对象是_________。 A.Header B.TextBox C.Column D.EditBOX 9.OptionGroup 是包含_______的容器。 A.CommandButton B.OptionButton C.CheckBox D.任意控件 10.在下列各组控件中,全部可与表中数据绑定的控件是________。 A.EditBox,Grid,Line B.ListBox,Shape,OptionButton C.ComBox,Grid,TextBox D.CheckBox,Separator,EditBox 11.选项按钮组中选项按钮的个数由_______属性决定。 A.ControlCount B.OptionCount C.ButtonCount D.ObjectCount 12.在下列各组控件中,全部可与表数据绑定的控件是________。 A.EditBox,Grid,Line B.ListBox,Shape,OptionButton C.ComBox,Grid,Textbox D.CheckBox,Separator,EditBox 13.要建一个有 6 个按钮的选项组,应将属性_______的值改为 6。 A.Option Group B.Button Count C.Bound Column D.Control Source 14.当某个控件绑定到一个字段时,移动记录指针后如果字段的值发生变化,则该控件 的________属性的值也随之变化。 ·233·


A.Value B.Name C.Caption D.没有 15.同一个对象的 Init,Load,Activate 和 Destroy 事件发生的顺序为________。 A.Init,Load,Activate,Destroy B.Load,Init,Activate,Destroy C.Activate,Init,Load,Destroy D.Destroy,Load,Init,Activate 16.页框(Page Frame)能包容的对象是________。 A.页面(Page) B.列(Colunm) C.标头(Header) D.表单集(FormSet) 17.下列各个基类均是容器型的是__________。 A.Grid,Column,TextBox B.CommandButton,OptionGroup,ListBox C.CommandGroup,DataEnvironment,Header D.Form,PageFrame,Column 18.关于表格控件,下列说法中不正确的是__________。 A.表格的数据源可以是表、视图、查询 B.表格中的列控件不包含其他控件 C.表格能显示一对多关系中的子表 D.表格是一个容器对象 19.某表单 FormA 上有一个命令按钮组 CommandGmupl,命令按钮组中有 4 个命令按钮: CmdTop,CmdPrior,CmdNext,CmdLast。若要求按下按钮 CmdLast 时,将按钮 CmdNext 的 Enabled 属性设置为.F.,则在按钮 CmdLast 的 Click 事件中应加入 ________命令。 A.This.Enabled=.F. B.This.Parent.CmdNext.Enabled=.F. C.This.CmdNext.Enabled=.F. D.Thisform.CmdNext.Enabled=.F. 20.如果某表单中有一命令按钮组,且已分别为命令按钮组和其中的各命令按钮设置了 Click 事件代码,则在表单的运行中单击某命令按钮时,系统执行的代码是__。 A.该命令按钮的 Click 事件代码 B.该命令按钮组的 Click 事件代码 C.先为该命令按钮组的 Click 事件代码,后为该命令按钮的 Click 事件代码 D.先为该命令按钮的 Click 事件代码,后为该命令按钮组的 Click 事件代码 21.下列几组控件中,均为容器类的是__________。 A.表单集、列、组合框 B.页框、页面、表格 C.列表框、列、下拉列表框 D.表单、命令按钮组、OLE 控件 二、填空题 1.在 VFP 中表单文件以______扩展名存储,通过______属性来引用表单对象。 2.如果要在表单启动后自动位于主窗口中央,则应该将表单的______属性设置为.T.。 3.将文本框控件与一个字段绑定,移动记录后字段的值发生变化,这时该控制对象的 ______属性的值也随之变化。 4.如果要让一个文本框的初值设置为当前日期且不能更改,则在该文本框的______事件 中设置代码为 This.Value=DATE(),同时要将它的______属性设置为.F.。 5.对于列表框控件,当其______发生变化时,将触发 InteractiveChange 事件。 6.选项按钮组是______对象;现有一个选项按钮组有 6 个选项按钮,如果用户选择了第 4 个按钮,则选项按钮组的 Value 属性值为______。 ·234·


7 . 组 合 框 的 数 据 源 RowSource 属 性 中 写 入 一 条 SELECT SQL 语 句 , 则 它 的 RowSourceType 属性应设置为______。 8.当______时,表单的 Error 事件被触发。 9.计时器(Timer)控件中设置时间间隔的属性 Interval 为大于 0 的值,定时发生的事件 为______。 10.要使标签(Lable)中的文本能够换行,应将______属性设置为.T.。 11.表格是一个容器对象,它能包含的对象是______。 12.要使表单中各个控件的 ToolTipText 属性的值在表单运行中起作用,必须设置表单的 ShowTips 属性的值为______。 13.一个 ComboBox 下拉列表对象的 Enabled 属性的值为______时,对象才能响应用户 引发的事件。______和______属性用来给出列表中各行数据的来源和类型。 14.ComboBox 下拉列表可以是包含多个列的列表,在______属性中设置列数,在______ 属性中指定绑定的列号,使 Value 属性和绑定数据源从这一列取选定值。 15.在 VFP 系统中,同时设定多个对象的同一个属性,设定前必须同时______这些对象。 16.在表单中,OLE 绑定型控件可显示表中______型字段。 17.表格的数据源是视图 RSVIEW,应设置属性 RecordSourceType=____________和属性 RecordSource=____________。 18.______包含 RowSource 属性,事件 Activate 应用于____________。 19.组合框兼有下拉列表框和______的功能。 20.复选框控件可以有 3 种状态,其 Value 属性值分别为.F.,.T.或______。 三、问答题 1.标签控件的主要属性有哪些?为了让某一标签对象可以显示多行文本信息,应如何设 置其属性? 2.文本框控件与编辑框控件有何不同? 3.列表框控件与组合框控件有何不同? 4.对于选项按钮组来说,如果 ControlSource 属性设置为某表的字段,则该字段中保存 的值是否为选项按钮组的 Value 属性值? 5.复选框控件有几种可能的状态?其 Value 属性值可以为哪几种数据类型? 6.表格的 DeleteMark 属性有何作用? 7.微调框控件的主要属性有哪些? 8.在利用计时器控件时,应考虑哪些方面的问题? 9.形状控件的 Curvature 属性值对形状对象的外观有何影响? 10.命令按钮控件的访问键应在哪个属性中进行设置? 11.系统默认的表单上各个控件的 Tab 键次序是什么?如何修改 Tab 键次序? 12.哪些属性可以控制表单上的控件是否有提示文本以及提示文本的内容? 13.页框的 Tabs 属性与 TabStyle 属性对页框的外观有何影响? 14.OLE 容器控件与 OLE 绑定型控件有何不同?

·235·


习题 7 类的创建和使用 一、选择题 1.在 VFP 中创建子类或表单时,不能新建的是_______。 A.属性 B.方法 C.事件 D.事件的方法代码 2.从 CommandButton 基类创建子类 cmdA 和 cmdB,再由 cmdA 类创建 cmdAA 子类, 则 CmdA,cmdB 和 cmdAA 必须具有相同的___________。 A.Caption 属性 B.Name 属性 C.BaseClass 属性 D.ParentClass 属性 3.子类或对象沿用父类的属性、方法和事件代码的特性称为___________。 A.继承性 B.多态性 C.封装性 D.抽象性 4.对于任何子类或对象,具有的属性一定是__________。 A.Caption B.BaseClass C.FontSize D.ForeColor 5.在 时需要创建新类。 A.总是可以直接基于基类建立程序 B.如果基类不具有某功能,而这一功能又不经常使用 C.如果基类不具有某功能,而这一功能又经常使用 D.VFP 建立程序时,总是先创建子类,再创建对象 6.在 VFP 中创建新类时, 。 A.只能基于基类 B.可以基于任何 VFP 基类和子类 C.只能基于子类 D.不能基于不可视类 7.对创建新类,VFP 提供的工具有 。 A.类设计器和表单设计器 B.类设计器和数据库设计器 C.类设计器 D.类设计器和查询设计器 8.关于子类的存储,正确的说法是 。 A.一个子类必须保存为一个类库 B.多个子类可以保存到一个类库中 C.具有父子关系的两个子类不能保存在同一个类库中 D.具有相同的基类的子类才能保存到一个类库中 9.要更改一个类库中某个子类的类名,可以 。 A.在类设计器中修改 Nam 属性 B.在表单设计器中修改 Nam 属性 C.在项目管理器或类浏览器中进行更改 D.在类设计器或类浏览器中进行更改 10.要调用父类的 Init 事件代码时,可以用 。 A.NODEFAULT 命令 B.DODEFAULT()函数 C. ::操作符 D.THIS.ParentClass.Init()

·236·


二、问答题 1.基类和子类有何关系? 2.什么是 VFP 基类、自定义类?它们各有什么用途? 3.在 VFP 系统中创建新类的方法有哪些?如何扩展基类? 4.为新类添加新属性和新方法程序的作用是什么? 5.编程方法设计类的要点是什么? 6.为什么使用对象存储数据?如何实现对父类方法的调用?

·237·


习题 8 查询和视图 一、选择题 1.有关查询与视图,下列说法中不正确的是 。 A.查询不可以更新源表数据,而视图可以更新源表数据 B.查询和视图都可以更新源表数据 C.视图具有许多数据库表的属性,利用视图可以创建查询和视图 D.视图可以更新源表中的数据,存储于数据库中 2.“查询”文件的扩展名为 。 A..PRG B..FPX C..QPR D..QPX 3.查询文件中保存的是 。 A.查询的命令 B.查询的结果 C.与查询有关的基表 D.查询的条件 4.如果 ComboBox 对象的 RowSourceType 属性设置为“3-SQL 语句” ,为了在表单运行 时不出现查询的浏览窗口,则在 RowSource 属性中写入的 SELECT 语句必须包含_________ 子句。 A.GROUP BY B.ORDER BY C.DISTINCT D.INTO 5.可以作为查询与视图的数据源的是 。 A.自由表 B.数据库表 C.查询 D.视图 6.可以作为查询和视图的输出类型是___________。 A.自由表 B.表单 C.临时表 D.数组 7.视图与基表的关系是 。 A.视图随基表的找开面打开 B.基表随视图的关闭而关闭 C.基表随视图的打开而打开 D.视图随表的关闭而关闭 8.下列关于查询和视图的叙述中,正确的是查询和视图都 。 A.保存在数据库中 B.可以用 USE 命令打开 C.可以更新基表 D.可以作为列表框对象的数据源 9.如果查询和视图的基表数据发生变化,要刷新查询和视图中的结果,正确的方法 是 。 A.查询需要重新运行,视图可以用 REQUERY()函数 B.需重新创建查询和视图 C.查询需要重新运行,视图会自动刷新 D.查询和视图都会自动刷新 10.对于视图不可以创建的是 。 A.字段的默认值 B.独立索引 C.临时关系 D.永久关系 11.下列说法中错误的是 。 A.视图是数据库的一个组成部分 B.视图中的源数据表也称为“基表” ·238·


C.视图设计器只比查询设计器多一个“更新条件”选项卡 D.远程视图使用 VFP 的 SQL 语法从 VFP 视图或表中选择信息 12.打开本地视图后,当基表中的数据发生变化时,则 。 A.视图中的数据将自动随之发生变化 B.必须先关闭视图,再打开视图后,视图中的数据才会变化 C.可以用 REQUERY()函数刷新视图 D.必须重新创建视图 13.要求仅显示两张表中满足条件的记录,应选择 类型。 A.内连接 B.左连接 C.右连接 D.完全连接 14.创建一个参数化视图时,应在筛选对话框的实例框中输入 。 A.*参数名 B.?参数名 C. !参数名 D.参数名 二、填空题 1.查询和视图在本质上都是一条 语句。查询和视图的基表可以 有 张。 2.查询文件以 为扩展名保存在 中,视图是一张 表,不 以文件形式保存,本地视图的基表在视图打开时 ,当视图关闭时基表 。 3.视图是一张虚表,视图定义保存在 中,视图的打开可用 命令来 实现。 4.查询中的分组依据是将记录分组,每个组生成查询结果中的 记录。 5.视图可以在数据库设计器中打开,也可以用 USE 命令打开,但在使用 USE 命令打开 视图之前,必须打开包含视图的 。 6.使用 子句实现分组结果的筛选条件。它应该同 子句一起使用。 7.VFP 的视图有 和 两类。 三、编程题 1.写出满足下列针对 RY 数据库查询要求的 SQL 语句。 (1)查询“基本情况”表中,每个职工的编号、姓名、年龄、性别和工资; (2)查询职称为“助经”的职工的工资情况(包括编号、姓名、技能工资、岗位工资、 浮动工资、其他工资、工资、扣款小计、实发工资) ; (3)按职称统计职工的人数、工资总额和平均工资; (4)查询部门编号为“04”的职工的基本情况和工资情况。 2.写出满足下列针对 XS 数据库查询要求的 SQL 语句。 (1)查询 2000 年 6 月各个销售商销售各种产品的情况。 (2)查询各种产品的库存情况。 (3)查询 2000 年 5 月上海一百的销售情况。 (4)查询 PANDA 2999 的价格、库存量以及 2000 年 5 月的销售情况。 (5)查询南京家电公司的负责人、电话以及 2000 年 6 月的销售情况。 (6)查询 PANDA 2177 的价格、库存量、2000 年 5 月的销售情况及销售商的电话。 (7)现要查询 1999 年 9 月 1 日所售各商品的名称,销量和零售总额,并按销量的降序排 序。

·239·


习题 9 选单和工具栏 一、填空题 1.用选单设计器设计的选单文件的扩展名是 ,备注文件的扩展名是 , 生成的选单程序文件的扩展名是 ,有一选单程序文件为 mymenu,mpr,则运行该选 单程序的命令是 。 2. 控件只能放到工具栏上,而不能放到表单上。 3.某选单项名称为“Save”,要为该选单设置热键 Alt+S,在名称中的设置则为_______。 4.恢复 VFP 系统选单的命令是 。 5.当用户在选定的对象上单击鼠标右键时出现的选单称为 。 6.在 Visual FoxPro 6.0 中,可以创建两种类型的选单,它们分别是________、________。 二、问答题 1.快捷选单的用途是什么?如何设计? 2.如何重新配置 Visual FoxPro 6.0 的系统选单? 3.创建自定义工具栏有何作用?如何创建? 4.自定义工具栏可以添加到单个表单中吗? 5.如何启用和废止选单项? 6.如何将自定义选单插入到系统选单栏中? 7.快速选单有何特点?如何进入? 8.如何在下拉式选单中添加分隔线? 9.如何在自定义选单中插入一个系统选单项? 10.设计表单选单与普通选单有何不同?

·240·


习题 10 报表和标签 1.报表文件的扩展名是_________。 2.要想在报表中每行打印多条记录的数据,则可采用______报表。 3.如果想在报表中每个记录数据上端都显示该字段标题,则应将这些字段标题设置在 ______带区中。 4.若想将某域控件的格式设置为“数值型”且“如果为零保持为空”,则格式符为_____。 5.用于创建报表的向导有报表向导、一对多报表向导和___________。 6.报表中将字段控件称做_______。 7.VFP 中使用__________命令打印报表。 8.若以页预览形式显示报表,则用_________子命令。 9.若在报表中不打印细节行,只打印总计和分类总计,则用_______子命令。 10.在数据分组时,数据源应根据分组表达式创建索引,且在报表的数据环境中设置表 的_____属性。 11.不用打印报表就能看到报表的外观,可通过报表的______________功能。 12.进行“计算字段”设置的字段的字段控件,一般位于报表的________、_________ 和___________带区。 13.报表设计中,数据分组有何作用?

·241·


第 3 部分 实

实验 1 Visual FoxPro 集成环境和项目 目的和要求 (1)熟悉 VFP 的集成环境(系统的选单、工具栏、命令窗口、对话框等); (2)掌握主窗口、工具栏和命令窗口的使用方法; (3)掌握查找帮助主题的方法; (4)掌握项目的创建、打开、使用和关闭方法。

实验准备 (1)熟悉 Windows 98 操作系统的环境和基本操作; (2)复习教材中第 1 章的内容; (3)在 D: 盘上创建工作文件夹 RY_MIS。

实验内容 1. Visual FoxPro 6.0 的启动 “开始”→“程序”→“Microsoft Visual FoxPro”→“Microsoft Visual FoxPro 6.0”。 2. 选单和常用工具操作 单击“文件”选单,系统显示文件选单项,选择“新建(N)…Ctrl+N”选单项,出现“新 建”对话框,选择“取消”。 直接按 Ctrl+N 键,系统出现“新建”对话框,选择“取消”命令。说明快捷键与上述选 单操作功能相同。 选择“常用”工具栏“新建”按钮,系统也出现“新建”对话框,选择“取消” 。说明工 具栏的按钮与上述选单操作功能相同。 浏览整个 VFP 系统选单,了解各选单中的选单项。熟悉各种选单项的操作方法。 3. 工具栏操作 打开工具栏有两种方法。 (1)单击“显示”选单,单击“工具栏”选单项,弹出“工具栏”对话框,在该选单中 进行选择,如图 T1.1 所示。 (2)将鼠标光标指向任一工具栏区域后,单击鼠标右键,出现工具栏快捷选单,在该选 ·242·


单中进行选择,如图 T1.2 所示。 (3)查看工具栏按钮的功能。将鼠标光标在“常用”工具栏第一个按钮上停留片刻,将 会显示“新建”功能提示。按钮的功能提示可以取消,只要在如图 T1.1 所示“工具栏”对话 框中,取消对“工具提示(P)”复选框的选择即可。 (4)改变工具栏的位置。启动 VFP 后,系统默认将“常用”工具栏位于(称为“停留”) 主窗口的顶部。将鼠标光标指向工具栏的非按钮位置,可拖动工具栏到主窗口的任意位置。 工具栏可停留在主窗口的四周。如果拖动到中央,则工具栏成为“浮动”的工具栏窗口,窗 口标题即为工具栏的名称。拖动工具栏窗口的边或角可以改变其形状。 双击“浮动”工具栏窗口的标题栏,可将工具栏停留到主窗口顶部。

图 T1.1

“工具栏”对话框

图 T1.2

工具栏快捷选单

4. 命令窗口的使用 命令窗口是用户直接输入 VFP 命令进行操作的地方。 (1)命令窗口的打开和关闭。进入 VFP 后,命令窗口处于打开状态,单击命令窗口的“关 闭”按钮关闭命令窗口。命令窗口关闭后可用下列方法打开。 ① 单击“常用”工具栏上的“命令窗口”按钮。 ② 使用“窗口”选单中的“命令窗口”项。 ③ 使用快捷键 Ctrl+F2。 (2)在命令窗口中执行命令。 ① 设置默认的工作文件夹: CD

&& 显示当前目录

SET DEFAULT TO D:\RY_MIS

&& 设置默认的工作文件夹为 D:\RY_MIS

CD D:\RY_MIS

&& 进入 D:\RY_MIS 文件夹

CD

&& 显示当前文件夹为 D:\RY_MIS

对于第 2 条 CD 命令可不必重打,使用鼠标将光标移动键把光标插入点移到第 1 个 CD 命令行上按回车键,命令将重新执行。如命令不完全一样,可修改后按回车键运行。 ② 清除屏幕内容: CLEAR

5. 连机帮助系统的使用 连机帮助系统的使用有如下步骤。 (1)使用“帮助”选单。单击“帮助”选单中的“Microsoft Visual FoxPro 帮助主题”选 单项,打开“帮助主题”窗口,其中有“索引”、 “搜索”和“书签”3 个选项卡。 ·243·


Microsoft Visual FoxPro 6.0 的帮助系统已合并到 MSDN Library Visual Studio 中, 如图 T1.3 所示。只有在 Microsoft Visual FoxPro 6.0 或在此后安装了的 MSDN, 系统才有帮助系统。MSDN 可单独安装,也可脱离 FoxPro 单独运行。

图 T1.3

MSDN Library Visual Studio 帮助系统

找到帮助主题时,应在“活动子集”列表框中选择“*Visual FoxPro”。如果已知所需的 帮助主题名或主题的前几个字符,可在“索引”选项卡“键入要查找的关键字”文本框中输 入,然后选择“显示” 。例如, “SET DEFAULT”,在“搜索”选项卡可键入需要帮助内容(主 题)后进行搜索。 “索引”和“搜索”的结果可在“书签”选项卡选择“添加”功能加入书签 中,下次需要同样帮助时,可直接在“书签”中选择。 (2)使用“HELP”命令。在命令窗口中输入并执行如下 HELP 命令,也可直接得到帮助 信息。例如: HELP SET DEFAULT

(3)在代码窗口得到帮助。选择帮助内容,按 F1 键。 6. 项目的创建、关闭和打开 (1)创建一个项目文件 RY_DAT.PJX。在“文件”选单选择“新建”;在“新建”对话框 中单击“项目”选项按钮,单击“新文件”按钮,出现“创建”对话框,如图 T1.4 所示。

图 T1.4 “创建”对话框

在“保存在”中选择 D:\RY_MIS,在“创建”对话框中选择“RY_MIS”文件夹,输入 ·244·


项目的文件名“RY_DAT” ,单击“保存”按钮。新建的项目 RY_DAT 被自动打开在“项目管 理器”窗口中,如图 T1.5 所示。

图 T1.5

“项目管理器-RY_DAT”窗口

单击项目管理器窗口右上角的“关闭”按钮,可关闭项目。 在命令窗口中输入命令 DIR RY_DAT.*,观察共有几个文件及它们的扩展名。 (2)打开项目 RY_DAT。刚建立的项目文件会列在“文件”选单中,要打开这个项目, 仅需直接选择这个选单项即可。一般情况下,打开项目文件,可选择“文件”选单中的“打 开”项,或单击“常用”工具栏中的“打开”按钮,出现“打开”对话框,在“搜寻”框中 选择 D:\RY_MIS,选择“文件类型”为“项目” ,选择或输入项目文件名 RY_DATl.pjx,单击 “确认”按钮。 7. Visual FoxPro 6.0 的退出 退出 VFP 系统有 3 种方式。 (1)单击主窗口右上角的“关闭”按钮。 (2)使用“文件”选单中的“退出(X) ”选单项。 (3)在命令窗口中执行“QUIT”命令。 8. 计算圆面积实例【例 Ex_CricleA】 计算圆面积实例如下。 (1)设计界面。文件选单→“新建”选单项→文件类型选择“表单”→“新建文件”→ 系统显示空白表单。 选择“表单”工具条上的“标签”控件,单击表单,表单上显示标签控件 Lable1,照此 再做 Lable2。选择“表单”工具条上的“文本框”控件,单击表单,表单上显示文本框控件 Text1,照此再做 Text2。选择“表单”工具条上的“命令按钮”控件,单击表单,表单上显 示命令按钮控件 Command1。界面如图 T1.6 所示。

图 T1.6 计算圆面积界面

·245·


(2)设置对象属性。对象属性如表 T1.1 所示。 表 T1.1 对象属性 对 象

属 性 名

属 性 值

Lable1

Caption

半径 R=

Lable2

Caption

圆的面积=

Text1

Value

0

Command1

Caption

计算

(3)编写事件代码。 * “计算”命令按钮 Command1 的 Click 事件: R=THISFORM.TEXT1.VALUE THISFORM.TEXT2.VALUE=3.14159*R*R

思考与练习 (1)哪些选单是始终存在于选单栏上的?哪些是动态的选单?为什么要有动态的选单? (2)创建文件有几种方法? (3)如何获得“CLEAR”命令的帮助? (4)启动 VFP 系统,创建 D:\MY_DIR 文件夹,在该文件夹中创建一个项目文件 MY_SYS.pjx。

·246·


实验 2 数据库、表的创建和操作 目的和要求 (1)掌握创建数据库的方法。 (2)掌握创建表结构的方法。 (3)掌握操作表记录的方法。

实验准备 (1)复习有关数据库、表结构的内容。 (2)在命令窗口中输入并执行命令“SET DEFAULT TO D:\RY_MIS” 。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 创建数据库 创建数据库有如下步骤。 (1)在 RY_DAT 项目管理器中创建 RY 数据库文件。在命令窗口中输入 SET DEFAULT TO D:\RY_MIS。打开“项目管理器-RY_DAT”窗口。 在“项目管理器-RY_DAT”窗口中选择“数据”选项卡,再选择“数据库”项,单击“新 建”按钮,打开“创建”对话框,在“数据库名”文本框中输入数据库的文件名“RY”。单 击“保存”按钮后,该数据库就会以 RY 作为文件名保存,并打开“数据库设计器”,如图 T2.1 所示。同时打开数据库设计器的工具栏,在系统选单区也同时出现“数据库”选单。右 击数据库设计器窗口区域时,会出现快捷选单。“数据库”选单、工具栏和快捷选单的功能项, 其大部分都是等价的。此时在项目管理器中的项列表中也增加了一个“RY”数据库。

图 T2.1 数据库设计器

·247·


用 CLOSE DATABASE 命令关闭数据库。 用 DIR RY.* 观察是否生成 3 个数据库文件。其中,数据库文件的扩展名为 RY.dbc,关 联的数据备注文件的扩展名为 RY.dct,关联的索引文件的扩展名为 RY.dcx。 (2)使用命令创建数据库文件。 CREATE DATABASE TEMP

观察命令方式创建的数据库 TEMP 不会被添加到当前的项目中;也不会打开数据库设计 器,但在“常用”工具栏中的已打开数据库下拉列表中可以看到 TEMP。 CLOSE DATABASE DELETE DATABASE TEMP DIR TEMP.*

&& 没有 TEMP 数据库

2. 表设计器创建“人员信息数据库表”表结构 下面通过创建人员信息 3 个数据库表的 3 种方法打开数据库表“表设计器”。 (1)建立“基本情况”表结构。打开 RY_DAT 项目管理器→选择“数据”选项卡→选择 “数据库”→选择“RY”→选择“表”→选择“新建表”→在“创建”对话框中,保存在选 择“D:\RY_MIS” ,输入表名框中输入“基本情况”,如图 T2.2 所示。最后单击“保存”按钮, 系统打开“表设计器”。

图 T2.2 “创建”对话框

打开“表设计器”后,在“表设计器”中选择“字段”选项卡,输入下列基本情况表结 构: 编号 C5 姓名 C8 出生时间 D C2 C6 C6 性别 文化程度 职称 N6 L G 工资 婚否 照片 备注 M 结果如图 T2.3 所示。单击“确定”按钮保存表结构退出。 观察生成的文件名: DIR 基本情况.* 应显示基本情况.DBF,基本情况.FPT。 (2)建立“工资情况”表结构。用命令打开“表设计器”,建立数据库表结构。 OPEN DATABASE RY

·248·


CREATE 工资情况

图 T2.3 基本情况表结构

如果不打开数据库而直接打开“CREATE 工资情况”命令,则建立的是自由表。 打开“表设计器”后,在“表设计器”中选择“字段”选项卡,输入下列工资情况表结 构: C5 C8 N4 编号 姓名 技能工资 N4 N3 N4 岗位工资 浮动工资 其他工资 扣款小计 N6.1 实发工资 N6.1 (3)建立“部门工资”表结构。选择“文件”选单→选择“打开”选单项→在打开对话 框中的文件类型选择“数据库(*.dbc) ” ,搜寻栏选择“D:\RY_MIS” ,单击 RY.DBC 文件名后 单击“确定”按钮,系统打开“数据库设计器”。选择新出现的“数据库”选单栏中的“新建 表”选单项,打开“表设计器”后输入下列表结构。 部门编号 C2 部门名称 C12 人数 N3 N8 N6 N6 技能工资 岗位工资 浮动工资 N6 N8.1 N8.1 其他工资 扣款小计 实发工资 3. 向基本情况数据库表输入数据 基本情况数据库表如图 T2.4 所示。在命令窗口输入下列命令: USE 基本情况 APPEND

(交互输入编号前 2 位为 01,02 的记录内容。)

图 T2.4 基本情况数据库表

·249·


(1)备注字段数据的输入。只要用鼠标双击字段区域中的“memo”,打开备注字段的编 辑窗口,在该窗口中可以输入任意长度的一段文字。输完后单击该窗口的“关闭”按钮,或 按 Ctrl+w 键结束并保存。此时,可以看到备注字段中的“memo”变为“Memo”。第 1 个字 母大写,表示备注字段中已包含内容。 (2)通用字段数据的输入。照片(通用字段)中的数据用鼠标双击照片字段区域中的 “gen”,打开通用字段的编辑窗口,插入图像、波形声音、MIDI 音乐、视频剪辑等多媒体数 据。 要插入图像数据有以下两种方法。 ① 先激活通用字段的编辑窗口,选择“编辑”选单中的“插入对象…”打开“插入对象” 对话框,选择对象类型为“BMP 图像” ,单击“确定”按钮,即可在通用字段编辑窗口中编 辑图片。 ② 可先把要插入的图像数据在图像编辑程序中(如 Windows 的画图程序)复制到剪贴 板上,然后将图片数据粘贴进来。 单击该窗口“关闭”按钮,退出编辑状态。此时可以看到字段中的“gen”变成了“Gen” 。 第 1 个字母大写表示通用字段中已包含内容。 BROWSE (交互输入编号前 2 位为 04 的记录内容。其中性别输入代码:1 为男,2 为女。) REPLACE 性别 WITH "男" FOR 性别="1" REPLACE 性别 WITH "女" FOR 性别="2" && 观察性别的代码是否变为汉字

BROWSE

4. 记录定位 在命令窗口打入下列命令: GO TOP DISPLAY

&& 显示第 1 条记录

? RECNO()

&& 显示 1

SKIP

&& 显示第 2 条记录

? RECNO()

&& 显示 2

GO BOTTOM && 显示最后 1 条记录

LIST NEXT 1 SKIP ? EOF()

&& 显示.T.

LIST RECORD 5

&& 显示第 5 条记录

SKIP –1 && 显示第 4 条记录

LIST NEXT 1 LOCATE FOR 编号="02"

&& 显示编号="02"的第 1 条记录

DISPLAY CONTINUE

&& 显示编号="02"的第 2 条记录

DISPLAY GO 1 LIST WHILE

·250·

编号="02"

&& 无记录显示


LOCATE FOR 编号="02" LIST WHILE

编号="02"

&& 显示编号="02"的所有记录

SET FILTER TO 编号="02" LIST

&& 显示编号="02"的所有记录

SET FILTER TO LIST

&& 显示所有记录

DELETE FOR 编号="02" BROWSE

&& 观察编号="02"的记录有黑块删除标记 (用户单击黑块,将删除标记去掉)

RECALL ALL BROWSE

&& 所有删除标记已被去掉

USE

5. 向工资情况和部门工资数据库表输入数据

·251·


实验 3 创建表的索引和表临时关系 目的和要求 (1)掌握结构复合索引的建立、维护和使用的方法。 (2)掌握设置主控索引的方法。 (3)掌握与索引有关的函数的用法。 (4)掌握建立表之间的临时关系的方法。

实验准备 (1)复习教材有关索引的内容。 (2)在命令窗口中输入并执行命令 SET DEFAULT TO D:\RY_MIS。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 创建表的结构复合索引 创建表的结构复合索引有如下步骤。 (1)表设计器创建基本情况表的结构复合索引文件。在项目管理器中选择“基本情况” 表,单击“修改”按钮,打开表设计器,选择“索引”选项卡,如图 T3.1 所示。

图 T3.1

基本情况表结构化复合索引

一行代表一个索引。设置完后,单击“确定”按钮,当出现“结构更改为永久性更改?” 对话框时,单击“是”按钮。 上述操作后,在当前文件夹中将创建与对应的表的主文件名相同的结构复合索引文件“基 本情况.cdx”,其中包含 5 个索引。 DIR 基本情况.*

&& 列出 3 个文件

照此,建立工资情况表结构复合索引和部门工资表结构复合索引,如图 T3.2、图 T3.3 所 示。

·252·


图 T3.2

工资情况表结构复合索引

图 T3.3

部门工资表结构复合索引

(2)用 INDEX 命令创建结构复合索引文件。 USE RY! 基本情况 INDEX ON 姓名+性别 TAG 性别 INDEX ON 职称+DOTOC(出生时间)TAG 职称年龄 FOR 职称#"

"

INDEX ON 工资 TAG 工资 DESCENDING INDEX ON LEFT(编号,2)TAG 部门编号 ?CDX(1)

&& CDX()函数测试打开的表的结构复合索引文件名

?TAGCOUNT()

&& TAGCOUNT()函数测试当前打开的复合索引文件的索引个数

?TAG(2)

&& 返回第 2 个索引的标识名

?KEY(2)

&& 返回第 2 个索引的关键字表达式

2.修改和删除表的结构复合索引 修改和删除表的结构复合索引的步骤如下。 (1)在表设计器中修改和删除结构复合索引。在表设计器中,在“索引”选项卡上可以 修改一个索引的标识名、类型以及表达式,也可以将一个索引删除。把鼠标指向要删除索引 行,单击“删除”按钮,单击“确定”按钮。 (2)用命令修改和删除索引。用 INDEX 命令建立索引标识相同名的索引时,系统提醒 “标识已存在,改写吗?”时,选择“是” ,就把原索引覆盖了。 INDEX ON 职称+姓名 TAG ZC ? KEY() INDEX ON 职称 TAG ZC ? KEY() ? TAGCOUNT()

用 DELETE TAG 命令可以删除索引标识。 DELETE TAG ZC

·253·


? TAGCOUNT()

3. 结构复合索引的使用 在结构复合索引所包含的多个索引中,只有被设置为主控索引的那个索引才对表起作用。 系统将按主控索引顺序来访问表。 用 INDEX 命令新建一个结构复合索引时,该索引将自动成为主控索引,但是在表设计器 中新建的索引却不会自动成为主控索引。 在打开一个包含结构复合索引的表时,结构复合索引文件将随表的打开而自动打开,但 结构复合索引中的任何一个索引却不会被自动设置为主控索引。此时,表中的记录仍按记录 的物理顺序显示和访问。当前的主控索引名可通过 ORDER()函数得到。 USE RY!基本情况 ?CDX(1)

&& 显示第一个结构复合索引文件

?ORDER()

&& 无显示,说明当前没有主控索引

BROWSE

&& 表记录按物理记录顺序显示

SET ORDER TO 工资 ? ORDER()

&& 显示"工资",说明当前主控索引名为工资

BROWSE

&& 表记录按工资从大到小顺序显示

当一个表被打开时,其对应的结构复合索引被自动打开,因此对表中的记录进行添加。 修改和删除操作时,系统对结构复合索引文件中的所有索引自动进行维护更新。当表被关闭 时,其结构复合索引也自动关闭。 USE RY!基本情况 ORDER 编号 ? ORDER() APPEND (交互输入编号="03"的人员数据) BROWSE

&&显示的顺序按编号从小到大

SET ORDER TO BROWSE

&&显示的为物理顺序

4. 利用索引进行快速查找 设置了主控索引后,可以使用 SEEK 命令或 SEEK 函数进行记录的快速定位。使用 SEEK 命令进行快速查找时,要注意 SEEK 指定的表达式必须与索引关键字匹配。 USE RY!基本情况 SET ORDER TO TAG 编号

&& 设置编号索引为主控索引

BMBH="02" SEEK BMBH+"001"

&& 快速查找"02001"的记录

?FOUND()

&& 找到该记录,显示.T.

? EOF()

&& 找到该记录,显示.F.

DISPLAY BMBH="05" ?SEEK(BH+"001")

·254·

?FOUND()

&& 未找到该记录,显示.F.

SET ORDER TO TAG 性别

&& 设置索引性别为主控索引


SEEK "肖文红 男"

&& 查找姓名为"肖文红"的记录

DISPLAY

5. 建立表之间的临时关系 建立表之间的临时关系的步骤如下。 (1)查看基本情况和工资情况相关表之间记录指针的跟动情况。 SELECT A USE 基本情况 ALIAS JB SELECT B USE 工资情况 ALIAS GZ SELECT JB SET RELATION TO 编号 INTO GZ LOCATE FOR 姓名="肖文红" DISPLAY 编号,姓名 SELECT GZ DISPLAY 编号,姓名 SELECT JB LIST 编号,姓名,GZ.编号,GZ.姓名

&& 显示编号姓名两边相同

SET RELATION TO LIST 编号,姓名,GZ.编号,GZ.姓名

&& 显示编号姓名两边不同步

CLOSE DATABASES

(2)人员、信息、数据库三表联动浏览。 SET DEFAULT TO D:\RY_MIS OPEN DATABASE RY USE 基本情况 IN 0 ORDER 1 USE 工资情况 IN 0 ORDER 1 USE 部门工资 IN 0 ORDER 1 SELECT 基本情况 SET RELATION TO 编号 INTO 工资情况 SET RELATION TO LEFT(编号,2)INTO 部门工资 ADDITIVE BROWSE FIELD 基本情况.姓名,部门工资.部门名称,工资情况.实发工资 CLOSE DATABASE

·255·


实验 4 创建数据表字段属性、表的转换和 SQL 目的和要求 (1)掌握设置数据表字段的标题、输入掩码、默认值和注释的方法。 (2)掌握数据库表与自由表的相互转换的方法。 (3)SQL 命令的操作表的方法。

实验准备 (1)复习教材有关索引的内容。 (2)在命令窗口中输入并执行命令 SET DEFAULT TO D:\RY_MIS。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 设置数据库表字段属性 字段的标题、输入掩码、默认值和注释等属性只能对数据库表的字段进行设置。 (1)数据库表设计器中设置基本情况表字段属性。在项目管理器中选择基本情况表,选 择“修改”,打开数据库表设计器,设置字段属性如下。 编号:输入掩码为"99999",字段有效性规则为编号>='01001'.AND. 编号<'19000'; 姓名:字段有效性规则为姓名# " "; 性别:默认值为"男"。 关闭数据库表设计器。 (2)字段属性验证。 USE RY!基本情况 APPEND BLANK

&& 本命令不能执行,为什么?

重新打开数据库表设计器,设置基本情况表中编号和姓名字段的默认值为非空。 USE RY!基本情况 APPEND BLANK

&& 本命令现在可以,为什么?

BROWSE

&& 观察显示的默认值

(交互修改默认值为实际内容)

参照基本情况表,设置工资情况表和部门工资表中各字段的属性。 (3)设置表记录属性。在项目管理器中选择工资情况表,选择“修改” ,打开数据库表设 计器,设置表记录属性如下。 表记录有效性规则:技能工资+岗位工资+浮动工资-扣款小计>=0 表记录有效性信息:“实发工资不能为负!” 关闭数据库表设计器。 ·256·


USE RY!工资情况 BROWSE

(选择“表”选单→选择“增加新记录 Ctrl+Y”选单项,在末尾追加一条记录,输入内 容,各工资项的值可输入任何值,但当“技能工资+岗位工资+浮动工资-扣款小计< 0”时不 能移出该记录。 ) (4)用命令修改字段属性。 OPEN DATABASE RY ? DBSETPROP("基本情况.编号","FIELD","DefaultValue","99001") ? DBSETPROP("基本情况.姓名","FIELD","DefaultValue","新名字") ? DBGETPROP ("基本情况.姓名","FIELD","DefaultValue")

&& 显示"新名字"

USE RY!基本情况 APPEND BLANK

&& 本命令现在可以,为什么?

BROWSE

&& 观察显示的默认值

2. 数据库表的移入和移出 OPEN DATABASE RY REMOVE TABLE 工资情况

&& 将工资情况表移出 RY 数据库成为自由表

MODIFY DATABASE

&& RY 数据库中没有工资情况表

RY

USE 工资情况 MODIFY STRUCTURE (没有字段属性) BROWSE (Ctrl+Y 追加新记录,不显示字段默认值) USE ADD TABLE 工资情况

&& 将工资情况表移入 RY 数据库成为数据库表

(用数据库表设计器或 DBSETPROP()重新设置字段属性)

3. SQL 操作表 OPEN DATABASE RY CREATE TABLE JBQK (编号 C(5),姓名 C(10),出生时间 D(8),工资 N(6,2)) USE JBQK MODIFY STRUCTURE

&& 观察表结构

ALTER TABLE JBQK ADD 附加工资 N(6,0) MODIFY STRUCTURE ALTER TABLE JBQK ALTER 编号 SET CHECK 编号!= "

" ERROR "编号不能空! "

ALTER TABLE JBQK ALTER 编号 SET DEFAULT "99001" MODIFY STRUCTURE

&& 观察编号字段属性

USE INSERT INTO RY!基本情况(编号,姓名,工资)VALUE ("01006","周全新",1200) UPDATE RY!基本情况 SET 基本情况.工资=基本情况.工资+100 USE RY!基本情况

·257·


BROWSE

&& 观察是否有插入的记录 && 工资字段数据是否变化

? RECCOUNT()

&& 观察当前表的记录数

DELETE FROM RY!基本情况 WHERE 编号="01006" ? RECCOUNT() USE ALTER TABLE 基本情况 ADD FOREIGN KEY LEFT(编号,2)TAG 部门编号 REFERENCES 部 门工资 MODIFY DATABASE CLOSE DATABASE

·258·

&& 观察永久关系连线


实验 5 程 序 设 计 目的和要求 (1)掌握设置数据表字段的标题、输入掩码、默认值和注释的方法。 (2)掌握数据库表与自由表的相互转换的方法。 (3)SQL 命令的操作表的方法。

实验准备 (1)复习教材有关索引的内容。 (2)在命令窗口中输入并执行命令 SET DEFAULT TO D:\RY_MIS。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 函数 S="01" ? LEN(S) ? LEN(S+"002") SET DEFAULT TO D:\RY_MIS CLOSE DATABASE USE 基本情况 ? RECNO() SKIP - 1 ? BOF() GO BOTTOM ? EOF() SKIP ? EOF() ? LEN(姓名) ? LEN(姓名+职称) ? INT(680.34) ? SQRT(4) ? LEFT("王 红",2) ? SUBSTR("王 红",5,2) ? TRIM("

AA BB ")+"CC"

? ALLTRIM("

AA BB ")+"CC"

·259·


S="" ? EMPTY(S) ? DATE() ? TIME() ? DATETIME() ? YEAR(DATE()) ? MONTH(DATE()) TT=DATE() ?TYPE("TT") TT=DTOC(DATE()) ? TYPE("TT") SET DATE ANSI TT=CTOD("99.10.01") ? TYPE("TT") TT=STR(1002) ? TT ? TYPE("TT") ? VAL("1002") ? CHR(65) ?ASC("AB") ? FILE("基本情况.DBF") ? MESSAGEBOX("aaa",2+48,"bbb")

2. 表达式 TT=21 ? TT*2/(4-TT%2) ? "AA "+"BB" ? "AA BB"$"AB" ? DATE()-{^2000.10.1} ? TT>4^2 .AND. YEAR(DATE())=1999 .OR. .F. SET DEFAULT TO D:\RY_MIS USE 工资情况 ? (LEFT(编号,2)="01".OR. LEFT(编号,2)="04").AND.岗位工资<200

3. IF 分支程序 求 ax2+bx+c=0 的方程的解。 求方程的解的公式如下:

x1, 2 (1)设计表单,如图 T5.1 所示。

·260·

− b ± b 2 − 4ac = 2a


图 T5.1

计算一元二次方程根界面

(2)设置对象属性,如表 T5.1 所示。 表 T5.1 计算一元二次方程根对象属性 对

属 性 名

属 性 值

Form1

Caption

计算方程根

Label1

Caption

a=

Label2

Caption

b=

Label3

Caption

c=

Label4

Caption

x1 =

Label5

Caption

x2 =

txtA

Value

0

txtB

Value

0

txtC

Value

0

cmdStart

Caption

计算

(3)编写代码。 * 计算按钮(cmdOK)的 Click 事件代码: a=Thisform.txtA.Value If a=0 Messagebox("a 不能为 0!") Return ENDIF b=Thisform.txtB.Value c=Thisform.txtC.Value DT=b*b-4*a*c If DT>=0 x1=(-b+Sqrt(DT))/(2*a) x2=(-b-Sqrt(DT))/(2*a) Thisform.txtX1.Value=x1 Thisform.txtX2.Value=x2 Thisform.Refresh Else Messagebox("没有实数解!")

·261·


Endif

练习: 比较上述程序与第 3 章代码的差别。 4. CASE 分支程序 统计成绩分数段。 (1)设计表单,如图 T5.2 所示。

图 T5.2 成绩分段统计界面

(2)设置对象属性,如表 T5.2 所示。 表 T5.2 成绩分段统计对象属性 对

属 性 名

属 性 值

Form1

Caption

成绩分段统计

Label1

Caption

请输入成绩

Label2

Caption

>=90 80~89 70~79 60~69 <60

txtCJ

Value

0

txt9

Value

0

Txt8

Value

0

Txt7

Value

0

Txt6

Value

0

Txt5

Value

0

cmdOK

Caption

确定

(3)编写代码。确定按钮(cmdOK)的 Click 事件代码: cj=Thisform.txtCJ.Value DO CASE Case cj<0.or.cj>100 Messagebox("输入的成绩不正确!") Case cj>=90.and.cj<=100 Thisform.txt9.Value=Thisform.txt9.Value+1 Case cj>=80.and.cj<90 Thisform.txt8.Value=Thisform.txt8.Value+1 Case cj>=70.and.cj<80 Thisform.txt7.Value=Thisform.txt7.Value+1

·262·


Case cj>=60.and.cj<70 Thisform.txt6.Value=Thisform.txt6.Value+1 Case cj<60 Thisform.txt5.Value=Thisform.txt5.Value+1 ENDCASE Thisform.Refresh

5. 循环程序 循环程序有如下几种。 (1)计算 1+2+3+4+5+…+30。 * FOR 循环 s=0 For i=1 To 30 s=s+i Endfor Messagebox("1+2+3+…+30="+Str(s)) * WHILE 循环 s=0 i=1 Do While i<=30 S=s+i i=i+1 Enddo ? "1+2+3+…+30=",s

(2)把 1~100 之间的不能被 7 整除的数输出。 FOR i=1 TO 100 IF i%7==0 Loop Endif ?i Endfor

(3)编程求 Fibonacci 数列的第 n 项。 Fibonacci 数列定义如下:

f(n)=

0 1 f(n-1)+f(n-2)

当 n=0 时 当 n=1 或 2 时 当 n>2 时

程序如下: n1=8 ? UF_fib(n1)

&& 结果为 21

Cancel

·263·


Function UF_fib Parameter n DO CASE Case n=0 Return 0 Case n=1 Return 1 Case n=2 Return 1 Other Return UF_fib(n-1)+UF_fib(n-2) Endcase

6. 自定义函数和变量的作用范围 Public X X=1 Y=1 Do EditXY Messagebox("X="+str(X))

&& 显示 X=2

Messagebox("Y="+str(y))

&& 显示 Y=1

Cancel

Procedure EditXY Local Y X=2 Y=2 Return

·264·


实验 6 表

目的和要求 (1)掌握表单设计器及表单属性、方法和事件。 (2)掌握表单对象事件先后顺序。

实验准备 (1)复习教材有关表单的内容。 (2)在命令窗口中输入并执行命令 SET DEFAULT TO D:\RY_MIS。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1.创建表单 创建表单的步骤如下。 (1)选择“文件”选单→“新建表单”,显示如图 T6.1 所示的对话框。

图 T6.1

“新建表单”对话框

(2)选择“新建表单”,系统显示一个空白的表单。用户即可在这个空白的表单上进行设 计。 (3)打开“表单设计器”和“表单控件”工具栏,如图 T6.2、图 T6.3 所示。

图 T6.2

图 T6.3

“表单设计器”工具栏

“表单控件”工具栏

·265·


(4)在“表单控件”选择“命令按钮”图标,单击表单,放置 3 个“命令按钮”Command1~ Command3,如图 T6.4 所示。

图 T6.4 表单命令按钮

图 T6.5

“布局”工具栏

(5)用鼠标拖动改变它们的大小,用方向键移动和改 变它们的大小。 (6)单击表单设计器“布局”工具栏按钮,如图 T6.5 所示,练习命令按钮对齐、对中、等宽和等高。 (7)单击表单设计器“设置 Tab 键次序”按钮,在表 单中的各个对象的左上方显示用 Tab 键选择操作对象时的 顺序,这个顺序是进入表单的先后顺序,也是系统执行时 初始化各对象的顺序,如图 T6.6 所示。

图 T6.6 Tab 键的次序显示

(8)单击表单设计器“数据环境” ,设置在表单中要用到的数据库和表,如图 T6.7 所示。 (9)单击表单设计器“属性窗口”按钮,设置表单下列属性,观察变化。 Top: 100 Left: 150 Caption: 我的表单标题

Width: 300

·266·

MaxButton: .F.

MinButton: .F.


图 T6.7 表单数据环境

2. 表单事件 设置表单事件的步骤如下。 (1)在下列事件中加入代码。 *

Form1 的 Load 事件

MessageBox("Form1.Load")

*

Form1 的 Init 事件

MessageBox("Form1.Init")

*

Form1 的 Click 事件

MessageBox("Form1.Click")

*

Form1 的 Destry 事件

MessageBox("Form1.Destry")

*

Command1 的 Init 事件

MessageBox("Command1.Init")

*

Command2 的 Init 事件

MessageBox("Command1.Init")

*

Command3 的 Init 事件

MessageBox("Command1.Init")

*

Command1 的 Click 事件

MessageBox("Command1.Click")

*

Command1 的 Destry 事件

MessageBox("Command1.Destry")

·267·


*

Command3 的 Click 事件

THISFORM.RELEASE

(2)保存和运行表单。 保存表单文件为 My_FORM1,目录为 D:\RY_DAT。 运行表单 My_FORM1,观察事件的先后顺序。

DO FORM My_FORM1 单击 Command3,观察事件的先后顺序。 (3)修改表单 My_FORM1。 打开表单 My_FORM1,加入一个文本框 Text1,给 Text1 编写下列事件代码: * Text1 的 When 事件 MessageBox("Text1.When") * Text1 的 GotFocus 事件 MessageBox("Text1.GotFocus") * Text1 的 Valid 事件 MessageBox("Text1.Valid") Return .T.

&& 返回为.F.观察效果

* Text1 的 LostFocus 事件 MessageBox("Text1.LostFocus")

运行表单 My_FORM1,单击 Text1 文本框,观察 Text1 对象事件的先后顺序。 3. 表单的类型 表单的类型有如下 2 种。 (1)打开表单 My_FORM1,修改表单的 ShowWindow 属性分别为 0, 1, 2,Desktop 属性 分别为.T.,.F.,参照书中内容,观察表单的变化。 (2)修改表单的 WindowType 属性为 0(无模式) ,用户不必关闭表单就可访问其他界面; WindowType 属性为 1(模式),用户必须关闭表单方可访问其他界面。观察表单的变化。 4. 表单新增属性和方法 表单新增属性和方法有如下步骤。 (1)打开表单 My_FORM1。 (2)在表单 Form1 新增属性 My_Value,赋默认值为“OK”;在表单 Form1 新增方法 My_Prog,写入如下代码: MessageBox("My Prog! ")

修改 Form1 对象的 Click 事件代码修改如下: THISFORM.Text1.Value=THIS.My_Value THIS.My_Prog

(3)运行表单 My_FORM1,单击表单,观察结果。

·268·


实验 7 控

目的和要求 (1)掌握控件的常用属性、方法和事件。 (2)掌握表单与控件及引进方法。

实验准备 (1)复习教材有关表单和控件的内容。 (2)在命令窗口中执行命令“SET DEFAULT TO D:\RY_MIS”。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 标签控件 【例 Ex_TextMove】“欢迎”在屏幕上移动。 (1)设计表单设置属性。在表单上设计一个标签 Label1,设置下列属性: Caption=欢迎 FontName=楷体_GB2312 FontSize=48 FontBold=.T. ForeColor=255,0,0 Alignment=2

如图 T7.1 所示。

图 T7.1

“欢迎”在屏幕上移动

(2)编写事件代码。 * 标签的 Click 事件代码: DO WHILE .T. FOR I=1 TO THISFORM.WIDTH step 10

·269·


THIS.LEFT=I && 延时 1s

=INKEY(1) NEXT I ENDDO

注意: 启动该程序,必须终止 FoxPro 方可停止运行。 练习: (1)修改代码,“欢迎”在屏幕从上到下移动。 (2)修改代码,每次启动仅移动 1 次、2 次。 (3)将代码移入标签的初始化代码中。 (4)给“欢迎”加上阴影。 2. 文本框控件 【例 Ex_Login】 在主程序 Ex_txt1 中先调用表单 Ex_Login 进行用户登录,如果用户名 和口令正确,调用表单 Ex_EditGZ 执行。 (1)设计表单设置属性。表单包含下列对象:标签 Label1~Label2 用于信息提示;文本 框 txtName 用于输入登录名,文本框 txtPassWord 用于输入口令;一个命令按钮 cmdOk 用于 确定登录用户;一个命令按钮 cmdExit 用于退出登录。用户登录界面如图 T7.2 所示。

图 T7.2 用户登录界面

(2)设置属性。口令文本框(txtPassWord)属性 PasswordChar=* (3)编写代码。 * 表单的 Activate 事件代码 THIS.txtPASSWORD.Enabled=.f.

&& 输入登录名后才能输入口令

THIS.txtNAME.SetFocus

&& 启动后先输入登录名

* txtNAME 文本框 KeyPress 事件代码 LPARAMETERS nKeyCode,nShiftAltCtrl IF nKeyCode=13.AND.!EMPTY(THIS.VALUE) THISFORM.txtPASSWORD.Enabled=.t. THISFORM.txtPASSWORD.SetFocus ENDIF * "确定(cmdOK)" 按钮的 Click 事件代码

·270·

&& 输入登录名后按回车键即进入输入口令


UNAME=THIS.PARENT.txtNAME.VALUE Yes=.F. DO CASE CASE Uname="ZHANG".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="123456" Yes=.T. CASE Uname="WANG".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="681266" Yes=.T. ENDCASE If Yes Messagebox("登录成功! ") Else Messagebox("登录名或口令不对!") Endif THISFORM. Release CLEAR EVENTS * "退出(cmdExit)"按钮的 Click 事件代码 THISFORM.Release CLEAR EVENTS * Ex_txt1.prg 程序代码 PUBLIC YES SET DEFAULT TO D:\RY_MIS DO FORM Ex_LOGIN READ EVENTS IF YES DO FORM Ex_EditGZ READ EVENTS ENDIF CANCEL

练习: (1)建立一个 SYS_USER 自由表,包含登录名和口令两个字段,输入若干条记录。 (2)将 SYS_USER 表作为数据环境。 (3)修改“确定(cmdOK) ”按钮的 Click 事件代码,使登录名、口令、SYS_USER 表记 录校对。 (4)修改程序,使登录名和口令可不分先后顺序输入。加判登录名和口令均不能为空。 3. 命令按钮控件 【例 Ex_ EditGz】修改人员工资数据,计算实发工资。 (1)设计界面。新建表单,将工资情况表加入数据环境;从数据环境中拖动工资情况中 的各字段进入表单;向表单中加入 5 个命令按钮,如图 T7.3 所示。 ·271·


图 T7.3

修改人员工资数据库表单

(2)设置对象属性。对象属性如表 T7.1 所示。 表 T7.1 对象属性 对

Form

属 性 名

属 性 值

Name

From1

Caption

From1

Label

Name

lbl 编号

Caption

编号

Label

Name

lbl 姓名

Caption

姓名

… txt 编号

TextBox

Name Readonly

.T.

TextBox

Name

txt 姓名

Readonly

.T.

Name

Txt 技能工资

Readonly

.F.

TextBox

… CommandButton

Name

Command1

Caption

第一个

CommandButton

Name

Command2

Caption

上一个

CommandButton

Name

Command3

Caption

下一个

Name

Command4

Caption

最后一个

CommandButton

(3)编写代码。 *

"第一个" 按钮(Command1)的 Click 事件代码

GoTop Thisform.Refresh

·272·


*

"上一个" 按钮(Command2)的 Click 事件代码

If !Bof() Skip –1 Endif Thisform.Refresh *

"下一个" 按钮(Command3)的 Click 事件代码

If !Eof() Skip Endif Thisform.Refresh

*

"最后一个" 按钮(Command4)的 Click 事件代码

Go Bottom Thisform.Refresh

*

"计算实发" 按钮(Command5)的 Click 事件代码

Replace All 实发工资 With 技能工资+岗位工资+浮动工资+其他工资-扣款小计 Thisform.Refresh

练习: (1)删除 Thisform.Refresh,运行程序,观察记录移动时,界面是否有同步变化。 (2)删除“计算实发” (Command5)命令按钮,单击“实发工资”文本框,计算当前记 录的实发工资。 (3)在移动记录前计算实发工资。如实发工资<0,则显示提示信息,不做移动记录操作。 (4)将计算实发工资的操作放入关闭表单的事件中。 4. 命令按钮组控件 【例 Ex_EditGZ_Gcmd】修改人员工资数据,计算实发工资。移动记录用命令按钮组实 现。 (1)设计界面。设计界面如图 T7.4 所示。

图 T7.4 命令按钮组实例

·273·


其中,CommandGroup1 命令按钮组容器包含 5 个命令按钮 Command1~Command5。命 令按钮(组)对象属性如表 T7.2 所示。 表 T7.2 命令按钮组实例对象属性 对

属 性 名

属 性 值

CommandGroup1

ButtonCount

5

CommandGroup1

AutoSize

.T.

Command1

Caption

第一个

Command2

Caption

上一个

Command3

Caption

下一个

Command4

Caption

最后一个

Command5

Caption

退出

* CommandGroup1 的 Click 事件代码 sel=This.Value DO CASE CASE sel=1 GO TOP CASE sel=2 IF !BOF() SKIP - 1 ENDIF CASE sel=3 IF !EOF() SKIP ENDIF CASE sel=4 GO BOTTOM ENDCASE THISFORM.REFRESH * 退出(Command5)的 Click 事件代码 THISFORM.Release

5. 组合框、选项按钮组和复选框控件 【例 Ex_Edit2】按人员编号增、删、改基本情况数据。 (1)设计表单界面。增、删、改基本情况数据界面,如图 T7.5 所示。 新建表单→将“基本情况”表加入数据环境→拖动基本情况表中编号、姓名和出生时间 到表单中;加入两个组合框(Combo1 和 Combo2) 、一个选项按钮组(OptionGroup1)和一 个复选框(Check1) ,用于操作表字段。另外,在表单下部用 1 个文本框(txtBH)输入定位 编号和 3 个命令按钮。两部分之间加入线控件进行分隔。

·274·


图 T7.5

修改增、删、改基本情况数据界面

(2)设置对象属性。 编号姓名和出生时间文本框: txt 编号. ControlSource=基本情况.编号 txt 姓名.ControlSource=基本情况. 姓名 txt 出生时间.ControlSource=基本情况. 出生时间 “文化程度”组合框(Combo1): ControlSource=基本情况.文化程度 RowSourceType=值 RowSource=研究生,本科,大专,高中,初中 Style=2

&& 只能选择列表项

“职称”组合框(Combo2): ControlSource=基本情况.职称 RowSourceType=值 RowSource=政工师,工程师,助工 “性别”选项按钮组(OptionGroup1)有 2 个单选按钮(Option1,Option2): Option1.Caption=男 Option2.Caption=女 ControlSource=基本情况.性别 “婚否”复选框(Check1): ControlSource=基本情况.婚否

(3)设置对象。设置 TxtBH 的属性 InputMask=99999。 观察字段文本框的 ControlSource 的属性如下: txt 编号. ControlSource=基本情况.编号 txt 姓名.ControlSource=基本情况. 姓名 txt 出生时间.ControlSource=基本情况. 出生时间

(4)编写代码。 *

“定位”命令按钮的 Click 代码

bh=Trim(This.Parent.txtBH.Value) jlh=recno()

·275·


Locate For 编号=bh If Eof() Go jlh =MessageBox("没有找到该编号!") Else Thisform.Refresh Endif

*

“追加”命令按钮的 Click 代码

Append Blank Thisform.Refresh

*

“删除”命令按钮的 Click 代码

yn=Messagebox("是否要删除?",4+32) If yn=6 Delete If Eof() Go top Else Skip Endif Thisform.Refresh Endif

6. 页框、页、图像和编辑框控件 【例 Ex_Edit3】按人员编号增、删、改基本情况和工资情况数据。 设计表单界面。新建表单;将基本情况和工资情况表加入数据环境,如图 T7.6 所示。

图 T7.6

两表的关联数据环境

数据环境中两表的关联:拖动基本情况关联字段“编号”到工资情况以“编号”作为关 键字的索引。 向表单加入 1 个页框,设置页框(PageFrame1)属性: PageCount=2

·276·


ActivePage=1

页(Page1 和 Page2)属性: Page1.Caption=基本情况 Page2.Caption=工资情况

在 Page1 页中拖入或加入与基本情况字段绑定的控件;在 Page2 页中拖入或加入与工资 情况字段绑定的控件;在表单的下部加入一个文本框 TxtBH 和定位、追加、删除 3 个命令按 钮,如图 T7.7 所示。

图 T7.7

增、删、改基本情况数据界面

其中图像控件用于显示“照片”,由于图像控件不能与照片字段直接绑定,而需通过图像 文件给 PICTURE 属性赋值方可显示。所以,在“定位”中要将“照片”字段拷贝成图像文 件,在“追加”时要将图像文件加入“照片”字段中。 练习: 照片字段通过 OLE 绑定型控件直接绑定。 7. 表格控件 【例 Ex_Grid】按姓名和部门过滤编辑基本情况数据。 (1)设计表单界面。将基本情况表和部门工资表加入数据环境,姓名和部门过滤编辑表 单界面如图 T7.8 所示。

图 T7.8

姓名和部门过滤编辑表单界面

·277·


(2)设置对象属性。 Grid1.RecordSourceType=别名 Grid1. RecordSource=基本情况 Grid1.ColumuCount=8 Column1.ControlSource=基本情况.编号 Column1. Header.Caption=编号 ……

部门组合框属性: Name=cboBM cboBM.RowSourceType=字段 cboBM.RowSourceT=部门工资.部门名称

姓名文本框属性: Name=txtName

确定命令按钮属性: Name=cmdOk

(3)编写代码。 *

“确定”命令按钮 Click 事件

If !Empty(This.Parent.txtName.Value) Set filter to 基本情况.姓名=Trim(This.Parent.txtName.Value) This.Parent.grdJB.Refresh Return Endif If !Empty(This.Parent.cboBM.Value) bm=Trim(This.Parent.cboBM.Value) Select 部门工资 Locate For 部门名称=bm bmbh=部门编号 Select 基本情况 Set Filter To Left(基本情况.编号,2)=bmbh This.Parent.grdJB.Refresh Return Endif

8. 定时器控件 【例 Ex_Spin】显示时间,刷新时间可调。 (1)设计表单界面。设计一个文本框( Text1)显示时间,一个微调按钮( Spinner1) 用于控制刷新的时间间隔,一个命令按钮( Command1)用于启动时间显示。一个计时器 ( Timer1)用于刷新时间。定时刷新界面如图 T7.9 所示。 (2)设置对象属性。 Text1.Value={}

·278·


&& 刷新的时间间隔不大于 60s

Spinner1.SpinnerHighValue=60 Spinner1.SpinnerLowHighValue=1 Spinner1.KeyBoardHighHighValue=60 Spinner1.KeyBoardLowHighValue=1

图 T7.9 定时刷新界面

(3)编写事件代码。 * Command1 的 Click 事件 THISFORM.Timer1.Interval=THISFORM.Spinner1.Value*1000 * Timer1 的 Timer 事件 THISFORM.Text1.Value=Time()

·279·


实验 8 类的创建和使用 目的和要求 (1)掌握“类设计器”创建类的方法。 (2)掌握编程创建类的方法。 (3)掌握创建类的使用方法。

实验准备 (1)复习教材类的创建和使用的内容。 (2)在命令窗口中执行命令 SET DEFAULT TO D:\RY_MIS。 (3)打开项目文件 RY_DAT.PJX。

实验内容 1. 创建类 【例 Ex_CRecmove】建立记录移动命令按钮组类。 (1)启动“类设计器” 。打开 RY_DAT 项目管理器→选择“类”选项卡→“新建类”对 话框,系统显示如图 T8.1 所示。

图 T8.1

“新建类”对话框实例

在“新建类”对话框输入上述内容,单击“确定”按钮,系统打开“类设计器”。 (2)命令按钮布局、属性。设置界面如图 T8.2 所示。

图 T8.2 “类设计器”实例

·280·


(3)编写事件代码。 *

My_RecordMove 的 Click 事件代码:

sel=THIS.Value DO CASE CASE sel=1 GO TOP CASE sel=2 IF !BOF() SKIP - 1 ENDIF CASE sel=3 IF !EOF() SKIP ENDIF CASE sel=4 GO BOTTOM ENDCASE THISFORM.REFRESH

(3)关闭类设计器,系统询问是否将 My_RecordMove 类保存到 RY_Class.VCX 库,回答 是即可完成新类的创建。 2. 类的使用 类的使用有如下几种,如图 T8.3、图 T8.4 所示。 (1)在工资情况表中使用。新建表单 Ex_CGZ→将“工资情况表”加入数据环境→拖动 工资情况的字段进入表单。 选择表单控件工具栏“查看类”按钮→在快捷选单中单击“添加”按钮→选择 D:|\RY_MIS 目录下的 RY_CLASS.VCX 文件后单击“打开”按钮,“表单控件”工具栏显示 RY_CLASS.VCX 类库中的所有类的图标。 选择 MY_RecordMove 图标→在表单上单击。

图 T8.3

类的使用(1)

运行表单→单击“移动记录”按钮→观察变化。 ·281·


(2)在基本情况表中使用。照上述步骤建立基本情况表表单 Ex_CJB: 运行表单→单击移动记录按钮→观察变化。

图 T8.4

类的使用(2)

(3)修改 My_RecordMove 类的 Click 事件代码。 打开类设计器→选择 RY_CLASS 类库中的 My_RecordMove 类→单击“修改”按钮; My_RecordMove 类的 Click 事件→删除 THISFORM.Refresh; 运行 Ex_CJB 表单→单击“移动记录”按钮→观察变化。 运行 Ex_CGZ 表单→单击“移动记录”按钮→观察变化。 3. 编程创建类 (1)编制程序文件。打开 RY_DAT 项目管理器→选择“代码”选项卡→“新建” ;输入 下列代码: *

Ex_CForm1 程序

PUBLIC MyForm MyForm1 = CREATEOBJECT ("Form1")

&& 根据定义表单类建立表单对象

MyForm2 = CREATEOBJECT ("Form1")

&& 根据定义表单类建立表单对象

MyForm1.Show

&& 显示表单对象 MyForm1

MyForm2.Show

&& 显示表单对象 MyForm2

MyForm2.Top=100 MyForm2.Left=100 READ EVENTS DEFINE CLASS Form1 AS Form ADD OBJECT COMM1 AS CommandButton;

&& 定义表单类 && 定义表单的“确定命令”按钮

WITH Caption='确定',Left=150,Top=140 ADD OBJECT COMM2 AS CommandButton;

&& 定义表单的“取消命令”按钮

WITH Caption='取消',Left=150,Top=180 PROCEDURE Click =MESSAGEBOX("Form 的 Click!") ENDPROC

·282·

&& 表单的 Click 事件代码


PROCEDURE Comm1.Click

&& 命令按钮的 Click 事件代码

=MESSAGEBOX("确定的 Click!") THISFORM.Release CLEAR EVENTS ENDPROC PROCEDURE Comm2.Click

&& 命令按钮的 Click 事件代码

=MESSAGEBOX("终止的 Click!") THISFORM.Release CLEAR EVENTS ENDPROC ENDDEFINE

保存上述程序,文件名为 EX_CForm1.PRG。 (2)运行 EX_CForm1.PRG: DO EX_CForm1

·283·


实验 9 创 建 查 询 目的和要求 (1)掌握用查询设计器创建和修改查询的方法。 (2)掌握创建基于单表和多表的查询方法。 (3)掌握 SELECT-SQL 语句的用法。 (4)掌握交叉表查询的创建方法。

实验准备 (1)复习教材有关查询和 SELECT-SQL 语句的内容。 (2)准备好前面实验所创建的项目、数据库和表。 (3)启动 Visual FoxPro 6.0 系统,并设置默认的目录。

实验内容 1. 查询设计器的打开方法 打开查询设计器的方法有下面 3 种。 (1)在“项目管理器”中,选择“查询”命令,单击“新建”按钮。据此,首先要有已 建的项目。 (2)在“文件”选单或工具栏中,选择“新建”命令。 (3)使用 CREATE QUERY 命令。

图 T9.1

“添加表或视图”对话框

2. 使用查询设计器创建基于单表的查询 建立一个查询,查询每个产品的名称、价格和库存量,并按价格升序排序。 (1)打开查询设计器,进入“新建查询”。 ·284·


(2)在“添加表或视图”对话框中,如图 T9.1 所示,选择产品表。 (3)在查询设计器的字段选项卡中,单击“全部添加”按钮,选定产品表的所有字段为 输出字段。 (4)在排序依据选项卡中,设置排序条件为按价格的升序排序。 (5)在完成了上述设置后,按下面 3 种方法运行查询,运行结果如图 T9.2 所示。 ① 单击“常用”工具栏上的“运行”按钮( )。 ② 在“查询”选单(或者快捷选单)中选择“运行查询”命令。 ③ 保存查询为 Simple.qpr 后,在命令窗口中用 DO Simple.qpr 命令。

图 T9.2 单表查询的结果

思考:如果要按产品库存量的降序输出结果,应该如何进行修改? 3. 使用查询设计器创建基于多表的查询 建立一个查询,查询每个销售商名称和负责人以及 2000 年 5、6 两个月的总销售额,并 按总销售额的升序排序。 思路:查询结果中涉及到的销售商的名称和负责人来自“销售商”表,分别是 khmc 和 fzr 字段;而销售额是由销售数量和单价相乘得到的,其中销售数量就是“产品销售”表中的 sl 字段,单价则是“产品”表中的 jg 字段。查询条件中涉及的年份和月份分别是“产品销售” 表的 nf 和 yf 字段。因此查询涉及 3 张表。其中“产品”表和“产品销售”表可以通过 cpmc (产品名称)字段进行连接。 “产品销售”表和“销售商”表可以通过 khmc(产品名称)字 段进行连接。这样,3 张表已经有效地连接起来了。 要按销售商统计销售总额并按升序排序,必须以 khmc 进行分组,并以销售总额作为排 序条件;另外,在筛选条件中要设置如下条件: 产品销售.nf=2000 AND 产品销售.yf=5 OR(产品销售.nf=2000 AND 产品销售.yf=6) 据此,创建查询的步骤如下。 (1)打开“查询设计器”,进入“新建查询”。 (2)在“添加表或视图”对话框中,选择产品、产品销售、销售商 3 张表。如果,在数 据库中已为这 3 张表建立了永久关系,则查询设计器以永久关系作为连接条件;否则,在添 加第 2 张表时,出现“连接条件”对话框,以设置连接条件。添加第 3 张表时,同样要设置 连接条件。 (3)在查询设计器的字段选项卡中,选定输出字段,如图 T9.3 所示。第 1 项 khmc 和第 2 项 fzr 都是销售商表中的字段,分别起了一个中文别名为“客户名称”和“负责人”,第 3 项是一个表达式,计算销售额,起了一个中文别名为“销售额”。 ·285·


图 T9.3

字段选取

(4)在筛选选项卡中,设置筛选条件如图 T9.4 所示。

图 T9.4 设置筛选条件

(5)在排序依据选项卡中,设置排序条件如图 T9.5 所示。 (6)在分组依据选项卡中,设置分组字段如图 T9.6 所示。

图 T9.5

设置排序条件

图 T9.6 设置分组字段

(7)在完成了上述设置后,单击“常用”工具栏上的“运行”按钮( ),可以运行查 询,运行结果如图 T9.7 所示。 (8)保存查询为 SellQuery.qpr。 思考:如果在查询结果中还需要列出总销售数量,应该如何进行修改? ·286·


图 T9.7 多表查询的结果

创建的查询,最终是生成一条 SELECT-SQL 语句,在查询设计器中单击“查询”选单中 的“查看 SQL”命令,即可将 SELECT-SQL 语句显示在浏览窗口;在命令窗口中,执行 TYPE SellQuery.qpr 命令可以显示 SELECT-SQL 语句;用 MODIFY COMMAND SellQuery.qpr 命令 编辑 SELECT-SQL 语句。 4. 使用查询向导创建交叉表查询 根据产品销售表,建立产品销售交叉表。要求将一种产品每个客户所销售的数量放在一 行中,并在最后一列有一个总和,如图 T9.8 所示。 Cpmc PANDA 2177

北京西单集团 100

PANDA 2188 PANDA 2198

上海第一百货

225

200

200 150

320 200

总 和

125

150

PANDA 2998 PANDA 2999

南京家电公司

320

300

260

760

图 T9.8 产品销售情况表

在“新建查询”对话框中选择“查询向导”,在“向导选取”中选择“交叉表向导” 。 (1)字段选取。“交叉表向导”的第 1 个步骤是字段选取,如图 T9.9 所示。需要为建立 的交叉表选取出一个表的 3 个字段。选取的 3 个字段将用于确定行、列以及内容。这里,选 择产品销售表的 3 个字段:Khmc,Cpmc 和 Sl。

图 T9.9

字段选取

(2)布局。 “交叉表向导”的第 2 个步骤是布局,如图 T9.10 所示。对话框的“可用字段” 列表中列出了上一步所选取的字段,这些字段会根据需要分别放在交叉表中的列、行和内容 ·287·


显示网格中。在对话框的右侧有 3 个空白区域,分别表示交叉表的列、行和数据 3 个部分。 可以用鼠标在“可用字段”列表中选取合适的字段拖动到“列”、“行”或“数据”空白区域 中。如果已经把字段拖动到合适的位置,这个空白区域中就会显示出字段的名字。

图 T9.10

布局

因为要让一种产品占一行,每个销售商的销售数量占一列,所以,把“Cpmc”字段拖到 “行”框中,把“Khmc”字段拖到“列”框中,把“Sl”字段拖到“数据”框。这样,在产 品销售表中有多少种产品,则在交叉表中就会有多少行;有多少个销售商,则在交叉表中就 会有多少列。 (3)加入总和信息。 “交叉表向导”的第 3 个步骤是加入总和信息,如图 T9.11 所示。在 这里,可以为查询结果指定一个“总计”列,这个“总计”列将会被加入到查询结果的最右 侧。在对话框的“总和”区域,可以为查询添加“求和” 、“计数” 、“平均” 、 “最小”、 “最大” 等运算的结果,系统默认为求和运算;在“小计”区域,可以选择“数据求和”、 “含数据的 单元格数目”、“表总计的百分比”和“无”等 4 个选项,指定这些选项中的一个也可以在查

图 T9.11

·288·

加入总和信息


询结果中添加小计的内容,系统默认选择了“小计”中的“数据求和” 。在本例中,选择了系 统的默认值。 (4)完成。 “交叉表向导”的第 4 个步骤是完成,如图 T9.12 所示。单击“预览”按钮可 以查看查询的结果,如果对结果满意,就可以单击“完成”按钮,结束交叉表向导的运行。 以 CrossQuery.qpr 作为文件名保存所创建的交叉表查询。 如果对查询的结果不满意,还可以单击“上一步”按钮,返回到向导的前几步重新选择 数据。

图 T9.12

完成

思考: (1)在查询结果中,如果要让一种产品占一列,每个销售商的销售数量占一行,应该如 何建立此查询? (2)通过建立一个查询,生成学生成绩一览表,格式如下: 学号

课程号 1

课程号 2

课程号 3

课程号 4

课程号 5

总 分

学号 1 学号 2 …

5. 使用 SELECT-SQL 语句 本例使用学生成绩数据库(XSCJ.dbc)中的学生情况表(XS.dbf)、课程表(KC.dbf) 、 课程成绩表(XS_KC.dbf) 。各表的详细结构见附录。 其中,XS.dbf 表中包含下列字段:XH(学号) 、XM(姓名) 、XB(性别) 、出生时间(年 龄)和 ZYM(专业名);KC.dbf 表中包含下列字段:KCH(课程号) 、KCM(课程名) 、XF (学分)和 XQ(开课学期);XS_KC.dbf 表中包含下列字段:XH(学号) 、KCH(课程号和 CJ(成绩)。 在命令窗口直接输入 SELECT-SQL 命令,可以进行查询操作。 (1)简单查询。 SELECT * FROM XS

&& 输出学生情况表中的所有字段

SELECT XM AS "姓名",CSSJ AS "出生时间" FROM XS

·289·


&& 给 XM 和 CSSJ 字段指定标题 && 不允许重复记录

SELECT DISTINCT XM FROM XS SELECT TOP 3

KCH,KCM,XF FROM KC

ORDER BY XF && 用 TOP 指定输出记录的个数

SELECT TOP 5 PERCENT KCM

FROM KC ORDER BY XF && 用 TOP 指定输出记录的百分比

SELECT XH,YEAR(DATE())-YEAR(CSSJ)FROM XS && 查询经过计算的值 SELECT XH,CJ

FROM XS_KC WHERE KCH="001" AND CJ>80 ORDER BY CJ DESC && 用 WHERE 子句筛选源表记录, 按 CJ 字段的降序排序(默认为升序)

(2)连接查询。 SELECT XM,CJ FROM XS,XS_KC WHERE XS.XH=XS_KC.XH AND KCH="001" && 用 WHERE 子句连接两张表

(3)联合查询。 SELECT XH FROM XS WHERE XH="99"; UNION SELECT XH FROM XS_KC

WHERE KCH="002" && 用 UNION 将两个查询结果做并操作

(4)嵌套查询。 SELECT XH FROM XS_KC; WHERE KCH IN (SELECT KCH FROM KC WHERE KCM="汇编语言")

(5)库函数。 SELECT KCH,COUNT(XH),MAX(CJ),MIN(CJ),AVG(CJ); FROM XS_KC; GROUP BY KCH

&& 按课程号统计选课人数,最高、最低及平均成绩

SELECT XM FROM XS; WHERE XH IN (SELECT XH FROM XS_KC GROUP BY XH HAVING COUNT(*)>3) && 列出至少选修了 3 门课程的学生姓名

·290·


实验 10 创建和使用本地视图 目的和要求 (1)了解视图向导的使用方法。 (2)掌握用视图设计器和命令创建、修改本地视图方法。 (3)掌握用视图更新基表数据的方法。 (4)掌握创建参数化视图的方法。 (5)掌握视图的使用。

实验准备 (1)复习教材中有关视图的内容。 (2)准备好前面实验所创建的项目、数据库和表。 (3)启动 Visual FoxPro 6.0 系统,并设置默认的目录。 (4)打开项目管理器。

实验内容 1.视图设计器的打开方法 启动查询设计器的方法有下面 3 种: (1)在“项目管理器”中,选择“视图”,单击“新建”按钮。 (2)在“文件”选单或工具栏中,选择“新建”命令。 (3)使用 CREATE SQL VIEW 命令。 2.创建本地视图 创建本地视图有以下几种方法。 (1)用视图设计器创建本地视图。为 XS 数据库创建一个本地视图,显示 2000 年 5 月份 的产品销售情况,包含下列字段:客户名称、产品名称、产品价格、销售数量、产品库存量 以及客户电话。结果按产品名称升序排序,再按销售数量降序排序。 选取 3 张表:产品、产品销售和销售商。 建立连接条件: 产品.cpmc=产品销售.cpmc 和产品销售.khmc=销售商.khmc 在字段选项卡中选择下列字段:销售商.khmc、产品.cpmc、产品.jg、产品销售.sl、产品.kcl、 销售商.dh。 在筛选选项卡中设置下列条件:产品销售.nf=2000 AND 产品销售.yf=5。 在排序依据选项卡中设置排序条件如下:先按产品.cpmc 的升序排序,再按产品销售.sl 的降序排序。 保存视图为 ViewSell。 ·291·


(2)用 CREATE SQL VIEW 命令创建本地视图。用 CREATE SQL VIEW 命令创建本地视 图 ViewProduct,包含了产品表的所有字段: CREATE SQL VIEW ViewProduct AS SELECT * FROM 产品 前面是用视图设计器创建本地视图,也可以用下列 CREATE SQL VIEW 命令创建: CREATE SQL VIEW ViewSell AS; SELECT 销售商.khmc,产品.cpmc,产品.jg,产品销售.sl,产品.kcl,销售商.dh; FROM 产品,产品销售,销售商; WHERE 产品销售.nf=2000 AND 产品销售.yf=5 ; ORDER BY 产品.cpmc,产品销售.sl DESC

3.使用视图更新基表数据 使用视图更新基表数据有以下几种方法。 (1)修改视图中的数据。查询的结果不能更新,它是只读的;而视图中的数据是可更新 的。可以在浏览窗口任意地修改视图中的数据,也可以通过命令方式修改视图中的数据。例 如,下列命令将视图 ViewProduct 中的库存量设置为 0,并浏览修改结果: UPDATE ViewProduct SET kcl=0 BROWSE

但是,这些修改是不会影响到基表的。可以用下列命令浏览产品表,看到表中的数据仍 是原来的: SELECT 产品 BROWSE

要想使得视图中的数据更新发送到基表中,必须设置视图的更新条件。 (2)设置视图的更新条件。在项目管理器中,选择 ViewProduct,单击“修改”按钮,进 入视图设计器,在更新条件选项卡中,如图 T10.1 所示,做如下设置:在“字段名”列表框 中,设置关键字段为 cpmc,可更新字段为 kcl;选择“发送 SQL 更新”复选框;保存对视图 的修改。

图 T10.1

更新条件选项卡

也可用下列命令来设置。 设置关键字段: =DBSETPROP("ViewProduct. cpmc","Field","KeyField",.T.) 设置可更新字段: =DBSETPROP("ViewProduct. kcl","Field","UpdateName","产品. kcl") 设置“发送 SQL 更新”:

·292·


=DBSETPROP("ViewProduct","View","SendUpdates",.T.)

这时,在视图中对 kcl 的修改将反映到基表,而对 cpmc 和 jg 的修改不会影响基表。 (3)检验更新条件的作用。在项目管理器中,选择 ViewProduct,单击“浏览”按钮,对 视图中的 kcl 和 jg 字段进行修改,关闭视图的浏览窗口。回到项目管理器,选择产品表,单 击“浏览”按钮,在浏览窗口可以看到,kcl 字段发生了变化,而 jg 字段保持不变。 思考:如果要在视图中修改基表中的 jg 字段的数据,则应如何设置更新条件? 4.创建参数化视图 为了使视图更加灵活,可以给视图的筛选条件设置参数,以避免每取一部分记录就创建 一个视图的情况。以后,运行视图时,Visual FoxPro 6.0 将提示输入参数值,系统根据所输入 的正确的参数值,找出符合条件的记录。 (1)定义参数化视图。修改视图 ViewSell,使得该视图可以根据输入的年份和月份来显 示产品销售情况。 在项目管理器中,选择 ViewSell,单击“修改”按钮,进入视图设计器,在“筛选”选 项卡中,设置筛选条件,如图 T10.2 所示。 也可以用下列 CREATE SQL VIEW 命令创建参数化视图: CREATE SQL VIEW ViewSell AS; SELECT 销售商.khmc,产品.cpmc,产品.jg,产品销售.sl,产品.kcl,销售商.dh; FROM 产品,产品销售,销售商; WHERE 产品销售.nf=?年份 AND 产品销售.yf=?月份 ; ORDER BY 产品.cpmc,产品销售.sl DESC

图 T10.2

设置筛选条件

(2)运行参数化视图。 ① 在视图设计器中运行。在视图设计器打开的情况下,单击常用工具栏中的运行按钮, 这时会出现“视图参数”对话框,如图 T10.3 所示,输入所需参数后,即可运行该视图。

图 T10.3 “视图参数”对话框

·293·


② 在命令窗口中运行。 年份=2000 月份=5 USE ViewSell BROWSE

思考:如果要根据产品名称随时了解某种产品的销售情况,则应如何设置视图参数? 5.视图的使用 视图的使用有以下步骤。 (1)视图的打开。在“项目管理器”中先选择一个数据库,再选择视图名,然后单击“浏 览”按钮,即可在浏览窗口中显示视图。也可以用 USE 命令打开视图。 OPEN DATABASE XS USE ViewSell BROWSE

(2)视图的关闭。仅关闭视图,用下列命令: SELECT ViewSell USE

关闭数据库中的所有视图和表,用下列命令: CLOSE TABLE

关闭数据库,则库中的表和视图也一起关闭,用以下命令: CLOSE DATABASES

(3)设置视图的字段属性。同表一样,可以给视图字段设置标题、注释、默认值和规则。 若要设置视图字段属性,可在“视图设计器”对话框的字段选项卡中,选定要设置属性 的一个字段,并选择“属性” ,即可打开“视图字段属性”对话框,这时,可以为该字段设置 一些属性,如图 T10.4 所示。

图 T10.4 设置视图字段属性

例如,可以将视图 ViewSell 的所有字段设置一个中文标题。 ·294·


实验 11 创 建 选 单 目的和要求 (1)掌握选单设计器创建和修改选单的方法。 (2)掌握创建快捷选单的方法。 (3)掌握创建表单选单的方法。

实验准备 (1)复习教材中有关选单的内容。 (2)准备好前面实验创建的表单和查询。 (3)启动 Visual FoxPro 6.0 系统,并设置默认的目录。

实验内容 1. 选单设计器的打开方法 打开选单设计器的方法有下面 3 种: (1)在“项目管理器”中,选择“选单”,单击“新建”按钮。 (2)在“文件”选单或工具栏中,选择“新建”命令。 (3)使用 CREATE MENU 命令。 2. 使用选单设计器创建普通选单 创建一个“销售管理”选单,下含“建立” 、“查询” 、 “报表” 、 “帮助”和“返回”5 个选单项。操作步骤如下。 (1)在“项目管理器”中,选择“选单” ,单击“新 建”按钮,在弹出的“新建选单”对话框中选择“选单” , 如图 T11.1 所示,进入选单设计器。 (2)在“选单名称”栏中输入“销售管理” ,在“结 果”栏中选择“子选单” ,如图 T11.2 所示。单击“创建” 按钮,进入下一级选单设计。 图 T11.1 “新建选单”对话框 (3)在“选单名称”栏中一一输入“建立” 、 “查询” 、 “报表” 、 “帮助”,在“结果”栏中都选择“子选单”;再在“选单名称”栏中输入“返回” , 在“结果”栏下选择“命令” ,在命令接收框中输入命令“SET SYSMENU TO DEFAULT” , 如图 T11.3 所示。选择“查询”,建立查询的子选单。 (4)在“选单名称”栏中输入“销售额情况”,在“结果”栏下选择“命令” ,在命令接 收框中输入命令“DO SellQuery.qpr” ;在“选单名称”栏中输入“销售量情况”,在“结果” 栏中选择“命令”,在命令接收框中输入命令“DO CrossQuery.qpr” ,如图 T11.4 所示。

·295·


图 T11.2

在“选单设计器”中定义选单栏

图 T11.3

定义选单栏下的子选单

图 T11.4

定义查询子选单

(5)选择系统选单栏中的“选单”下的“生成” ,弹出“生成选单”对话框,输入选单文 件名“SellMenu.mpr” ,如图 T11.5 所示,单击“生成”按钮。

图 T11.5

·296·

“生成选单”对话框


(6)选择新建的选单 SellMenu,单击“运行”按钮,运行所建的选单,如图 T11.6 所示。

图 T11.6 运行选单

(7)重新打开选单设计器,修改选单 SellMenu,将其添加到系统选单栏的“帮助”选单 之前。 选择系统选单栏中“显示”选单的“常规选项”命令,弹出“常规选项”对话框,如图 T11.7 所示。

图 T11.7

“常规选项”对话框

单击“在…之前”单选按钮,在这个单选按钮的右侧显示一个下拉式列表,其中列出了 所有的系统选单名。选择“帮助”选单,单击“确定”按钮,则这个选单在执行时将会显示 在“帮助”选单之前。 选择“选单”中的“生成”命令,重新生成该选单的程序代码。在命令窗口输入命令: DO SellMenu.MPR。 于是,在系统选单栏中“帮助”选单之前出现了刚才所修改的自定义选单,如图 T11.8 所示。

图 T11.8

自定义选单插入到系统选单栏中

3. 创建快捷选单 创建快捷选单的方法与普通选单非常相似,步骤如下。 (1)在“项目管理器”中,选择“选单”,单击“新建”按钮,在弹出的“新建选单”对 话框中选择“快捷选单”,进入快捷选单设计器。 (2)在快捷选单设计器中输入如图 T11.9 所示的内容。 在“选单名称”栏下输入“TOP”,在“结果”栏下选择“过程”,单击“创建”按钮, 在弹出的过程编辑窗口中输入命令:GO TOP。 ·297·


图 T11.9

快捷选单设计器

类似的操作建立“BOTTOM”, “UP”, “DOWN”选单项。 “BOTTOM”选单项的命令代码是:GO BOTTOM “UP”(上一个记录)选单项的命令代码是: IF NOT BOF() SKIP –1 ENDIF

“DOWN”(下一个记录)选单项的命令代码是: IF NOT EOF() SKIP ENDIF

(3)生成快捷选单 QuickMenu.mpr。 下面将快捷选单 QuickMenu 附加到表单中,步骤如下。 (1)选择要附加快捷选单的表单 EX_grid.scx。 (2)设置对象属性。在表单的属性窗口中选择“方法程序”选项卡,并选择“RightClick Event”项,如图 T11.10 所示。

图 T11.10

设置对象属性

(3)设置代码。双击“RightClick Event”项,在代码窗口中输入 DO QuickMenu.mpr 命 令,如图 T11.11 所示。 ·298·


图 T11.11 设置代码

(4)运行修改后的表单,单击鼠标右键,检查快捷选单的效果,如图 T11.12 所示。

图 T11.12

运行快捷选单

4. 创建表单选单 建立表单选单与建立普通用户自定义选单的不同之处在于:当选单设计完成以后,必须 将其设置为“顶层选单”才能在表单中得以执行。操作步骤如下。 (1)在选单设计器中,设计一个选单如图 T11.13、图 T11.14 所示。其中“查找”子选单 的 4 个选单项的命令代码与快捷选单的相同。

图 T11.13

表单选单内容(一级选单)

(2)设置为“顶层选单” 。选择系统选单栏中的“显示”选单下的“常规选项”命令,弹 出“常规选项”对话框,单击右下角的“顶层表单”复选按钮,表示这个选单是结合表单的 顶层选单,如图 T11.15 所示,以 FormMenu.mpr 生成选单。

·299·


图 T11.14

表单选单内容(查找子选单)

图 T11.15

设置为“顶层选单”

(3)修改表单的属性。打开要添加顶层选单的表单 EX_grid.scx,在表单的属性窗口中, 选择“布局”选项卡,将“ShowWindow”属性设置为“2—作为顶层表单”,如图 T11.16 所 示;再选择“方法程序”选项卡,为“Init Event”属性添加如下代码,如图 T11.17 所示: DO FormMenu.mpr WITH THIS,.T.

图 T11.16 设置表单“Show Window”属性

·300·


图 T11.17

设置“Init Event”属性的代码

则运行表单时,所添加的选单将加载在表单中,如图 T11.18 所示。

图 T11.18

表单选单的运行

5. 配置系统选单 练习使用 SET SYSMENU 命令重新配置系统选单。 (1)有选择地去掉系统选单栏中的某些选单。在命令窗口输入以下命令,观察系统选单 栏的变化。 SET SYSMENU TO _MFILE,_MEDIT,_MSYSTEM SET SYSMENU TO _MFILE,_MEDIT,_MSYSTEM,_MTOOLS,_MWINDOW SET SYSMENU TO _MFILE,_MSYSTEM SET SYSMENU TO

(2)有选择地去掉系统选单栏中的某个选单下的选单项: RELEASE BAR _MED_SLCTA OF _MEDIT RELEASE BAR _MED_PREF OF _MEDIT

去掉“编辑”选单下的“全部选定”和“属性”选单项。

·301·


实验 12 创建自定义工具栏 目的和要求 (1)掌握类设计器的使用方法。 (2)掌握用类设计器创建自定义工具栏的方法。

实验准备 (1)复习教材中第 7 章有关创建自定义工具栏的内容。 (2)准备好前面实验所创建的项目和表单。 (3)启动 Visual FoxPro 6.0 系统,并设置默认的目录。

实验内容 1.类设计器的打开方法 打开类设计器的方法有下面 2 种。 (1)在“项目管理器”中,选择“类”选项卡,单击“新建”按钮。 (2)在“文件”选单或工具栏中,选择“新建”命令。 2.创建自定义工具栏 创建一个自定义工具栏,含有 5 个命令按钮,按钮的功能如下。 (1)定位表的记录,包括第一个记录、上一个记录、下一个记录、最后一个记录、保存。 (2)根据记录指针的当前位置,确定自定义工具栏上的按钮是否可用。例如,当指针指 向第 1 个记录时,前两个按钮不能使用;当指针指向最后一个记录时,第 3 和第 4 个按钮不 能使用。操作步骤如下。 ① 在项目管理器中选择“类”选项卡,单击“新建”按钮,弹出“新建类”对话框,如 图 T12.1 所示。

图 T12.1 “新建类”对话框

② 在“类名”中输入所建新类的名称 MyToolBar;在“派生于”列表框中选择“Toolbar” 基类,以使用工具栏基类;在“存储于”栏中输入存储所建新类的类库名,例如 MyToolBar.vcx。 ·302·


单击“确定”按钮,进入“类设计器”对话框,如图 T12.2 所示。

图 T12.2 “类设计器”对话框

③ 在类设计器中,使用表单控件工具栏向新建的工具栏类添加 4 个命令按钮。 从“表单控件”工具栏中,单击要添加命令的按钮;单击自定义工具栏,将命令按钮放 置在自定义工具栏上;再从“表单控件”工具栏中选择“分隔符”控件,放到自定义工具栏 上;重复上面 3 步,将所需的 4 个命令按钮都放置到自定义工具栏上。 ④ 设置自定义工具栏上 4 个命令按钮的属性。用鼠标选中第 1 个按钮,单击鼠标右键, 从弹出的快捷选单中选择“属性”命令;在“属性”对话框中,如图 T12.3 所示,选择“布 局”选项卡,设置“Picture”属性。

图 T12.3

设置“Picture”属性

单击“…”按钮,进入图 T12.4 所示的“打开(图片文件) ”对话框,为命令按钮设置一 个图标为 ,重复上面 3 步,将 4 个命令按钮的 Picture 属性都设置好,其余 3 个的图标分 别为: ,如图 T12.5 所示。 ⑤ 为每个对象编写处理程序,这与为表单中的控件编写处理程序的方式一样。例如,为 第 1 个命令按钮设置 Click 事件代码,用鼠标双击第 1 个命令按钮,进入代码窗口;在代码 窗口输入执行该命令按钮要执行的代码: GO TOP THISFORM.Refresh

·303·


重复为第 2、第 3 及第 4 个命令按钮分别设置代码。

图 T12.4

“打开(图片文件)”对话框

⑥ 保存自定义工具栏。 3.将自定义工具栏添加到表单集中 将上面所建的自定义工具栏加入到表单中的步骤如下。 (1)在表单设计器中打开 EX_edit.scx。 (2)在表单控件工具栏中单击“查看类”按钮,在弹出的下拉列表中单击“添加”按钮, 显示“打开”对话框。 (3)从对话框中选择 RY_CLASS.VCX 类库,单击“打开”,这时,表单控件工具栏显示 如图 T12.6 所示,第 3 个按钮(MyToolBar)即为所定义的工具栏新类。

图 T12.5 自定义工具栏

图 T12.6

表单控件工具栏

(4)单击 MyToolBar 控件,并单击表单中的某个地方,如果打开的表单是单个表单,而 非表单集,则系统给出如图 T12.7 所示的提示。单击“是”按钮,则系统首先创建一个含有 被打开表单的表单集,然后将新的工具栏加入到表单中。

图 T12.7 “创建表单集”对话框

(5)保存对表单的修改,执行表单,可看到自定义工具栏出现在表单中,如图 T12.8 所 示。

·304·


图 T12.8 表单中的自定义工具栏

·305·


实验 13 报 表 设 计 目的和要求 (1)掌握报表向导的操作方法。 (2)掌握快速报表的操作方法。 (3)掌握用报表设计器创建和修改报表的方法。

实验准备 (1)复习教材中有关报表的内容。 (2)准备好实验所创建的项目、数据库和表。 (3)启动 Visual FoxPro 6.0 系统,并设置默认的目录。

实验内容 1. 使用报表向导创建报表 利用报表向导创建一张基于产品表的简单报表,内容为产品价目表,步骤如下。 (1)打开“报表向导”。在“项目管理器”的“数据”选项卡中选择产品表,在“文档” 选项卡中选择“报表”项目,单击“新建”按钮,进入“新建报表”对话框。在“新建报表” 对话框中单击“报表向导”按钮,进入“向导选取”对话框,选择“报表向导” 。 (2)步骤 1:字段选取。选择产品表中的 cpmc 和 jg 字段。 (3)步骤 2:分组记录。不分组。 (4)步骤 3:选择报表样式。选择经营式。 (5)步骤 4:定义报表布局。设置列数为 3。 注意,如果在向导的步骤 2 设置了记录分组,则这里的“列数”和“字段布局”是不可 用的。 (6)步骤 5:排序记录。选择以 jg 字段的升序排序。 (7)步骤 6:完成。可以设置报表的标题,在离开向导之前预览报表,选择退出向导的 方式。预览报表后,以 LabReport1 保存报表。 2. 使用快速报表创建报表 利用“快速报表”设计时,操作步骤如下。 (1)打开“报表设计器”。在“项目管理器”的“数据”选项卡中选择销售商表,在“文 档”选项卡中选择“报表”项目,单击“新建”按钮,进入“新建报表”对话框。单击“新 建报表”按钮,进入“报表设计器”。 (2)进入“快速报表” 。选择“报表”选单下的“快速报表”选项,出现“打开”对话框, 选择要使用的“工资情况”表,单击“确定”按钮后,出现“快速报表”对话框。 选择字段布局为列布局。 ·306·


选中“标题”复选框、“添加别名”复选框和“将表添加到数据环境中”复选框。 (3)选择字段。设置了报表布局后,单击“字段”按钮,进入“字段选择器”对话框, 为报表选择所需的字段 khmc,fzr,dh。字段选择好后,返回“快速报表”对话框。在“快速 报表”对话框中,单击“确定”按钮,返回“报表设计器” 。此时,“报表设计器”中显示出 报表的布局。 (4)预览并保存报表。选择“显示”选单中的“预览”命令,可以预览报表的结果。 预览了报表的输出结果后,关闭预览窗口,回到报表设计器,以 LabReport 2 保存报表文 件。最后,关闭报表设计器。 3. 使用报表设计器创建报表 用报表设计器设计一张产品销售情况报表。 (1)打开“报表设计器” 。 (2)向报表中添加数据源。单击“报表设计器”工具栏的“数据环境”按钮,出现“数 据环境设计器”对话框。在该窗口中任意区域单击鼠标右键,出现快捷选单,在快捷选单中 选择“添加” ,出现“添加表或视图”对话框,选择 XS 数据库,将产品销售表添加到“数据 环境设计器”中。然后,用鼠标拖动选取的字段到“报表设计器”的细节带区。在“数据环 境设计器”中单击鼠标右键,设置 cpmc 字段的 Order 属性,这样,报表输出记录时可按 cpmc 排序。 (3)合理安排报表布局。可以用手动调整或“布局”工具栏将所选字段排列成所需的格 式。手动调整时,可先将“显示”选单下的“网格线”和“显示位置”打开,便于准确地调 整字段位置。用鼠标单击所选字段后,即可对其进行大小和位置的调整。如果没有特殊要求, 使用“布局”工具栏进行排列会更加快捷、方便和准确。 经过这 3 个步骤,一张简单的销售情况报表已经设计出来,如图 T13.1 所示。可以在“显 示”选单下选择“预览”命令,浏览一下设计的结果,如图 T13.2 所示。 单击常用工具栏上的“保存”按钮,将所设计的报表用 reportsell 保存起来。

图 T13.1

用报表设计器创建报表

图 T13.2

浏览报表设计结果

(4)修改报表布局。一张设计完美的报表应保证重点突出、易于查阅,同时给人赏心悦 目的感觉。下面,对刚才所建的报表 reportsell,利用报表控件对报表进行美化,形成如图 T13.3 所示的报表。 打开报表 reportsell 所在的项目管理器,在“文档”选项卡中选择要修改的报表 reportsell, 单击“修改”按钮,进入报表设计器,对报表进行修改,如图 T13.4 所示。 ① 添加分组。选择“报表”选单的“数据分组”命令,进入“数据分组”对话框,设置 分组表达式为:产品销售.nf+产品销售.yf,这样,可以按月输出产品销售情况。在组属性中, ·307·


选择“每组从新的一页上开始”和“每页都打印组标头” ,如图 T13.5 所示。

图 T13.3

产品销售情况表

图 T13.4 用报表设计器修改报表

图 T13.5 为报表添加数据分组

·308·


这时,在报表设计器中,在原来的 3 个带区(页标头、细节、页注脚)的基础上,又增 加了组标头和组注脚两个带区。 ② 修改页标头带区。在页标头带区添加一个标签控件:单击报表控件工具栏上的标签控 件按钮,在页标头带区单击后,输入“产品销售情况表” ,单击“格式”选单下的“字体”选 项,出现“字体”对话框,设置字体为粗体和字体大小为 4 号,如图 T13.6 所示。

图 T13.6

为报表文字设置字体和字号

注意:如果要修改标签控件中的文字,必须先单击“标签工具栏”按钮,再单击该标签 控件进行修改。 ③ 修改组标头带区。在组标头带区添加一些标签控件、域控件和线条控件,用于设计出 报表的表头。 首先,添加一个域控件:单击报表控件工具栏上的域控件按钮后,在组标头带区中,利 用鼠标的拖动操作生成大小合适的域控件。在随即打开的报表表达式对话框中,输入表达式: STR(产品销售.nf,4)+"年"+ STR(产品销售.yf,4)+"月",用来显示图 T13.3 中报表标题 下面的日期,如图 T13.7 所示。

图 T13.7 “报表表达式”对话框

然后,添加 3 个标签控件,分别输入“产品名称” 、 “销售商名”和“销售数量”作为表 ·309·


头中 3 列的标题。 最后,添加一些线条控件,画出表头的表格线。 ④ 修改细节带区。在细节带区添加线条控件,用于画出报表中的表格线。选中报表的左 右两条边框线,选择“格式”选单下的“绘画笔”命令,可以在下一级子选单中选择直线的 类型和样式。这里,选择 2 磅的线。 ⑤ 修改页注脚带区。在页注脚带区添加 2 个标签控件,作为“主管:”和“制表: ”两项。 至此,这张报表的修改已经完成,修改后的情况如图 T13.4 所示。预览了报表的输出结 果后,关闭报表预览窗口,返回报表设计器,保存报表文件。

·310·


第 4 部分 VFP 综合应用实习 VFP 综合应用实习的目标是让读者综合应用本教程介绍的知识解决一个小的问题。实习 中用到的表单、报表和查询等有些与书中的实例类似,又不完全相同,并且把他们串起来, 更便于消化理解。 实习的思路是:编一个程序文件 EX_MAIN.PRG 作为项目的主文件,由它调用用户登录 表单 EX_LOGIN。用户登录成功,由登录表单调 EX_MENU 系统选单。在系统选单中调操作 人员数据库及其表的表单、查询和报表。文件选单用于设置路径、打开 RY 数据库容器和退 出应用系统。 表单中分别操作基本情况、工资情况;查询中把包括部门工资表在内的 3 个表关联起来。 实习中的所有内容均在计算机上调试通过。用户解决问题可据此模仿。 1.创建项目 创建实习项目,项目文件名为 RY_test.PJX。打开“项目管理器-RY_test”。 2.创建 RY 数据库 创建 RY 数据库的步骤如下。 (1)在“项目管理器-RY-test”中的数据页加入 RY 数据库,3 个数据表同时被加入并显 示在项目管理器中,如图 P.1 所示。

图 P.1

项目管理器-RY-test

(2)分别选 3 个数据表,按附录 A 的表结构建立或核对一致。分别创建 3 个表的索引。 工资情况表的索引如图 P.2 所示。基本情况表的索引与工资情况表的索引相同。部门工资表 的主索引表达式为部门编号,索引名也为部门编号。

·311·


图 P.2

工资情况表的索引

(3)创建永久关系。选择 RY 数据库,单击“修改”按钮,建立下列永久关系后数据库 如图 P.3 所示。

图 P.3 创建永久关系

① 基本情况表主索引编号和工资情况表主索引编号之间。 ② 部门工资表主索引部门编号和工资情况表普通索引部门编号(表达式为 LEFT,编号, 2)之间。 ③ 部门工资表主索引部门编号和基本情况表普通索引部门编号(表达式为 LEFT,编号, 2)之间。 (4)在工资情况表“表”选项卡设置记录有效性和触发器,如图 P.4 所示。

图 P.4

·312·

工资情况表“表”选项卡


(5)编辑 RY 数据库的存储过程,代码如下: FUNCTION UF_DELETE yes= MESSAGEBOX("是否删除"+姓名+"记录",4+32,"人员基本情况") IF yes=6 RETURN .T. ELSE RETURN .F. ENDIF FUNCTION UF_INSERT IF !EMPTY(编号) RETURN .T. ELSE RETURN .F. ENDIF FUNCTION UF_UPDATE IF UNAME="ADMIN" RETURN .T. ELSE RETURN .F. ENDIF

保存后数据库的存储过程显示如图 P.5 所示。

图 P.5

RY 存储过程

练习:如果把存储过程中的程序放入程序文件或过程文件中,修改系统的代码实现原功 能。 3. 创建查询 选择“查询” ,单击“新建”按钮,打开查询设计器。生成 EX_QUERY.QPR 文件。 (1)数据环境和输出字段。在数据环境中加入基本情况表、工资情况表和部门工资表, 查询结果输出字段如下。 ·313·


① 基本情况表:编号和姓名字段。 ② 工资情况表:实发工资等所有数值字段。 ③ 部门工资表:部门名称字段。 把这些字段拖动到“选定字段”中,如图 P.6 所示。

图 P.6

数据环境和选定字段

(2)选择连接条件。因为输出的字段包含 3 个表,所以这 3 个表要建立合适的关联,如 图 P.7 所示。

图 P.7

建立 3 表关联

(3)确定输出顺序。在排序依据页选择“基本情况.编号” 。 生成的 SQL 语句如下所示。 SELECT 基本情况.编号,基本情况.姓名,部门工资.部门名称,; 工资情况.实发工资,工资情况.技能工资,工资情况.岗位工资,; 工资情况.浮动工资,工资情况.其他工资,工资情况.扣款小计; FROM

ry!基本情况 INNER JOIN ry!工资情况;

INNER JOIN ry!部门工资; ON LEFT(工资情况.编号,2)= 部门工资.部门编号; ON 基本情况.编号 = 工资情况.编号; ORDER BY 基本情况.编号

(4)预览结果,如图 P.8 所示。

·314·


图 P.8

3 表查询预览结果

练习:用视图实现上述查询功能。 4. 创建类 创建类有以下 2 种。 (1)创建记录移动类。选项目管理器“类”页,新建 RY_CLASS.VCX 类库,取名为 RY_CLASS。在类库中创建 CommandGroup 类,取名为 MY_RECORDMove,在其中放 4 个 移动命令按钮 Command1,Command2,Command3,Command4,如图 P.9 所示。

图 P.9

创建记录移动类

在 MY_RECORDMove 的 Click 事件中写入记录移动代码,记录移动代码如下: * CommandGroup1 的 Click 事件代码: sel=THIS.Value DO CASE CASE sel=1 GO TOP CASE sel=2 IF !BOF() SKIP - 1 ENDIF CASE sel=3 IF !EOF() SKIP ENDIF CASE sel=4

·315·


GO BOTTOM ENDCASE THISFORM.REFRESH

最后保存到类库中即可。 练习:用编程方式创建类和类库。 (2)在 RY_CLASS.VCX 类库创建记录移动工具类 MY_ToolBar。请用户自己完成。 5. 创建表单 加入和新建下列表单到项目文档中,如图 P.10 所示。

图 P.10 项目文档

(1)EX_cEDITGZ 表单,如图 P.11 所示。

图 P.11

EX_cEDITGZ 表单

① 数据环境:工资情况表。 ②“计算实发”按钮代码。 repl all 实发工资 with 技能工资+岗位工资+浮动工资+其他工资-扣款小计 GO TOP thisform.refresh

·316·


③“均值计算”按钮代码: S=0 JS=0 BH=LEFT(编号,2) Scan For 编号=BH S=S+工资情况.技能工资 Thisform.Refresh Wait "

" Timeout 1

JS=JS+1 Endscan Messagebox("部门编号为"+BH+"的平均工资="+Str(S/JS))

④“追加”按钮代码。 * 请用户自已编写,注意已经设置了 UF_INSERT()触发器。 ⑤“删除”按钮代码。 * 请用户自己编写,注意已经设置了 UF_DELETE()触发器。 ⑥ 将表单中使用记录移动的 MY_RECORDMove 类换成 MY_ToolBar 再进行调试。 (2)EX_EDIT3 表单,如图 P.12 所示。

图 P.12

EX_EDIT3 表单

①“定位”按钮代码。 bh=trim(this.parent.txtBH.value)

&& 定位前的文本框是 txtBH

jlh=recno() loca for 编号=bh if eof() go jlh else thisform.refresh endif

②“追加”按钮代码。 append blank thisform.refresh

·317·


③“删除”按钮代码。 yn=messagebox("是否要删除?",4+32) if yn=6 delete if eof() go top else skip endif thisform.refresh endif

(3)EX_GRID 表单,如图 P.13 所示。

图 P.13

EX_GRID 表单

“确定按钮”代码。 If !Empty(This.Parent.txtName.Value) Set filter to 基本情况.姓名=Trim(This.Parent.txtName.Value) This.Parent.grdJB.Refresh Retu Endif If !Empty(This.Parent.cboBM.Value) bm=Trim(This.Parent.cboBM.Value) Select 部门工资 Locate For 部门名称=bm bmbh=部门编号 Select 基本情况 Set Filter To Left(基本情况.编号,2)=bmbh This.Parent.grdJB.Refresh Retu Endif

·318·


(4)EX_LOGIN 表单,如图 P.14 所示。

图 P.14

EX_LOGIN 表单

①“确定”按钮代码。 UNAME=THIS.PARENT.txtNAME.VALUE YES=.F. DO CASE CASE Uname="ZHANG".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="1234" YES=.T. CASE Uname="ADMIN".AND.TRIM(THISFORM.txtPASSWORD.VALUE)=="AABB" YES=.T. ENDCASE IF YES DO EX_MENU.MPR ENDIF THISFORM.RELEASE CLEAR EVENTS

②“退出”按钮代码。 thisform.release CLEAR EVENTS

练习:把操作基本情况的表单放在一个表单集,把操作工资情况的表单放在一个表单集, 修改和调试程序。 6. 创建选单 在项目管理器的“其他”页,选择选单,单击“新建”按钮。打开选单设计器,设计应 用系统选单。应用系统选单分成两级。生成的选单文件为 EX_MENU.MNX。 (1)应用系统主选单,如图 P.15 所示。 (2)“文件”子选单,如图 P.16 所示。 (3)“基本情况”子选单,如图 P.17 所示。 (4)“工资情况”子选单,如图 P.18 所示。 (5)系统运行时的主选单,如图 P.19 所示。

·319·


图 P.15

应用系统主选单

图 P.16

“文件”子选单

图 P.17

“基本情况”子选单

图 P.18

“工资情况”子选单

图 P.19

系统运行时的主选单

练习: (1)把“报表管理”主选单放入工资情况子选单,并在单击该子选单时调用该报表。把 系统选单中的所有选单项建立一个工具条分别对应这些选单项。 (2)把图 P.10 中的类记录移动功能用快捷选单实现。 7. 创建报表 一个应用系统一般都由报表作为系统的输出。这里,我们选择一个工资报表。报表格式 具有实用意义。 在项目管理器的“文档”页,选择报表,单击“新建”按钮。打开报表设计器,设计工 ·320·


资报表,如图 P.20 所示。生成的报表文件为 ex_gz.frx。

图 P.20

报表设计器

请用户将报表设计器上的信息和图 P.21 的预览结果进行设计。数据环境为工资情况表。 金城石化公司热电厂工资发放明细表

签字

图 P.21

工资报表预览结果

8. 创建程序 一般来说,一个应用系统需要很多程序文件。这里,作为实习,我们安排创建一个程序 文件,而且是作为该项的主文件。 在项目管理器的“代码”页,选择程序,单击“新建”按钮。打开程序设计器,设计系 统程序。生成的程序文件为 EX_MAIN.PRG。 EX_MAIN.PRG 代码 PUBLIC UNAME SET DEFA TO D:\RY_MIS

·321·


DO FORM EX_LOGIN READ EVENTS CLEAR CLOSE ALL

·322·


附录 A 本书使用的数据库 A.1

人员信息数据库 RY

1.基本情况表 编号 C5 C8 姓名 D 出生时间 性别 C2 文化程度 C6 C6 职称 N6 工资 婚否 L 照片 G M 备注 2.工资情况表 编号 C5 姓名 C8 N4 技能工资 N4 岗位工资 浮动工资 N3 其他工资 N4 N6.1 扣款小计 N6.1 实发工资 3.部门工资表 部门编号 C2 C12 部门名称 N3 人数 技能工资 N8 岗位工资 N6 N6 浮动工资 N6 其他工资 扣款小计 N8.1 实发工资 N8.1

前 2 位为部门编号

前 2 位为部门编号

·323·


A.2

产品销售数据库 XS

1. 产品表 CPMC 产品名称 JG 价格 库存量 KCL 2. 销售商表 KHMC 客户名称 DQ 地区 负责人 FZR 电话 DH 3.产品销售表 NF 年份 月份 YF 产品名称 CPMC KHMC 客户名称 SL 数量

A.3

C12 N5 N4 C12 C10 C8 C12 N4 N2 C12 C12 N4

学生成绩数据库 XSCJ

学生成绩数据库 XSCJ 中包含学生情况 XS、课程 KC 和学生课程成绩 XS_KC 等数据库 表。 1. 学生情况表 XS 学号 XH 姓名 XM ZYM 专业名 XB 性别 出生时间 CSSJ 总学分 ZXF JXJ 奖学金 BZ 备注 2. 课程表 KC 课程号 KCH

C6 C8 C10 L D N3 N6.2 M C3

前 2 位为年,中间 2 位为班号,后 2 位为序号

男.T.,女.F.

前 1 位为课程类别(输入时只能选 1~5),后 2 位为序号 类别为:1—通修;2—必修;3—专修;4—方向;5—任选

KCM C16 课程名 开课学期 XQ N1 输入时只能选 1~8,默认值为 1 学时 XS N3 XF N2 学分 3. 学生课程成绩表 XS_KC 学号 XH C5 ·324·


课程号 成绩 学分

KCH CJ XF

C3 N3 N2

·325·


附录 B 创建安装程序 在应用程序调试完成后,应对应用程序所属的工程进行连编生成(.EXE)可执行程序, 然后即可创建一个能够正确安装应用程序的安装程序(又称打包) ,此后即可使用该安装程序, 将设计的应用程序安装到别的计算机上。

B.1

可发布文件

根据 Microsoft 授权协议,Visual FoxPro 6.0 中文版可以发布不受限制的任何文件,文件 必须与相关的应用程序一同发布。下列文件是可发布文件。 1. 类库 应用程序创建的(.VCX)类库文件可以随应用程序一起发布,但需要包括在项目中并在 连编应用程序时用到。 2. ODBC 文件 ODBC 是开放式数据库连接的简称,它是数据库服务器的一种标准协议。Visual FoxPro 通过 ODBC 驱动程序与数据库相连。随同应用程序一起发布的可以包括 ODBC 文件。至于具 体发布哪些 ODBC 文件,请参考随 Visual FoxPro 6.0 中文版一同发出的 Microsoft 授权协议中 有关再发布 ODBC 文件的限制条款。 3. ActiveX 控件 如果在安装 Visual FoxPro 6.0 中文版时选择了“完全安装”选项,则默认安装 ActiveX 控件。如果未选择此选项,可以在任何时候运行 Visual FoxPro 6.0 中文版安装程序,并只安 装 Activex 控件。Activex 控件被安装在 Windows 9x 的 SYSTEM 目录中,或者在 Windows NT 的 SYSTEM32 目录中。 ActiveX 控件与系统本身固有控件相同,可以把它放在表单上,使用户加强与一个应用 程序的交互能力,ActiveX 控件文件有.OCX 的后缀名称。 使用 Visual FoxPro 6.0 中文版的 OLE 容器控件,可以将 ActiveX 控件添加到应用程序的表单中。 4. 安装向导自动识别文件 在 DISTRIB.SRC 和 SETUP 目录下,可以发布用于支持相应的应用程序的所有文件。当 使用安装向导制作发布磁盘时,将自动以压缩格式把所需的文件从这些目录复制到发布磁盘 中。在安装时,这些文件被自动解压,并以原文件名装入需安装应用系统的用户机器中的适 当目录下,没有必要再复制这些文件到发布目录。 注意:在 SAMPLES 和 API\SAMPLES 目录下的文件是提供给用户学习的,用户不能未 经修改就发布这些示例程序,可以在自己的应用程序中参考示例中的部分代码。如果使用了 SAMPLES 或 API\SAMPLES(包括所有的.BMP,.ICO 和.CUR 文件)目录下的任何文件,那 么这些文件必须包括在项目中,并加入到应用程序的连编过程当中,它们不能用原名出现于 发布盘中,并且不可以独立于应用程序发布。 5. 受限制文件 在 Visual FoxPro 6.0 中文版中包含有许多只供设计、开发和测试使用的授权文件。这些 ·326·


文件都是受限制的文件,不允许同应用程序一起发布。Microsoft 授权协议规定,不允许将受 限制的文件随同应用程序一起发布。如果用安装向导来发布应用程序,安装向导将会查找这 些文件,如果找出这些受限制的文件,会将其从发布的磁盘上删除。

B.2

安装向导介绍

安装向导根据发布树中的文件创建发布磁盘,然后利用这些发布的磁盘,就可以轻松地 来安装并运行应用程序。 在“工具”选单下选择“向导”子选单,选择“安装”命令,弹出“安装向导”对话框。 安装向导运行以下步骤。 1.步骤 1—定位文件 第 1 步为定位文件。定位文件指定要建立的应用程序的所有源文件及其工作环境文件。 这些文件一般都放在相同的目录下。按照运行向导的方式打开安装向导,打开“定位文件” 对话框,如图 B.1 所示。

图 B.1

“定位文件”对话框

在“定位文件”对话框上部有一列表框显示向导步骤,如步骤 1—定位文件。框内下部 有一个“发布树目录”文本框,用于输入发布树指定目录,而且该目录必须包含要在用户环 境中建立的所有文件和子目录(Automation 服务程序除外) 。发布树文本框的右边有一个“…” 对话按钮,单击此按钮即可出现一对话框,可从中选择发布树目录。如果指定了发布树目录, 安装向导将把此目录树作为要压缩到磁盘映像子目录中的文件源。另外安装向导还会记录对 每个发布树选项的设置值,并作为下一次对同样发布树建立安装时的默认值。 注意:用户不能使用 DISTRIB 目录,因为安装向导将把它作为发布树目录使用。同时, 为了系统安全最好放置在 Visual FoxPro 目录。 2.步骤 2—指定组件 单击“下一步”按钮即可进入步骤 2,进入指定组件对话框,如图 B.2 所示。它为应用 程序选择使用的组件,可选的组件共有下列 6 种。

·327·


图 B.2

“指定组件”对话框

(1)Visual FoxPro 运行时刻组件:如果选择了此项,则需运行 Visual FoxPro 运行库并将 库文件自动包含在应用程序文件中,可以在用户的计算机上正确地安装。 (2)Microsoft Graph 8.0 运行时刻:如果选择了此项,则可在应用程序中包含使用 Microsoft Graph 8.0 控件的表单。 (3)ODBC 驱动程序:此项的功能是为了应用程序同不是 Visual FoxPro 的 DBF 的表进 行通信。如果选择此项,则会显示“ODBC 驱动程序”对话框,如图 B.3 所示。可以从中选 择 ODBC 驱动程序。

图 B.3

“ODBC 驱动程序”对话框

(4)COM 组件:如果选择此项,将会弹出“添加 COM 组件”对话框,如图 B.4 所示。 单击“加入”按钮,在弹出的“打开”对话框中选择需要添加的组件,单击“确定”按钮即 可添加指定的应用程序组件。如果用户需安装远程 COM 组件,可在对话框中选中“安装远 程 COM 组件”复选框。 (5)ActiveX 控件:如果选择此项,将打开“添加 ActiveX 控件”对话框,如图 B.5 所示。 可以从该对话框中选择需要安装的 ActiveX 控件。 (6)HTML 帮助引擎:如果选择此项,可以将超文本识别语言帮助引擎安装到应用程序 组件中。 用户应根据当前发布的应用程序情况确定选择的组件。 3.步骤 3—磁盘映像 单击“下一步”按钮建立磁盘映像,如图 B.6 所示。决定在哪个目录下建立磁盘映像, 同时为磁盘映像选择类型。向导建立一个发布子目录,其中包含每种指定类型磁盘的映像。 ·328·


图 B.4

图 B.5

安装远程 COM 组件

添加 ActiveX 控件

在运行向导之前可以建立磁盘映像子目录。如果想让向导来建立,在文本对话框中键入 新的名称。在运行安装向导之前,向导把前一次放置的位置作为默认值。 磁盘映像有 3 种类型:1.44MB 3.5 英寸、Web 安装和网络安装。如果选用“1.44MB 3.5 英寸” ,则按照此尺寸建立映像磁盘。如果选择“Web 安装”复选框,向导将进行压缩 Web 安装。如果选择“网络安装”复选框,向导将建立惟一的子目录包含所有的文件,进行非压 缩安装。

图 B.6

磁盘映像

·329·


4.步骤 4—安装选项 步骤 4—安装选项对话框主要是为应用程序指定标识,如图 B.7 所示。在安装对话框标 题栏中,可以填写安装标题。 “安装向导”在建立安装对话框时,将会在“安装对话框标题” 文本框中指定用户安装系统时所用的标题。同时还可以在“版权信息”文本框中为应用程序 设置版权信息。可以通过安装应用程序的帮助选单中的“关于”选单项来访问应用程序的版 权信息。 “执行程序”文本框内输入项是可选项,如果为此项选择了执行程序,在安装应用程 序完毕后将会立刻执行此应用程序。

图 B.7

安装选项

5.步骤 5—默认目标目录 下一步,设置默认目标目录,如图 B.8 所示。安装程序将把应用程序放置在安装向导“默 认目标目录”文本框指定的目录中,在指定目录名称时,不要选择已使用的目录名称。如果 在“程序组”文本框中指定了一个名称,当用户安装应用程序时,安装程序会为应用程序创 建一个程序组并使这个应用程序出现在用户的开始选单上。选择“用户可以修改”选项,用 户在安装过程可以更改默认目录的名称和程序组。

图 B.8

·330·

默认目标目录


6.步骤 6—改变文件设置 将一些文件安装到别的目录中,或者更改程序组属性和为用户的文件注册 ActiveX 控件, 如图 B.9 所示。安装向导以表格的形式列出了所有文件,可以通过单击要改变的项来改变设 置。

图 B.9

改变文件设置

下面对一些选项做简单介绍。 (1)文件:用于指定在用户机器上创建文件时使用的名称。 (2)目标目录:设置文件的安装目录。一般文件能够安装在用户机器上的应用程序目录、 Windows 目录或者 Windows 系统目录内。 (3)程序管理器项:如果选择此选项,向导将显示“程序管理器项”对话框,如图 B.9 所示,从中可以指定程序项的属性:说明、命令行和图标。在命令行可以使用嵌入的%s 序列 代替应用程序目录,其中的 s 必须小写。要将程序安装到应用程序子目录中应使用%s,这可 以确保在用户为应用程序子目录指定了不同于默认值的名称时,文件也可以安装到正确的目 录中。例如在下面示例中,把 CUSTOMER.DBF 文件安装到应用程序的 DATA 子目录下,为 此可以键入如下内容:%s\DATA\CUSTOMER.DBF。如果指定了源树之外的图标,安装例程 将在应用程序子目录中安装所有的图标。 (4)ActiveX:如果选择该项,安装程序将在用户的机器上注册 ActiveX 控件。在用户的 机器上不能为该控件注册设计许可权。因此最好使用安装程序注册 ActiveX 控件,以确保用 户使用控件的正确版本。需要强调的是,只有购买了 ActiveX 控件及其许可权,同时在机器 上安装它,Visual FoxPro 6.0 中文版才允许建立或者实例化 ActiveX 控件。许可信息与表单或 类保存在一起,允许在用户机器上运行发布的表单。用户不能在设计时修改这些表单,除非 在代理商那里购买了设计许可权。另外,还可以发布包含 ActiveX 控件的可视类库。基于这 些可视类库的新控件可以添加到运行的表单中,用户不能修改这些可视类库,但是可以在它 们上面建立控件或者子类。当前有两个版本的 ActiveX 控件:设计许可和运行许可。设计许 可版本允许创建新的 ActiveX 控件,运行许可版本允许运行包含 ActiveX 控件的表单。这是 由于许多 ActiveX 控件可能在未收取费用或未被许可的情况下开发和发布。所以大多数控件 需要经过设计,在未被许可的情况下使 ActiveX 控件失效。 ·331·


7.步骤 7—完成 最后一个步骤是完成对话框,如图 B.10 所示。当单击“完成”按钮时,安装向导将记录 下可以在下次从发布树中创建发布磁盘时使用的配置值,然后开始创建应用程序磁盘映像。 在向导创建了指定的磁盘映像之后,可以把映像复制到主盘上,然后复制其他磁盘的内容并 把它们组合成发布包。在建立一系列的主盘之后,可以删除磁盘映像子目录。不过最好请保 存 COMPRESS 子目录,这样在以后使用安装向导建立新的发布盘时,安装向导只需压缩改 变的文件,这可节约很多时间。

图 B.10

完成

注意:第 1 次运行向导时将建立并且压缩几个文件M,并保存这些文件,以便再次使用 安装向导时使用。因此首次运行向导要花费更多的时间。

·332·


附录 C 江苏省 VFP 等级考试(笔试部分) (本试卷考试时间为 120 分钟) 第 1 部分 计算机基础知识(略) 第 2 部分 VFP 6.0 程序设计 一、选择题(用答题卡答题,答案依次填在 21~30 答题号内) 1. Visual FoxPro 是一个 21 。 A. 数据库系统 B.数据库管理系统 C.数据库 D.数据库管理员 2. 实体模型反映实体及实体之间的关系,是人们的头脑对现实世界中客观事物及其相互 联系的认识,而 22 是实体模型的数据化,是观念世界的实体模型在数据世界中的反映, 是对现实世界的抽象。 A.数据模型 B.物理模型 C.逻辑模型 D.概念模型 3. 学生表(XS.DBF)的表结构为:学号(XH,C,8) ,姓名(XM,C,8) ,性别(XB, C,2) ,班级(BJ,C,6) ,用 INSERT 命令向 XS 表添加一条新记录,记录内容为: XH

XM

XB

BJ

10

李小平

984461

下列命令中正确的是 23 。 A. INSERT INTO XS VALUES("10","李小平","男","984461") B. INSERT TO XS VALUES("10","李小平","男","984461") C. INSERT INTO XS(XH,XM,XB,BJ)VALUES(10,李小平,男,984461) D. INSERT TO XS(XH,XM,XB,BJ)VALUES("10","李小平","男","984461") 4. 建立两个表之间的临时关系时,必须设置 24 。 A.主表的主索引 B.主表的主控索引 C.子表的主索引 D.子表的主控索引 5. 下列几组控件中,均为容器类的是 25 。 A.表单集、列、组合框 B.页框、页面、表格 C.列表框、列、下拉列表框 D.表单、命令按钮组、OLE 控件 6. 在 Visual FoxPro 中创建数据库后,系统自动生成的 3 个文件的扩展名分别为 26 。 A. .PJX,.PJT,.PRG B. .DBC,.DCT,.DCX C. .FPT,.FRX,.FXP D. .DBC,.SCT,.SCX 7. 在 Visual FoxPro 中,创建 27 将不以独立的文件存储。 A. 查询 B. 类库 C. 视图 D. 选单 8. 如果某表单中有一个命令按钮组,且已分别为命令按钮组和命令按钮组中的各个命令 按钮设置了 Click 事件代码,则在表单的运行过程中单击某命令按钮时,系统执行的代码是 28 。 A. 该命令按钮的 Click 事件代码 B. 该命令按钮组的 Click 事件代码 ·333·


C. 先该命令按钮组的 Click 事件代码,后该命令按钮的 Click 事件代码 D. 先该命令按钮的 Click 事件代码,后该命令按钮组的 Click 事件代码 9. 学生表(XS.DBF)的结构为:学号(XH,C,8) 、姓名(XM,C,8) 、性别(XB, C,2)和班级(BJ,C,6) ,并且按 XH 字段设置了结构复合索引,索引标识为 XH。如果 XS 表不是当前工作表,则下列命令中 29 可以用来查找学号为"96437101"的记录。 A.SEEK 96437101 ORDER XH B.SEEK "96437101" ORDER XH C.SEEK "96437101" ORDER XH IN XS D.SEEK 96437101 ORDER XH IN XS 10. 下列说法中不正确的是 30 。 A. 报表包含的 3 个基本带区是指页标头、细节区及总结区 B. 报表的页标头包含的信息在每页报表中出现一次 C. 向报表中放置对象就是在报表设计区中设置需要打印的内容 D. 设计报表时,如果需要可以为报表设置数据环境 二、填空题(请把答案填写在答题纸的相应答题号内,每个答题只占一行) 1. 表达式"ABC">"BC"的值为 (1) 。LEN(ALLTRIM("3.14") )的值为 (2) 。 2. 关系模型是用 (3) 的结构形式表示实体及其实体间的关系。 3. 在多用户环境下,Visual FoxPro 系统以两种锁定方式提供缓冲,即开放式和 (4) 。 4. 一个 OLE 对象可以连接或嵌入到表的 (5) 型字段中。 5. 如果要无条件地废止一个选单项(即让该选单项变成灰色),则在该选单项的“跳过 <expl>”框中键入表达式 (6) 。 6. 使用 SET FILTER TO 命令所设置的过滤器,对 DELETE-SQL 命令、UPDATE-SQL 命 令及 (7) 命令不起作用。 7. 英文缩写 ODBC 的中文含义是 (8) 。 8. 若当前数据库中有一个名为 GBDA 的表,且表中有一个名为 XM 的字段,则利用函 数设置该字段的标题属性为“姓名”的命令为:=DBSETPROP("gbda.xm", (9) ,"姓 名")。 9. 已知自由表 STUDENT 中含有 20 条记录, 执行下列程序段后, N 的值为 (10) 。 程序清单如下: USE STUDENT DELETE NEXT4 SET DELETED ON N=RECCOUNT( ) 10. 要使表单中各个控制的 ToolTipText 属性的值在表单运行中起作用,必须设置表单的 ShowTips 属性的值为 (11) 。 11.设学生表(XS.DBF)中含有:学号(XH,C,8) 、姓名(XM,C,8)和出生日期(CSRQ, D,8)字段,该表所在的数据库的存储过程中有一个求学生年龄的自定义函数 AGE,代码如 下: FUNCTION AGE PARAMETERS dBirthday LOCAL nResult nResult=-1 ·334·


IF NOT EMPTY("dBirthday") nResult=YEAR(DATE() )-

(12)

ENDIF RETUPRN nResult 12. 执行下列命令后: SET EXCLUSIVE OFF USE JS USE XS EXCLUSIVE IN 0 JS 表的打开方式是 (13) ,XS 表的打开方式是 13. 执行下列命令后:

(14) 。

CLOSE TABLES ALL SELECT 0 USE XS ALIAS STU USE JS IN 0 函数 USED("JS")的值是(15) ,函数 SELECT()的值是(16) ,函数 ALIAS() 的值是 (17) 。 14. 在“表单设计器”中设计的表单有一标签控件,如下图所示。根据图中的情况,标 签控件的 AutoSize 属性值为 (18) 、Caption 属性值为 (19) 。

15. 某数据库中有下列所述结构的 2 个表(BRDA 和 MXB) ,并且已创建了一对多关系。 病人档案(BRDA)

病人取药明细情况表(MXB)

字段号

类 型

宽 度

字段名

类 型

宽 度

病历号

C

6

病历号

C

6

姓名

C

8

药品编号

C

8

性别

L

1

单价

N

7,2

年龄

N

3

数量

N

3

联系地址

C

40

日期

D

8

下列的查询语句用于查询病人用药总金额大于 1000 的病人信息(病历号、姓名、总金额), 请完善该语句: SELECT 病历号,姓名,SUM(单价*数量)AS 总金额; FROM brda, mxb; WHERE (20) ; GROUP BY 1; ·335·


HAVING (21) 16. 已知某表单子类 cFrmA 含有一个命令按钮,且命令按钮的 Click 事件代码为: Thisform.Backcolor=RGB(255, 255, 0) 。基于该子类创建并运行表单 FrmA,则单击表单上的 命令按钮后,表单的背景色为 (22) 。如果在表单 FrmA 中重新为命令按钮设置了 Click 事件代码:Thisform.Backcolo=RGB(0, 255, 255) ,则运行该表单后单击命令按钮,表单的背 景色为 (23) 。 注:RGB(255, 255, 0)为黄色、RGB(0, 255, 255)为蓝色。 17. 学生管理数据库中有 2 张表:学生表和成绩表,表结构分别如下。 学生表(XS.DBF)

成绩表(CJ.DBF)

学号

XH

C, 8

学号

XH

C, 8

姓名

XM

C, 8

课程号

KCH

C, 2

性别

XB

C, 2

课程号

KCM

C, 20

出生日期

CSRQ

D

成绩

CJ

N, 3

基于以上 XS 表和 CJ 表创建视图 XSZCJ(学生总成绩) ,有一个按班级号查该班每一个 学生总成绩的表单如下图。

班级号由学号的前 6 位组成,表单中表格控件的 RecordSource 属性值为视图 XSZCJ,该 视图对应的 SELECT-SQL 命令应为: SELECT xs.xh, xs.xm, SUM(cj.cj)AS zcj; FROM xs, cj; WHERE xs.xh=cj.xh; GROUP BY (24) 表格控件的第 3 列( “总成绩” )列控件的 ControlSource 属性值应设置为 (25) 。表单 中组合框对象的 RowSourceType 属性值为 3-SQL,RowSource 属性值为: SELECT DISTINCT SUBSTR(xs.xh, 1, 6)FROM xs INTO CURS xtmp 要求当组合框的内容发生变化时,表格中只显示相应班级的学生总成绩,则组合框的 InterActivateChange 事件的代码应为: LOCAL lsxh lsxh=ALLT(This.Value) SET FILTERTO SUBSTR(xszcj.xh, 1, 6)= (26) ·336·


Thisfrom.Refresh 18. 某公司商品数据库中包含供货商表和商品表,表结构如下所示。 供货商表的表结构

商品表的表结构

字段名

数据类型

宽 度

字段名

数据类型

宽 度

供应商 ID

N

8

产品 ID

N

8

公司名称

C

40

产品名称

C

40

联系人

C

30

供应商 ID

N

8

地址

C

60

类别

C

20

城市

C

10

单位数量

N

6

邮政编码

C

6

单价

N

7,2

电话

C

24

库存量

N

8

商品表的主关键字是“产品 ID” ,供货商表的主关键字是“供应 ID” ,这两个表存在一对 多关系,且所有的商品都是来自已知的供货商。其中主表是 (27) 表。如果要在这 2 个表 之间建立永久关系,则应在主表中以 (28) 字段为索引关键字建立主索引,在子表中以 (29) 字段为索引关键字建立普通索引。 以上 2 个表的部分记录如下所示。建立的参照完整性规则为:更新级联、删除限制、插 入限制。就表中已知的数据而言,如果把供货商表中记录号为 125 的记录的“供应商 ID”字 段值更改为 2037,则商品表中会有 (30) 条记录被更改。 供货商表数据 记录号

供应商 ID

公司名称

联系人

地 址

城市

邮政编码

125

2034

佳佳乐

陈小姐

西大街 10 号

北京

100023

(010)65552222

126

3028

康富食品

黄小姐

幸福街 90 号

北京

100045

(010)65554822

127

3475

福满多

胡先生

前进路 22 号

福州

848100

(0544)5603237

商品表数据 记录号

产品 ID

产品名称

供应商 ID

类 别

单位数量

单 价

库存量

356

11

苹果汁

2034

饮料

每箱 24 瓶

18.00

96

357

20

牛奶

2034

饮料

每箱 24 瓶

19.00

4

358

23

蕃茄酱

3475

调味品

每箱 12 瓶

10.00

120

359

34

麻油

3028

调味品

每箱 12 瓶

21.30

36

360

39

海苔酱

3028

调味品

每箱 24 瓶

21.05

33

361

46

肉松

3028

调味品

每箱 24 瓶

17.00

58

362

50

龙虾

3475

海鲜

每袋 500 克

6.00

308

·337·


附录 D 江苏省 VFP 等级考试上机试卷 (本试卷考试时间为 70 分钟) 一、项目、数据库和表操作 打开软盘根目录中的项目文件 TESTI,在该项目中已有一数据库 SJK。 1. 按如下要求修改 SJK 中 CJ 表(成绩)的结构: (1)设置 KCDH 字段的标题为“课程代号”。 (2)修改 CJ 字段(成绩)使得该字段能容纳 3 位整数和 1 位小数。 (3)设置 CJ 字段(成绩)的有效性规则:要求成绩应在 0~100 之间(包含 0 和 100) 。 (4)添加备注型字段,字段名为 QKSM。 2. 在 SJK 中的 KC(课程)表中按下列表格中的数据添加一条记录: KCDH

KCM

KSS

BXK

XF

11

高等数学

2

.T.

2

3. 在 SJK 的 JS 表和 RK 表之间设置参照完整性:删除级联。 4. 在 TESTI 项目中为 SJK 中的视图 STA 添加说明“任课课程”。 5. 把软盘根目录中的表文件 JSB.DBF 添加为 TESTI 项目中的自由表。 6. 把 TESTI 项目中的自由表 ZYB 的包含状态设置为“排除” 。 二、设计查询和视图 1. 在 SJK 的 JS 表中含有 XIMING (系名) 字段。 在 TESTI 项目中已存在查询 CHAXUNA, 按如下要求设计该查询: 基于 JS 表(教师)查询所有的系名。要求输出字段为 XIMING,查询结果中不允许出现 相同的系名,查询结果按系名的升序排序,查询去向为临时表 XIMING。 2. 已知 SJK 数据库包含 JS 表(教师)和 STA 视图(包含 GH 和课程名字段) ,RK 表中 KSS 字段的含义为“课时数”。在 TESTI 项目中已存在查询 CHAXUNB,按如下要求设计该 查询: 基于 JS 表和 STA 视图查询教师的姓名和所担任课程的课程名。要求输出字段为:GH, XM,KCM,KSS。查询结果按 GH 的升序和 KCM 的降序排列。 三、设计选单 TESTI 项目中已存在选单 MENUI,含有一个选单栏“统计查询” 。利用选单设计器按如 下要求修改选单: (1)在“统计查询(Q)”选单栏之前插入两个选单栏:“系统(S) ” 、 “基本信息输入(I) ” , 并设置这 2 个选单栏的热键分别为 Alt+S 和 Alt+I。 (2)在“系统(S) ”选单栏下创建子选单,如图 1 所示,其中“关闭”和“退出”选单 项均为 VFP 系统选单中的“关闭”和“退出”。 (3)在“关闭”和“退出”选单项之间插入分组线。 (4)在“基本信息输入(I) ”选单栏下创建下级子选单: “教师基本信息”和“学生基本 信息” 。 ·338·


(5)设置“学生基本信息”选单项的结果为“命令” ,内容(要求)为:运行软盘根目录 中的表单文件 FROMA。 (6)设置“学生基本信息”选单项的快捷键为 Ctrl+S,提示信息文本为“维护学生记录”。 修改后的选单运行时显示如图 1 所示。

图1

四、设计表单 根据下列要求修改 TESTI 项目中的表单文件 FROMI,该表单用来查看教师的基本情况, 并且可以按不同方式进行排序,如图 2 所示。

图2

(1)表单居中。 (2)将 Gridl 设置为只读,但能获得焦点。 (3)在表单中添加一个选项按钮组控件,选项按钮的个数为 3,3 个按钮的标题分别为: 工号、职称、基本工资。并将该选项按钮组放置在表单左上角的“排序方式”标签的右侧。 (4)已知 JSB 表(教师)的结构复合索引中已经建立了 3 个索引,索引名及索引表达式 分别为: 索引名

索引类型

索引表达式

JSGH

候选索引

GH

JBGZ

普通索引

JBGZ

ZC

普通索引

ZC

要求当用鼠标单击选项按钮组中某一个选项按钮时,下面表格中的数据按选项按钮指定 的方式进行重新排序,试在选项按钮组的 InteractiveChange 事件中编制相应的事件代码。 (5)在表单上有一个退出命令按钮,试为它编制相应的事件代码,要求当单击该按钮时, 关闭该表单。

·339·

Visual FoxPro 實用教程 (第2版)  

Visual FoxPro 實用教程 (第2版)

Visual FoxPro 實用教程 (第2版)  

Visual FoxPro 實用教程 (第2版)

Advertisement