免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4866 | 回复: 15
打印 上一主题 下一主题

在RPGLE中实现模糊检索的例程(带详细注释) [复制链接]

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

RPGLE程序:

     H DATEDIT(*YMD)
     FADDRES    IF   E           K DISK
     FADDR01D   CF   E             WORKSTN SFILE(SFL01:#RRN01)
     D AR1             S              1    DIM(40)
     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
     C                   MOVEA     D#ADDR        AR1
     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
     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

     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

论坛徽章:
0
2 [报告]
发表于 2005-09-01 13:10 |只看该作者

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

很好,偶看可行!建议加精

论坛徽章:
0
3 [报告]
发表于 2005-09-01 13:11 |只看该作者

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

不错 加精~

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

论坛徽章:
0
4 [报告]
发表于 2005-09-01 13:15 |只看该作者

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

楼主,是原创吗?

论坛徽章:
0
5 [报告]
发表于 2005-09-01 13:15 |只看该作者

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

楼主,俺对你的敬仰如滔滔江水。。。

论坛徽章:
0
6 [报告]
发表于 2005-09-01 13:16 |只看该作者

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

是俺今天上午抽空瞎写的,多多指教,多多指教。

论坛徽章:
0
7 [报告]
发表于 2005-09-01 13:17 |只看该作者

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

呵呵,看起来比我们那个模糊查询代码要少些。
:wink:

论坛徽章:
0
8 [报告]
发表于 2005-09-01 13:19 |只看该作者

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

那时当然了呵呵!!

论坛徽章:
0
9 [报告]
发表于 2005-09-01 13:30 |只看该作者

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

我正在搞模糊查询的东东!

多谢了

论坛徽章:
0
10 [报告]
发表于 2005-09-01 14:00 |只看该作者

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

刚刚把说明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
     C                   MOVEA     D#ADDR        AR1
     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
     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

     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 一行会超长。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP