前言:本文用于PowerBuilder12.6程序员,PowerBuilder最初由Sybase发布,能很快捷开发C/S程序或者多层应用系统。SAP以58亿美元现金收购Sybase以抗衡甲骨文,PowerBuilder 12.6是SAP收购Sybase后与2014发布的版本。这是第二部分:数据类型。
PowerBuilder 标准数据类型类似于其他编程语言,包括char, integer, decimal, long, 和string。PowerScript语言中,使用这些数据类型来声明变量或者数组。
下表是标准 PowerScript 数据类型清单:
(相关资料图)
二进制大对象。用于存储海量数据,例如,普通二进制数据、图像、文字处理文件之类的大文本。
真true或者假false
8位无符号整数,从0到255.
可以作为常量,使用任意0~255内的完整正整数,而前面的加号+是可以不需要的,例如18和+18是完全一样的。
单个Unicode字符。
如果想要在应用程序中解析基于字符的数据,那么可能想要将其定义为Char类型的数组。相对字符串而言,解析一个Char数组是更容易和更快捷的。如果想要传递基于字符的数据给外部函数,那么可能想要使用Char二维数组,而不是字符串。
可以作为常量,需使用单引号或者双引号,例如:
char cc = "T"c = "T"
一个日期Date值,包含年(1000到3000),月(01到12),日(01到31)。
可以作为常量,需使用连字符-来分隔年月日,例如:
2001-12-25 // 2001年12月25日 2003-02-06 // 2003年2月6日
日期时间类型作为单一数据类型,仅仅用于从数据库中读写DateTime值。转换DateTime值到PowerBuilder中使用的数据类型的情况有:
Date(datetime) 函数:在读数据库后,转换DateTime 到 PowerBuilder日期Date值
Time(datetime) 函数:在读数据库后,转换DateTime 到PowerBuilder时间Time值
DateTime(date, time) 函数:在写数据库的DateTime列之前,转换date和time到DateTime,其中time是可选的.
PowerBuilder在数据库接口中支持毫秒,条件是采用支持毫秒的任何数据库管理系统DBMS.
有符号十进制数,正数或者负数,最大28位。可以放置小数点在28位里面任何位置,例如:123.456, 0.000000000000000000000001 或者12345678901234.5678901234。
为了赋值给一个常量,可以带小数点或者指数。加号是可选的。对于0和1之间的数,0在小数点的左边,但是0是可选的,例如,0.1和.1是一样的。对于整数,0在小数点右边,但是0也是可选的,例如32.00, 32.0, 和32.都是一样的。例如:
12.34 0.005 14.0 -6500 +3.5555
有符号的浮点数,15位精度,范围从2.2250738585073E-308 到1.79769313486231E+308,还有–2.2250738585073E-308 to –1.79769313486231E+308。
16位有符号整数,从-32768到+32767.16。
可以使用任意整数,整数、负数、0,作为常量。正号是可选的,例如:
1 123 1200 +55 -32
32位有符号整数,从-2147483648 到+2147483647。
64-bit signed integers, 64位有符号整数,从-9223372036854775808 到9223372036854775807。
有符号浮点数,带6位精度,范围从3.402822E-38 到3.402822E+38, 还有-3.402822E-38 到-3.402822E+38。
可使用带E的十进制数值作为常量,E后面跟一个整数,注意中间没有空格。E之前的数值约定为一个小数。E后面+号是可选的,3E5 和3E+5是一样的。例如:
2E4 2.5E38 +6.02E3 -4.1E-2-7.45E16 7.7E+8 3.2E-38
Unicode字符的任意字串,长度0 到1073741823。
应用程序多数基于字符的数据都会被定义为字符串,例如名称、地址等等。PowerScript 提供许多函数,可以用来操作字符串,例如转换英文字符为大写,移除前置后置空白。
常量字符串可以封装多至1024位字符到单引号或者双引号中,也可以封0长度字符串或者一个空字符串,例如:
string s1s1 = "This is a string"s1 = "This is a string"
可以嵌入一个引号到一个字符串常量中,例如:
string s1s1 = "Here"s a string."
也可以使用波浪号嵌入到引号到一个带有引号的字符串常量中,例如:
string s1 = "He said, "It~"s good!""
复杂嵌套:当嵌套一个字符串到嵌套了另外一个字符串的字符串中时,可以使用波浪号来告诉解析器怎么解释引号。两个波浪号看做一个波浪号,一个波浪号和引号对看做一个单独的引号。
实例1
这个字符串包含两层嵌套:
"He said ~"she said ~~~"Hi ~~~" ~" "
第一次处理结果为:
He said "she said ~"Hi ~" "
第二次处理结果为:
she said "Hi"
第三次处理结果为:
Hi
实例2
一个更可能发生的例子是用Modify函数来设置DataWindow属性的一个字符串。参数字符串经常需要复杂引号,因为必须指定一个或多个层次的嵌套字符串。为了更便于理解,思考PowerBuilder怎么解析字符串。下面的字符串是Modify函数的一个可能参数,它混合了单引号和双引号来减少波浪号的数量。
"bitmap_1.Invert="0~tIf(empstatus=~~"A~~",0,1)""
双引号告诉PowerBuilder解析参数为字符串。它包含赋值给Invert属性的表达式,也是字符串,因此必须使用引号。表达式自身包含一个嵌套字符串:A。首先,PowerBuilder评估Modify参数,赋值单引号字符串给Invert属性。传递字符串后,转换两个波浪号为一个。赋值给Invert的字符串变为:
"0[tab]If(empstatus=~"A~",0,1)"
最终,PowerBuilder评估属性表达式,转换波浪号引号对为引号,并设置相应的位图颜色。
实例3
对于嵌套字符串的特定集合,有许多方法来指定引号。下面用于Modify函数的表达式有相同的结果:
"emp.Color = ~"0~tIf(stat=~~~"a~~~",255,16711680)~"""emp.Color = ~"0~tIf(stat=~~"a~~",255,16711680)~"""emp.Color = "0~tIf(stat=~~"a~~",255,16711680)"""emp.Color = ~"0~tIf(stat="a",255,16711680)~""
引号和波浪号规则:
波浪号告诉解析器:下一个字符应该被当做一个字,二狗不是字符串终结符。
两个单引号能用于存在引号双引号对的地方 (~")
波浪号波浪号单引号 (~~") 能用于存在三个波浪号一个双引号的地方 (~~~")
Time采用24制,含时(00到23)、分(00-59)、秒(00-59)和秒的小数(最大六位数),范围 00:00:00 到23:59:59.999999。
支持微秒,用于支持微秒的数据库的访问接口。
可使用冒号来分隔时间,但是秒的小数部分使用小数点来分隔。例如:
21:09:15 // 晚上9点9分15秒06:00:00 // 上午6点整10:29:59 // 上午10点30分前1秒10:29:59.9 // 上午10点30分前1/10秒
16位无符号整数,0 到65535
32位无符号整数, 0 到4294967295。
PowerBuilder 也支持 Any 数据类型, 可以容纳任何类型的值,包括阿标准数据类型,对象,结构和数组。类型为Any的变量是一个可变数据类型——可以赋值任何值。
不要在EAServer组件定义中使用Any
Any数据类型是特殊的,EASever组件的IDL不支持。CORBA也有Any数据类型,能够在运行时呈现任何合法的IDL类型,但语义上不等效于PowerBuilder 的Any类型。必须从组件接口定义中排除Any数据类型,但是可以在组件内部使用它。
可以声明Any变量为任何其他变量。也可以声明Any数组变量,每个元素能采用不同的数据类型。
赋值数据到Any变量,可采用标准赋值语句。能赋值任何数组到一个简单的Any变量。
赋值到Any变量后,能使用ClassName函数测试变量,找出实际的数据类型,例如:
any la_spreadsheetdatala_spreadsheetdata = ole_1.Object.cells(1,1).valueCHOOSE CASE ClassName(la_spreadsheetdata) CASE "integer" ... CASE "string" ...END CHOOSE
Any赋值的规则如下:
能赋值任何东西到Any变量,
必须知道Any变量的内容,才能赋值Any变量到兼容数据类型。
如果一个简单Any变量的值是数组,不能访问数组的元素直到给合适数据类型的数组变量赋值。
如果Any变量值是结构,你不能用点符号来访问结构的元素,直到你赋值给结构一个合适的数据类型的数据。
在Any变量赋值后,不能转换到普通Any变量,因为不能指定其数据类型。即使你赋值为NULL,它仍然保留赋值类型,直到你赋值另外一个值。
能在Any变量上指定操作,就像Any变量数据的数据类型对操作符很适合一样。如果数据类型不适合于操作符,一个执行错误将会产生。
例如,如果变量 ia_1和ia_2包含数字型数据,这个语句是有效的:
any la_3la_3 = ia_1 - ia_2
如果ia_1和ia_2是字符串,可以使用串联操作符:
any la_3la_3 = ia_1 + ia_2
但是,如果ia_1是数字,而ia_2是字符串,就会得到一个执行错误:
数据类型转换函数:
PowerScript 数据类型转换函数接收Any变量作为参数。当调用函数时,Any变量必容纳能转换为指定类型的数据。
例如,如果ia_any容纳字符串,能赋值到一个字符串变量:
ls_string = ia_any
如果ia_any是一个想转换为字符串的数字,你可以调用String函数:
ls_string = String(ia_any)
其他函数:
如果函数的原型不允许Any作为参数的数据类型,不能不通过转换函数而直接使用Any变量,即使他容纳正确类型的值。当编译脚本时,你将得到编译器错误,就像:Unknown function 或者Function not found。
例如,Len函数的参数指向DataWindow的字符串列,而表达式自身含有Any类型:
IF Len(dw_notes.Object.Notes[1]) > 0 THEN // 无效
Any表达式的字符串值显式转换为字符串:
IF Len(String(dw_notes.Object.Notes[1])) > 0 THEN
类型为Any的表达式:
获取类型为未知(unknown)的表达式在编译时其类型为Any。在OLE对象或者DataWindow对象中,这些表达式内含表达式或者函数:
myoleobject.application.cells(1,1).valuedw_1.Object.Data[1,1]dw_1.Object.Data.empid[99]
表达式指向的对象会改变,因此数据类型也会改变。
指向DataWindow数据的表达式能返回数组、结构或者结构的数组。为了更好的性能,赋予DataWindow 表达式到合适的数组或者结构,而不需要使用中间的Any变量。
不使用Any变量,而应该使用有效数据类型选择。有两个原因:
运行时采用Any变量会比较慢。
PowerBuilder必须做更多的处理,在赋值或者执行涉及Any变量的操作时决定数据类型。特别地,如果使用Any变量来替代适合的类型,循环中会执行许多时间的操作会遭受更多问题。
编译时,使用Any变量会移除程序的错误检查层。
PowerBuilder 编译器保证在代码执行以前数据类型是正确的。对于Any变量,一些编译器引起的错误在代码运行前不容易被发现。
对于PowerScript来说,系统对象是特殊的数据类型。在Browser的System标签中可以看到系统对象清单。
构建PowerBuilder 应用程序时,可操作诸如窗口window、菜单menu、按钮CommandButton、列表框ListBox和图形。PowerBuilder内部定义对象这些对象的每一个作为一种数据类型。通常不必关心这些对象数据类型自身,程序员可以在PowerBuilder 绘图区简单定义对象,并使用他们。
有时候程序员需要理解PowerBuilder 怎样在数据类型体系中维护系统对象。例如,当程序员需要定义窗口的实例时,程序员可定义数据类型为window的变量。当需要创建菜单实例在窗口中弹出时,可以定义数据类型为menu的变量。
PowerBuilder 在类体系中维护系统对象。每种对象类型都是类(class)。类形成祖先和后代的继承体系。
所有类均展示在Browser中,这些类都是数据类型,都能用到应用程序中,能定义任意类的变量。
例如,下面的代码定义了window和menu变量:
window mywinmenu mymenu
如果程序员在window中有几个按钮,需要跟踪其中一个,例如点击最后一个,可以声明CommandButton 变量,并赋值:
// 窗口中的实例变量commandbutton LastClicked// 窗口按钮的Clicked事件// 指示按钮是最后一个// 被用户点击的按钮LastClicked = This
LastClicked 变量有CommandButton的所有属性。最后赋值之后,LastClicked属性有和window中最近被点击的按钮同样的值。
和系统对象(system object)一样,枚举类型也是PowerScript特殊类型。有如下两种枚举类型:
函数参数 对象或者控件的属性通过Browser中Enumerated 标签,可以列出所有枚举类型。
不能创建自己的枚举类型,作为替代,可以声明常量变量集合并赋一个初始值。
枚举类型变量能赋值为固定集合。枚举值总是以感叹号结尾。例如:枚举类型Alignment,指定为文本对齐方式,有三个值Center!, Left!, and Right!
mle_edit.Alignment=Right!
不能使用引号来包含枚举值,否则会接收一个编译器错误:
Incorrect syntax 不正确语法
枚举类型相比标准数据类型有优势。当枚举类型被使用时,编译器检查数据,并保证其实正确类型。例如,如果你设置枚举变量到其他任何类型,或者不正确值,编译器不允许这样做。
先于EAServer 6.0, 所有EAServer 组件接口定义在标准 CORBA IDL中。下表列举了 EAServer Manager预定义的所有类型, CORBA IDL 类型和PowerBuilder 类型的映射。
EAServerManager | CORBA IDL | PowerBuilder |
Integer (16-bit) | Short | Integer |
Integer (32-bit) | Long | Long |
Integer (64-bit) | Long long | LongLong |
Boolean | Boolean | Boolean |
Float | Float | Real |
Double | Double | Double |
String | String | String |
Binary | BCD::Binary | Blob |
Decimal | BCD::Decimal | Decimal |
Money | BCD::Money | Decimal |
Date | MJD::Date | Date |
Time | MJD::Time | Time |
Timestamp | MJD::Timestamp | DateTime |
ResultSet | TabularResults::ResultSet | ResultSet |
ResultSets | TabularResults::ResultSets | ResultSets |
Void | Void | None |