Crystal Reports是目前国内应用得比较普及的报表工具。该工具随Visual Basic和Visual C++提供给用户,许多数据库软件设计者都把它作为报表设计的首选工具。Crystal Reports的基本功能很强大,但是用户对于报表内容和格式的要求往往更高,特别是对于不同条件下的累计,这时候就需要利用Crystal Reports的公式功能来增强报表功能。
目前国内用户使用的Crystal Reports主要有两个版本:一个是随Visual Basic 5.0/6.0提供的Crystal Reports 4.6,另一个是可以从http://www.seagatesoftware.com/免费下载的Crystal Reports 6.0(注:现在这个免费版本已经不能从该站点下载了。)。两者在使用上略有不同,所以我们分别加以介绍。
Crystal Reports 4.6版本提供一个独立的报表设计器。在这个报表设计器中,用户可以设计、修改和打印报表。插入公式的方式同插入数据库字段类似,选择菜单Insert|Formula Field项,这时会出现图1所示的对话框。这个对话框中将列出当前报表的所有公式。如果你想建立一个新的公式,可以为这个公式起一个新的名字。
图1 在设计报表时,插入公式
如果你要建立新的公式,Crystal Reports会接着显示图2所示的对话框。对话框上方的三个列表框显示可以在公式中使用的数据库字段、函数和操作符。Crystal Reports的公式中只能使用Crystal Reports定义的语法,其语法同Visual Basic有许多不同之处,我们将在下面的“Crystal Reports公式语法”中详细介绍。输入公式之后,选择Check按钮,可以检查公式语法是否正确。如果正确,按Accept按钮完成公式的修改。
公式可以象其他字段一样放置在报表的各个部分,也可以象其他字段一样指定格式、字体等,也可以进行求和等累计操作。
图2 编辑公式的对话框
Crystal Reports 6.0是Crystal Reports 4.6的一个替代版本。该软件的工作方式同Crystal Reports 4.6有较大差别,而比较接近另一个著名的报表工具ActiveReports以及Visual Basic 6.0的Data Reports。相比较而言,它较Crystal Reports 4.6有比较大的提高,又比Data Reports易于使用和控制,而且还是免费的,所以建议Crystal Reports 4.6的用户升级到这个版本。
Crystal Reports 6.0没有独立的设计工具,要设计报表需要从Project菜单中选择Add ActiveX Designer|Crystal Reports 6.0启动Crystal Reports Expert。在默认情况下,Crystal Reports Expert将建立一个Crystal Reports报表并建立一个窗体用来预览和打印报表(图3)。为了建立一个新的公式,先从报表设计窗口的左侧的列表中选择Formula Fields右击(图4),从菜单上选择New就可以建立新公式。编辑和使用公式的步骤同Crystal Reports 4.6类似。
Crystal Reports 6.0还支持Format事件,允许用户在事件代码窗口中填写Visual Basic代码以便在打印过程中调用,利用这种方式也可以完成一些以前必须利用公式完成的工作,如累计等。限于篇幅,在此不加讨论。
图3 Crystal Reports 6.0建立报表
图4 建立新的公式
除了可以将公式插入到报表中外,还可以在选择记录(Record)和组(Group)时使用公式。比如选择菜单Report|Edit Selection Formula|Record项,然后输入公式:
{file.price} < 100
则只打印满足上条件的所有记录的报表。
Crystal Reports公式的语法比较简单,但支持的操作符和函数非常多。在公式中可以使用变量、常量。也可以引用数据库字段,其格式为:
{库名.字段名}
Crystal Reports支持大量的操作符,有些是常见的,也有些是Crystal Reports特有的。
Crystal Reports支持+、-、*、/,还支持%(百分比)操作符,如100 % 500 = 20。
转换操作符为$,它将数字转换为货币型,这样Crystal Reports会按照报表中的货币格式设置打印数据。
Crystal Reports支持的比较操作符与Visual Basic相同:=、<>、<、>、>=、<=。
字符串连接的操作符为“+”。
从字符串中取指定的字符使用“[]”操作符,相当于Visual Basic的Mid函数。“[]”内为字符的位置,第一个字符的编号为1。如:
{file.ItemNumber} [4 to 5]
判断一个字符串是否包括在另一个字符串使用in操作符。比如:"c" in "pcc"返回True。
Crystal Reports允许用户建立一个范围,并判断数据是否包括在指定范围内。如“100.00 to 250.00”包括100到250之间的数据,而使用“50 in (100 to 250)”可以判断50是否在指定的范围内。
布尔操作符包括And、Not和Or。
Crystal Reports 支持数组,比如[100,200,300,400]是一个由4个元素组成的数组。可以使用in操作符判定数据是否是一个数组的元素,如:{file.State} in ["CA", "HI", "AK"]。
匹配操作符包括StartsWith和Like。StartsWith判断一个字符串是否以指定的字符串开头,如"PCC" startwith "P"返回True。Like操作符的用法类似Visual Basic,也是将字符串表达式和通配符表达式中的样式做比较。
另一个重要的操作符是If…Then … Else …,就是我们所熟悉的条件判断,在我们后面得示例部分可以看到这个操作符的威力。
如果要为变量赋值,需要使用“:=”符号,这是与Visual Basic不同的。
在公式中也可以加上注释以方便阅读。注释符号为“//”,“//”符号后面的内容将被忽略。
公式中也可以包括多个语句行,行尾使用“;”分割。
Crystal Reports支持大量函数,包括数学函数、统计函数、日期函数、字符串函数、数组函数等等。在Crystal Reports的帮助文件对每个函数都有详细的介绍。
下面,我们通过几个实例来说明如何使用Crystal Reports的公式。
这是一个非常简单的例子,主要是为了演示在公式中进行不同变量类型的转换和计算。
有时数据库字段的单位和报表中显示的单位不同,我们需要进行计量单位之间的转换,这时就离不开公式的使用。比如,我们的数据库中有一个Length字段,它记录以米为单位的长度,而在打印时需要以厘米为单位,我们就可以使用下面的函数。
ToText({Order Details.Length} *100) + '厘米'
这里的ToText函数就是转换数字型为字符型。常用的转换函数还有ToNumber等。
在这个例子中我们将演示如何进行字符串操作。
我们在打印报表时经常会遇到显示中文星期的问题。Crystal Reports有DateOfWeek函数可以判断一个日期是星期几,比如DateOfWeek返回4时表示星期三。我们可以使用下面的公式来显示中文星期。这里的Today函数只是一个示例,你可以将其修改为你所需的日期函数或字段。
StringVar x;
NumberVar n;
x:="日一二三四五六";
n:=DayOfWeek (Today);
x:="星期"+x[2*n-1 to 2*n]
前两行,我们定义了字符串变量x和数字变量n。一个公式可以有很多行,但只有最后一行的计算结果才会作为整个公式的结果打印在报表中。
在这个例子中我们重点演示如何使用If-Then-Else操作符。
条件计算在报表中使用得非常普遍。例如,我们要根据用户购买的总价格决定折扣的多少。我们假定用户购买200元以下的产品,不打折;200元到1000元提供5%的折扣;1000元以上提供7%的折扣。我们可以使用下面的公式计算最终用户需要付多少钱。
CurrencyVar cValue;
cValue := {Order Details.UnitPrice} *{Order Details.Quantity}; //计算总价格
If cValue < 200 Then
cValue
Else If cValue < 1000 Then
cValue * 0.95
Else
cValue * 0.93
Crystal Reports提供了一些基本的统计功能,可以按分组进行统计。但是实际应用中的统计往往更为复杂。比如,我们需要根据一定的条件进行统计。假定我们要统计每组中单价超过10元的商品的销售数量。我们可以先在报表的Detail部分插入一个公式。假定该公式名字为ConditionSum,在公式内输入如下内容:
If {Order Details.UnitPrice} < 10 Then
0
Else
{Order Details.Quantity}
右击ConditionSum公式字段,选择Change Format,设置打印格式。在Crystal Reports 4.6的Format对话框中选择Hide when printing,这样该字段不会在打印时显示出来(图5)。如果使用Crystal Reports 6.0,应该选择Format对话框中的Suppress项(图6)。这是一个非常重要的技巧,有时我们使用公式并不是为了打印公式结果,而只是为了进行方便计算,页可以利用这个办法避免中间计算结果被打印。右击ConditionSum公式字段,在快捷菜单选择Insert Subtotal,这样我们就可以对每组中满足条件的记录进行求和。
图5 设置格式为Hide when printing,避免字段被打印
图6设置格式为Suppress,避免字段被打印
设计报表时,有时需要加上每页的各项本页总计。首先在报表的Detail部分插入一个公式。假定该公式名字为SimpleSum,在公式内输入如下内容:
NumberVar x;
NumberVar page;
if page<> PageNumber then x:=0;
page := PageNumber;
x := x+{Order Details.Quantity};
这里{Order Details.Quantity}假定是你要统计的字段。公式中的PageNumber函数为当前打印页码,我们使用page变量记录当前打印页码。如果换了新页,则page变量和PageNumber不相等,此时我们对变量进行清零。然后象上例那样设置该字段为隐藏。打印每页总计的地方通常是页脚,可以在页脚插入公式,在公式中写上:
{@SimpleSum}
Crystal Reports通常是同VB协同工作,我们可以在VB中根据用户输入修改报表中的公式。假定,我们在Crystal Reports输入以下公式@VarC:
NumberVar c;
c
然后在VB程序中设置@VarC公式。Crystal Reports 4.6和6.0在这方面有所不同。我们分别加以介绍。
使用Crystal Reports 4.6时,在VB的窗体上放置Crystal Reports控件并设置有关属性。下面的代码将修改VarC公式:
CrystalReport1.Formulas(0) = "VarC=" + CStr(nCount) "*{file.SALES}"
CrystalReport1.PrintReport
使用Crystal Reports 6.0时,默认的情况下Crystal Reports会建立一个窗体显示和打印报表。我们可以在这个窗体中声明的Report变量来修改报表中的公式。Report变量有FormulaFields集合,其中包括所有定义的公式。按Crystal Reports 6.0帮助的说明,似乎可以使用Report.FormulaFields("VarC")的格式来引用VarC公式,但实际实验发现不行。FormulaFields集合必须通过一个数字下标来引用公式。为此,编写了FindField来确定公式的下标。下面的代码就是修改VarC公式的。
Private Function FindField(s As String) As Integer
Dim i
For i = 1 To Report.FormulaFields.Count
If Report.FormulaFields(i).FormulaFieldName = s Then
FindField = i
Exit Function
End If
Next
End Function
Private Sub Form_Load()
CRViewer1.ReportSource = Report
Report.FormulaFields(FindField("@VarC")).Text = _
CStr(nCount) "*{dao.SALES}"
CRViewer1.ViewReport
End Sub
以上只是Crystal Reports强大的报表功能的一些简单介绍,相信只要充分利用好这些功能,你可以打印出完美的报表。
如果您有任何建议,请给我发电子邮件:
。
版权所有 李海,热情软件屋 1997-2006