PowerBuilder编程俱乐部

Author: 柯建勋 Date: 1999年 第35期 13版

    大家好!PowerBuilder编程俱乐部今天正式与大家见面了,欢迎各位PB爱好者参与进来!为了方便与大家的交流,俱乐部特开放两个Email信箱:kjx@263.net和pb7@990.net,大家如果有PB方面的问题,可以发Email到这两个信箱。当然,更欢迎各位到我的主页http://kjx.126.com或http://pb70.yeah.net的BBS讨论区提交问题或解答问题,以便大家都能从中学到知识。互相学习、共同进步是PB编程俱乐部的宗旨,热切希望爱好PB编程的读者加入到PB编程俱乐部来! 
    一、问:一个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中。