您的位置:首页 > 其它

解决Search help (F4 help)区分大小写的问题

2012-06-01 13:29 363 查看
在abap编程中,search help是一个非常有用,也经常涉及到的东东。它有个问题是,自动区分大小写。而且没有设置去更改这种行为。有客户抱怨说,他搜索时不需要区分大小写。解决方法是建一个search help exit(也就是指定一个function module)去自定义搜索内容。

这里,我提供两种代码实现方式。

方法一:

FUNCTION yzr_fto_f4help_exit .
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  TABLES
*"      SHLP_TAB TYPE  SHLP_DESCT
*"      RECORD_TAB STRUCTURE  SEAHLPRES
*"  CHANGING
*"     REFERENCE(SHLP) TYPE  SHLP_DESCR
*"     REFERENCE(CALLCONTROL) LIKE  DDSHF4CTRL STRUCTURE  DDSHF4CTRL
*"----------------------------------------------------------------------

DATA: it_shlpselop TYPE ddshselops,
wa_shlpselop LIKE LINE OF it_shlpselop,
lv_name1 TYPE /sapsll/v_orgbp-name1,
lv_usrname1 TYPE /sapsll/v_orgbp-name1,
lv_tabix TYPE i,
it_shlp TYPE shlp_descr-fielddescr,
wa_shlp LIKE LINE OF it_shlp.

CONSTANTS: BEGIN OF gc_memory,                            "#EC *
fto_name1 TYPE char16 VALUE 'FTO_F4HELP_NAME1', "#EC *
vbs_name1 TYPE char16 VALUE 'VBS_F4HELP_NAME1', "#EC *
END OF gc_memory.                              "#EC *

* Step1: Save input parameters to memory and delete them from Selection Options to let search help return whole list.
IF callcontrol-step = 'SELECT'.
DELETE FROM MEMORY ID gc_memory-fto_name1.
LOOP AT shlp-selopt INTO wa_shlpselop.
IF wa_shlpselop-shlpfield EQ 'NAME1'.                 "#EC *
lv_usrname1 = wa_shlpselop-low.
EXPORT lv_usrname1 TO MEMORY ID gc_memory-fto_name1.
DELETE shlp-selopt INDEX sy-tabix.
ENDIF.
ENDLOOP.
ENDIF.

* Step2: Restore selection options by comparing with the original text.
IF callcontrol-step = 'DISP'.
IMPORT lv_usrname1 TO lv_usrname1 FROM MEMORY ID gc_memory-fto_name1.
IF NOT lv_usrname1 IS INITIAL.
*      TRANSLATE lv_usrname1 TO UPPER CASE.
LOOP AT record_tab.
lv_tabix = sy-tabix.
READ TABLE shlp-fielddescr INTO wa_shlp
WITH KEY tabname   = 'YZR_V_ORGBP' "#EC *
fieldname = 'NAME1'.         "#EC *
wa_shlp-offset = wa_shlp-offset / 2.
lv_name1 = record_tab-string+wa_shlp-offset(40).
*        TRANSLATE lv_name1 TO UPPER CASE.
IF NOT lv_name1 CP lv_usrname1.
DELETE record_tab INDEX lv_tabix.
ENDIF.
ENDLOOP.
ENDIF.
ENDIF.


其主要做法是:

1. 在‘SELECT’事件里,把输入的选择条件保存在全局缓存中,并从shlp-selopt中擦除。这样,search help会把所有记录都找出来。

2. 在‘DISP’事件里,把搜索条件从缓存中读出来,并手动删除不符合条件的记录。这里一定要算准字段的位置和值,并注意使用‘CP’操作符,支持‘*’通配符查询。

此方法有个问题:我们所操作的记录是基于search help自动产生的。Search Help画面中的允许输出最大值将影响到这些记录。比如最大值被设定为500,那么我们操作的记录集最多也只有500条,真正符合条件的则更少。这就带来一个潜在的bug,有可能真正符合条件的有20条,但由于search help本身限定了500条,所以可能这20条中,只有10条在这500条中,其余10条没有传给我们。那结果一定是不正确的。把最大值设为很大很大,可以解决这个问题,但对用户来说是不合理的。

方法二:

FUNCTION /sapsll/shlp_exit_project.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  TABLES
*"      SHLP_TAB TYPE  SHLP_DESCT
*"      RECORD_TAB STRUCTURE  SEAHLPRES
*"  CHANGING
*"     REFERENCE(SHLP) TYPE  SHLP_DESCR
*"     REFERENCE(CALLCONTROL) LIKE  DDSHF4CTRL STRUCTURE  DDSHF4CTRL
*"----------------------------------------------------------------------
DATA:
lt_shlpselop  TYPE ddshselops,
wa_shlpselop  LIKE LINE OF lt_shlpselop,
lv_pronr      TYPE /sapsll/pronr,
lv_ernam      TYPE /sapsll/ernam,
lv_aenam      TYPE /sapsll/aenam,
lv_text1      TYPE /sapsll/text60,
lv_text2      TYPE /sapsll/text60,
lv_text3      TYPE /sapsll/text60,
lv_tabix      TYPE int4,
lt_project    TYPE TABLE OF /sapsll/v_lcpro,
wa_project    LIKE LINE OF lt_project.

FIELD-SYMBOLS: <lt_tab> TYPE table.

CHECK ( callcontrol-step = 'SELECT' ).

LOOP AT shlp-selopt INTO wa_shlpselop.
CASE wa_shlpselop-shlpfield.
WHEN 'PRONR'.                                         "#EC *
lv_pronr = wa_shlpselop-low.
WHEN 'ERNAM'.                                         "#EC *
lv_ernam = wa_shlpselop-low.
WHEN 'AENAM'.                                         "#EC *
lv_aenam = wa_shlpselop-low.
WHEN 'TEXT1'.                                         "#EC *
lv_text1 = wa_shlpselop-low.
WHEN 'TEXT2'.                                         "#EC *
lv_text2 = wa_shlpselop-low.
WHEN 'TEXT3'.                                         "#EC *
lv_text3 = wa_shlpselop-low.
WHEN OTHERS.
ENDCASE.
ENDLOOP.

SELECT t1~pronr t2~text1 t2~text2 t2~text3 t1~ernam t1~aenam
FROM /sapsll/lcpro  AS t1
JOIN /sapsll/lcprot AS t2
ON t1~guid_lcpro = t2~guid_lcpro
AND t1~mandt = t2~mandt
AND t2~langu = sy-langu
INTO CORRESPONDING FIELDS OF TABLE lt_project
ORDER BY t1~pronr.

DELETE ADJACENT DUPLICATES FROM lt_project.

IF ( lv_pronr IS NOT INITIAL )
OR ( lv_ernam IS NOT INITIAL )
OR ( lv_aenam IS NOT INITIAL )
OR ( lv_text1 IS NOT INITIAL )
OR ( lv_text2 IS NOT INITIAL )
OR ( lv_text3 IS NOT INITIAL ).
LOOP AT lt_project INTO wa_project.
lv_tabix = sy-tabix.
IF ( lv_pronr IS NOT INITIAL AND NOT wa_project-pronr CP lv_pronr )
OR ( lv_ernam IS NOT INITIAL AND NOT wa_project-ernam CP lv_ernam )
OR ( lv_aenam IS NOT INITIAL AND NOT wa_project-aenam CP lv_aenam )
OR ( lv_text1 IS NOT INITIAL AND NOT wa_project-text1 CP lv_text1 )
OR ( lv_text2 IS NOT INITIAL AND NOT wa_project-text2 CP lv_text2 )
OR ( lv_text3 IS NOT INITIAL AND NOT wa_project-text3 CP lv_text3 ).
DELETE lt_project INDEX lv_tabix.
ENDIF.
ENDLOOP.
ENDIF.

*   'Maximum Number of Rows' logic
callcontrol-maxexceed = abap_false.
IF callcontrol-maxrecords > 0.
*   restrict result table to max. rows specified in MAXRECORDS;
*   set MAXEXCEED if there are more than MAXRECORDS rows
DELETE lt_project FROM callcontrol-maxrecords + 1.
IF sy-subrc = 0.
*     more rows exist than requested
callcontrol-maxexceed = abap_true.
ENDIF.
ENDIF.

ASSIGN lt_project TO <lt_tab>.

CALL FUNCTION 'F4UT_RESULTS_MAP'
TABLES
shlp_tab    = shlp_tab
record_tab  = record_tab
source_tab  = <lt_tab>
CHANGING
shlp        = shlp
callcontrol = callcontrol.

callcontrol-step = 'DISP'.

ENDFUNCTION.


此方法主要原理是:

1. 在‘SELECT’事件里,直接从数据库中搜索出所有记录,然后根据过滤条件,手动删除不符合的记录。

2. 判断符合记录的数量是否超过了最大允许输出值,把多余的删除。

此方法解决了方法一中碰到的问题,比较稳妥。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: