第十二章:添加查询和报表

创建了应用程序的表和表单之后,您就可以在应用程序中添加查询和报表,并用这些查询和报表选择和显示用户数据。其中的查询可以将结果输出到不同的目标,这样您就可以在应用程序的其他地方使用查询结果。当然,也可以在运行报表时不使用查询。本章着重讲述了一些方法,按照这些方法,您可以使用查询或添加报表,还可以设置查询和报表与用户打交道。

当您在应用程序中使用查询或视图时,实际是在使用 SELECT - SQL 语句。本章说明了在应用程序中使用 SELECT-SQL 语句的各种方法,这里的 SELECT - SQL 语句可以由查询设计器中定义的查询来创建;也可以是由视图设计器定义的视图来创建;还可以在事件代码或过程代码中创建。有关视图的详细内容,请参阅《用户指南》中的第二部分“查找信息”

本章内容要点:

添加查询

添加到应用程序中的查询,可以对数据源进行各种组合,并有效地筛选记录、管理数据并对结果排序。所有这些工作都是用 SELECT-SQL 语句完成的。通过使用 SQL 语句,您可以完全控制查询结果以及结果的存放位置。

一个查询是一条 SELECT-SQL 语句

您可以将 SELECT-SQL 语句添加到过程或事件代码中。有关事件的详细内容,请参阅第四章“深入了解事件模型”

创建 SELECT-SQL 语句

若要创建一个 SELECT-SQL 语句

例如,您可以从 TasTrade 数据库的 Customer 表中,选择 country 字段值为“Canada”的所有记录。

SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = "Canada"

如果您要立即执行上述命令,可以在“命令”窗口中输入该语句。如果想要每个子句在窗口中都占一行,则除最后一行外,将其他各行以分号结尾,这时 Visual FoxPro 会在到达最后一行才处理这条命令。

选择一定数量或一定百分比的记录

在查询的结果集合中,如果只需要其中一定数量或百分比的记录,可以在“查询设计器”或“视图设计器”中,使用“杂项”选项卡上的“列在前面的记录”属性设置数量或百分比,也可以在 SELECT - SQL 命令中添加 TOP 子句。在 TOP 子句中,所允许的数值范围为 1 到 32767;如果使用的是百分数,则范围为 0.001 到 99.99。

例如,如果要选择具有最高总订货量的前10位顾客,可以用 GROUP BY 指定 CUST_ID 字段,来显示每个顾客的合计记录,然后在 ORDER BY 子句中按照 ORDER_AMT 排序。若要得到最高的前十个记录,需要在 ORDER_AMT 上面指定降序排列,从而使具有最高订货量的顾客在结果中最先显示。如果使用升序排列,结果记录则按照订货量由少到多的次序排列,那么在结果集合中选择的前几个记录实际上是订货量最少的。

SELECT TOP 10 *;
 FROM  testdata!customer INNER JOIN testdata!orders ;
 ON  Customer.cust_id = Orders.cust_id;
GROUP BY Customer.cust_id;
ORDER BY Orders.order_amt DESC

指定输出目标以保存查询结果

使用 SELECT - SQL 语句的各个子句,可以指定多种不同的输出目标来保存查询结果。

若要将查询结果输出到 使用此子句
独立的表 INTO TABLE mytable
数组 INTO ARRAY aMyArray
临时表 INTO CURSOR mycursor
活动窗口 TO SCREEN
浏览窗口 如果没有指定其他目标,则用它作默认值。

保存了查询结果之后,您就可以使用命令将存储的结果加以适当组织,以便显示或打印。

将查询结果存储到表、数组或临时表中

查询结果可以存储到表、数组或临时表中,以备它用,例如处理表单以及打印报表和标签。如果只想暂时保存结果,则可将它们发送到数组或临时表中。若要永久保存结果,则应该将它发送到一个表中。

若要指定一个表作为输出目标

下面的示例演示了如何用一个 INTO 子句指定一个表:

SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = "Canada" ;
   INTO TABLE mytable

若要指定一个数组作为目标

下面的示例演示了如何用 INTO 子句指定一个数组。

SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = "Canada" ;
   INTO ARRAY aMyArray

若要指定一个临时表作为目标

以下示例演示了如何用 INTO 子句指定一个临时表。

SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = "Canada" ;
   INTO CURSOR mycursor

如果您创建了一个表或数组,则可以象使用 Visual FoxPro 的其他表或数组一样使用它们。若创建的是一个临时表,则可以浏览其中的内容。临时表在最小的可用工作区中打开。您可以通过在 SELECT-SQL 语句中使用临时表的名称来访问临时表。

以下两个过程说明了两种常用方法,它们将存储在表和临时表中的查询结果包含到应用程序中。

填充表单控件

若要在表单中显示查询结果,可以用表、数组或临时表的内容填充表格、列表框或组合框。

若要用一个表或临时表的内容填充表单中的控件

  1. “表单设计器”中,设计表单,让此表单中包含您要填充的控件。

  2. RowSourceType 属性设置为 3 - SQL 语句。

  3. 在控件的 RowSource 属性中,输入一个包含 INTO TABLE 或 INTO CURSOR 子句的 SELECT - SQL 语句。

若要用一个表或临时表填充表格控件

  1. “表单设计器”中修改表单,其中包含您要填充的控件。

  2. 在表单的 Load 事件中,输入一个包含 INTO TABLE 或 INTO CURSOR 子句的 SELECT - SQL 语句。

  3. 将表格的 RecordSource 属性设置为第二步中建立的表或临时表的名称。

  4. 将表格的 RecordSourceType 属性设置“0 - 表”(对于表)或“1- 别名”(对于临时表)。

在报表或标签中打印结果

如果您的报表或标签需要包含许多组数据,或者它们需要对其中的数据进行排序,那么可以使用 SELECT-SQL 语句的各种子句得到所需要的报表或标签。

若要将结果发送到已有的报表或标签中

以下示例使用了 GROUP BY 和 ORDER BY 子句以及 REPORT FORM 命令:

SELECT * ;
FROM tastrade!customer ;
WHERE customer.country = "Canada" ;
GROUP BY customer.region ;
ORDER BY customer.postal_code, customer.company_name ;
INTO CURSOR MyCursor
REPORT FORM MYREPORT.FRX

下面的示例使用了 LABEL FORM 命令:

SELECT * ;
FROM tastrade!customer ;
WHERE customer.country = "Canada" ;
GROUP BY customer.region ;
ORDER BY customer.postal_code, customer.company_name ;
INTO CURSOR mycursor
LABEL FORM MYLABEL.LBX

尽管 SELECT-SQL 语句是填充报表或标签最灵活的方法,但它不是唯一方法。有关设置报表数据源的详细内容,请参阅本章稍后的“控制数据源”部分。有关如何将报表对象加入到应用程序中的详细内容,请参阅本章稍后的“集成查询和报表”部分。

在窗口中显示结果

如果想要显示 SELECT-SQL 语句的结果,您可以将它们发送到窗口中。浏览窗口是查询结果默认的输出窗口,这样您就可以不包含目标子句。当然也可以把结果发送到 Visual FoxPro 主窗口或者其他活动窗口。

若要在 Visual FoxPro 主窗口中显示查询结果

若要在其他活动窗口中显示查询结果

下面的代码示例定义了一个标题为 Top Customers 的临时窗口,用来显示年订货额超过 $50,000 的公司名。

在窗口中显示查询结果
代码 注释
frmMyForm=createobj("form")
frmMyForm.Left = 1
frmMyForm.Top = 1 
frmMyForm.Width = 130
frmMyForm.Height = 25
frmMyForm.Caption = "Top Customers"
frmMyForm.Show
创建并启动一个临时窗口对象。
SELECT customer.company_name,
  SUM(orders.freight) ;
  FROM tastrade!customer,
  tastrade!orders ;
  WHERE customer.customer_id =
  orders.customer_id ;
  GROUP BY customer.company_name ;
  HAVING SUM(orders.freight) > 5000 ;
  ORDER BY 2 DESC
输入一个 SELECT-SQL 语句。

添加报表和标签

在收集和组织数据之后,您可以向应用程序中添加报表或标签,以将数据打印出来或显示在屏幕上。您可以通过选择数据源来控制报表中所要包含的数据;您还可以创建报表变量配合原始数据的使用。报表变量可以用来保存报表中的一些计算结果和要用到的值。

控制数据源

若要控制报表的数据源,您可以定义一个与报表一起存储的数据环境,或者每次运行报表时在代码中激活指定的数据源。有关使用“数据环境设计器”的详细内容,请参阅第九章“创建表单”

若要
总是使用同一数据源 将表或视图添加到报表的数据环境中。
DO query 命令或 SELECT - SQL 命令添加到报表数据环境的 Init 事件代码中。
使用不同的数据源集合 USE table,USE view,DO query 命令或者 SELECT-SQL 语句添加到 Click 事件代码或其他位于 REPORTLABEL 命令前的代码中。

如果要使用表作为数据源,则其中记录的处理和打印是按照它们在表中出现的顺序进行的。使用报表时,当您只使用表作为数据源时,才可使用别名。如果您使用一个视图或查询作为数据源,并且将别名包含在报表控件中,则报表可能在报表页上重复地显示相同的记录。

控制记录的顺序

可以利用报表所使用的数据源,来控制报表中记录的显示顺序。按照在表、视图或查询中的顺序处理和显示记录。若要在表中排序记录,可以在代码(或报表的数据环境)中建立一个索引。对于视图、查询或 SELECT - SQL 代码,可以使用 ORDER BY 子句排序。如果您不想使用数据源对记录进行排序,唯一可对报表中记录进行排序的方法是利用在数据环境中的临时表上的 ORDER 属性。

控制记录的选取

除了可以控制报表中记录显示的顺序,您还可使用数据源、报表打印选项或两者兼用,来控制输出哪些记录。

若要使用 请添加
视图或查询 “筛选”选项卡上的条件
SELECT - SQL WHERE 或 HAVING 子句
报表设计器 “打印选项”对话框中的设置
REPORT 命令 Scope、FOR 或 WHILE 表达式
筛选索引

保护报表的数据工作期

若要防止其他设计器中对全局数据工作期的更改影响您的报表数据工作期,可以把报表数据工作期设置为私有的。

若要设置私有数据工作期

有关使用“数据环境设计器”的详细内容,请参阅第九章“创建表单”。有关数据工作期的详细内容,请参阅第十七章“共享访问程序设计”

如果想使用图形来显示查询结果,则可用“图形向导”“查询设计器”SELECT - SQL 命令。要使用“查询设计器”或 SELECT - SQL 命令,请参照下面的步骤。在结果集合中,必须至少包含一个数值字段,方可建立图形。对于查询结果,有六种类型的图形可供选择,每个图形都有两个变量。

若要修改图形

  1. 浏览包含该图形的表。

  2. 双击其中的通用字段来显示图形。

  3. 双击该图形打开 Microsoft Graph,显示 Microsoft Graph 工具栏。

  4. 在 Microsoft Graph 中修改图形。

调整页面布局

在报表中,可以定义多个列,也可以改变页面中的带区高度,从而重新设计页面布局。

在页面上定义多个列

如果要建立电话目录,邮件标签或其他类型的列表,可以在每个页面上定义多个列。

若要定义一个多列报表

  1. 从“文件”菜单上,选择“页面设置”。

    带有多列定义的“页面设置”对话框

  2. 在“列”区域中,输入页面所需的列数目,该数目就是一页上显示的记录列数。

  3. 在“宽度”框中,输入列的宽度值。

  4. 在“间隔”框中,输入所需要的列间距。

    提示 如果要在一个新页上显示分组记录,请不要使用“打印顺序”选项。

  5. 选择“确定”。

    “报表设计器”将反映出设置的改变。

如果在页面布局改变以前,“细节”带区中已经包含了报表控件,则布局改变后可能需要重新移动控件或改变控件的尺寸,以适合新列的边界。

设置报表带区的高度

在设计报表时,可以改变报表带区的高度。报表带区的高度是指一个报表带区可用的页面空间(在页边距的范围内)。例如,如果“标题”带区设置为 1.5 英寸,则“标题”将在顶部页边距下的 1.5 英寸区域内显示。细节带区指定每个要显示的记录所需要的区域。下面有关带区高度的信息对所有的报表带区都适用。对于“组标头”带区和“组注脚”带区,还可以设置附加的参数。有关分组带区的详细内容,请参阅《用户指南》第七章“设计报表和标签”中的“按布局分组数据”一节。

若要精确设置带区的高度

  1. 双击相应带区的条形栏。

    将出现一个与该带区对应的对话框。

  2. 在“高度”框中,输入所需的高度值。

  3. 选择“确定”。

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

在报表或者标签中,可以包含域控件来显示一些表达式 — 比如,表或视图的字段、内存变量,以及他们之间的运算值等。下面将对多个字段、日期和页号这些常用的表达式和函数一一描述。

添加域控件

可以使用几种方法来添加域控件。

若要从数据环境中添加表字段作为域控件

  1. 打开报表的数据环境。

  2. 选择一个表或视图。

  3. 将字段拖拉到页面中。

若要从工具栏中添加表的字段作为域控件

  1. 从“报表控件”工具栏中,插入一个域控件。

  2. “报表表达式”对话框中,选择“表达式”框后的对话按钮。

  3. 在“字段”框中,双击所需要的字段名。

    则表名和字段名将出现在“报表字段的表达式”框中。

    注释 如果“字段”框中为空,请向数据环境中添加一个表或视图。

    在表达式中,不必保留表的别名。可以删除表的别名,也可清除“表达式生成器”选项。

  4. 选择“确定”。

  5. 在“报表表达式”对话框中,选择“确定”。

在输入表达式后,可以改变格式,也可设置打印、位置或伸展等选项。有关详细信息,请参阅《用户指南》第七章“设计报表和标签”中的“为报表控件添加注释”和本章稍后的“为控件设置打印选项”

插入由字段连接构成的域控件

把表的字段添加到报表中之后,您可能注意到,这些字段没有按照在页面上所希望的方式显示。例如,在分别显示 City、Region 和 Postal Code 这些字段的域控件时,会在每个值之间产生一些不必要的空格。您可以将这些字段连接成一个域表达式,同时删除多余的空格。每个控件对应值所需的空间可能不同,这时可适当调整控件。

若要将几个表字段连接成一个域表达式

  1. 从“报表控件”工具栏中,插入一个域控件。

    提示 将域控件的大小设为表达式求值后所必须的最小值。您可以设置控件,使它能够在表达式求值后需要更多的空间时自动伸展;如若所需空间较小,则控件不会缩小。但控件所占的空间不会比在设计时设定的更小。

  2. 在“报表表达式”对话框中,选择“表达式”框后的对话按钮。

  3. “表达式生成器”中,从“字符串”框中选择 ALLTRIM(expC)。

    该字符串函数出现在“报表字段的表达式”框中,同时选定了 expC

  4. 双击想要在控件中显示的第一个字段名字。

    该字段名字将代替“报表字段的表达式”框中的 expC

  5. 在字段名后键入一个 + 号,也可从“字符串”函数框中选择一个 + 号。

  6. 输入文字或者从字符串函数列表中选择文字,然后键入一个逗号。

  7. 重复上面的第三步和第四步来处理其他的字段,直至完成表达式,再选择“确定”。

  8. 在“报表表达式”对话框中,选择“溢出时伸展”。

    在显示报表时,若设计时设定的控件的大小不够包含其中的表达式的值,则控件自动向后伸展,直至完全能够显示整个值。有关“溢出时伸展”的详细内容,请参阅本章后面的“打印变长度值的控件”

为了将几个字段合为一个表达式,对每个字段名前使用 ALLTRIM( ) 函数,在引号中加入标点符号,而每个表达式元素之间用 + 号连接。如果字段值长度不变(象邮政编码和某些缩写),则可以象下例中那样只插入字段名字:

ALLTRIM(city)+", "+region+"  "+postal_code

注意在引号中是空格,而不是逗号。这些空格是用来分隔地区字段和邮政编码字段的。

若要获得更多的示例,请参阅 Solution 示例中的 INVOICE.FRX 报表。

裁剪及合并字符表达式

在“表达式生成器”中,要想快速裁剪及合并字符表达式,可以使用逗号分割字符表达式,则逗号之前的表达式求值后多余的空格被裁剪去。若使用分号,则除了裁剪多余的空格外还使显示另起一行,但要求被裁剪后的值不能为空。下面的示例说明在邮件地址域中的字符表达式:

contact_name; address; city, region, postal_code

注释 如果您不想在显示值时包含标点,可使用上面的方法。

当使用这些方法时,需保证该域控件已被设置为“溢出时伸展”。有关详细内容,请参阅本章后面的“打印变长度值的控件”

插入当前日期

可以插入一个域控件显示当前日期。

若要插入当前日期

  1. 从“报表控件”工具栏中,插入一个域控件。

  2. “报表表达式”对话框中,选择“表达式”框后的对话按钮。

  3. “表达式生成器”中,从“日期”列表中选择 DATE( )。

  4. 选择“确定”。

  5. 在“报表表达式”对话框中,选择“确定”。

插入一个页码

每一页的页标头带区或者页注脚带区通常会包含一个页码。如果使用向导或快速报表,页码会自动插入页注脚带区中。

若要插入一个页号

  1. 从“报表控件”工具栏中,插入一个域控件。

  2. “报表表达式”对话框中,选择“表达式”框后的对话按钮。

  3. “表达式生成器”中,从“变量”列表中选择 _pageno。

  4. 选择“确定”。

  5. 在“报表表达式”对话框中,选择“确定”。

    提示 使用如上过程,可以向报表中插入任意一个变量列表中的系统变量。

定义报表变量

若要在报表中操作数据或显示计算结果,您可以使用报表变量。使用报表变量,可以计算各种值,并且可以用这些值来计算其他相关值。

若要定义报表变量

  1. 请打开或创建一个报表。

  2. 从“报表”菜单中选择“变量”命令。

  3. “报表变量”对话框中,选择“变量”框并键入一个变量名。

  4. 在“要存储的值”框中,键入一个字段名或其他表达式。

  5. 如果需要,选择一个计算选项。

  6. 如果需要,在“初始值”框中键入一个设置初始值的表达式。

  7. 选择“确定”按钮。

在此之后,您便可以在报表的任何表达式中使用此变量。

若要统计 Company 表中所有的 Canadian 项,可以使用以下表达式并选择记数作为计算选项。

IIF(country="Canada",1,0)

下表列出了三个变量,用于显示一张简明时间表。

要存储的值 创建的变量 使用的表达式
雇员到达时间
tArrive
hour_in + (min_in / 60)
雇员离开时间
tLeave
hour_out + (min_out / 60)
雇员出勤时间
tDayTotal
tLeave - tArrive

您可以在其他各种计算中使用 tDayTotal 变量,例如计算一周、一月或一年的工作小时数以及平均日工作小时数等等。

关于报表变量的示例,请参阅 Solutions 示例中的 PERCENT.FRX 和 INVOICE.FRX 报表。

重新排序报表变量

报表变量是根据它们出现的先后顺序来计算,并且会影响引用了这些报表变量的表达式的值。例如,如果用变量 1 定义变量 2 的值时,那么变量 1 应该在变量 2 之前出现。例如,在前一个示例中,tArrive 和 tLeave 就必须在 tDayTotal 之前出现。

若要更改报表变量的顺序

  1. 请从“报表”菜单中,选择“变量”。

  2. 在“变量”框中,拖动变量左边的按钮,重新调整顺序。

  3. 选择“确定”按钮。

设置变量的初始值

如果在计算中使用了一个变量,一定要用非零值初始化变量,以防出现除数为零的错误。如果没有指定值,则由 Visual FoxPro 指定默认值 0。

若要设置变量的初始值

  1. 请从“报表”菜单中,选择“变量”。

  2. 在“变量”框中,选择要设置的变量。

  3. 在“初始值”框中,输入值。

  4. 选择“确定”按钮。

当您重新设置了报表中分组的优先顺序时,系统不会根据正确的字段重置报表变量。例如,如果您的报表中有两个组,第一次分组依据国家/地区分组,而第二次分组依据日期分组,当您交换了分组顺序时,变量却仍然根据原来的分组顺序重置。

通过指定变量何时重置可以更改计算的结果。默认情况下,Visual FoxPro 在报表尾重置报表变量。

若要在报表尾、页尾或列尾重置变量

  1. 请从“报表”菜单中,选择“变量”。

  2. 在“重置”框中,选择某一选项。

  3. 选择“确定”按钮。

若要在带区的入口或出口处重置变量

  1. “报表设计器”中,打开报表。

  2. 双击报表带区栏。

  3. 在带区对话框的“运行表达式”中,选择“入口处”或“出口处”框后的对话按钮。

  4. 输入表达式以便每次进入或退出该带区时重置变量。

设置域控件的格式

在插入一个域控件后,可以改变控件的数据类型和显示格式。数据类型可为:字符型、数值型或日期型。每个数据类型都有自己的格式选项,其中包括了用户建立自己的格式模板的选项。当打印报表或标签时,格式可以控制字段的显示方式。

可以在“报表表达式”对话框的“表达式”框中直接输入格式函数,也可以在“格式”对话框中进行选择。

下面列出一些可能遇到的典型情况:您可能需要将所有的输出字母转化为大写,也可能需要用逗号或小数点分隔数值型的输出,或用货币格式显示数值型的输出,或将日期类型的输出转化为其他格式等等。

设置报表控件的格式的选项

在域控件中,可以对每种数据类型设置不同的格式选项。

若要设置一个域控件的格式

  1. 选择“域控件”。

  2. “报表表达式”对话框中,选择“表达式”框后的对话按钮。

  3. 在“格式”对话框中,为该字段选择数据类型:“字符型”、“数值型”或“日期型”。

    “编辑选项”区域将会显示该数据类型下的各种格式选项。

    注释 此处选择的数据类型只反映该报表控件中表达式的数据类型,不会改变相应表中字段的数据类型。

  4. 选择对齐方式和所需的格式选项。

“格式”对话框“编辑选项”区域中所显示的选项根据您所选定的数据类型的不同而不同。通过在“格式”框中键入字符,还可以建立一个格式模板。

在域中对齐文本

在域中对齐文本不会改变控件在报表上的位置,只是在控件内对其内容进行格式调整。有两种方法可以调整控件中内容的位置。

直接在域控件中调整文本对齐

  1. 选择要更改的控件。

  2. 在“格式”菜单中,选择“文本对齐方式”。

  3. 从该子菜单中,选择合适的选项。

在域中调整文本对齐

  1. 选择“域控件”。

  2. “报表表达式”对话框中,选择“格式”框后的对话按钮。

    数值表达式的格式对话框

  3. 在“格式”对话框中,选择该字段的数据类型:“字符型”、“数值型”或者“日期型”。

  4. 选择对齐格式和所需的格式选项。

定义域格式模板

格式模板允许您自定义域中数据的格式。在“报表表达式”对话框的“格式”框或者“格式”对话框里输入一系列普通字符或代码,就可以建立各种打印格式。输入的普通字符将与域中的值一同出现在域中,而输入的代码则用来确定字段输出的外观。例如,如果为一个十位数的数值字段指定如下的格式模板,那么,象括号、空格和破折号这样的字符将和数值型数据一起打印。

格式模板 显示的输出
(999) 999-9999 (123) 456-7890

例如,可使用如下模板来显示一个电话号码。

格式模板 显示的输出
(999) 999-9999 (123) 456-7890

改变字体

对于每个域控件或标签控件,可以改变字体和文本的大小。您还可改变整个报表的默认字体。

若要在一个报表中改变字体和字号

  1. 选择控件。

  2. 选择“格式”菜单中的“字体”。

    这时出现“字体”对话框。

  3. 选择合适的字体和大小,然后单击“确定”按钮。

若要更改默认的字体

  1. 选择“报表”菜单中的“默认字体”。

  2. 在“字体”对话框中,选择需要作为默认值的合适字体和大小,然后单击“确定”按钮。

    只有在改变默认字体后插入的控件才反映出新的字体设置。对于现有的对象,须将它们全部选定,然后再使用“格式”菜单上的“字体”选项更改设置。

裁剪、缩放一个图片或 OLE 对象

对于建立的控件边框,插入其中的图片或 OLE 对象可能不会刚好合适。默认情况下,该图片或 OLE 对象将保持原有的大小。也可以将它们裁剪或按比例缩放,使之和控件的大小相适应。

如果图片或 OLE 对象比“报表设计器”中建立的框架大,那么,只有部分的图片或 OLE 对象显示出来。显示从图片或 OLE 对象的左上角开始,其超出边界的右下部分将看不到。

若要使图片正好与边框大小相符

  1. “报表设计器”中,建立一个“图片/ActiveX 绑定控件”

  2. “报表图片”对话框中,选择“缩放图片,保留形状”选项。

这时,整个图片显示出来,并保持原有的比例,尽可能的和控件框架相适应。这可防止图片的横向或纵向变形。

若要使图片添满整个边框(图片的比例可能改变)

  1. 在“报表设计器”中,建立一个“图片/ActiveX 绑定控件”。

  2. 在“报表图片”对话框中,选择“缩放图片,填充图文框”。

整个的图片将按照所定义的边框大小进行填充。如果必要的话,为了和边框的大小相适应,图片可能会在在横向或者纵向发生变形。

如果要查看带有图片的报表示例,请参阅 Solutions 示例中的 WRAPPING.FRX 报表。

将一个 OLE 对象居中放置

在通用字段中的 OLE 对象具有可变的形状和尺寸。如果在通用字段中的 OLE 对象比控件的框架小,它将位于框架的左上角。您应将其居中放置,这样可保证比控件框架小的所有对象都能放在控件的中央。由于存储在文件中的图片的形状和尺寸固定,因此无须居中放置。

若要居中放置通用字段中的 OLE 对象

  1. “报表设计器”中,建立一个“图片/ActiveX 绑定控件”

  2. “报表图片”对话框中,选择“图片居中”。

当预览打印结果或者打印报表时,OLE 对象在相应区域内居中显示。

改变报表控件的颜色

可以改变字段、标签、线条或者矩形的颜色。

若要改变颜色

  1. 选择要更改的控件。

  2. 在“调色板”工具栏上,选择“前景色”或者“背景色”。

  3. 选择所需的颜色。

将报表另存为 HTML

创建报表时,使用“文件”菜单上的“另存为 HTML”命令可以将表单的内容另存为 HTML(超文本标记语言)文件。

若要将报表另存为 HTML

  1. 打开报表。

  2. 选择“文件”菜单上的“另存为 HTML”命令。(如果报表已被修改,系统将提示您进行保存。)

  3. 单击对话按钮,输入要创建的 HTML 文件名,然后选择“保存”按钮。

控件设置打印选项

总的来说,控件的布局和它所处的带区的位置决定了控件打印时的位置和时间。除此之外,还可以为每个控件设置特定的打印选项。每个控件都有一个默认的尺寸,该尺寸或是由它的值(对于字段或标签来说)决定,或是在创建控件的时候确定(对于线条、矩形或者图形来说)。控件在页面上的长度指定了该控件的显示宽度。由于有些控件的值根据记录的不同而不同,您可将控件的高度设置为可向下伸展,以显示整个的值,否则,有些数据将在显示的时候将被截断。除了标签控件之外,所有的控件的大小均可变。

打印变长度值的控件

为了使控件尽可能少的占用报表的空间,可将其设置为可伸展的。例如,一个表达式的值可能依记录的不同而不同,这时,最好不要在报表上为这个控件分配一个固定的可容最长记录值的空间,而应将控件设置为可伸展,即可容纳所有的数值。对于该控件下方的控件,可将其设置为可向下浮动的。

设置为可伸展和可浮动的控件示例

伸展选择项适用的控件包括域、垂直线、矩形和圆角矩形。

若要查看可伸展和可下移的控件示例,请参阅 Solutions 示例中的 WRAPPING.FRX 报表。

若要将域设置为可按值自动伸展的

  1. 双击该域控件,以显示它的对话框。

  2. 选择“溢出时伸展”。

和可伸展控件相邻的控件必须设置为可浮动的,否则这些控件会被覆盖。

若要将控件设置为可浮动的

  1. 双击该控件,显示它的对话框。

  2. 在控件的对话框中,选择“浮动”。

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

可以将线条、矩形和圆角矩形设置为溢出时伸展。它们一方面可根据带区的大小来伸展;另一方面,如果它与其他控件构成一个控件组,它可根据组中最大的控件伸展。

若要将线条或者矩形设置为可伸展

  1. 双击该控件,显示它的对话框。

  2. 在“向下伸展”区域中,选择某一项。

要打印某个可伸展控件的边框

  1. 在可伸展控件周围画一个矩形。

  2. 双击该矩形,显示“矩形/线条”对话框

  3. 在“向下伸展”区域中,选择“相对于组中最高的对象伸展”选项。

  4. 选择“确定”。

  5. 拖出一个选择框,使之包含整个矩形。

  6. 从“格式”菜单中,选择“分组”。

这时,选择控制点出现在矩形的四个角上。从现在开始,可以将其内的所有控件作为一个整体处理,该矩形将和可伸展的域一起伸展。无论域中的值如何向下伸展,矩形框将始终包围在域的外面。可以在页面中并排放置两个这样的组,它们之间互不影响。

在可伸展控件的下方显示另一个控件

  1. 在页面中,将一个控件插入到另一个下面。

  2. 双击控件顶部,显示该控件的对话框。

  3. 在“对象位置”区域中,选择“相对于带区顶端固定”,然后单击“确定”按钮。

  4. 双击下面的控件,显示该控件的对话框。

  5. 在“对象位置”区域中,选择“浮动”,然后单击“确定”按钮。

这两个控件中的数值将完整的显示,不会相互覆盖。

设置一个控件的打印选项

在报表中,可以对控件的打印时间和方式进行控制。有关控件打印选项的详细内容,请参阅“打印条件”对话框

不输出重复值

对于域控件,不连续输出记录的重复值。也就是说,如果某域中的同一个值在数个记录中重复出现,则只须在第一次出现时打印该值,在后面的记录中不打印该值,直至数值发生改变。例如,如果要打印一个发票,其中包含事务的日期字段,对于相同日期的事务,可以只打印一次日期。

若要不输出重复值

  1. 双击该控件,显示控件的对话框。

  2. 选择“打印条件”以显示“打印条件”对话框。

    “打印条件”对话框

  3. 在“打印重复值”的区域,选择“否”,然后“确定”。

若要在同一页(或列)中不打印重复值,换页(或列)后,遇到第一个新记录时,打印重复值

  1. 双击该控件。

  2. 选择“打印条件”。

  3. 在“打印重复值”的区域,选择“否”。

  4. 在“有条件打印”的区域中,选择“在新页/列的第一个完整信息带内打印”,然后选择“确定”。

当细节带区内容溢出到新页(或列)中时,输出重复值

  1. 双击该控件。

  2. 选择“打印条件”。

  3. 在“有条件打印”的区域中,选择“当细节区数据溢出到新页/列时打印”,然后选择“确定”。

建立打印表达式

可以为控件设置表达式,该表达式在打印之前被计算出来。如果表达式的值为“假”(.F.),则不打印该字段。添加表达式之后,在“打印条件”对话框中除了“若是空白行则删除”选项外,其他选项全部无效。

如果要查看“打印条件”的示例,请参阅 Visual Studio …\Sample\Vfp98\Solution\Reports 目录中的报表 Colors.frx 和 Ledger.frx。

若要添加一个打印表达式

  1. 双击该控件。

  2. 选择“打印条件”。

  3. 在“仅当下列表达式为真时打印”框中,输入一个表达式。

    - 或者 -

    单击对话按钮,使用“表达式生成器”建立一个表达式。

不打印空行

对于报表中的某些域控件,记录中往往会没有数值。默认情况下,Visual FoxPro 将为那些空的域保留区域。您可以将这些空白的区域清除,使所显示的信息更为理想、更为连续。

若要不打印空行

  1. 双击在报表中可能会引起空行的控件。

  2. 选择“打印条件”。

  3. 选择“若是空白行则删除”。

如果一行中所有域的值经计算后都为空,则 Visual FoxPro 从报表中删除此行。如果不打印该域,或者域中的值为空,Visual FoxPro 将会检查该行的其他控件:找不到的话,此行被删除。如果没有选择该选项,而且该行中没有其他的控件,那么会打印一个空行。

为组设置打印选项

在报表中,可以对组的打印方式进行控制。有时可能希望同一个组中的内容不要跨页显示;有时可能希望控制何时打印组标头。

设置组的分页

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

选择一个组标头选项

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

在输入表达式之后,可以从“组属性”区域选择这些选项。

防止出现孤立的组标头

有时,一个组可能会分别打印在两页上,组的标头打印在前一页上,而组的大多数内容在另外一页上。为了避免这种情况,可以设置打印时组标头到底部的最小距离。如果标头和底部的相对位置比所规定的尺寸(用英寸或厘米表示)要小,Visual FoxPro 会将标头移到新的一页中打印。

若要防止出现孤立的组标头

  1. 从“报表”菜单中,选择“数据分组”。

  2. “数据分组”对话框中,在“小于右值时组从新的一页上开始”框中选择或输入您设定的值。

    提示 为了给孤立控件确定一个比较理想的值,可以将组标头带区的高度扩大到细节带区高度的一至三倍。

当组改变时,打印忽略的值

如果已经设置了不输出重复值,但当某个特殊的组发生变化,需要将重复值输出。

当组发生变化时,若要打印重复值

  1. 双击该控件,显示控件的对话框。

  2. 选择“打印条件”按钮显示“打印条件”对话框。

  3. 选择“当此组改变时打印”。

    为报表所定义的组会出现在框中。

  4. 从框中选择一个组,然后选择“确定”。

重复输出组标头

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

若要在下一页上重复组标头

控制报表和标签的输出

使用 REPORTLABEL 命令的下列某一关键字,可以控制报表和标签输出的地方:

如果您不使用任何关键字,报表将输出到屏幕或活动窗口中。

选择要打印的记录

在打印一个报表时,若要限制在报表中出现的记录数量,可以使用筛选条件:

可以任意组合使用上述方法,使用 WHILE 表达式将忽略其他的条件。

打印一定数量或者范围内的记录

限制记录数目的一种方法是指定一定数量或者一定范围内的记录。使用“作用范围”选项,可以在文件中选择单个记录或者一组连续存放的记录。

注释 活动的索引或者当前记录的指针会影响 Scope 子句中 Next 和 Rest 选项。例如,在一个表中,按照 last name 字段索引的下个记录和按照 state 字段索引的下个记录可能会不同。但 Record 选项不会受影响,这是因为当表被索引之后,表中每个记录号码并不会变化。

若要选择一定数目的记录

  1. 从“文件”菜单中,选择“打印”。

  2. 在“打印”对话框中,选择“选项”。

  3. 在“打印选项”对话框中,选择“选项”。

    “报表和标签打印选项”对话框

  4. 在“报表和标签打印选项”对话框中,选择“作用范围”。

  5. 选择合适的“作用范围”选项。
    若要打印 请选择该范围选项
    源文件中的所有记录 ALL
    从第一个记录开始的一定范围的记录 NEXT
    由记录号码指定的某个记录 RECORD
    当前记录到文件尾部的所有其他记录 REST

    Visual FoxPro 使用您选择的记录范围内的数据打印报表。

打印满足某个条件的记录

如果所要选择的记录在表中不连续,可以建立一个逻辑表达式指定记录的筛选条件,只有满足条件的记录才打印。例如,可以打印某个记录字段值为特定值的所有记录。

若要输入选择记录的条件

  1. 从“文件”菜单中,选择“打印”。

  2. 在“打印”对话框中,选择“选项”。

  3. 在“打印选项”对话框中,选择“选项”。

  4. 在“报表和标签打印选项”对话框中,选择“作用范围”。

  5. 在“For”框中输入一个 For 表达式。

    - 或者 -

    确认所有报表所需的记录源全部都已打开,然后选择“For”对话按钮,使用“表达式生成器”

    注释 在表达式中,无须包含 FOR 命令。例如,键入 country = "Canada" 查看所有的加拿大数据。

    Visual FoxPro 计算所有的记录值,然后使用这些满足条件的记录打印报表。

控制将打印记录的选择范围

使用 WHILE 表达式也可控制报表的打印。实际上,Visual FoxPro 在真正打印报表之前首先从数据源中选择符合条件的记录。如果条件中包含WHILE 表达式,那么 Visual FoxPro 在选择数据时不断地对该表达式求值。若表达式为真,则继续选择;一旦表达式为假,则停止选择过程,并打印前面选择的所有数据。WHILE 表达式允许我们使用数据源字段值以外的信息控制打印记录的选取。

提示 如果在没有经过适当索引的文件上使用 WHILE 表达式,可能会忽略某些记录,因为有可能还没有查看完所有合适的记录,选择处理过程就结束了。因此若使用了 WHILE 表达式,在打印报表之前,须确保数据源表经过了适当的索引。

若要输入停止记录选择的筛选条件

  1. 从“文件”菜单中,选择“打印”。

  2. 在“打印”对话框中,选择“选项”。

  3. 在“打印选项”对话框中,选择“选项”。

  4. 在“报表和标签打印选项”对话框中,选择“作用范围”。

  5. 在“While”框中输入一个 WHILE 表达式。

    - 或者 -

    选择“While”对话按钮,使用“表达式生成器”

    注释 在表达式中,无须包含 WHILE 命令。例如,键入 sales > 1000,可查看销售额在 1000 美元以上的记录。

    Visual FoxPro 在表达式为真时选取记录,然后使用这些记录打印报表。

打印报表和标签

若要把报表送到打印机,可以将它直接输出到打印机,也可以先显示“打印设置”对话框。

若要将报表送到打印机

例如,以下代码把报表 MyReport 发送到默认打印机,而不在屏幕上输出:

REPORT FORM MYREPORT.FRX TO PRINTER NOCONSOLE

若要在将报表发送到打印机之前显示“打印设置”对话框

例如,以下代码显示“打印设置”对话框,然后发送报表 MyReport 到默认打印机,而不在活动窗口中显示:

REPORT FORM MYREPORT.FRX TO PRINTER PROMPT NOCONSOLE

预览报表和标签

如果要预览报表,您可以将它发送到报表设计器中的“打印预览”窗口。

若要预览报表

例如,下面的代码可以将报表在一个模式窗口中显示出来:

REPORT FORM MYREPORT.FRX PREVIEW

默认情况下,“预览”窗口是一个模式窗口,但可以访问“打印预览”工具栏。若要将预览窗口设置成为非模式窗口,您可以在 REPORT 命令中添加关键字 NOWAIT。

例如,下面的代码可以在一个非模式窗口中显示报表:

REPORT FORM MYREPORT.FRX PREVIEW NOWAIT

如果想在指定的窗口中预览结果,可以使用 WINDOW 子句指定这个窗口,该窗口或是一个表单、或是一个用 DEFINE WINDOW 命令建立的窗口。

REPORT FORM MYREPORT.FRX PREVIEW WINDOW MYPREVIEWFORM

将报表打印到文件中

若要创建报表的电子文件,您可以将它发送到一个打印机格式文件中,或者发送到一个 ASCII 文件中。把报表发送到文件中,可以方便以后使用打印机成批打印。

若要创建 ASCII 文件,可以创建一个仅包含文本、虚线和加号以代表线条和形状的文件。文件中不包含对字体和颜色的设置。还可以指定每行的字符数和每页的行数。

若要将报表打印到 ASCII 文件

下面的示例为 ASCII 页定义了几个变量,然后将一个名为 Myreport.frx 报表打印到名为 Myfile.txt 的 ASCII 文件中。

打印到 ASCII 文件
代码 注释
_asciirows = nLines
定义每页行数
_asciicols = nChars
定义每行字符数
REPORT FORM MYREPORT.FRX
  TO FILE MYFILE.TXT ASCII
运行报表

将报表另存为 HTML

创建或修改报表时,使用“文件”菜单上的“另存为 HTML”命令可以将报表内容另存为 HTML (超文本标记语言)文件。

若要将报表另存为 HTML

  1. 打开报表。

  2. 选择“文件”菜单上的“另存为 HTML”命令。此命令仅当报表已保存在磁盘上时才可用。

  3. 单击对话按钮,输入要创建的 HTML 文件名,然后选择“保存”按钮。

集成查询和报表

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

集成查询和报表的方法

您可以将执行查询或报表的代码添加到应用程序的下列对象中:

若要添加查询、视图或程序

例如,可以添加与下列代码类似的代码:

DO MYQUERY.QPR
DO MYPROGRAM.PRG
USE myview

将报表集成到应用程序中,有以下几种选择:

若要运行报表和标签

例如,您可以使用如下类似代码:

REPORT FORM MYREPORT.FRX
LABEL FORM MYLABEL.LBX

若要修改报表和标签

例如,可以添加如下类似代码:

MODIFY REPORT MYREPORT.FRX
MODIFY LABEL MYLABEL.LBX

若要创建报表和标签

例如,您可以使用如下类似代码:

CREATE REPORT MYREPORT.FRX
CREATE LABEL MYLABEL.LBX

用查询收集用户输入

如果想从表单中收集值,可以在 SELECT - SQL 语句中使用变量,然后在该语句中立即使用它们,或者以后再执行该 SELECT-SQL 语句。

若要收集立即使用的值,在 SELECT - SQL 语句中,您可以使用表单的名称引用一个表单,也可以使用一个快捷引用。在下面的示例里,WHERE 子句中使用了快捷引用。

在 SELECT-SQL 语句中使用快捷引用收集值

代码 注释
SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = ;
    THISFORM.ControlName1.Value ;
   AND customer.region = 
THISFORM.ControlName2.Value ;
   GROUP BY customer.postal_code ;
   ORDER BY customer.postal_code, 
customer.company_name



THISFORM 是当前活动表单的快捷引用。请用实际的控件名替换 ControlName1ControlName2

如果不想使用控件的引用,可以在代码中定义变量。使用变量存储从表单得到的值,这样,以后即便表单已被释放,您仍可以通过变量使用那些从表单中得到的用户输入。

收集值以备后用

代码 注释
cValue = THISFORM.ControlName.Value
定义变量。
SELECT * ;
   FROM tastrade!customer ;
   WHERE customer.country = cValue ;
   GROUP BY customer.postal_code ;
   ORDER BY customer.postal_codecustomer.company_name
在 SELECT-SQL 语句中使用已定义的变量。

若没有在运行查询之前定义变量,则会出现“找不到变量”的错误信息。如果变量没有在代码中定义,则 Visual FoxPro 假定变量在代码运行前已经初始化。