在RPGLE中实现模糊检索的例程(带详细注释)
发表于:2007-05-26来源:作者:点击数:
标签:
说明: 1、这是一个在 数据库 中模糊检索地址的RPGLE程序。在画面上输入检索字串(用空格分开),回车后,SFL中显示DB中所有带有这些字串的地址 2、子程序说明:@KEN01为模糊检索,@C LR 01为SFL初始化,@WRT01为写SFL,@DEF为变量定义,@END为结束程序。[co
说明:
1、这是一个在
数据库中模糊检索地址的RPGLE程序。在画面上输入检索字串(用空格分开),回车后,SFL中显示DB中所有带有这些字串的地址
2、子程序说明:@KEN01为模糊检索,@C
LR01为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
|
谢谢.........
认真学习.....................
|
原文转自:http://www.ltesting.net
|