pb笔记(二)

PowerBuilder相关 专栏收录该内容
1 篇文章 0 订阅
 

pb笔记(二)

 

//DWDBError事件

string          error_text

CHOOSE CASE sqlDBCode

          case 1                   error_text = '违反唯一索引!'

             case 1400          error_text = '字段不能为空!'

             case 1407          error_text = '字段不能为空!'

          case 1401          error_text = '字段太长!'

          case 1438          error_text = '数值大于列允许的最大精度!'

          case 2291          error_text = '出现非法字段!'        

          case 1031          error_text = '权限不足!'

          case 911          error_text = '注册名无效!'                  //权限专用

          case 922          error_text = '特殊字符无效!'          //权限专用       

          CASE 1017          error_text = '非法的用户名或口令,拒绝登录!'

          CASE 12154          error_text = '不能分解服务名称!'

          CASE 01005          error_text = '未给出口令或口令错误,拒绝登录!'

          CASE 01935          error_text = '注册名项输入的名称为系统关键字,禁止作为注册名使用!'

          CASE 540          error_text = '数据表或视图不存在!'

          CASE 942          error_text = '数据表或视图不存在!'

          CASE 903          error_text = '非法列名!'

          CASE 1403          error_text = '未查找到符合条件的数据!'               

          CASE -3                  error_text = '在您读入数据和存盘操作过程中,服务器中的数据已被别的用户或窗口改变,请重新读取数据后再试!'

          CASE 6                  error_text = '网络同数据库服务器的连接已经中断,请关闭应用程序然后重新打开.'

          CASE 50                  error_text = '网络同数据库服务器的连接已经中断,请关闭应用程序然后重新打开.'               

          case 1920          error_text = '用户名称与另外的用户或角色名称冲突'

          case 988          error_text = '缺少口令或其非法!'

          case 1918          error_text = 'ORACLE用户不存在!'

          case 1940          error_text = '不能放弃一个当前被连接的操作员,即当前删除的操作员正在使用!'

          CASE ELSE

                  if isnull(sqlca.sqlErrText) or sqlca.sqlErrText = '' then

                          error_text = '数据操作失败!'

                  else

                          error_text = sqlca.sqlErrText

                  end if

END CHOOSE

return MessageBox('错误',error_text,RetrYCancel!,1)       

//DBError参数

Buffer                  发生错误所在的缓冲区

Row                          发生第一笔错误的行数

SqlDBCode          数据库错误代码

SqlErrText          数据库错误信息

 

 

//MessageBox(title,text,icon,button,default)

icon参数:

information!          提示(缺省)

stopSign!                  中止

exclamation!          警告

question!                  询问

none!                          没有

button参数:

ok!                                  确定(缺省)

okCancel!                  确定,取消

yesNo!                          ,

yesNoCancel!          ,,取消

retryCancel!          重试,取消

abortRetryIgnore! 终止,重试,忽略

 

 

//如何在DBError event中处理多笔数据的错误

Rollback Using SQLCA;

If buffer = primary! Then

          Messagebox("error in row:" + string(row),"Code:" + string(sqldbcode) + "," + sqlerrtext)

          This.scrollToRow(row)

          return 1          //避免显示PB缺省的错误信息

end if

 

 

//数据窗口的规则检查

当用户在编辑控件中输入数据时,数据并不会立即写入数据窗口的缓冲区中,直到发生下面任何一种情况,

PowerBuilder才会把数据从编辑控件写入数据窗口的缓冲区中.

1.用户按下Enter

2.用户按下Tab键跳到下一个字段

3.用户按下鼠标键跳到其它字段

4.运行AcceptText()函数

在完全通过4个步骤的规则检查后,才会真正把数据从编辑控件写入数据窗口缓冲区.任何一个步骤的错误

都会产生数据窗口的ItemError Event.数据窗口的数据规则检查步骤如下:

1.数据是否改变?

2.数据类型是否符合?

3.是否符合用户自定字段规则?

4.是否符合ItemChanged Event的程序?

 

 

//编辑控件函数

AcceptText():将编辑控件中的数据写入数据窗口缓冲区中.

不要在ItemchangedItemError event中编写Acceptext()函数,因为Acceptext()函数有可能驱动

ItemChangedItemError event,这将造成死循环的出现.

GetText():读取编辑控件的文字.

 

 

//每一个事件event和函数Function类似,会有参数argument和返回值return value.

ItemChanged Event返回值:

0.接受数据的值(缺省)

1.拒绝数据的值

2.拒绝数据的值并改变焦点

ItemError Event返回值:

0.拒绝数据的值,并且显示系统错误信息(缺省)

1.拒绝数据的值,但是不显示系统错误信息

2.接受数据的值

3.拒绝数据的值并改变焦点

 

 

//dwupdate属性

Where 条件子句的产生方式:

1. Key Columns:比较原始数据缓冲区和当前数据库的数据时所产生的where子句条件不够严谨,所以在同

一个时间内,当很多的用户在一起使用数据库时有可能会发生将别人所更改过的数据覆盖的情况.为了

避免这样的情况发生,通常我们会将KeyColumns的方式用在单一用户或是关系表格中,所有的字段都是

Primary Key的情况.

2.Key and Updateable Columns:因为在比较原始数据缓冲区内的数据和当前数据库的数据时所产生的

where条件子句非常的严谨,所以在同一个时间内,当很多的用户一起使用数据库时,不会发生将别人所

更改过的数据覆盖的情况.因此,我们可以得到数据保存时最大的一致性.

3.Key and Modified Columns:因为在比较数据缓冲区内的数据与当前数据库的数据时所产生的where子句

条件比较有弹性(当前所要修改Modified的字段的数值),所以在同一个时间内,当很多用户一起使用数据

库时,可能会发生将别人所更改过的数据覆盖的情况.

主要字段(Key Column)的修改的方式:

1.Use Delete then Insert:这是数据窗口在主要字段(Key Column)的修改时的缺省选项,选用这种方式

修改数据时,数据会先被删除然后再重新增加一笔数据.但是在使用上要特别注意的是,如果在关系

数据库中,当设计删除为Cascade Delete,在修改数据时候可能会导致其它不希望删除的数据被删除.

另外,在选择字段时必须要选择所有的字段,否则会没有办法再重增加一笔数据.

2.Use Update:这个选项会直接修改Key字段的数值,但是并不是所有的关系数据库(DBMS)都提供这样的

功能.

 

 

//动态数据窗口

数据窗口对象语法:

ls_syntax = sqlca.syntaxFromSql('select kind,name from tab_t','style(type=tabular)',ls_err1)

dw_1.create(ls_syntax,ls_err2)

dw_1.setTransObject(sqlca)

dw_1.retrieve()

 

 

//读取多行数据

1. DECLARE说明游标;(后无须检查SQLCode属性,要使用分号结束该语句。)

2. OPEN语句打开游标;

3. 使用FETCH语句读取一行数据;

4. 处理数据;

5. 判断是否已经读完所有数据,未读完时重复执行35步;

6. 使用CLOSE语句关闭游标。

int Emp_num

string Emp_name

DECLARE Emp_cur CURSOR FOR

          SELECT employee.emp_number, employee.emp_name FROM employee;

open emp_cur;

FETCH Emp_cur INTO :Emp_num, :Emp_name ;

          if sqlca.sqlcode = -1 then

                  rollback;

                  messagebox('','')

                  return

          end if

CLOSE Emp_cursor;

 

 

//动态SQL(有四种类型)

//1.既无输入参数、也无结果集

string Mysql

Mysql = "CREATE TABLE Employee "&

          +"(emp_id integer not null,"&

          +"dept_id integer not null,"&

          +"emp_fname char(10) not null,"&

          +"emp_lname char(20) not null)"

EXECUTE IMMEDIATE :Mysql USING SQLCA;

//2.有输入参数、但没有结果集

int Emp_id_var = 56

PREPARE SQLSA FROM "DELETE FROM employee WHERE emp_id=?" ;

EXECUTE SQLSA USING :Emp_id_var ;

//3.编译时已经知道参数和结果集的列(游标或存储过程)

int Emp_id_var

String Emp_state_var = "北京",Sqlstatement

Sqlstatament = "SELECT emp_id FROM employee WHERE emp_state = ?"

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA;

PREPARE SQLSA FROM :Sqlstatement;

OPEN DYNAMIC my_cursor using :Emp_state_var;

FETCH my_cursor INTO :Emp_id_var;

          if sqlca.sqlcode = -1 then

                  rollback;

                  messagebox('','')

                  return

          end if

CLOSE my_cursor;

//

int Emp_id_var

String Emp_state_var = "北京",proc,ls_error,ls_prompt

proc = "execute bb_pstn_complete_wp_p(?)"

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA;

PREPARE SQLSA FROM :proc;

OPEN DYNAMIC my_cursor using :Emp_state_var;

          if sqlca.sqlcode = -1 then

                  ls_error = sqlca.sqlErrText

                  rollback;

                  MessageBox('提示信息','过程执行失败!' + char(13) + ls_error)

          end if

FETCH my_cursor INTO :Emp_id_var;

          if li_flag = -1 then

                  rollback;

                  MessageBox('提示信息','过程执行失败!' + char(13) + ls_prompt)       

          end if

CLOSE my_cursor;

//4.开发程序时尚不知道参数和结果集

string Stringvar, Sqlstatement

int Intvar

Sqlstatement = "SELECT emp_id FROM employee"        

PREPARE SQLSA FROM :Sqlstatement ;

DESCRIBE SQLSA INTO SQLDA ;

DECLARE my_cursor DYNAMIC CURSOR FOR SQLSA ;

OPEN DYNAMIC my_cursor USING DESCRIPTOR SQLDA ;

FETCH my_cursor USING DESCRIPTOR SQLDA ;

//FETCH语句执行成功时,动态描述区SQLDA中包含了结果集的第一行数据,反复执行FETCH语句即可得到

//其余数据。SQLDA.NumOutputs中包含了输出参数的个数。SQLDA.OutParmType数组中包含了各参数的数据

//例如TypeInteger!, TypeString!,使用CHOOSE CASE语句针对不同的输出参数类型调用不同的对象

//函数得到相应参数的值。

CHOOSE CASE SQLDA.OutParmType[1]

             CASE TypeString!

                     Stringvar = GetDynamicString(SQLDA, 1)

      CASE TypeInteger!

              Intvar = GetDynamicNumber(SQLDA, 1)

END CHOOSE

CLOSE my_cursor;

//DECLARE语句外,其它语句执行后都应该检查事务对象的SQLCode属性,以判断当前SQL语句的执行是否

//成功。

 

 

//得到下拉数据窗口中的显示值

ls_value = dw_1.Describe("Evaluate('LookupDisplay(column_name)',"+string(row_number)+")")

 

//固定数据窗口前几列的方法,例如第一列名为“id”,固定该列且后半部分从下一列开始显示:

dw_1.HSplitScroll = True

dw_1.Object.DataWindow.HorizontalScrollSplit = dw_1.object.id.Width

dw_1.Object.DataWindow.HorizontalScrollPosition2 = dw_1.object.id.Width

 

 

//打印数据窗口最后一页的方法:

string ls_pagecount

ls_PageCount = dw_1.describe("Evaluate('PageCount()',0)")

dw_1.object.datawindow.print.page.range = '" + ls_PageCount + "'"

dw_1.print()

 

 

//当编辑框得到焦点时自动选中内容:

this.selecttext(1,len(sle_1.text))

 

 

//判断数据窗口中是否存在某列

可以利用Describe("column_name.width")是否为"!"来判断;

 

 

//隐藏任务栏的方法,OnCreate事件里利用Window API函数SetWindowLongSetWindowLong(Application.Handle,GWL_EXSTYLE,WS_EX_TOOLWINDOW);

PB使用时首先声明函数FUNCTION long SetWindowLong(ulong hWnd, integer nIndex, ulong dwNewLong) library "user32.dll" ALIAS FOR "SetWindowLongA"

然后调用:SetWindowLong(Handle(this),-20,128)

 

 

//如果大于本月23号,则将时间设置为下月1号,否则取当前时间

//方法1:

if day(today())>23    then

          if month(today())+1>12 then

                  this.text=left(string(today(),'yyyy-mm-dd'),5)+'01-01'

          else

                  this.text=string(date(year(today()),month(today())+1,1))

          end if

else

          this.text=string(today())

end if

//方法2:

dateld_temp = today()

if day(ld_temp) > 23 then ld_temp = date(year(RelativeDate(ld_temp, 10)), month(RelativeDate(ld_temp, 10)), 1)

sle_1.text = string(ld_temp)

 

 

//两个有用的PB内部函数

1.shRunDefltBrowser 调用缺省的浏览器,打开指定页面

版本:PBVM60.dll,PBVM80.dllPB7我没用过,不过我想应该有。

函数声明:function long shRunDefltBrowser(string szUrl) library "pbvm60.dll"

调用方法:shRunDefltBrowser("www.pdriver.com")

2 shCenterWindow 将窗口位于屏幕中央

版本:PBVM60.dll,PBVM80.dllPB7我没用过,不过我想应该有。

函数声明:function long shCenterWindow(long hWnd) library "pbvm60.dll"

调用方法:shCenterWindow(handle(w_about))

 

 

//允许用户修改新增加的记录,而检索出来的记录则不允许修改。

打开列的属性中的Expressions,在protect中输入条件判别式:

if(isRowNew(),0,1)

 

 

//使用Ole对象与Word等通讯时,如何避免启动多个Word等程序:

OLEObject ole_object

ole_object = CREATE OLEObject

li_ret = ole_object.ConnectToObject("","word.application")

IF li_ret <> 0 THEN

    //如果Word还没有打开,则新建。

    li_ret = ole_object.ConnectToNewObject("word.application")

    if li_ret <> 0 then

       MessageBox('OLE错误','OLE无法连接!错误号:' + string(li_ret))

       return

    end if

    ole_object.visible = true

END IF

 

 

//进展条的使用

PowerBuilder中虽然没有这样的控件,可是在PowerBuilder所带的例子中有一用户对象

uo_progress_bar能够完成所需要求。将用户对象拷贝到用户的应用所在的库,将它放置在用户的界面中

需要出现的地方。然后在任务进展的时候,用对象的uf_set_position()函数指示当前任务的进展情况。

 

 

//PB中调用屏幕保护的方法:

send(handle(This),274,61760,0)

 

 

//得到一个应用程序如Outlook的路径

RegistryGet("HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/App Paths/MSIMN.EXE", &

          "Path",ls_outlook_path)

//Outlook的路径将保存在string型变量ls_outlook_path中。

 

 

//得到程序运行时的路径

//global external functions声明:

Function uLong GetModuleFileNameA(long hinstModule, Ref String lpszPath, uLong cchPath) Library kernel32.dll

//程序路径保存在变量ls_AppPath

string ls_AppPath

int li_ret

ls_AppPath = Space(128)

li_ret = GetModuleFileNameA(Handle(GetApplication()),ls_apppath,128)

//要编译成可执行文件.exe才可用,否则得到的是Powerbuilderpb60.exePB050.exe的路径。

 

 

//在程序中动态设定列的编辑风格为下拉数据窗口(DropDownDataWindow)

//假设所设定列为部门号"department_id",相关连的子数据窗口为"d_dddw_dep"

//显示列为部门名称"dept_name",数据列为部门号"dept_id",实现方法如下:

dw_1.Modify("department_id.DDDW.Name=d_dddw_dep ")

dw_1.Modify("department_id.DDDW.DisplayColumn='dept_name' ")

dw_1.Modify("department_id.DDDW.DataColumn='dept_id' ")

//或:

dw_1.object.department_id.dddw.name = "d_dddw_dep"   

dw_1.object.department_id.DDDW.DisplayColumn = "dept_name"

dw_1.object.department_id.DDDW.DataColumn = "dept_id"  

//注:PowerBuilder有一个小工具DWSyntax(程序名为:dwsyn60.exe),提供了获得及修改数据窗口、

//列等的各项属性值的语法,对编程非常有帮助。上述脚本在DWSyntax中都能找到。

 

 

//增量查询功能实现

//1.定义单行编辑器的用户事件ue_enchange,事件的ID为:pbm_enchange。这个事件能响应键盘的输入。

//2.在单行编辑器的ue_enchange事件中编写如下脚本:

long ll_found_row

string ls_find

ls_find = string(id) like + ″′″ + this.text + %′″ //查找条件(左部分与单行编辑器文本相等)

ll_found_row = dw_1.Find(ls_find, 1, dw_name.RowCount()) //查找符合条件的行

if ll_found_row <= 0 then return

dw_1.ScrollToRow(ll_found_row) //滚动到相匹配的行

dw_1.SelectRow(0,false)

dw_1.SelectRow(ll_found_row,true) //将匹配行加亮显示

 

 

//如何在程序中对BLOB数据库进行写入

和后台数据库有关:以SQLANYWAY为例:

一般用 UPDATEBLOB SELECTBLOB 两个SQL语句来实现。

建一个表TABLE1,一个字段是ID,另一个是BLOB

SELECTBLOB BLOB FROM TABLE1 WHERE ID='xx';

UPDATEBLOB SET BLOB = :BLB_X FROM TABLE1 WHERE ID='yy';

删除时删除ID'mm'的记录即可,新增是先插入一条ID'mm'的记录,然后 UPDATEBLOB将数据写入

表内。 其他的数据库可参照手册进行,其命令与上述差别不大!

 

 

//如何取出DDDW中的Display Column的内容。

dw_1.describe("Evaluate('lookupdisplay(column_name)',1)")

//column_name=列名 ,'1'表示第一行;看看Help中的Describe

 

 

//屏蔽窗口的ALT+F4

//方法一:

1.在窗口的systemkey事件中增加以下代码:

IF KeyDown(KeyF4!) THEN

    Message.Processed = TRUE

END IF

2.在窗口的closequery事件中增加如下代码:

Long ll_ret

IF KeyDown(keyF4!) THEN

     ll_ret = 1

END IF

return ll_ret

//方法二:

建一实例变量,在你的关闭程序上赋一个True然后在closequery中判断该值, 如为FalseReturn 1

 

 

//当程序中用到了动态加入的对象,如BMP资源文件、数据窗口对象,PB编译时是扫描不到的,解决方法:

1.将此对象写入到资源文件中:

用记事本创建资源文件dw_object.pbr,写入:c:/myprogram.pbl(dw_sj)

编译时将此文件选入Resource File Name处。

2.将应用编译成PBDDLL文件。

 

 

//如何在PB中实现延时:

subroutine Sleep(long dwMilliseconds) library "kernel32.dll"

延时1秒则调用: Sleep(1000)    //单位是毫秒。

 

 

//用下面表达式可得到记录在某组中的行号:

Getrow()-First(Getrow() for Group 1)+1

 

 

//调用API函数步骤:

1、在适当的位置声明函数,如窗口内,Application内,UserObject内,

定义在Local External FunctionGlobal External Function中,如播放声音的:

Function boolean sndPlaySoundA(string SoundName, uint Flags) Library "WINMM.DLL"

Function uint waveOutGetNumDevs() Library "WINMM.DLL"

也可以创建一个UserObject,集中声明常用的API及函数本地化,如定义用户对象 u_external_function

Declare Local External Function(定义外部函数):

Function boolean sndPlaySoundA(string SoundName, uint Flags) Library "WINMM.DLL"

Function uint waveOutGetNumDevs() Library "WINMM.DLL"

Declare User Object Function(定义用户对象函数):

uf_play_sound(string as_wave_name, integer ai_option)

函数内容如下:

//参数:as_wave_name wav文件名 ai_option :同步或异步(1/0)

uint lui_numdevs

lui_numdevs = WaveOutGetNumDevs()

If lui_numdevs > 0 Then

          sndPlaySoundA(as_wave_name,ai_option)

      return 1

Else

          return -1

End If

2、调用时在程序中定义一个实体并调用其函数:

u_external_function iu_external_function

iu_external_function = create u_external_function

iu_external_function.uf_play_sound('c:/windows/media/ding.wav',1)

试试看,如果有声卡,就会听到"叮”的一声。其它API函数也是如此处理。

 

 

//数据窗口的GRID格式下,根据实际情况控制每一行的背景

//调整detail的属性中的colorexpression就可以了,如:

if(currentrow()=getrow(),rgb(255,240,194),if(mod(getrow(),2)=1, rgb(255,254,249) , rgb(247,247,239)))

//表达式中rgb(255,240,194)为黄色,rgb(255,254,249)为浅白色,rgb(247,247,239)为浅黄色。

//CurrentRow()得到数据窗口当前得到输入焦点的行的行号。

//GetRow()返回数据窗口相应带中的当前行行号。

 

 

//实现对数据窗口中的某一列/行显示为一指定颜色

//如果符合条件,则显示灰色的背景,否则白色;

本方法同样可以设置该列的字体颜色:其中"column_name"为列名。

dw_1.object.column_name.background.color = "16777215~tif(fromid='string',rgb(192,192,192),rgb(255,255,255))"

也可以是一行都变色:

dw_1.object.Datawindow.detail.color = "16777215~tif(fromid='string',rgb(192,192,192),rgb(255,255,255))"

 

 

//固定数据窗口前几列的方法,例如第一列名为"id”,固定该列且后半部分从下一列开始显示:

dw_1.HSplitScroll = True

dw_1.Object.DataWindow.HorizontalScrollSplit = dw_1.object.id.Width

dw_1.Object.DataWindow.HorizontalScrollPosition2 = dw_1.object.id.Width

 

 

//在数据窗口中如何隐藏某计算单元

在它的properties/expression/visible属性中设置为"IF(1=2,1,0)”就可以了。

 

 

//超链接

Inet linet_base

GetContextService("Internet", linet_Base)

linet_Base.HyperlinkToURL('http://www.neusoft.com')

Destroy(linet_base)

 

 

//===========================================================================

//函数功能:返回计算表达式的值

//参数:    string     thestr      计算表达式,如 2 * (3+5)

//返回值:string     retVal      计算表达式的结果值,如 2 * (3+5)的结果值为 16

//        如果是一个不正确的表达式,则返回 false.

//===========================================================================

string retVal

datastore lds_evaluate

lds_evaluate = create datastore

lds_evaluate.create('release 8;~r~ntable()')

retVal = lds_evaluate.describe("evaluate('" + thestr + "', 1)")

destroy lds_evaluate

return retVal

 

 

 

//通过代码更改数据窗口对象的方法

string error_syntaxfromSQL, error_create

string new_sql, new_syntax

new_sql = 'SELECT emp_data.emp_id,emp_data.emp_name from emp_data ' &

          + 'WHERE emp_data.emp_salary>45000'

new_syntax = SQLCA.SyntaxFromSQL(new_sql,'Style(Type=Form)', error_syntaxfromSQL)

IF Len(error_syntaxfromSQL) > 0 THEN          // Display errors

          mle_sfs.Text = error_syntaxfromSQL

ELSE          // Generate new DataWindow

          dw_new.Create(new_syntax, error_create)

          IF Len(error_create) > 0 THEN

                  mle_create.Text = error_create

          END IF

END IF

dw_new.SetTransObject(SQLCA)

dw_new.Retrieve()

 

 

//打开动态窗口的方法:

window newarray[3]

string win[3]

int i

win[1] = "w_employee"

win[2] = "w_customer"

win[3] = "w_sales"

for i = 1 to 3

      Open(newarray[i], win[i])

next

 

 

//显示一个与Windows操作系统风格一致的About对话框。 首先声明如下外部函数:

function int ShellAboutA(ulong al_hWnd, string as_szApp, string as_szOtherStuff, ulong hIcon) library "shell32"

ShellAboutA(handle(parent),"关于...#摆渡人工作室","欢迎光临摆渡人工作室",0)

 

 

//如何将COLUMN的显示风格在EDITDDDWDDLB之间相互切换:

(1)切换成DDDW

dw_1.Modify("#1.dddw.Name='dddw_jg'")

dw_1.Modify("#1.dddw.DisplayColumn='name_jg'")

dw_1.Modify("#1.dddw.DataColumn='id_jg'")

(2)切换成DDLB

dw_1.Modify("#1.ddlb.case='any'")       

dw_1.Object.#1.Values ="red~t1/white~t2"

(3)切换成EDIT

dw_1.Modify("#1.edit.case='any'")

dw_1.Modify("#1.edit.AutoSelect='Yes'")

(4)获取当前风格:

dw_1.Describe("#1.Edit.Style")

(5)如果还不行,可能得要如下操作:

dw_1.Modify("#1.dddw.Name=''")一下;

 

 

//dw_1中选定想要打印的几条记录

long ll_pos

dataStore lds_ds

lds_ds = create dataStore

lds_ds.dataObject = dw_1.dataObject

for ll_pos = 1 to dw_1.rowCount()

     if dw_1.IsSelected(ll_pos) then

               dw_1.RowsCopy(ll_pos,ll_pos,Primary!,lds_ds,lds_ds.rowCount()+1,Primary!)

     end if

next

lds_ds.print()

 

 

//实现在循环时可以通过点击按钮终止循环

integer n

//sb_interrupt 是共享变量

sb_interrupt=false

for n=1 to 3000

          yield()

          if sb_interrupt then //sb_interrupt的值在"取消”按纽的Clicked事件中修改为true

                  MessageBox("我不干了","你真坏!")

                  sb_interrupt=false

                  exit

          else //其它处理,在单行编辑器中显示当前n

                  sle_1.text = string(n)

          end if

next

 

 

//SQL语句调用规范

INTEGER li_customer_id = 1

STRING ls_city_code = '501'

PREPARE SQLSA FROM "DELETE bb_customer_info_t WHERE city_code =? AND customer_id = ?" ;

EXECUTE SQLSA USING :ls_city_code,:li_customer_id;

 

 

//通过modify函数来同时修改多个表

1、新建一个数据窗口d_grid_dep_emp,它的Select语句为

SELECT department.dept_id,

department.dept_name,

employee.emp_id,

employee.emp_fname,

employee.emp_lname

FROM department, employee

WHERE employee.dept_id = department.dept_id

2、设置数据窗口d_grid_dep_emp的属性,将列的taborder改为非0值;并点击菜单Rows——>Update

Properties,设置此数据窗口Allow UpdatesTable to Update设为departmentUpdateable Columns

department.dept_iddepartment.dept_name

3、在窗口中更新数据窗口按钮的clicked事件编写脚本:

long ll_rtn

// 修改Department(Department表在第2步已设置为可更新)

ll_rtn = dw_1.update(true, false)

If ll_rtn = 1 then

          //关闭对Department表的修改

          dw_1.Modify("department_dept_name.Update = 'No'")

          dw_1.Modify("department_dept_id.Update = 'No'")

          dw_1.Modify("department_dept_id.Key = 'No'")

          //设置Employee表成为新的可修改表

          dw_1.Modify("DataWindow.Table.UpdateTable = 'employee'")

          dw_1.Modify("employee_emp_id.Update = 'Yes'")

          dw_1.Modify("employee_emp_fname.Update = 'Yes'")

          dw_1.Modify("employee_emp_lname.Update = 'Yes'")

          dw_1.Modify("employee_emp_id.Key = 'Yes'")

          //修改Employee

          ll_rtn = dw_1.Update()

          IF ll_rtn = 1 THEN

                  COMMIT USING SQLCA;

                  dw_1.retrieve()

                  messagebox('提示信息','更新成功!')

          ELSE

                  ROLLBACK USING SQLCA;

                  MessageBox('提示信息', '更新失败!')

          END IF

          //重置修改标志

          dw_1.Modify("department_dept_name.Update = 'Yes'")

          dw_1.Modify("department_dept_id.Update = 'Yes'")

          dw_1.Modify("department_dept_id.Key = 'Yes'")

          dw_1.Modify("DataWindow.Table.UpdateTable = 'department'")

          dw_1.Modify("employee_emp_id.Update = 'No'")

          dw_1.Modify("employee_emp_fname.Update = 'No'")

          dw_1.Modify("employee_emp_lname.Update = 'No'")

          dw_1.Modify("employee_emp_id.Key = 'No'")

ELSE

          ROLLBACK USING SQLCA;

          MessageBox('提示信息', '更新失败!')

END IF

//可以将以上功能作成一个函数,在必要的时候调用即可。

 

 

//单击编辑框选中其中内容 

getfocus事件中书写代码:this.selecttext(1,len(this.text))。保存后运行,却得不到我们想要的

效果。想到了一个另类办法:以pbm_bnclicked为事件ID,创建单行编辑框的自定义事件ue_clicked

代码是:this.selecttext(1,len(this.text))

getfocus事件的代码改为:This.Post Event ue_clicked()。保存后运行,效果出来了!

 

 

//怎样得到字符串中汉字的个数

For i = 1 to Len(aString)

          ls_ch = Mid(aString,i,1)

          If Asc(ls_ch) >= 128 then //是汉字

                  li_num++

                  i = i+1

          End if

Next 

//最后,li_num就是汉字的个数了

 

 

//DW支持双击标题进行排序

String ls_old_sort,ls_column,ls_name,ls_criteria

Char lc_sort

IF Right(dwo.Name,2) = '_t' THEN     //取得是否是列标题名

          ls_column = LEFT(dwo.Name, LEN(String(dwo.Name)) - 2)

          ls_old_sort = this.Describe("Datawindow.Table.sort")

          IF ls_column = LEFT(ls_old_sort,LEN(ls_old_sort) - 2) THEN

                  lc_sort = RIGHT(ls_old_sort,1)

                  IF lc_sort = 'A' THEN

                          lc_sort = 'D'

                  ELSE

                          lc_sort = 'A'

                  END IF

                  this.SetSort(ls_column + " " + lc_sort)

          ELSE

                  ls_criteria = ls_column + " A"

                  this.SetSort(ls_criteria)

          END IF

          this.Sort()

END IF

 

 

//DW支持单击按CtrlShift进行多选

int          il_last_row                  //il_last_row为实例变量,记录上次单击的行

int li_current_row          //当前单击行

int li_row                          //中间变量

//未选择就返回

if row = 0 then

          return

else

          li_current_row = row

end if

if keydown(keyshift!) then          //按下SHIFT

     if il_last_row = 0 then

                  this.selectRow(row,true)

                  il_last_row = li_current_row

          else       

        this.selectRow(0,false)

        if li_current_row > il_last_row then

           for li_row = il_last_row to li_current_row

              this.selectrow(li_row,true)

           end for

        else

           for li_row = il_last_row to li_current_row step -1

              this.selectrow(li_row,true)

           end for

        end if

          end if

else                                                  //未按下SHIFT

          il_last_row = li_current_row

     if keydown(keycontrol!) then           //按下CTRL

        if this.isSelected(li_current_row) then

           this.selectrow(li_current_row,false)

        else

           this.selectrow(li_current_row,true)

        end if

     else                                                           //CTRL键或SHIFT键按下

        this.selectrow(0,false)

        this.selectrow(li_current_row,true)

     end if

end if

 

 

//改变DW的查询条件语句

string ls_select,ls_filter

ls_select = dw_1.getSqlSelect()

ls_select = mid(ls_select,1,pos(upper(ls_select),'FROM ')+30)

ls_filter="WHERE service_kind=" + vi_service_kind + " ORDER BY FEE_ID ASC "       

ls_select = ls_select + ls_filter

dw_1.Reset()

dw_1.SetTransObject(SQLCA)

dw_1.SetSQLSelect(ls_select)

dw_1.Retrieve()

 

 

//数据窗口的closeQuery事件:提示保存数据

dw_1.AcceptText()

IF dw_1.ModifiedCount() + dw_1.DeletedCount() > 0 THEN

          CHOOSE CASE MessageBox("操作提示","数据已经发生变化,是否保存?",Question!,YesNoCancel!,1)

                  CASE 1       

                          cb_save.TriggerEvent(clicked!)

                  CASE 2       

                          Return 0          //不做任何操作直接关闭窗口

                  CASE 3       

                          Return 1          //不会运行Close Event,维持原来的情况

          END CHOOSE

END IF

 

 

//提示:请选择要删除的记录

if dw_2.GetSelectedRow(0)= 0 then

          MessageBox("提示信息","请选择要删除的记录!")

          return

end if

 

 

//按某字段进行排序

IF dwo.name = "fee_id_t" THEN

          this.setSort("fee_id a")

          this.sort()

elseif dwo.name = "fee_position_t" then

          this.setsort("fee_position a, fee_id a")

          this.sort()

END IF

 

 

//控制DATAWINDOW里每页显示的行数

1、在Datawindow中增加一个计算域,起名为:ceil_page,此计算域必须放在Detail段中,

Expression中输入 ceiling(getrow()/25) 25表示每页打印25行,也可以是一个参数。

2、分组,选择菜单Rows/Create Group,选择ceil_page

ceil_page分组,并选中New Page On Group Break(意思是新组开始时换页)

3、将此计算域设为隐藏(在属性页中的expression页中在visible属性中写0)

4、补空行:

在窗口的open事件中写如下代码:

long li_count,li_i

li_count=dw_1.retrieve()

if mod(li_count,25)<>0 then

          for li_i=1 to 25 - mod(li_count,25)

                  dw_1.insertrow(0)

          next

end if

 

 

//如何实现数据窗口数据的自动折行

1) DataWindow Painter中打开此DataWindow对象。

2) 在需设定自动折行的列上双击鼠标, 弹开此列的属性窗口。

3) 选择Position标签, 选中Autosize Height 多选框。

4) 选择Edit标签, 不选中Auto Horz Scroll多选框。

5) 单击OK按钮, 保存所做的修改。

6) 点中Detail Band (即写有Detail的灰色长带), 单击鼠标右键, 选择 Properties... 菜单项。

7) 选中Autosize Height多选框。

8) 单击OK按钮, 保存所做的修改。

9) 保存此DataWindow

注意:连在一起的汉字(中间没有标点或空格分隔), 系统将认为是一个单词, 不会自动进行折行,

英文也是如此……DW窗口折行如果有汉字的话就必需中间加空格才会折行,否则怎样设置都不行。例如你

如果想在第20位折行,就先判断第20位是否是个汉字,如不是就在第20位后加空格,如果是汉字就在

19位加空格。判断是否是汉字可以用它的ASCII码是否大于127来判断。

 

 

//按条件对某行数据进行颜色区分

case(cj when is >= 90 then rgb(255,0,0) when is < 60 then rgb(0,255,0) else rgb(0,0,255)))

 

 

//PB中同时连接多个数据库,如连接SQLServer2000Oracle8

string ls_startupfile

ls_startupfile='hisini.ini'

sqlca.DBMS = ProfileString(ls_startupfile, "database", "dbms", "")

sqlca.database = ProfileString(ls_startupfile, "database", "database", "")

sqlca.userid = ProfileString(ls_startupfile, "database", "userid", "")

sqlca.dbpass = ProfileString(ls_startupfile, "database", "dbpass", "")

sqlca.logid = ProfileString(ls_startupfile, "database", "logid", "")

sqlca.logpass = ProfileString(ls_startupfile, "database", "LogPassWord", "")

sqlca.servername = ProfileString(ls_startupfile, "database", "servername", "")

sqlca.dbparm = ProfileString(ls_startupfile, "database", "dbparm", "")

remote_trans= CREATE transaction

remote_trans.DBMS = ProfileString(ls_startupfile, "Database_remote", "dbms", "")

remote_trans.database = ProfileString(ls_startupfile, "Database_remote", "database", "")

remote_trans.userid = ProfileString(ls_startupfile, "database_remote", "userid", "")

remote_trans.dbpass = ProfileString(ls_startupfile, "database_remote", "dbpass", "")

remote_trans.logid = ProfileString(ls_startupfile, "database_remote", "logid", "")

remote_trans.logpass = ProfileString(ls_startupfile, "database_remote", "LogPassWord", "")

remote_trans.servername = ProfileString(ls_startupfile, "database_remote", "servername", "")

remote_trans.dbparm = ProfileString(ls_startupfile, "database_remote", "dbparm", "")

//hisini.ini

[Database]

DBMS=MSS Microsoft SQL Server 6.x

Database=his

UserId=

DatabasePassword=

ServerName=.

LogId=sa

Lock=

Prompt=0

computer='11'

ocx= 0

use0='之住院管理'

cfprint='1'

[Database_remote]

DBMS = "O84 Oracle8/8i(8.x.4+)"

ServerName = "oracle8"

LogId = "dba"

Database=zx

UserId=

DatabasePassword=

Lock=

Prompt=0

computer='11'

ocx= 0

cfprint='1'

 

 

//PB6.5连接Oracle8i9i的情况

SQLCA.DBMS = "O84 Oracle8/8i (8.x.4+)"

SQLCA.LogPass = "test"

SQLCA.ServerName = "myora"

SQLCA.LogId = "test"

SQLCA.AutoCommit = False

SQLCA.DBParm = "TableCriteria=',test,''TABLE'',''VIEW'''"

 

 

//在检索的数据行上再加上一行记录

dataWindowChild dwc

dw_service.getchild('svcid',dwc)

dwc.settransobject(sqlca)

dwc.retrieve()

dwc.insertrow(1)

dwc.setitem(1,'svcid','00')

dwc.setitem(1,'svcname','不区分')

dw_service.setTransObject(sqlca)

dw_service.Retrieve()

 

 

//数据窗口中按enter键实现tab功能(在数据窗口的Enter事件中)

send(handle(this),256,9,long(0,0))

return 1

 

 

//send用法:Send(handle,message#,lowword,long)

//This statement scrolls the window w_emp up one page:

Send(Handle(w_emp), 277, 2, 0)

//Both of the following statements click the CommandButton cb_OK:

Send(Handle(Parent), 273, 0, Handle(cb_OK))

cb_OK.TriggerEvent(Clicked!)

//minimizes the DataWindow:

Send(Handle(dw_1), 274, 61472, 0)

//maximizes the DataWindow:

Send(Handle(dw_1), 274, 61488, 0)

//returns the DataWindow to its normal, defined size:

Send(Handle(dw_1), 274, 61728, 0)

 

 

//重设数据窗口的检索语句

ls_accept_city = gs_citycode

ld_beg_date = datetime(date(em_assign_beg_date.text),time('00:00:00'))

ld_end_date = datetime(date(em_assign_end_date.text),time('23:59:59'))

ls_where = " WHERE b.assign_date >= :id_begin_date &

          AND b.assign_date <= :id_end_date &

          AND a.register_number = b.register_number &

          AND a.accept_city = :is_accept_city &

          AND a.action = 6 AND current_action = 1 AND status IN(1,-1) "

ls_sql = dw_wp.Describe("DataWindow.Table.Select")

if pos(ls_sql,'WHERE') <> 0 then

          ls_sql = mid(ls_sql,1,pos(ls_sql,'WHERE') - 1)

end if

ls_sql = 'DataWindow.Table.Select=" ' + ls_sql + ls_where + '"'

ls_err_info = dw_wp.modify(ls_sql)

if ls_err_info <> "" then

          messagebox('提示信息','查询异常,请核查' + ls_err_info)

          return

end if

af_connect()

dw_wp.settransobject(sqlca)

dw_wp.retrieve(ld_beg_date,ld_end_date,ls_accept_city)

af_disconnect()

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值