背景:
最近在做项目的时候,涉及超长字符串无法通过SM30配置的问题,原本想通过批导程序传到表中,但是查看和编辑都很困难,最后干脆使用自定义长文本来管理。
目前还没找到标准的长本文管理工具,那就自己写一个。
简短实用,记录一下。
主要功能:
长文本查询、编辑、保存。
涉及知识点及表:
SE75 - SAPscript 设置 ( 创建 自定义长文本对象)
STXH - 长文本的抬头信息
STXL - 长文本是明细信息
开发详细步骤:
1、创建长文本对象
事务码:SE75
选择 文本对象和标识 -> 更改
创建->文本对象
双击新建的对象 -> 创建文本标识->保存
注意:这个时候表 STXH 和 STXL 还没有记录,因为新对象还没有记录。
此时确定的是:文本对象(tdobject)、文本标识(tdid) ,另外两个重要参数:文本名称(tdname)、语言代码(tdspras)均由文本创建时指定。
2、报表程序
屏幕设计1:选择屏幕作为子屏幕(编号 101)
"子屏幕 - 选择条件
SELECTION-SCREEN BEGIN OF SCREEN 101 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK bk1 WITH FRAME TITLE TEXT-001.
PARAMETERS:
p_objct TYPE thead-tdobject , "文本: 应用程序对象
p_name TYPE thead-tdname , "名称
p_id TYPE thead-tdid , "文本标识
p_spras TYPE thead-tdspras DEFAULT sy-langu. "语言代码
SELECTION-SCREEN END OF BLOCK bk1.
SELECTION-SCREEN END OF SCREEN 101.
屏幕设计2:主屏幕(编号 100 )
子屏幕 SUBSCREEN_SEL - 存放选择条件
定制控制 CONTAINER_TEXT - 长文本编辑器
主屏幕逻辑流:
PROCESS BEFORE OUTPUT.
"设置屏幕状态和标题
MODULE status_0100.
"初始化 长文本容器 及 设置属性
MODULE init_0100.
"加载子屏幕
CALL SUBSCREEN subscreen_sel INCLUDING sy-repid '101'.
PROCESS AFTER INPUT.
"刷新子屏幕(一定要优先调用,否则最新条件取不到)
CALL SUBSCREEN subscreen_sel.
"响应事件
MODULE user_command_0100.
REPORT ztools_long_text.
DATA: g_ucomm TYPE sy-ucomm.
DATA: ok_code TYPE sy-ucomm.
DATA: gv_mode TYPE c VALUE 'D'." C - Create ; U - Update ; D - Display
"长文本使用
DATA:
* Create reference to the custom container
custom_container1 TYPE REF TO cl_gui_custom_container,
editor1 TYPE REF TO cl_gui_textedit,
lines TYPE STANDARD TABLE OF tline,
header TYPE thead,
texttable TYPE TABLE OF textline.
"子屏幕 - 选择条件
SELECTION-SCREEN BEGIN OF SCREEN 101 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK bk1 WITH FRAME TITLE TEXT-001.
PARAMETERS:
p_objct TYPE thead-tdobject , "文本: 应用程序对象
p_name TYPE thead-tdname , "名称
p_id TYPE thead-tdid , "文本标识
p_spras TYPE thead-tdspras DEFAULT sy-langu. "语言代码
SELECTION-SCREEN END OF BLOCK bk1.
SELECTION-SCREEN END OF SCREEN 101.
START-OF-SELECTION.
CALL SCREEN 100.
*&---------------------------------------------------------------------*
*& Module STATUS_0100 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
SET PF-STATUS '100'.
SET TITLEBAR '100'.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0100 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
g_ucomm = ok_code.
CASE g_ucomm.
WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
LEAVE TO SCREEN 0.
WHEN '&SRCH'.
PERFORM frm_get_data.
WHEN '&SAVE'.
PERFORM frm_save_data.
WHEN '&EDIT'.
IF gv_mode = 'D'..
gv_mode = 'U'.
ELSE.
gv_mode = 'D'.
ENDIF.
WHEN OTHERS.
LEAVE TO SCREEN 0.
ENDCASE.
CLEAR: g_ucomm,ok_code.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Module INIT_0100 OUTPUT
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
MODULE init_0100 OUTPUT.
IF editor1 IS INITIAL.
" 初始化 长文本容器 及 设置属性
* 创建容器
CREATE OBJECT custom_container1
EXPORTING
container_name = 'CONTAINER_TEXT' "容器(表控件)名
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I'
NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CREATE OBJECT editor1
EXPORTING
wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
parent = custom_container1
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
OTHERS = 6.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE 'I'
NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* 去掉状态栏
CALL METHOD editor1->set_statusbar_mode
EXPORTING
statusbar_mode = cl_gui_textedit=>false.
* 去掉工具栏
CALL METHOD editor1->set_toolbar_mode
EXPORTING
toolbar_mode = cl_gui_textedit=>false.
ENDIF.
* 设置可编辑状态
IF editor1 IS NOT INITIAL.
"C - Create U - Update D - Display
IF gv_mode = 'C' OR gv_mode = 'U'..
CALL METHOD editor1->set_readonly_mode "用户长文本 可编辑
EXPORTING
readonly_mode = '0'
EXCEPTIONS
error_cntl_call_method = 1
invalid_parameter = 2
OTHERS = 3.
ELSE.
CALL METHOD editor1->set_readonly_mode "用户长文本 不可编辑
EXPORTING
readonly_mode = '1'
EXCEPTIONS
error_cntl_call_method = 1
invalid_parameter = 2
OTHERS = 3.
ENDIF.
ENDIF.
ENDMODULE.
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_get_data .
IF p_objct IS INITIAL OR
p_name IS INITIAL OR
p_id IS INITIAL OR
p_spras IS INITIAL..
MESSAGE '全部筛选条件必填' TYPE 'S' DISPLAY LIKE 'E'.
EXIT.
ENDIF.
CLEAR: header.
header-tdobject = p_objct.
header-tdname = p_name.
header-tdid = p_id.
header-tdspras = p_spras.
CLEAR: lines,texttable.
* 读取文本对象的文本
CALL FUNCTION 'READ_TEXT'
EXPORTING
id = header-tdid
language = header-tdspras
name = header-tdname
object = header-tdobject
TABLES
lines = lines
EXCEPTIONS
id = 1
language = 2
name = 3
not_found = 4
object = 5
reference_check = 6
wrong_access_to_archive = 7
OTHERS = 8.
* IF lines IS NOT INITIAL.
* 转换文本流
CALL FUNCTION 'CONVERT_ITF_TO_STREAM_TEXT'
EXPORTING
language = sy-langu
TABLES
itf_text = lines
text_stream = texttable.
* 将取到的文本写入画面的文本框中
CALL METHOD editor1->set_text_as_stream
EXPORTING
text = texttable
EXCEPTIONS
error_dp = 1
error_dp_create = 2
OTHERS = 3.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_save_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& --> p1 text
*& <-- p2 text
*&---------------------------------------------------------------------*
FORM frm_save_data .
FIELD-SYMBOLS <fs> TYPE REF TO cl_gui_textedit.
DATA : lt_table TYPE STANDARD TABLE OF tdline,
l_modi TYPE i,
lt_tlines TYPE TABLE OF tline,
ls_tlines TYPE tline,
l_thead TYPE thead.
ASSIGN editor1 TO <fs>.
* 获取长文本输入框的内容
CLEAR:lt_table,l_modi,lt_tlines.
CALL METHOD <fs>->get_text_as_r3table
IMPORTING
table = lt_table
is_modified = l_modi
EXCEPTIONS
error_dp = 1
error_cntl_call_method = 2
error_dp_create = 3
OTHERS = 4.
IF sy-subrc <> 0.
ELSEIF l_modi = 1.
LOOP AT lt_table INTO ls_tlines-tdline.
APPEND ls_tlines TO lt_tlines.
ENDLOOP.
CLEAR:l_thead.
l_thead-tdid = header-tdid.
l_thead-tdspras = header-tdspras.
l_thead-tdname = header-tdname.
l_thead-tdobject = header-tdobject .
* 调用方法创建保存文本对象
CALL FUNCTION 'CREATE_TEXT'
EXPORTING
fid = l_thead-tdid
flanguage = l_thead-tdspras
fname = l_thead-tdname
fobject = l_thead-tdobject
TABLES
flines = lt_tlines
EXCEPTIONS
no_init = 1
no_save = 2
OTHERS = 3.
ENDIF.
gv_mode = 'D'.
ENDFORM.