PowerBuilder编程俱乐部
一、问:一个MIS系统采用C/S的开发模式,前台开发工具用PB6.5,后台数据库为Oracle7.3。我通过OBOC却连不上数据库,请问应该如何配置?
答:PB提供了与当前流行的大型数据库如Oracle、Informix、Sybase等的专用接口,连接时无需通过ODBC。配置步骤具体如下:
1.首先要通过SQL*Net配置数据库别名。
启动SQL*Net Easy Configuration后,选择“添加数据库别名” ( Add Database Alias),输入数据库别名,如hello。选择协议TCP/IP,输入TCP/IP主机名(TCP/IP Host Name),可为主机名或IP地址输入数据库名(Database Instance)如ora7。单击“确定”按钮,生成数据库别名(hello)后,按“取消”退出。连接数据库,测试SQL*Net是否连通。运行SQL*PLUS,用自己的用户名,如kukoc进入,在用户名处输入kukoc/kukoc@hello 。若进入远程数据库,则SQL*Net 配置成功。
2.然后,在PB6.5中配置 DB Profile。
选择073 Oracle7.3,按Button New,输入Profile Name,如hello。
输入Server:@hello(此处一定要为@+开始配置的数据库别名)
输入Login ID:kukoc
输入Password:kukoc
单击确定按钮结束。
我们也可以通过配置文件(.ini)实现数据库连接,如hello.ini文件中数据库配置如下:
[Database]
DBMS=O73 ORACLE 7.3
Database=
UserId=
DatabasePassword=
LogPassword=kukoc
ServerName=@hello
LogId=kukoc
Lock=
DbParm=
Prompt=0
二、问:我在编写数据窗口录入程序的时候,若用户录入违反了约束(如关键字重复、非空项没输入等),程序老报一大堆英文出错信息,用户也看不明白。我怎样才能屏蔽它,并显示中文的错误信息?
答:可以自己编写一个错误信息函数,如f_dwerror_message(),参数为错误信息代码(Long型),返回值为1。函数中根据传入的错误代码给出相应的中文错误信息。在数据窗口的dberror事件中调用它:
return f_dwerror_message (sqldbcode)
而且,我们还可以将此数据窗口作成用户对象,要用到的地方继承即可。
三、问:在PB中如何打开一个文件(如.txt,.doc),就像在资源管理器中双击打开文件一样?
答:可以通过API函数来实现。
在应用程序的Global External Functions中定义:
Function long ShellExecuteA (ulong hwnd, string lpOperation, string lpFile, & string lpParameters, string lpDirectory, long nShowCmd) library “shell32.dll”
调用如下:
String ls_null
SetNull (ls_null)
ShellExecuteA(Handle(Parent), ls_null, “c:\doc\hello.txt”, ls_null, ls_null, 1)
四、问:PB中数据窗口输入栏目(域)间的切换通过按键盘最左边的Tab 键来实现,既不方便又影响录入速度。如何能用Enter键替代Tab 键切换栏目,实现焦点的转移?
答:由于按Enter键是Windows直接支持的消息,故我们可以使用用户事件来解决此问题。在用户事件中,PowerBuilder提供的一条pbm_事件对应Windows的一条或几条消息。我们在数据窗的用户事件中选择pbm_dwnProcessEnter并命名为ue_Enterkeydown。当我们按下Enter键时,将触发此事件。
提供两种方法(推荐用第二种):
1.利用数据窗口的SetColumn函数。
在所定义的ue_Enterkeydown事件下写代码:
long ll_column_count
long ll_column
ll_column_count =long(this.Describe(“DataWindow.Column.Count”))
ll_column = this.GetColumn()
if ll_column = ll_column_count then
return
else
this.SetColumn(ll_column + 1)
end if
用上面脚本,须注意几点:
(1) 按Enter键,焦点的切换是按所选列的顺序,而不是按设置的Taborder的顺序。
(2) 若某列的visible属性为false 或 TabOrder = 0, 则以上方法不起作用。
若不合以上要求,即所选列的顺序与要录入域顺序不一致,或某些列的visible属性为false或 其TabOrder = 0,此时不能用上述代码,但也可用类似方法实现,只是稍繁琐一点,举例如下:
long ll_column
string ls_column_name
ll_column = this.getcolumn()
ls_column_name = this.Describe(“#”+string(ll_column)+“.Name”)
choose case ls_column_name //列名
case ‘no'
this.SetColumn(‘name')
case ‘name'
this.SetColumn(‘age')
case ‘age'
…
end choose
2.把消息传递给Tab键,同时忽略Enter键的处理,这种方法最为方便简洁。在ue_Enterkeydown事件中
编写脚本如下:
Send(Handle(this),256,9,Long(0,0))
Return 1
五、问:Datawindow中要匹配的条件是变化的,如输入一个名字(名字放在变量ls_name中),用dw_name.setfilter(“name = ” + ls_name )不起作用。如何用setfilter将这条记录找出来?
答:因 ls_name 是string型的,filter语句应该这样写:
dw_name.SetFilter(“name = ‘” + ls_name + “'”)
dw_name.Filter( )
当ls_name = “张三”时,脚本实际为:
dw_name.SetFilter(“name = ‘张三’”)
dw_name.Filter( )
六、问:怎样得到一个应用程序如Outlook的路径?
答:可用RegistryGet()函数从系统注册表中获得。具体用法如下:
li_return = RegistryGet (“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows & \CurrentVersion\App Paths\MSIMN.EXE”,“Path” , ls_outlook_path )
执行此脚本后,Outlook的路径将保存在string型变量ls_outlook_path中。