• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

在RPGLE中实现模糊检索的例程(带详细注释)

发布: 2007-6-08 22:43 | 作者: seanhe | 来源: | 查看: 27次 | 进入软件测试论坛讨论

领测软件测试网
说明:
1、这是一个在数据库中模糊检索地址的RPGLE程序。在画面上输入检索字串(用空格分开),回车后,SFL中显示DB中所有带有这些字串的地址
2、子程序说明:@KEN01为模糊检索,@CLR01为SFL初始化,@WRT01为写SFL,@DEF为变量定义,@END为结束程序。[color=red:d18865074c]红色的代码为全角检索专用。如果仅用于半角检索,可以删去。[/color:d18865074c]
3、ADDR01D为画面程序(只带最基本的SFL功能,仅供测试用),ADDRES为PF文件(只有地址一个字段)。画面入力项及DB字段长度均定义为40,使用时可根据实际情况修改(全角检索时需同时修改配列长度)。
4、为了提高效率,应将@KEN01中的字串截取部分单独写成一个子程序,并将截取的各子串赋给配列,这样就不用每读一条记录都重复执行字串截取了。我有空的时候会做如上修改。同时也欢迎大家多提宝贵意见。 [color=red:d18865074c](已修正,见后贴)[/color:d18865074c]

RPGLE程序:

     H DATEDIT(*YMD)
     FADDRES    IF   E           K DISK
     FADDR01D   CF   E             WORKSTN SFILE(SFL01:#RRN01)
     [color=red:d18865074c]D AR1             S              1    DIM(40)[/color:d18865074c]
     C*
     C                   DO        *HIVAL
     C*
     C                   WRITE     FMT99
     C*
     C                   IF        #RRN01 <> 0
     C                   SETON                                        29
     C                   ENDIF
     C*
     C                   SETON                                        28
     C                   EXFMT     CTL01
     C                   SETOFF                                       2829
     C*
     C                   IF        *IN03 = *ON
     C                   EXSR      @END
     C                   ENDIF
     C*
     C                   EXSR      @CLR01
     C                   EXSR      @KEN01
     C*
     C                   ENDDO
     C*****************************************************************
     C     @END          BEGSR
     C*
     C                   SETON                                        LR
     C                   RETURN
     C*
     C                   ENDSR
     C*****************************************************************
     C     @KEN01        BEGSR
     C*
     C                   SETOFF                                       92
     [color=red:d18865074c]C                   MOVEA     D#ADDR        AR1[/color:d18865074c] 
     C*
     C     *LOVAL        SETLL     ADDRESR
     C                   READ      ADDRESR                                90
     C                   DOW       *IN90 = *OFF AND #RRN01 < 9999
     C*
     C* 模糊检索
     C                   Z-ADD     1             W#FROM
     C*
     C                   DO        *HIVAL
     C*
     C* 第一个空格以外的字符位置 = W#FROM
     C     ' '           CHECK     D#ADDR:W#FROM W#FROM                   91
     C  N91              LEAVE
     C*
     C* 下一个空格的位置 = W#TO
     C     ' '           SCAN      D#ADDR:W#FROM W#TO                     91
     C  N91              LEAVE
     [color=red:d18865074c]C*
     C* 判断子字符串开头是否为汉字起始控制符
     C                   IF        AR1(W#FROM) = X'0E'
     C                   ADD       1             W#FROM
     C                   ENDIF
     C*
     C* 判断子字符串结尾是否为汉字结束控制符
     C                   IF        AR1(W#TO - 1) = X'0F'
     C                   SUB       1             W#TO
     C                   ENDIF[/color:d18865074c]
     C*
     C* 子字符串长度 = W#LEN
     C     W#TO          SUB       W#FROM        W#LEN
    C* 
    C                   IF        W#LEN <> *ZERO 
     C*
     C* 子字符串 = W#SUB
     C     W#LEN         SUBST(P)  D#ADDR:W#FROM W#SUB
     C*
     C* 检索
     C     W#SUB:W#LEN   SCAN      ADADDR                                 92
     C  N92              LEAVE
     C*
     C                   ENDIF
     C*
     C* 下一次取子字符串的开始位置 = W#FROM
     C     1             ADD       W#TO          W#FROM
     C                   ENDDO
     C*
     C   92              EXSR      @WRT01
     C*
     C                   READ      ADDRESR                                90
     C                   ENDDO
     C*
     C                   ENDSR
     C*****************************************************************
     C     @CLR01        BEGSR
     C*
     C                   SETON                                        27
     C                   WRITE     CTL01
     C                   SETOFF                                       27
     C*
     C                   Z-ADD     *ZERO         #RRN01
     C
     C                   ENDSR
     C*****************************************************************
     C     @WRT01        BEGSR
     C*
     C                   ADD       1             #RRN01
     C                   MOVEL     ADADDR        S#ADDR
     C                   WRITE     SFL01
     C*
     C                   ENDSR
     C*****************************************************************
     C     @DEF          BEGSR
     C*
     C                   Z-ADD     *ZERO         #RRN01            4 0
     C                   Z-ADD     *ZERO         W#FROM            2 0
     C                   Z-ADD     *ZERO         W#TO              2 0
     C                   Z-ADD     *ZERO         W#LEN             2 0
     C                   MOVEL     *BLANK        W#SUB            40
     C*
     C                   ENDSR

画面文件

     A                                      CF03(03 '终了')
     A*****************************************************************
     A          R SFL01                     SFL
     A            S#ADDR        40O     5 15TEXT('地址')
     A*****************************************************************
     A          R CTL01                     SFLCTL(SFL01)
     A                                      OVERLAY
     A                                      SFLSIZ(9999)
     A                                      SFLPAG(0016)
     A  27                                  SFLCLR
     A  28                                  SFLDSPCTL
     A  29                                  SFLDSP
     A*
     A                                  1 30'地址模糊检索'
     A                                      DSPATR(RI)
     A                                  1 63DATE
     A                                      EDTWRD('0  /  /  ')
     A                                  1 72TIME
     A                                  3  2'地址:'
     A            D#ADDR        40O  B  3 15
     A*****************************************************************
     A          R FMT99
     A                                 24  3'F3:终了'
     A                                      DSPATR(HI)

PF文件:

     A          R ADDRESR
     A*
     A            ADADDR        40O

 zhu_jihui 回复于:2005-09-01 13:10:56
很好,偶看可行!建议加精

 xuguopeng 回复于:2005-09-01 13:11:08
不错 加精~

不过如果把RPGLE的代码逐句注解出来 相信会成为一个好的模糊查询教材~~

 zhu_jihui 回复于:2005-09-01 13:15:24
楼主,是原创吗?

 teresa99 回复于:2005-09-01 13:15:39
楼主,俺对你的敬仰如滔滔江水。。。

 armycat 回复于:2005-09-01 13:16:50
是俺今天上午抽空瞎写的,多多指教,多多指教。

 Inyan 回复于:2005-09-01 13:17:41
呵呵,看起来比我们那个模糊查询代码要少些。
 :wink:

 zhu_jihui 回复于:2005-09-01 13:19:47
那时当然了呵呵!!

 mamei 回复于:2005-09-01 13:30:38
我正在搞模糊查询的东东!

多谢了

 armycat 回复于:2005-09-01 14:00:51
刚刚把说明4中提到的问题修正了一下:

1、增加了两个配列:AR2中存放各字串的内容(长度40的入力项最多有20个字串,每个字串最大长度40),AR3中存放各字串的长度。

     D AR2             S             40    DIM(20)
     D AR3             S              2  0 DIM(20)

2、@KEN01做以下修正:

     C     @KEN01        BEGSR
     C*
     C* 取得各子字符串放入配列
     C                   Z-ADD     1             W#FROM
     C                   Z-ADD     *ZERO         W#N
     [color=red:fa551973d8]C                   MOVEA     D#ADDR        AR1[/color:fa551973d8]
     C*
     C                   DO        *HIVAL
     C*
     C* 第一个空格以外的字符位置 = W#FROM 
     C     ' '           CHECK     D#ADDR:W#FROM W#FROM                   91
     C  N91              LEAVE
     C*
     C* 下一个空格的位置 = W#TO 
     C     ' '           SCAN      D#ADDR:W#FROM W#TO                     91
     C  N91              LEAVE
     [color=red:fa551973d8]C*
     C* 判断子字符串开头是否为汉字起始控制符 
     C                   IF        AR1(W#FROM) = X'0E' 
     C                   ADD       1             W#FROM 
     C                   ENDIF 
     C* 
     C* 判断子字符串结尾是否为汉字结束控制符 
     C                   IF        AR1(W#TO - 1) = X'0F' 
     C                   SUB       1             W#TO 
     C                   ENDIF[/color:fa551973d8] 
     C* 子字符串长度 = W#LEN 
     C     W#TO          SUB       W#FROM        W#LEN
     C*
     C                   IF        W#LEN <> *ZERO
     C*
     C* 子字符串 = W#SUB 
     C     W#LEN         SUBST(P)  D#ADDR:W#FROM W#SUB
     C*
     C* 写入配列
     C                   ADD       1             W#N
     C                   MOVEL(P)  W#SUB         AR2(W#N)
     C                   Z-ADD     W#LEN         AR3(W#N)
     C*
     C                   ENDIF
     C*
     C* 下一次取子字符串的开始位置 = W#FROM
     C     1             ADD       W#TO          W#FROM
     C*
     C                   ENDDO
     C*
     C                   SETOFF                                       92
     C     *LOVAL        SETLL     ADDRESR
     C                   READ      ADDRESR                                90
     C                   DOW       *IN90 = *OFF AND #RRN01 < 9999
     C*
     C* 模糊检索
     C     1             DO        W#N           W#I
     C                   Z-ADD     AR3(W#I)      W#L
     C     AR2(W#I):W#L  SCAN      ADADDR                                 92
     C  N92              LEAVE
     C                   ENDDO
     C*
     C   92              EXSR      @WRT01
     C*
     C                   READ      ADDRESR                                90
     C                   ENDDO
     C*
     C                   ENDSR

3、@DEF中增加三个工作变量的定义:

     C                   MOVEL     *BLANK        W#N               2 0      
     C                   MOVEL     *BLANK        W#I               2 0      
     C                   MOVEL     *BLANK        W#L               2 0      

可能有仔细的朋友会发现我定义了一个不必要的变量W#L。这是没有办法的事情,否则AR2(W#I):W#L  SCAN      ADADDR 一行会超长。

 nhxingliang 回复于:2005-09-01 16:46:18
谢谢.........

认真学习.....................

延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网