PowerScript语法参考手册
前言:本文用于PowerBuilder12.6程序员,PowerBuilder最初由Sybase发布,能很快捷开发C/S程序或者多层应用系统。SAP以58亿美元现金收购Sybase以抗衡甲骨文,PowerBuilder 12.6是SAP收购Sybase后与2014发布的版本。
这是第一部分:语言基础。
语言基础
注释
和C++/Java类似,支持两种注释方式:
双斜杠:
代码 // 注释
斜杠+星号对:
/* 注释 */
示例
(1)双斜杠
// This entire line is a comment.
// This entire line is another comment.
amt = qty * cost // Rest of the line is comment.
// The following statement was commented out so that it
// would not execute.
// SetNull(amt)
(2)单斜杠+星号
/* This is a single-line comment. */
/* This comment starts here,
continues to this line,
and finally ends here. */
A = B + C /* This comment starts here.
/* This is the start of a nested comment.
The nested comment ends here. */
The first comment ends here. */ + D + E + F
标识符
标识符规则如下:
- 必须以字母或者下划线开头
- 不能使用保留单词或者关键词
- 最高40个字符,而且不能有空格
- 大小写不敏感
- 可包含字母、数字、破折号、下划线、$、#、%的任意组合
示例
(1)有效标识符
ABC_Code
Child-Id
FirstButton
response35
pay-before%deductions$
ORDER_DATE
Actual-$-amount
Part#
(2)无效标识符
2nd-quantity // Does not start with a letter
ABC Code // Contains a space
Child'sId // Contains invalid special character
标签
标签是GOTO语句指向标志。一个有效的标识符就是有效的标签,但是需要加上冒号。
示例
(1)自成一行
FindCity:
IF city=cityname[1] THEN ...
(2)和后续语句一行
FindCity: IF city=cityname[1] THEN ...
特殊字符
在字符串中能加入特殊字符。例如,可以加入一个TAB到字符串中,这样可以保证恰当的留白。
语法
分类 | 名称 | 替代字符串 | 备注 |
普通ASCII 字符 | Newline | ~n | |
Tab | ~t | ||
Vertical tab | ~v | ||
Carriage return | ~r | ||
Form feed | ~f | ||
Backspace | ~b | ||
Double quote | ~" | ||
Single quote | ~' | ||
Tilde | ~~ | ||
任意ASCII 字符 | Decimal | ~### | ### = a 3-digit number from 000 to 255 |
Hexadecimal | ~h## | ## = a 2-digit hexadecimal number from 01 to FF | |
Octal | ~o### | ### = a 3-digit octal number from 000 to 377 |
示例
(1)ASCII字符
字符串 | 描述 |
"dog~n" | dog和新的空白行 |
"dog~tcat~ttiger" | 单词dog, tab字符, 单词cat, 第二个tab字符,单词tiger |
(2)十进制、十六进制、八进制数字
字符串 | 描述 |
"~249" | 表示249十进制数字的ASCII字符串 |
"~hF9" | 表示 F9十六进制数字的ASCII字符串 |
"~o371" | 表示371八进制数字的ASCII字符串 |
NULL
Null 意思是未定义或者未知,和空白字符串、0、日期0000-00-00不同。null既不是0也不是非0。null经常用于数据库记录值。
(1)变量初始值
尽管PowerBuilder可以让所有变量都能赋值 null ,然而并没有把变量自动初始化为null. 当变量在声明时没有初始化时,变量会自动初始化为默认值,例如numeric 默认值为0,boolean默认值为false,string的默认值为空串 ("") 。
(2)变量中的Null
如下情况会让一个变量成为null:
- 从数据库读入null值到变量中。如果数据库支持null, 当SQL语句 INSERT 或者UPDATE 插入或者修改某字段值为null ,那么使用SELECT 或者FETCH 语句读取null到变量中。
- 使用SetNull 函数来显式设置变量为null. (3)函数和表达式中的Null
函数:任何参数值为null,则返回null。
表达式:任何变量值为null,则结果为null。但是,结果为null的布尔表达式实际上是未定义,因此实际值为false。
(4)null的测试
使用 IsNull 函数来测试是否为null,而不能使用=来测试。
示例
(1)实例1
下列语句均没有发出beep声 (变量nbr被赋值为null, 因此每个if语句判断均为 false):
int Nbr
// Set Nbr to NULL.
SetNull(Nbr)
IF Nbr = 1 THEN Beep(1)
IF Nbr <> 1 THEN Beep(1)
IF NOT (Nbr = 1) THEN Beep(1)
(2)实例2
布尔表达式值为false, 因此 ELSE语句被执行。
int a
SetNull(a)
IF a = 1 THEN
MessageBox("Value", "a = 1")
ELSE
MessageBox("Value", "a = NULL")
END IF
(3)实例3
当焦点不在任何控件上,GetFocus 返回 null 对象的引用,布尔表达式值为false,于是 ELSE 表达式被执行:
IF GetFocus( ) THEN
. . . // Some processing
ELSE
MessageBox("Important", "Specify an option!")
END IF
保留字
保留字是PowerBuilder内部使用的词,而不能被用作标识符。 如果强行使用,则编译器会告警。但是,如果在保留字前面加星号,那么保留字能被用于函数名称。
下表展示了所有的保留字:
PowerBuilder系统类内部的private属性也不能用作标识符,强制使用的话也会得到一个编译器告警。如果部署一个DataWindow到Web应用中,不能使用JavaScript保留字来命名字段或者绑定对象。
代词
PowerScript使用代词(pronoun)来引用对象或者控件。即使对象或者控件变更,引用也不会错误。
若要使用对象名称,则在函数或者事件中可使用代词来引用对象,例如:
- 在对象或者控件中触发事件
- 操控或者变更对象或者控件
- 获取或者变更属性的设置下表列出了PowerScript 代词:
代词 | 用途 | 指向 |
This | 窗口(Window), 自定义用户对象,菜单(menu) , 应用程序对象(application object), 控件(control) | 对象或者控件自身 |
Parent | 窗口的控件 | 包含控件的窗口 |
自定义用户对象中的控件 | 包含控件的自定义用户对象 | |
菜单 | 上级菜单项 | |
Super | 派生对象或者控件 | 父对象 |
派生窗口或者用户对象 | 窗口或者用户对象的直接祖先 | |
派生窗口或者用户对象中的控件 | 父窗口或者用户对象的控件的直接祖先 |
ParentWindow 属性
可使用菜单Menu对象的ParentWindow 属性,就象Menu脚本的代词一样。当程序运行时,ParentWindow 属性标识和菜单关联的窗口。
Parent 示例
(1)Window控件
如果在窗口的CommandButton 中Clicked事件脚本中使用下面这句,那么点击按钮就会关闭含有这个按钮的窗口。
Close(Parent)
如果在CommandButton脚本中使用下面这句,那么点击这个按钮就会显示窗口的水平滚动条,窗口的HScrollBar 属性为true。
Parent.HScrollBar = TRUE
(2)用户对象控件
如果在用户对象CheckBox 控件的Clicked 事件脚本中包含下面这句,那么点击检查框会隐藏这个用户对象。
Parent.Hide( )
如果在CheckBox脚本中使用下面这句,那么点击检查框会禁用用户对象,用户对象的Enabled 属性为false。
Parent.Enabled = FALSE
(3)菜单
如果在菜单项Clicked 脚本中使用下面这句,该菜单项是Select下面的Select All菜单项,那么点击Select All就会禁用Select菜单项。
Parent.Disable( )
如果在Select All菜单项的Clicked 事件脚本中使用下面这句,那么点击Select All 菜单项就会使能上级菜单Select。
Parent.Checked = TRUE
This 示例
实例1
在一个菜单脚本中使用下面这句,那么就会放置一个检查标志。
This.Check( )
实例2
在下面的函数调用中,This将传递一个包含自身脚本的对象引用。
ReCalc(This)
实例3
下面这句,x指向一个本地变量,而不是控件的X属性,因为没有使用This。但是如果没有本地变量,那么x就会指向对象的X属性。
x = x + 50
实例4
使用This能保证显式引用属性。下面这句用于CommandButton的Clicked 事件脚本,则点击按钮将会改变按钮的水平位置,即改变按钮的X属性。
This.x = This.x + 50
Super 示例
实例1
下面这句调用祖先函数wf_myfunc,有可能派生类也有同名函数。这个例子必须存在于派生窗口的函数或者脚本,而不能用于窗口的控件。如果用于派生窗口中按钮的Clicked 事件,那么编译器将会提示一个语法错误:“Supplying arguments”,“Be certain to supply the correct number of arguments for the ancestor function”。
Super::wf_myfunc(myarg1, myarg2)
实例2
下面这句用于CommandButton 脚本,调用窗口或者用户对象的直接祖先中CommandButton控件 的Clicked 事件。
Super::EVENT Clicked()
语句接续(行接续)
一般每行只放置一条语句,但是有时候会需要把一条语句放在多行中。语句的接续字符是&符号。(在加速键中&符号的使用方法参见其他资料)
语法
Start of statement &
more statement &
end of statement
&符号必须放在最后,作为行末非空字符,否则编译器会认为它是语句的一个部分。
用法提示
不能把&符号用于:
- 注释行的接续,参见注释的用法
- SQL语句的接续,PowerBuilder的SQL语句必然以分号结束
示例
(1)字符串的接续
下面这种方法就是把&符号放置在字符串的中间,然后分拆字符串为两行。注意,&符号之前的任何空白,例如tab键或者space键,都是字符串的一个部分;下一行的行首的任何空白也是字符串的一个部分。
IF Employee_District = "Eastern United States and&
Eastern Canada" THEN ...
下面这句在IF...THEN语句中使用&符号拆分字符串,为了可读性,tab键加在第二行行首,但是这可能导致编译器报错或者不是程序员所期望的字符串(加入tab就不是本意)。
IF Employee_District = "Eastern United States and&
Eastern Canada" THEN ...
最好的办法是加上双引号或者单引号,如下:
IF Employee_District = "Eastern United States and "&
+" Eastern Canada" THEN ...
(2)变量名称的接续
不要对变量名称使用&符号拆分为两行。这会导致错误,因为接续符号&把一个变量名称分成了两个名称。
Total-Cost = Price * Quan&
tity + (Tax + Shipping)
语句分割
每行放置一条语句是常见的,但是也可以把多条语句组合成一行,注意每条语句的结尾是分号,分号是语句分割符号。
Statement1; statement2
示例
下面这个例子包含了三个语句
A = B + C; D = E + F; Count = Count + 1
空白
空白页、制表符TAB、换页符和注释就是空白的形式。编译器把空白作为分隔符,而不会对空白字符进行具体处理或者计数。
用法提示
(1)字符串常量中的空白
当空白字符作为字符串常量的一部分时,空白字符会保留,注意这种字符串常量是使用单引号或者双引号标记的字符串。
(2)标识符中的破折号
如果不想在标识符中使用破折号,那么必须采用前后留白的方式来标记减号,注意使用破折号时PowerBuilder 会认为破折号是变量的一个部分
Order - Balance // Order减Balance
Order-Balance // 变量名称是 Order-Balance
示例
实例1
下面这句含有空格和注释,编译器都会忽略这些空白
A + B /*Adjustment factor */+C
实例2
下面这句是字符串常量,含有很多空格,编译器不会忽略这些空格
"The value of A + B is:"
条件编译
条件编译指令用于编译器编译之前,可以让PowerBuilder 预处理器解析代码块。
#IF { NOT } DEFINED predefined_symbols THEN
action1
{ #ELSEIF DEFINED predefined_symbolsTHEN
action2}
{ #ELSE
action3}
#END IF
语法解释如下表:
项目 | 解释 |
predefined_symbols | 一个预定义的标识符,或者一个通过AND或者OR操作的预定义标识符组合。不能针对用户定义标识符。 |
action1, action2, action3 | 欲执行的操作 |
用法提示
条件编译让程序员可以根据指定目标类型或者在程序中设定目标类型来有条件纳入PowerScript 代码。也可以在应用程序中纳入调试代码,在Project面板中指定是否加入到应用程序的可执行文件。
预处理器会替换以#符号开头的语句为空白。判断预处理条件是否满足,若满足则传送action语句中的代码到编译器,或者转换为空白行。
下表展示了预定义符号、关联项目类型和对编译器接收的代码的影响。
预定义符号 | 目标(平台)类型 | 处理块中的代码 |
PBNATIVE | 标准PowerBuilder C/S或者分布式应用程序 | 对于.NET,完整解析标准应用程序,以及转换为空白行 |
PBWINFORM | .NET Windows Forms 应用程序 | 对于NET Windows Forms,完整解析,以及,对于其他目标,转换为空白行 |
PBWEBSERVICE | .NET Web Service 组件 | 对于.NET Web Service,完整解析,对于其他目标,转换为空白行 |
PBDOTNET | Windows Forms 应用程序, .NET Assembly, .NET Web Service组件 | 对于所有.NET目标,完整解析; 对于其他目标,转换为空白行 |
DEBUG | 所有PowerBuilder 标准程序和.NET | 当一个项目Enable DEBUG Symbol 检查框被选中时,代码被编译器完整解析,纳入到所要部署的应用程序中。当检查框被清除时代码转换为空白行。DEBUG symbol总是在开发环境中被定义。 |
可以使用NOT操作符来引入代码到所有非程序员定义的目标类型中。也可以使用AND和OR操作符来组合符号。例如,下面这句代码将会被除了标准PowerBuilder 应用程序、.NET Windows Forms外的所有目标(平台)所解析。
#if NOT defined PBNATIVE OR PBWINFORM then
注释可以被加入到条件编译代码块中,但是要求在同行中使用双斜杠注释。不能在条件编译代码语句中使用PowerScript 行接续符号&,也就是说,当使用&分拆当行代码为多行时,必须嵌入到条件编译块的代码中。
局限性和错误消息
DataWindow、结构、菜单对象均不支持条件编译。对于包含跨函数、事件或者变量定义边界的条件编译块的对象来说,不能编辑源代码。
加入DEBUG条件块后,必须重新构建应用程序。
下表展示了对应不正确的条件编译代码给出错误消息的类型:
预处理器返回的错误消息类型 | |
错误消息 | 描述 |
Invalid if statement | #if 语句没有定义符号,或者不正确定义符号,或者没有then子句 |
#end if directive expected | #if 语句没有带#end if语句 |
Unexpected preprocessor directive | #else, #elseif, or #end if语句之前没有#if语句 |
Preprocessor syntax error | 当文本不先于注释符号//时,#else或者#end if语句之后有文本 |
示例
当在开发环境中运行或者调试应用程序时,下面的代码总是被解析,总能看到消息框。当运行可执行文件时,如果在Project面板的General页面中DEBUG符号被使能,那么代码才能被解析。
#if defined DEBUG then
MessageBox("Debugging","Ctr value is " + string(i))
#end if
对于.NET使用条件编译的例子,请参考.NET相关文档。