Crystal语法

水晶报表默认支持的公式语言(除此之外还支持Basic),可参考VS报表官方文档基础教程

  • 大小写不敏感

  • 由一系列表达式组成,最后一个表达式是公式的返回值

  • 公式必须返回一个基本类型的值

1.基本类型

数字、货币、字符串、布尔值、日期、时间、日期时间。

// 货币
$10000
-$20
$1.23
CCur (10000)
CCur (-20)
CCur (1.23)
// 字符串
"This is a string."
"123"
"The word ""hello"" is quoted."
'This is also a string.'
'123'
'Last Year''s Sales'
"hello" [2] //Equal to "e"
"hello" [-5] //Equal to "h"
"604-555-1234" [1 to 3] //Equal to "604"
"abcdef" [-3 to -1] //Equal to "def"
// 日期 时间 日期时间
#8/6/1976 1:20 am#
#August 6, 1976#
#6 Aug 1976 13:20:19#
#6 Aug 1976 1:30:15 pm#
#8/6/1976#
#10:20 am#
// 转为日期时间
CDateTime ("8/6/1976 1:20 am")
CDateTime ("10:20 am")
// 转为日期
CDate ("Aug 6, 1969")
CDate (1969, 8, 6) //指定年、月、日。
CDate (#Aug 6, 1969#)
// 转为时间
CTime ("10:30 am")
CTime (10, 30, 0) //指定小时、分钟、秒。
CTime (#10:30 am#)

2.范围数据类型

除布尔值外,所有基本类型都可以使用范围类型。

// [2, 5]
2 To 5
// (2, 5]
2 _To 5
// <= 5
UpTo 5 
// < 5    
UpTo_ 5  
#Jan 5, 1999# To #Dec 12, 2000#
UpFrom #Jan 1, 2000#    

结合IF

Select {Student.Test Scores}
Case UpFrom 90 :
"A"
Case 80 To_ 90 :
"B"
Case 70 To_ 80 :
"C"
Case 60 To_ 70 :
"D"
Default :
"F";

结合IN

5 In 2 To 10; //True
5 In 2 To_ 5; //False
5 In 2 To 5; //True

结合最大值或最小值获得边界

Maximum (2 To 10) //Returns 10

3.数组数据类型

与其他语言相似

[10, 5, 20] [2 To 3] // = [5, 20]

4.变量

声明

Local NumberVar x := 10 + 20;
Local StringVar y := "Hello" + " " + "World";
Local DateVar z := CDate (#Sept 20, 1999#);
Local NumberVar Range gradeA := 90 To 100;
Local NumberVar Range gradeA;
Local DateVar Range quarter;
gradeA := 90 To 100;
quarter := CDate (1999, 10, 1) To CDate (1999, 12, 31);

作用域:局部、全局、共享。

局部变量通过Local关键字声明。局部变量仅单个公式共享。

//Formula A
Local NumberVar x;
x := 10;
//Formula B
EvaluateAfter ({@Formula A})
Local NumberVar x;
x := x + 1;

全局变量通过Global关键字声明,可省略Global。全局变量在主报表中共享。

Global StringVar y;
StringVar y; //等同于: Global StringVar y;

共享变量使用相同的内存块,在整个主报表和所有子报表中共享。在主报表和子报表都需要声明。

Shared NumberVar x := 1000; // 主报表
Shared NumberVar x;         // 子报表

5.数组变量

声明

//将 x 声明为数字数组类型的全局变量
Global NumberVar Array x := [10 , 20, 30];
//Cost 是货币数组类型的全局变量。
//由于忽略了作用域指定符(Local、Global 或 Shared 其中之一),因此它将自动成为全局变量。
CurrencyVar Array cost := [$19.95, $79.50, $110.00, $44.79, $223.99];
//payDays 是日期数组类型的全局变量。
Global DateVar Array payDays := [CDate(1999, 5, 15), CDate(1999, 5, 31)];
//y 是字符串范围数组类型的共享变量。
Shared StringVar Range Array y := ["A" To "C", "H" To "J"];
//days 是字符串数组类型的局部变量。
Local StringVar Array days;
days := ["Sun", "Mon", "Tue", "Wed", "Th", "Fri", "Sat"];

调整数组变量的大小

Local NumberVar Array x;
Redim x [2]; // x = [0, 0]
x [2] := 20; // x = [0, 20]
Redim x [3]; // x = [0, 0, 0]
x [3] := 30; // x = [0, 0, 30]
Redim Preserve x [4]; // x = [0, 0, 30, 0]
"finished"
Local StringVar Array a;
Redim a [2];
a[1] := "good";
a[2] := "bye";
a[1] & a[2] //该公式返回字符串“goodbye”

结合for

Local NumberVar Array b;
Redim b[10];
Local NumberVar i;
For i := 1 To 10 Do
(
b[i] := 10 * i
);
b [2]

6.类型转换

支持:数字到货币、日期到日期时间、简单类型到同一简单类型的范围值

Local CurrencyVar cost;
//等同于: cost := $10
cost := 10;
Local DateTimeVar orderDate;
//等同于: orderDate := CDateTime (1999, 9, 23, 0, 0, 0)
orderDate := CDate (1999, 9, 23);
Local NumberVar Range aRange;
//等同于: aRange := 20 To 20
aRange := 20;
Local NumberVar Range Array aRangeArray;
//等同于: aRangeArray := [10 To 10, 20 To 25, 2 To 2]
aRangeArray := [10, 20 To 25, 2];

货币到数字

Local NumberVar num;
num := 5 + $10;
//正确 - 使用 CDbl 函数转换为数字类型
num := CDbl (5 + $10)

7.运算符

算数运算符: 加 (+)、减 (-)、乘 (*)、除 (/)、整除 ()、百分比 (%)、求余 (Mod)、求反 (-) 和求幂 (^)。

//未上市的优先股占普通股的百分比。
{Financials.Preferred Stock} %
{Financials.Common Stock};
7 + 2 * 3 - 2 + Sqr(6 + 3) * Length("up");
//该公式返回 17。

布尔运算符: Not、And、Or、Xor、Eqv 和 Imp。

8.条件分支

IF

条件结果类型应当保持一致

If {Employee.Dept} = "Sales" Then
{Employee.Salary} * 0.06
Else
{Employee.Salary} * 0.04

分组时返回值类型也应当保持一致,如下所示可颠倒表达式的顺序,都返回0

Local StringVar message;
Local CurrencyVar ship;
If {Orders.Ship Date} - {Orders.Order Date} <= 3 Then
(
message := "Rush";
ship := {Orders.Order Amount} * 0.05;
0
)
Else
(
ship := {Orders.Order Amount} * 0.02;
message := "Regular";
0
);
message & " shipping is " & CStr (ship)

Select

Select {Customer.Fax}[1 To 3]
Case "604", "250" :
"BC"
Case "206", "509", "360" :
"WA"
Default :
"";

9.循环

For

Local StringVar str := "";
Local NumberVar strLen :=
Length ({Customer.Customer Name});
Local NumberVar i;
For i := 1 To strLen Do
(
Local NumberVar charPos := strLen - i + 1;
str := str + {Customer.Customer Name}[charPos]
);
str

For Step

Local StringVar str := "";
Local NumberVar strLen :=
Length ({Customer.Customer Name});
Local NumberVar i;
For i := strLen To 1 Step -1 Do
(
str := str + {Customer.Customer Name}[i]
);
str

Exit For退出循环

Global StringVar Array names;
//名称数组已初始化,并已填充到其他公式中。["Frank", "Helen", "Fred", "Linda"]
Local NumberVar i;
Local NumberVar result := -1;
//UBound 函数返回其数组参数的大小。
For i := 1 to UBound (names) Do
(
If names [i] = "Fred" Then
(
result := i;
Exit For
)
);
result

While Do 或Do While,Exit While可退出循环

Local StringVar inString := "The 7 Dwarves";
Local NumberVar strLen := Length (inString);
Local NumberVar result := -1;
Local NumberVar i := 1;
While i <= strLen And result = -1 Do
(
Local StringVar c := inString [i];
If NumericText (c) Then
result := i;
i := i + 1;
);
result

循环存在一个安全机制

每个公式求值最多有100000次循环条件求值。

安全机制针对每个公式,并非应用每个循环。

触发演示一

Local NumberVar i := 1;
While i <= 200000 Do
(
If i > {movie.STARS} Then
Exit While;
i := i + 1
);
20

触发演示二

Local NumberVar i := 1;
For i := 1 To 40000 Do
(
Sin (i);
);
While i <= 70000 Do
(
i := i + 1;
)

10.公式大小限制

除了安全机制中的100000次循环条件求值,还有

  • 字符串最大长度65534

  • 数组最大大小1000个元素

  • 参数个数不定的函数最多支持1000个参数,如Choose

  • 日期1-9999(Visual Basic为100-9999)

11.常用函数

Mid截取字符串

Local StringVar x := "hello";
Local StringVar y;
//从位置 2 开始,直到字符串的末尾。
y := Mid (x, 2); //y 现在为 "ello"。
//Start at position 2, extract 1 character
y := Mid (x, 2, 1) //y 现在为 "e"。

空值

IsNull({Product.Color}) Or
InStr({Product.Color}, " ") = 0

反向字符串

StrReverse ({Customer.Customer Name})

除此之外,在编辑公式的弹窗中,软件提供了【函数】【运算符】参考。

eg.

循环

WhilePrintingRecords;
Local StringVar Array InputNum := {?StringMultiParam};

Local StringVar str := "";
Local NumberVar strLen := Count (InputNum);
Local NumberVar i;        
For i := 1 to strLen Step + 1 Do 
(str := str + '+' + InputNum[i] + chr(13));
str

条件

WhilePrintingRecords;
Local StringVar Array InputNum := {?StringMultiParam};

Local StringVar str := "";
Local NumberVar strLen := Count (InputNum);
Local NumberVar i;        
For i := 1 to strLen Step + 1 Do 
(
If i = strLen Then
(
If InputNum[i][1] = 'a' Then
str := str + 'o ' + InputNum[i][2 to Length(InputNum[i])]
Else
str := str + 'x ' + InputNum[i][2 to Length(InputNum[i])]
)
Else
(
If InputNum[i][1] = 'a' Then
str := str + 'o ' + InputNum[i][2 to Length(InputNum[i])] + '   '
Else
str := str + 'x ' + InputNum[i][2 to Length(InputNum[i])] + '   '
)
);
str

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值