第八章 SMART FORMS设计
要点列表
概览;
Form(表格);
Smart Styles(样式);
Text Module(文本模块);
使用标准表方式打印;
使用模板方式打印;
在程序中调用SmartForms;
特定处理流程;(循环,条件,命令行,输出条件)
检查与测试Form;(break-point,直接F8处理)
其它的知识点;(两种方式传递内表)
课时要求
讲义内容确定依据自底向上方法进行估算
主要知识点的说明和使用方法
-
- 概览
SmartForm是在SAPScript的基础之上产生的一种新的FORM制作方式,它完全兼容SAPScript。在做SMARTFORM的过程中基本上不需要多少编程知识,它有一个图形界面来帮助我们完成工作。下面是一个简单SmartForm输出结果:
-
- Form(表格)
1.做Smart Form前要了解的概念
(1)FORM的结构:一个FORM往往是由页面(PAGES)、输出区域(OUTPUT AREAS即WINDOWS)、地址栏(ADRESS)、图形(GRAPHICS,比如公司LOGO)、数据(DATA)、以及文本内容(TEXT)组成。
(2)主窗体和子窗体:(MAIN WINDOWS AND SUB WINDOWS)这是页面上两个不同的输出区域,用来输出数据,文本等内容。对于主窗体,你在一个FORM中只能定义一个窗体作为主窗体;不同PAGE上的主窗体必须宽度相同,但是高度可以不同;一个没有主窗体的PAGE指向的下一个页面不能为它自己。对于子窗体,它也可以在多个页面上面显示,但是那些不匹配SUB WINDOWS的值,子窗体不会将它们显示出来。
2.启动SMARTFORM设计
输入TCODE:SMARTFORMS:
注:上面另外两个选项 Style、Text module分别是用来定义FORM的样式和文本模块的。
输入名称ZCXTRIAN_08_FORM,点击“创建”按钮,进入下面的Form Builder界面:
上面的屏幕分为三个部分:
(1)树形导航工具(最左边):它主要用来显示一个SMARTFORM的层次结构。当你在层次结构中选择了一个NODE(结点)后,在上面截屏的中间部分会显示这个NODE的MAINTENANCE屏幕。
(2)维护屏幕(中间):根据当前树状结构中选择的不同节点类型,会出现和种标签,对应相关的选项卡,在这些选项卡中可以进行该节点相关属性的设计。
(3)窗口绘制器(最右边):主要用来设计SMARTFORM输出页面的格式,可以在页面上包含窗口和图形,还可以指定它们在页面上的位置以及它们的大小等。在图片左上角的工具栏有一个按钮
可以用来显示和隐藏这个窗口。
3.全局设置
(1)表格属性:设置表格的样式,页面的格式(即页面大小),输出格式等。
(2)表格接口:它用来描述这个Smart Form的接口属性,比如IMPORT、EXPORT、TABLES、EXCEPTION。如果从ABAP程序中调用这个FORM的话,就会用到这些接口来传递参数。
(3)全局定义:主要用来定义一些全局数据,还有FIELD SYMBOLS,初始化等。
4.节点元素
Smart Form是通过Form Builder树形结构下的一系列节点组成的,这些节点是可以添加到窗口中输出或者对页面、版式进行控制的元素。
当一个版式被创建后,Form Painter中已经存在两个必需的根节点。其一为全局设置节点,该节点包含三个固定后继节点表格属性、表格接口、全局定义。另一个页和窗口节点,该节点还可以包含多种其它类型的后继节点,用于创建Smart Form的输出页面、在页面中放置元素及确定这些元素的处理顺序。下图为节点处理流程:
(1)页节点:每一个Form至少包含一个页(Page)节点。
(2)窗口节点:窗口是输出数据的区域。可以在窗口节点设定该区域大小和在版面中的位置。Smart Form中也包含主窗口和子窗口的区别,主窗口中的数据可以在多个打印页面中连续输出。
(3)文本节点:一般使用文本节点在已经定义的窗口中添加和种类型的文本元素,唯一的例外是地址类型的文本元素也可以通过Address节点来添加。SAP Smart Form中含下列类型的文本:
①文本元素:使用Smart Form中的PC Editor在Form创建过程中编辑的新文本。
②文本模块:独立于Smart Form,可以直接添加至Form,或参照文本模块生成Form文本元素。在接下来的章节中会单独介绍文本模块的创建及应用。
③包含文本:已经插入设计好的SAPScript标准文本(在SO10中创建,可通过SE75查找),体现了二者之间的兼容性。
(4)地址节点:地址是经常出现在各种信函中的文本,在SAPScript中,它是文本元素的一部分。通过地址的好处是保证地址是根据发信人国家的书写规范输出,使用地址节点有一个前提条件,即该用户必须具有SAP CAA的管理员权限,否则只有通过文本节点进行地址添加。
(5)图形节点:用于在页面中添加图片(必须使用SE78将图片上传至SAP系统内部)。
(6)模板节点:用于创建文档中的静态表格。所谓静态表格指的是该表格的布局和大小已经确定。
(7)动态表格:动态表格可以通过表格节点和循环节点等实现。
(8)节点的组合:如果一个Form中所包含的节点过多,其树形结构体系就可能显得不太清晰,因而在Smart Form中还提供了节点的组合功能,可以将多个相关联的节点组合成一个目录节点,以增加节点树的可读性。
-
- Smart Styles(样式)
1.运行事务代码SmartForms,选择样式(或者直接输入事务代码SmartStyles),输入名称:
点击“创建”按钮,这里面只把字体修改成了CNSONG:
2.设置样式表的段落格式及字符格式:
可以定义适合自己所用的段落格式和字符格式,定义好段落格式后,激活的时候会提示设置标准的段落,
此时需要在标准设置/标准段落里选择一个默认格式:
3.上传下载:菜单/实用程序/上载 下载,可以把样式表保存到本地或者把本地的样式表上传到服务器。
4.注意事项:设置完成后,一定要保存并激活样式。
-
- Text Module(文本模块)
1.事务代码:SmartForms,选择文本模块,输入名称:
点击创建,选择刚创建的样式表:
完成文本的输入及格式的设置,完成后保存即可。
2.上载下载:菜单/实用程序/上载 下载,可以把文本模块保存到本地或者上传到服务器。
-
- 使用标准表方式打印
输入功能代码SmartForms显示初始屏幕,选择表格,输入名称,点击创建:
下图是一个完整的TABLE实现的打印功能及程序调用后界面:
下面一步一步来介绍实现此功能:
表格属性:需要输入描述文本,在TAB属性页输出选项中可以引用自己的样式,系统默认为SYSTEM样式。
表格接口:需要输入描述文本,在TAB属性页中我们只需要设置表的接口,导入、导出、例外取系统默认值(此处的定义相当于定义了输入参数类型是一个表SPFLI)。
全局定义:需要输入描述文本,在TAB属性页中定义一个全局变量GS_OUT,相当于全局内表。类型、字段符号、初始化、格式化程序、货币/数量字段取系统默认值。
创建表:右键点击MAIN主窗口/创建/表,初始页面如下:
点击
细节按钮,设置行类型LINE_TITLE标题,LINE_HEADER表头,LINE_CONTENT数据,LINE_FOOTER表尾如第几页/共几页日期等:
设置数据(注意此处是把传入的参数表GT_OUT表中循环写入到全局变量GS_OUT中):
设置样式(在输出选项中选择样式,此处选择刚创建的样式ZCXTRAIN_08_STYLE):
创建标题行:右键点击表头/创建/表行,选择行类型(LINE_TITLE)及样式,
系统会根据刚才创建的行类型,自动分为一个列,然后再新列中再创建文本,修改后,效果如下:
创建表头行:右键点击表头/创建/表行,选择行类型(LINE_HEADER),系统会根据刚才创建的表行类型,自动分为四个列,然后在新列中分别创建文本,文本中分别输入表头要显示的字段名称,效果如下:
在一般属性中可以看到自定义的样式C1中_宋_12pt(小4)等。
创建主要区域数据显示行:右键点击主要区域/创建/表行,选择行类型(LINE_CONTENT),系统会根据刚才创建的表行类型,自动分为四个列,然后在新列中分别创建文本。点击按钮
字段列表打开/关闭,在左下侧会出现字段树,找到定义的全局变量GS_OUT,页面如下:
然后选择左侧要显示的字段拉到右侧一般属性显示区域。
创建脚标行:右键点击脚标/创建/表行,选择行类型(LINE_FOOTER),系统会根据刚才创建的表行类型,自动分为一个列,然后在新列中创建文本。注意此处选择是的文本类型为文本模块,然后输入名称ZCXTRAIN_08_TEXT,页面如下:
绘制表格线:双击表TABLE_SPFLI航班计划表示例,定位到“表”TAB页,
选中想要加边框的区域,
分别点击
外部框架,
内部框架,完成边框的绘制。如果是较复杂的表头,可以使用
来完成绘制。注意边框的宽度:默认为15TW。在实际工作中建议设置为20TW,用来适应针式打印机,激光打印机,喷墨打印机等。
-
- 使用模板方式打印
输入功能代码SmartForms显示初始屏幕,输入名称,点击创建:
下图是一个完整的模板实现的打印功能及程序调用后界面:
下面一步一步来介绍实现此功能:
表格属性:需要输入描述文本,在TAB属性页输出选项中可以引用自己的样式,系统默认为SYSTEM样式,此处引用的是自定义样式ZCXTRAIN_08_STYLE。
表格接口:由于此处是采用字段符号方式来实现的,所以在表格接口中没有定义数据,保留初始值。
全局定义:需要输入描述文本,在TAB属性页中定义全局变量及初始化变量的值。类型、字段符号、格式化程序、货币/数量字段取系统默认值。
GT_OUT:全局变量,内表。
GS_OUT:全局变量,工作区。
G_ROWNUM:每页的行数,此处默认值为18。
G_MOD:模数,主要用于分页。其值取表的索引号SY_TABIX mod G_ROWNUM。
G_ROWCOUNT:内表的行数。在初始化中赋值。
G_FLAG:一个标识符,主要是控制显示最后一页的页脚。SY_TABIX、G_ROWCOUNT相等的时候其值为‘X’。默认为’’。
ITAB_RESULT:类型,要求必须与程序中定义的结构一致,里面的字段顺序也必须一致。
记得要把输入参数,输出参数填写完整。主要是初始化内表,及得到内表的行数。
data: field(70).
field-symbols: <dbtable> type any.
*"要加程序名哦,不然哪里来,在调用SMART中和全局数据啥关系都没有
field = '(ZCXTRAIN_08_01)GT_SPFLI[]'.
assign (field) to <dbtable>.
gt_out[] = <dbtable>.
if <dbtable> is assigned.
unassign <dbtable>.
endif.
*得到数据共多少行 or DESCRIBE TABLE gt_out LINES g_rowcount.
*一定要写到下面,因为此时gt_out才被赋过值
G_ROWCOUNT = lines( gt_out ).
%PAGE1新页面:此处定义了横向格式,即输出的时候宽为29.2CM,高度为21CM。
创建循环及模板:右键点击MAIN主窗口/创建/流逻辑/循环,设置数据(注意此处是把内表GT_OUT表中循环写入到全局变量GS_OUT中)
创建程序行:右键点击%LOOP1新循环1/创建/流逻辑/程序行,创建程序行的目的取得模数及判断数据是否是最后一行,页面如下:
注意输入参数,输出参数。此处是得到模数及判断是否是最后一行,然后给变量赋值。
g_mod = sy-tabix mod g_rownum.
if g_rowcount = sy-tabix.
g_flag = 'X'.
endif.
创建标题模板:右键点击%LOOP1新循环1/创建/模板,然后再添加一个文本元素,可以自己手动画线来划分单元格,也可以通过细节来精确设置单元格:
标题行模板输出的条件:
点
细节按钮:
标题文本设置如下:
标题文本的输出选项,即定义输出到哪个单元格里面。注意下面的输出结构,行1列1,因为在标题模板中只定义了一行一列。
创建表头模板:右键点击%LOOP1新循环1/创建/模板,可以自己手动画线来划分单元格,也可以通过细节来精确设置单元格:
点击
细节,可以查看精确设置,此处设置的是两行表头,单元格宽度分别为:
第一行:2CM(空),2CM(空),6.5CM(起飞地点),6.5CM(到达地点), 6CM(时间明细),2.2CM(空)
第二行:2CM,2CM,2CM,2.5CM, 2CM,2CM,2.5CM,2CM, 2CM,2CM,2CM,2.2CM 合计25.2CM
表头输出是有条件的,如果不设置条件,那在此循环中每行数据都会显示表头:
然后在表头模板中分别加入文本元素:
起飞地点、到达地点、时间明细 分别对应第一行中的3,4,5列。
航线承运人ID、航班连接ID、国家代码、起飞城市、起飞机场、国家代码、目标城市、目的机场、航班时间、启程时间、到达时间、距离 分别对应第二行中的1---12列。
航线承运人ID,它对应输出的位置是第二行第一列,所以在输出结构中行2列1。
创建数据模板行:右键点击%LOOP1新循环1/创建/模板,可以自己手动画线来划分单元格,也可以通过细节来精确设置单元格:
数据模板输出条件:
点击细节,可以查看精确设置,此处设置报表内容共分为12个单元格宽度分别为2CM,2CM,2CM,2.5CM, 2CM,2CM,2.5CM,2CM, 2CM,2CM,2CM,2.2CM:
然后分别加入文本元素:航线承运人ID、航班连接ID、国家代码、起飞城市、起飞机场、国家代码、目标城市、目的机场、航班时间、启程时间、到达时间、距离;
点击按钮字段列表打开/关闭,在左下侧会出现字段树,找到全局数据/GS_OUT展开,分别对应上述文本元素把数据字段拉到右侧窗口中即可,页面如下:
输出结构为行1,列1。完成后可把其它文本字段都赋值,再分别设计输出选项。
创建页脚模板行:右键点击%LOOP1新循环1/创建/模板,页脚行相对简单一行一列:
要显示表尾的条件比较复杂,第一项是G_MOD=0的时候,或者G_FLAG=‘X’的时候:
然后加入文本元素:
-
- 在程序中调用SMARTFORMS
REPORT zcxtrain_08_01.
TABLES: spfli.
TYPE-POOLS: slis.
DATA: gt_spfli TYPE TABLE OF spfli WITH HEADER LINE.
DATA: g_repid TYPE sy-repid.
START-OF-SELECTION.
PERFORM frm_get_data.
END-OF-SELECTION.
PERFORM frm_display.
*&---------------------------------------------------------------------*
*& Form frm_get_data
*&---------------------------------------------------------------------*
* 把数据查询出来放到内表中
*----------------------------------------------------------------------*
FORM frm_get_data .
SELECT * INTO TABLE gt_spfli FROM spfli.
ENDFORM. " frm_get_data
*&---------------------------------------------------------------------*
*& Form frm_display
*&---------------------------------------------------------------------*
* 使用ALV显示数据
*----------------------------------------------------------------------*
FORM frm_display .
g_repid = sy-repid.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = g_repid
i_structure_name = 'SFLIGHT'
i_callback_pf_status_set = 'FRM_SET_MENU'
i_callback_user_command = 'FRM_USER_COMMAND'
i_save = 'A'
TABLES
t_outtab = gt_spfli.
ENDFORM. " frm_display
*&---------------------------------------------------------------------*
*& Form frm_show_status
*&---------------------------------------------------------------------*
* 调用状态栏
*----------------------------------------------------------------------*
FORM frm_set_menu USING rt_extab TYPE slis_t_extab.
SET PF-STATUS 'STANDARD'.
ENDFORM. "frm_set_menu
*&---------------------------------------------------------------------*
*& Form frm_user_command
*&---------------------------------------------------------------------*
* 用户按钮事件
*----------------------------------------------------------------------*
* -->P_UCOMM text
* -->SELFIELD text
*----------------------------------------------------------------------*
FORM frm_user_command USING p_ucomm LIKE sy-ucomm selfield TYPE slis_selfield.
CASE p_ucomm.
WHEN 'PRTTABLE'.
PERFORM frm_print_table.
WHEN 'PRTTEMPLET'.
PERFORM frm_print_templet.
WHEN 'EXIT' OR 'CANCEL' OR 'UP'.
LEAVE TO SCREEN 0.
ENDCASE.
ENDFORM. "FRM_USER_COMMAND
*&---------------------------------------------------------------------*
*& Form frm_print_table
*&---------------------------------------------------------------------*
* 调用使用TABLE创建的模板
*----------------------------------------------------------------------*
FORM frm_print_table .
DATA: fm_name TYPE rs38l_fnam.
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
formname = 'ZCXTRAIN_08_01'
IMPORTING
fm_name = fm_name.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
* FM_NAME 即 '/1BCDWB/SF00000210'
CALL FUNCTION fm_name
* EXPORTING
* ARCHIVE_INDEX =
* ARCHIVE_INDEX_TAB =
* ARCHIVE_PARAMETERS =
* CONTROL_PARAMETERS =
* MAIL_APPL_OBJ =
* MAIL_RECIPIENT =
* MAIL_SENDER =
* OUTPUT_OPTIONS =
* USER_SETTINGS = 'X'
* IMPORTING
* DOCUMENT_OUTPUT_INFO =
* JOB_OUTPUT_INFO =
* JOB_OUTPUT_OPTIONS =
TABLES
gt_out = gt_spfli
* EXCEPTIONS
* FORMATTING_ERROR = 1
* INTERNAL_ERROR = 2
* SEND_ERROR = 3
* USER_CANCELED = 4
* OTHERS = 5
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDFORM. " frm_print_table
*&---------------------------------------------------------------------*
*& Form FRM_PRINT_TEMPLET
*&---------------------------------------------------------------------*
* 调用使用模板创建的模板
*----------------------------------------------------------------------*
FORM frm_print_templet .
DATA: l_fm_name TYPE rs38l_fnam.
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
formname = 'ZCXTRAIN_08_02'
IMPORTING
fm_name = l_fm_name.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
CALL FUNCTION l_fm_name
* EXPORTING
* ARCHIVE_INDEX =
* ARCHIVE_INDEX_TAB =
* ARCHIVE_PARAMETERS =
* CONTROL_PARAMETERS =
* MAIL_APPL_OBJ =
* MAIL_RECIPIENT =
* MAIL_SENDER =
* OUTPUT_OPTIONS =
* USER_SETTINGS = 'X'
* IMPORTING
* DOCUMENT_OUTPUT_INFO =
* JOB_OUTPUT_INFO =
* JOB_OUTPUT_OPTIONS =
* EXCEPTIONS
* FORMATTING_ERROR = 1
* INTERNAL_ERROR = 2
* SEND_ERROR = 3
* USER_CANCELED = 4
* OTHERS = 5
.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
ENDFORM. " FRM_PRINT_TEMPLET
GUI状态:
小技巧:Smart Form制作完成后,记得要激活。然后点击执行 (或者F8)按钮,会出现如下窗口:
记下此处的Function Module的名称:/1BCDWB/SF00000223。
在程序调用的时候,把光标定位到要调用的方法中,然后点击模式按钮:
在CALL FUNCTION后面输入刚才的值,系统会自动生成调用Smart Form的标准程序代码。然后再修改程序代码。
-
- 特定处理流程
-
- 检查与测试Form
-
- 其它的知识点
1.不管哪种方式来打印,页面的上边距+下边距+数据显示区域(表头,主要区域,脚标)的高度不能大于所选择的页面的高度;页面的左边距+右边距+数据显示区域(各列宽度之和)的宽度不能大于所选择的页面的宽度。
2.两种方式调用SmartForm(参考ZCXTRAIN_08_01程序),一种是通过全局设计/表格接口来实现,另一种方式是通过字段符号来传递参数。
3.边框宽度:因为在实际工作中所使用的打印机不一样,导致有的边框线条打印不出来,所以建议设计成20TW(为临界值)。
4.程序调用Smart Form的时候,一定要用CALL FUNCTION ‘SSF_FUNCTION_MODULE_NAME’先根据Smart Form名称得到它的函数名称fm_name。然后再 CALL FUNCTION fm_name调用Smart Form。因为Smart Form的fm_name可以重新分配,是个不固定值。