---- 在PowerBuilder开发环境中,存在一个Powersoft资料库,它由五张表组成,记录了用户在开发过程中,创建或修改一张表属性的情况,如定义或修改表中各列的标签和列标题,有效性规则、显示格式 和编辑风格等。巧妙地使用这些表格,可减轻系统开发的工作量,提高开发效率,系统在运行过程中也易于维护。
---- 这五张表及分别存贮的信息如下:PBCatCol每列的名称、标题、标签及位置信息 ;PBCatEdt列的编辑风格及定义;PBCatFmt列的显示风格及定义;PBCatVld列的有效性规则及定义。下面介绍的是利用PBCatCol和PBCatEdt表,用户无须建立代码表,可实现由代码值求显示值的功能。
---- 在PBCatCol表中涉及的主要列及其含义如下: pbc_tnam:表名称 , pbc_cnam:表中某列的名称,pbc_edit:该列所对应的编辑风格;在PBCatEdl表中涉及的主要列及其含义如下: pbe_name:编辑风格名称,pbe_edit: 编辑风格可能的值包括代码、显示值或下拉式数据窗口的显示字段名、值字段名等,pbe_type:编辑风格的种类,如87表示下拉列表,88表示下拉式数据窗口等,pbe_seqn每个编辑风格的值的序号。不同的编辑风格在表中有不同的存贮格式。对下拉列表,第一个记录为开始的标志,而后各行依次存放下拉列表的各代码值、显示值;而下拉数据窗口,通常有三个记录,三个记录中的Pbe_edit列的值分别为数据窗口对象名称、代码字段名,显示值字段名。根据上述特性就可实现对任一给定表,已知某一列的代码值,求出其显示值。
---- 该功能由一个函数完成,输入参数为:表名、列名、代码值、存储显示值的字符串变量。返回值为整型,等于0未转换,大于0转换成功。实现方法:首先利用表名、列名在PBCatCol表中找到该记录,取出pbc_edit列的值,它表示该列定义的编辑风格的名称,如果为空表示未定义编辑风格,无须进行转换;否则,到PBCatEdl表中查找该编辑风格,按Pbe_seqn顺序找到第一个记录,从该记录中取出pbe_type列值,以判断编辑风格的类型。如果该值等于”87”, 表示编辑风格为下拉列表,转换方法:从PBCatEdl表中按Pbe_seqn列的序号依次取出Pbe_edit列的值,Pbe_edit列按照先显示值后代码值的顺序依次存诸下拉列表的每个条目,一旦找到代码值即可确定显示值;等于”88”,表示编辑风格为下拉数据窗口,转换方法:从PBCatEdl表中按Pbe_seqn列的序号依次取出三个记录中的Pbe_edit列的值,它们分别为提供数据源的数据窗口对象名称、用于存储的列名称,用来显示的列名称,而后对该数据窗口对象进行查找即可得到和存储的代码值对应的显示值。
附:程序清单(Powerbuilder 6.0运行通过)
//返加值等于False:未转换,True:转换成功
//fielddisp变量为reference类型的字符串变量, 用于返加显示值。
string s1,s2,vpbe_type,val1,val2
long ll_found
boolean findflag
datastore ds,ds1
findflag=False
//取出指定表、列的编辑风格
SELECT "pbcatcol"."pbc_edit"
INTO :s1
FROM "pbcatcol"
WHERE ( "pbcatcol"."pbc_tnam" = :tabname ) AND
( "pbcatcol"."pbc_cnam" = :fieldname ) ;
IF s1="" THEN
RETURN findflag //未指定编辑风格
END IF
//取出编辑风格数据
DECLARE t1 CURSOR FOR
SELECT "pbcatedt"."pbe_edit" ,
"pbcatedt"."pbe_type"
FROM "pbcatedt"
WHERE "pbcatedt"."pbe_name" =:
s1 ORDER BY "pbcatedt"."pbe_seqn";
OPEN t1;
FETCH t1 INTO :s2 ,:vpbe_type;
CHOOSE CASE vpbe_type
CASE "88"
//建立数据存储,用于表示下拉式数据窗口对应的数据窗口对象
ds=CREATE datastore
ds.dataobject=s2
ds.SetTransObject(sqlca)
ds.Retrieve()
//存取显示值、存储值的列名
FETCH t1 INTO :val1 ,:vpbe_type;
FETCH t1 INTO :val2 ,:vpbe_type;
CLOSE t1;
//在数据窗口对象中进行查找
s2=val1+"="+"''"+fieldvar +"''"
ll_found = ds.Find(s2,1,ds.RowCount())
IF(ll_found>0 ) THEN
//取出给定代码值的显示内容
fielddisp=ds.GetItemString(ll_found,val2)
findflag=true
END IF
DESTROY ds
CASE "87"
FETCH t1 INTO :s2 ,:vpbe_type; //从下拉列表取数据
DO WHILE (sqlca.sqlcode = 0 AND NOT Findflag)
fielddisp=s2 //当前显示内容
FETCH t1 INTO :s2,:vpbe_type; //当前显示内容对应的代码
IF(sqlca.sqlcode <> 0) THEN
EXIT
END IF
IF s2=fieldvar THEN //等于给定代码值
findflag=true
CONTINUE
END IF
FETCH t1 INTO :s2,:vpbe_type ;
LOOP
END CHOOSE
CLOSE t1;
RETURN findflag