PowerBuilder文摘
首页 | 原创 | 译文 | 转载 | 源码 | 工具 | 灌水 | 全部 | PB助手 | 相册 | 留言 | 登陆 | 注册
公告

今天你PB了吗?
今天你摘了吗?
欢迎来到PB文摘:)

我的网摘

统计信息
日志: 54
评论: 821
到访: 795146 [统计]
今日: 13
用户: 202 [列表]
在线: 1
日历
2021 - 04
    123
45678910
11121314151617
18192021222324
252627282930 
最新日志
最新评论
搜索
归档
友情链接
杂项
Get RSS Feed (Version 1.0)
Get RSS Feed (Version 2.0)
Get Atom Feed (Version 0.3)
编码:  UTF-8
Creative Commons
Powered by Bo-Blog V1.6.1114
利用PB动态创建数据窗口
2006年7月13日09:53星期四  [转载]

 摘自: 51cto.com

利用PowerBuilder建立数据窗口时,用户通常不能自己选择数据来源和显示类型。如何让用户在应用程序中自己定义数据窗口的数据来源和显示类型呢?为了达到这个目的,我们必须在运行程序阶段根据用户自己的需求,动态地建立一个数据窗口。

在建立动态数据窗口之前,必须先得到数据窗口对象的语法,PB中为我们提供了SyntaxFromSQL( )函数,利用这个函数可以得到建立数据窗口的语法。SyntaxFromSQL()函数的基本格式如下:

事物对象.SyntaxFromSQL(数据来源字符串,显示类型字符串,错误字符串)

下面是建立一个数据窗口对象语法的范例∶

// 声明变量

string ls_sql, ls_present,ls_err, ls_syntax

// 定义数据窗口的数据来源

ls_sql = "select emp_id from employee"

//定义数据窗口显示字符串

ls_present = "style(type=tabular)"

// 得到建立数据窗口对象语法

// 如果错误发生,SyntaxFromSQL 返回一个空字符串

ls_errls_syntax = SQLCA.SyntaxFromSQL(ls_sql, ls_present , ls_err)

利用 SyntaxFromSQL( )所建立的数据窗口对象是在运行阶段才建立的对象,并不会自动保存在PB的对象数据库 Library 中。为了以后可以重复使用这个数据窗口对象,可以利用 LibraryImport( )函数保存数据窗口对象。

在利用 SyntaxFromSQL( )函数建立一个数据窗口语法后,必须将它与窗口上的数据窗口控件结合,这个数据窗口控件必须已经存在于窗口中 。要将数据窗口对象语法和一个已经存在的数据窗口控件结合,必须利用Create( )函数,下面是范例程序∶

// 声明变量string ls_syntax ,ls_err

ls_errdw_1.Create(ls_syntax, ls_err)

dw_1.SetTransobject(SQLCA)

dw_1.retrieve( )

在上面程序中,ls_syntax是运行SyntaxFromSQL( )函数后所返回的字符串。除此之外,也可以利用LibraryExport( )函数从PB对象数据库中得到已经存在于PBL中的数据窗口对象语法。因为Create( )函数会破坏先前数据窗口与事物对象的结合,所以必须利用SetransObject( )函数重新结合事物对象给新的数据窗口对象,最后再运行Retrieve( )函数,从数据库中读取数据。

最后,我们需要利用SQL 语句字符串,动态创建一个新的数据窗口对象到一个数据窗口控件当中。虽然,在运行阶段并不能直接在窗口上建立一个数据窗口控件,但却可以利用用户对象建立一个与窗口上一样的数据窗口控件,在运行阶段时再动态打开这个用户对象。下面是动态建立数据窗口控件的步骤∶

在用户对象画板内,建立一个标准数据窗口的用户类。

可以在这个控件中增加功能、程序、用户对象函数和用户自定义事件后,保存用户对象到对象数据库中。

利用 OpenUserObject( )函数建立一个数据窗口用户对象的复件,一般格式如下∶OpenUserObject(用户对象变量,{ x坐标值,y坐标值 })。下面是在窗口上鼠标点击的坐标位置建立一个用户对象 u_dw的范例∶ OpenUserObject(u_dw, Pointerx( ),Pointery( ))

以上是建立一个动态数据窗口的基本步骤,感兴趣的朋友不妨一试。



阅读全文
Posted by tigerchamp | 评论(12) | 阅读2003次
浅析PowerBuilder下动态SQL语句
2006年7月13日09:36星期四  [转载]

 
http://www.51cto.com 2005-09-21 11:23 作者:51cto.com整理 出处:51cto.com  
 
 PowerBuilder是目前最流行的数据库开发工具之一。PowerBuilder提供了在程序代码中加入嵌入式SQL语句的功能来支持对数据库的访问。但这种嵌入式SQL语句只能支持一些固定的标准的SQL语句,即在进行程序代码编译处理时这些SQL语句必须是确定的,另外这种方式也不能执行像Creat Table,Creat Database等这些数据库定义的语句(DDL)。

因此这种嵌入式SQL语句在实际应用中有一定的局限性。为克服这种方式的局限性,可以使用PowerBuilder提供的动态SQL语句,这种对数据库访问的方式可以完成嵌入式SQL语句无法实现的功能。如建库、建表这一类的数据库定义语句(DDL);其次,由于动态SQL语句允许在执行时才确定到底要执行怎样的SQL语句,因此使用动态SQL语句可以使程序实现参数化设计,具有很大的灵活性和通用性。

一、动态SQL语句的应用分析 PowerBuilder提供了四种格式的动态SQL语句,每种格式都有自己不同的特点和作用。

(一)第一种格式

当执行没有输入参数并且没有返回结果集的SQL语句时可以使用这种格式,这种格式使用比较简单,其实现的操作也比较少。

1语法

EXECUTE IMMEDIATE SQLStatement{ USING TransactionObject };

其中SQLStatement是要执行的SQL语句,可以直接用引号将要执行的SQL引起来用,或者用字符串变量的形式提供SQL语句。通过使用字符串变量可以在具体执行的时候才指定要执行什么样的SQL语句。TransactionObject是用户所使用的事务对象,缺省为SQLCA。

2应用实例

①建立一张数据库表(base),SQL语句的表述用引号引起来直接使用。

EXECUTE IMMEDIATE‘CREATE TABLE base(code char(6),name char(30))’USING SQLCA;

②执行对数据库记录的操作,在表base中插入一条记录,SQL语句通过字符串变量传递执行语句。

STRING lsSQL

LsSQL=”INSERT INTO TABLE base VALUES(’320201’,’市中区支行’)”

EXECUTE IMMEDIATE:lsSQL;

(二)第二种格式

当执行带输入参数但没有返回结果集时的SQL语句可以采用第二种格式。该格式不仅可以动态地指定要执行的SQL语句,同时还可以动态地确定SQL语句所需要的参数值。

1语法

PREPARE DynamicStagingArea FROM SQLStatement{ USING TransactionObject };

EXECUTE DynamicstagingArea{ USING Parameterlist };

其中:DynamicstagingArea是PowerBuilder提供的一种数据类型。PowerBuilder本身提供了一个名字为SQLSA的DynamicstagingArea类型的全局变量,用于保存要执行的动态SQL语句信息。

2应用实例

删除base表中的满足一定条件的记录。

STRING lsCode

lsCode=”320101”

PREPARE SQLSA FROM“DELETE base WHERE code=?”;

EXECUTE SQLSA USING:lsCode;

(三)第三种格式

当执行有输入参数并且返回结果集的格式在编译时可以确定的SQL语句时可以使用第三种格式。这种格式语法比较复杂,但要比前面两种功能强,可以返回结果集。在返回结果时由于不知道满足过滤条件的记录到底有多少条,因此第三种格式通常采用游标的形式。

1语法

DECLARE cursor DYNAMIC CURSOR FOR DynamicStagingArea;

PREPARE DynamicStagingArea FROM SQLStatement{ USING TransactionObject };

OPEN DYNAMIC cursor { USING Parameterlist };

FETCH cursor INTO VariableList;

CLOSE cursor;

其中cursor是用户所定义的游标的名字。

2应用实例

将表base中的code字段中间两位为”01”的所有记录读取出来并分别进行相应处理。

STRING lsSQL,lsCode,lsName,lsFilter

LsFilter=”01”

LsSQL=”SELECT code,name FROM base WHERE substring(code,3,2)=?”

DECLARE cursor_base DYNAMIC CURSOR FOR SQLSA;

PREPARE SQLSA FROM:lsSQL;

OPEN DYNAMIC cursor_base USING:lsFilter;

FETCH cursor_base INTO:lsCode,:lsName;

DO WHILE SQLCA.SQLCODE=0

 . ∥对满足条件的记录根据要求分别进行处理

 . FETCH cursor_base INTO:lsCode,:lsName;

LOOP

CLOSE cursor_base;

(四)第四种格式

当执行有输入参数并且返回结果集的格式在编译时无法确定的SQL语句时可以使用第四种格式。有时候我们执行一些SQL语句时,不仅带有参数而且返回的结果集中有多少个字段,每个字段是什么类型的数据都不确定,这时只能使用第四种格式来实现。

1语法

PREPARE DynamicStagingArea FROM SQLStatement{ USING TransactionObject };

DESCRI...

阅读全文

Posted by tigerchamp | 评论(12) | 阅读2167次
Pb中定制打印页长
2006年7月12日10:52星期三  [转载]

---- 在使用连续纸打印数据窗口的情况下,需要定制打印的页长,以保证打印机走纸正确,不用人工干预,实现连续打印。在PB中须调用外部函数来自定义纸张长度,比较繁琐。本文介绍一种直接对打印机的控制方法,简单实现对页长的设定。


---- 一、 预备知识


---- 计算机与打印机的通讯使用ASCII码进行,其中标准ASCII码包括可打印字符及非打印字符(控制码),打印机使用控制码来定制打印机。大多数打印机指令使用控制码escape作为其指令序列的第一个序列码。下面介绍本文用到的几个指令码序列:


设置换行量(行距)1/8 英寸
ASCII码 ESC 0
十进制码 27 48


设置以行为单位的页长
ASCII码 ESC C n


十进制码 27 67 n
其中n 为每页行数范围(1-127)

---- 二、 PB中控制码的传送及定制页长的实现


---- 在PB中通过函数Printsend(printjobnumber,string,{ zerochar })来实现向打印机发送控制码。各参数定义如下:


printjobnumber: 由printjob()函数返回的打印作业号;
string:         控制字符串,使用ASCII码;
zerochar:       用来替代string中的数字0;

---- 由于字符串中,0终止字符串,如果string 中包含0,则需利用其他字符来表示0,参数zerochar即为此用途而设,当PB发送控制字符串给打印机时,把替代的字符zerochar转化为0。


---- 下面是具体的完成定制页长打印数据窗口的程序(定制页长为2.75英寸):


long ll_job
dw_print.reset()
ll_job = printopen()
if ll_job = -1 then
messagebox(gs_title,"打印机未准备好")
return
end if
//定制行距1/8英寸
PrintSend(ll_job, CHAR(27)+CHAR(48))
//设定页长22行
PrintSend(ll_job, CHAR(27)+CHAR(67)+CHAR(22))
printdatawindow(ll_job,dw_print)
printclose(ll_job)
摘自: http://www.cnread.net/cnread1/dnwl/cxsj/pb/syjq/014.htm


阅读全文
Posted by tigerchamp | 评论(4) | 阅读1749次
将人民币金额转换成大写的金额
2006年6月30日01:48星期五  [转载]


提供两种方法:

//////////////////////////////////////////////////////////////////////
//将钱数转化为大写
//////////////////////////////////////////////////////////////////////
constant string ls_bit = "万仟佰拾亿仟佰拾万仟佰拾元角分"
constant string ls_num = "壹贰叁肆伍陆柒捌玖"
long lmax = len( ls_bit ) + 1
string ls_je, ls_dw, ls_result = ''
long ll_len, i, k
ls_je = string( data, "#############.00" )
ll_len = len( ls_je ) - 1
ls_je = replace( ls_je, ll_len - 1, 1, '' )
for i = ll_len to 1 step -1
lmax -= 2
ls_dw = mid( ls_bit, lmax, 2 )
k = long( mid( ls_je, i, 1 ) )
if k = 0 then
choose case ls_dw
case '元','万','亿'
ls_result = ls_dw + ls_result
case '分'
ls_result = '整'
case '角'
if ls_result <> '整' then ls_result = '零' + ls_result
case else
choose case left( ls_result, 2 )
case '万', '亿', '元', '零'
case else
ls_result = '零' + ls_result
end choose
end choose
else
ls_result = mid( ls_num, k * 2 - 1, 2 ) + ls_dw + ls_result
end if
next
return ls_result


--------------------------------------------------------
//入口参数:DECIMAL numb
INTEGER i //循环变量
STRING s_numb //以字符串表示
STRING s_money
INTEGER i1
s_numb = String(numb,"########.00")
IF Len(s_numb) < 11 THEN s_numb = Space(11-len(s_numb))+s_numb
i = 1
s_money = ""
//去掉前导空格
DO WHILE i<8 AND Mid(s_numb,i,1) = " "
i ++
LOOP

i1 = 11 - i + 1

INTEGER digit
DO WHILE i<=4
digit = Integer(Mid(s_numb,i,1))
IF digit = 0 THEN
DO WHILE i<=4
digit = Integer(Mid(s_numb,i,1))
IF digit <>0 THEN exit
i ++
LOOP
IF i<=4 THEN s_money += "零"
ELSE
s_money += Mid("壹贰叁肆伍陆柒捌玖",digit*2-1,2) +&
Mid("仟佰拾万",i*2-1,2)
i ++
END IF
LOOP

IF i1 >= 8 THEN
IF Integer(Mid(s_numb,4,1)) = 0 THEN s_money += "万"
END IF

DO WHILE i<=8
digit = Integer(Mid(s_numb,i,1))
IF digit = 0 THEN
DO WHILE i<=8
digit = Integer(Mid(s_numb,i,1))
IF digit<>0 THEN exit
i ++
LOOP
IF i<=8 THEN
s_money += "零"
ELSE
IF Integer(Mid(s_numb,1,8)) <> 0 THEN
s_money += "元"
IF Integer(Mid(s_numb,11,1))<>0 THEN s_money += "零"
END IF
END IF
END IF
IF digit <> 0 THEN
s_money += Mid("壹贰叁肆伍陆柒捌玖",digit*2-1,2) + &
Mid("仟佰拾万仟佰拾元",i*2-1,2)
END IF
i ++
LOOP

digit = Integer(Mid(s_numb,10,1))
IF digit<>0 THEN
s_money += Mid("壹贰叁肆伍陆柒捌玖",digit*2-1,2) + "角"
ELSE
IF Integer(Mid(s_numb,11,1))<>0 AND Integer(Mid(s_numb,1,9)) <> 0 THEN
s_money += "零"
END IF
END IF

digit = Integer(Mid(s_numb,11,1))
IF digit <> 0 THEN
s_money += Mid("壹贰叁肆伍陆柒捌玖",digit*2-1,2) + "分"
ELSE
IF Len(Trim(s_money)) <> 0 THEN s_money += "整"
END IF

RETURN s_money

摘自: http://www.computernews.com.cn/Article/2004-10-13/4368.html

阅读全文
Posted by tigerchamp | 评论(7) | 阅读1789次
SYBASE数据库浏览器
2006年6月30日01:42星期五  [工具]

自己给自己做个广告吧。

     SYBASE数据库浏览器1.0 新鲜出炉!她独特的数据库界面显示,体贴的人性化设计定能令您眼前一亮。四大独门绝技:主/从表同步显示更新、 数据块拷贝粘贴、表数据查找替换、任意缩放的打印预览,让您笑傲同侪,独步江湖,复杂的数据库操作从此游刃有余。
      PB + SYBASE 开发的最佳拍档:PB小助手 + SYBASE数据库浏览器 !

主/从表同步修改,彻底摆脱外键约束!可自定义主/从表关联;
支持表中数据的块拷贝、粘贴;
对表中显示的数据进行查找及替换;
功能强大的打印预览功能;
列选择定义自动保存,在下次该表打开时仅显示相关定义列 ……
本地下载                 天空下载  华军下载  CSDN下载



阅读全文
Posted by tigerchamp | 评论(3) | 阅读1585次
PB小助手
2006年6月30日01:34星期五  [工具]

自己给自己做个广告吧。

欢迎使用PB小助手。作为一名PB程序员,您是否有过为了查找某一语句而不辞辛劳地打开一个又一个事件或函数,在其脚本中苦苦寻觅的痛苦经历;而为了找到某一变量或函数的定义,您不得不在错综复杂的对象继承关系中刨根溯源、上下求索。有了PB小助手,这些问题都将迎刃而解。她能帮您在一大堆对象或脚本中迅速找到您想要的,快人一步,胜人一筹!

对象检索。在PB应用中搜索名称中包含指定字符串的对象;
脚本检索。在PB应用源码中搜索指定字符串;
辅助注释。按自定义模板格式插入代码注释;
浮动窗口。工具条窗口显示,操作简单快捷;
代码统计。想知道您写了多少代码?来试试吧。
代码美化。按缺省的缩进格式对代码进行整理美化。
代码浏览。PowerScript语法高亮显示。
PB工具栏。自动集成到PB IDE工具栏,操作更方便快捷。



阅读全文
Posted by tigerchamp | 评论(3) | 阅读1552次
PB11 Beta release
2006年6月16日08:15星期五  [原创]

PB11可以方便地将PB程序转成.net 的WebForm或WinForm的应用,这是在网上找到的PB11 Deploy 到ASP.net的截屏。menu, toolbar, tabpage一应俱全,看上去不错。



阅读全文
Posted by tigerchamp | 评论(3) | 阅读1856次
PB10.5 新特性
2006年6月1日01:33星期四  [原创]

在code examples目录有一个新的目录New DataWindow and UI,里面展示了一些关于DW & UI的新特性,有兴趣的可以看一下:

新的Menu & Toolbar

TreeView DW



以下是从pdriver.com上收集的:
powerbuilder 10.5新功能
从sybase下了个powerbuilder 10.5 beta版,整理了帮助中新功能介绍如下:
1、PB控件
1)增加了MonthCalendar和DatePicker控件
对MonthCalendar控件
a. 如果是EditMask control ,编辑属性时,选择'Maskdatatype'为'datemask!'或'datetimemask!'后,激活'drop-down calendar'选项框,选择打勾,运行程序后可以移动到EditMask control 处直接下拉选择框出现MonthCalendar日历控件
b. 数据窗体日期字段可以设置下拉MonthCalendar 形式的日历,可在constructor等事件中 加入如下语句实现:
dw_1.Modify(字段名称+".EditMask.DDCalendar='Yes'")
运行程序后,可以对字段名称直接下拉选择框出现下拉日历控件
2)DatePicker的ValueChanged事件,MonthCalendar的DateSelected 事件
DatePicker的ValueChanged事件 和MonthCalendar的DateSelected事件中可以加入相关代码.比如可以加入如下代码修改single-line edit box文本编辑框的text值:
date dt_selected
integer li_ret
string ls_date
li_ret = GetSelectedDate( dt_selected)
ls_date = string(dt_selected)
sle_2.text = ls_date
3). Animation动画控件
       好像只能设置avi后缀名的非压缩或BI_RLE8格式压缩的影像文件.

4)、InkEdit和InkPicture控件
InkEdit:借助Tablet PC(图形输入板)和Tablet PC的书法识别引擎可以转换写入信息为文本;
InkPicture: 借助Tablet PC可以把写入信息叠在一张图片上,可以为图片加注释或直接用来签名.
2、新增调用扩展和decimal数值类型支持
1)可以直接在System Tree通过右键弹出式菜单' imported PB extension '导入 主程序搜索目录下的.pbx or .dll 后缀名文件到库中,省去以前版本 要同时拷贝 PBX or DLL 文件并设置运行时的主程序搜索目录;
2)decimal数值类型由支持以前版本的18 digits 到32digits.datawindow中的表达式也对此提供相关支持.



阅读全文
Posted by tigerchamp | 评论(90) | 阅读3923次
Sybase中文新闻组
2006年5月26日09:41星期五  [原创]

news server: forums.sybase.com
group: sybase.public.chinese.powerbuilder.general

没事可以上去看看,发发牢骚,呵呵。这些天比较忙,又没摘些新东西,抱歉。



阅读全文
Posted by tigerchamp | 评论(3) | 阅读1914次
PB动态报表格式自由定义的实现
2006年4月20日03:55星期四  [转载]

  在通常的Server/Client方式MIS开发中,总是有没完没了的报表需要制作,调试报表花费的时间也是最多而且乏味,还常常不能满足客户的要求。要是能够让用户自己调整报表的格式和内容,然后将它保存下来,程序下次启动时它自动调用保存了的报表格式那有多好。本人通过如下方法最终实现了用的要求。
PB(PowerBuilder)有一种以PSR结尾的特殊的保存报表的文件格式(本文简称作PSR文件)。根据数据窗口可以直接读取PSR文件生成报表的原理,程序通过生成PSR文件,实现动态报表格式的保存。

  一、实现原理:

  PB中的报表其实就相当于是数据窗口。

  第一步,动态报表的实现。通过设置数据窗口对象(dataobject)中文本、列等的Resizeable和moveable属性为1来实现对象位置的拖动控制,通过数据窗口的Modify函数实现对象值的更改(包括增加和删除)。

  第二步,报表格式的保存。在一个应用当中,数据窗口对象的名称总是唯一的,将每一个数据窗口对象转化成PSR文件存于数据库表中。在窗口打开时,程序先校验报表格式是否存在。如果存在,先将报表格式读取出来放在一个临时文件当中,然后设置数据窗口(datawindow)的数据对象(dataobject)为这个报表文件,然后提取数据;如果不存在,直接提取数据即可。

  二、实现过程:

   1、建立一个数据库表用以保存报表格式文件。
表名:dyn_report  
Dwobject Varchar2(20) 数据窗口对象名称 Primary key  
Rptitle Varchar2(80) 报表的标题名称    
Memo Long raw  报表格式    

   2、建立一个窗口w_temp。 定义实例变量如下:

   string is_dwtype,is_dwobject //保存报表中对象的类型及名称

控件名称  控件含义  
Dw_print 数据窗口对象  
Cb_exit 退出按钮
Cb_savereport  报表格式保存按钮  
  
   3、在窗口的OPEN事件中加入如下代码, 校验报表格式是否存在
  blob emp_pic
   long ll_handle
   string ls_dwobject,ls_reportfile,ls_path
   ls_dwobject = dw_print.dataobject
   //判断是否存在该数据窗口的报表格式
   select count(*) into:ll_count from dyn_report where dwobject =:ls_dwobject;
   if ll_count>0 then
     //读取报表格式文件到大文本变量
     selectblob memo into:emp_pic from dyn_report where dwobject =:ls_dwobject;
     //创建psr临时文件到硬盘
     ls_reportfile = '\temp7089.psr'
     ll_handle = FileOpen(is_reportfile,StreamMode!,write!,LockWrite!,Replace!)
     FileWrite(ll_handle,emp_pic)
     FileClose(ll_handle)
     dw_print.dataobject = ls_reportfile
     dw_print.settransobject(sqlca)
   else
     Dw_print.settransobject(sqlca)
   End if
   Dw_print.retrieve()
   4、报表格式的保存。通过Cb_savereport按钮的clicked实现。
   string ls_filename
   long ll_count
   blob Emp_id_pic
   ls_filename = "temp70201.psr"
   //保存报表格式到硬盘临时文件
   dw_print.saveas(ls_filename,PSReport! ,false)
   sqlca.autocommit = true
   select count(*) into :ll_count from dyn_report where dwobject =:is_dwobject;
   if ll_count =0 then
     insert into dyn_report(dwobject,rptitle)
     values(:is_dwobject,:ls_filename,:ls_path);
   end if
   //从硬盘临时文件读取数据保存到数据库表中
   emp_id_pic = of_readbmpfile(ls_filename)//该函数将二进制文件内容读到大文本对象中
   //更新数据库
   UPDATEBLOB dyn_report SET memo = :Emp_id_pic where dwobject = :is_dwobject;
   sqlca.autocommit = false


  5、动态报表的实现。通过数据窗口dw_print的clicked事件捕获数据窗口中对象,并将对象名存放在实现变量is_dwobject中,为下一步修改报表作准备。

   string ls_type,ls_dwoname
   //得到对象类型和名称
   ls_type = trim(upper(dwo.type))
   ls_dwoname = trim(dwo.name)
   is_dwtype = ls_type
   choose case ls_type
     case "TEXT...

阅读全文

Posted by tigerchamp | 评论(1) | 阅读1678次