抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

本篇笔记记录一下Smartforms相关技术的内容,供后面学习和参考。

Smartforms 案例

一、Smartform概述

1.简介

Smartform是在SAPScript的基础上产生的一种新的表单制作方式,它完全兼容SAPScript,但是相较于SAPScript更加的独立,且使用起来更加方便。

2.SAPscript与Smartform区别

  • Smartform在激活时会自动创建一个功能模块,但是SAPscript不会生成;
  • Smartform可以直接书写子程序,使用程序行节点。而SAPscript则只能使用控制命令语句PERFORM调用SUBROUTINE;
  • SAPscript是基于Client的,而Smartform不区分任何Client;
  • Smartform的字体可使用Color,但是SAPscript不可以;
  • SAPscript的每个page都只能统一按照横向和竖向页面格式,而Smartform则可以不统一格式。

以上内容摘自[SmartForm]SAPscript 与 smartform 区别[转]

二、Smartform功能介绍

1.事务码 Smartforms

虽然技术的名称叫做Smartform,但是事务码却是Smartforms

1.事务码Smartforms

进入Smartform的界面后在界面上有三个对应的功能对象。

  • Form:Smartform表单对象
  • Style:Smartform表单中各类文本对象的样式
  • Text Module:文本模块

2.Style 文本样式

(1)介绍

在上图中新建一个Style后会进入到下面的页面中。

2.Style主界面

在该页面可以设置段落和字体样式,在设置的同时,在最下方也有一个可供预览的窗口。窗口中的内容是可以进行变更的,而你设置的无论是段落的样式还是字体的样式都可以在下方看到具体的变化内容。

接下来对其中的功能进行简单介绍。

  • 标准段落:设置默认的段落格式。当在Smartform中设置了Style但是没有设置段落样式时,使用该样式。

  • 每英寸字符数:设置字符间距,设置逻辑为每英寸中字符数。

  • 制表空格:制表符间距。

  • 每英寸行数:设置行字符间距,设置逻辑为每行中字符数。

  • 字体:设置字体样式,可以通过SE73对SAP中的字体进行维护。

  • 字体大小:设置字体的大小。

  • 字体样式:设置字体的 空(默认)/斜体/粗体/斜粗体。

  • 下划线:文字添加下划线。

  • 颜色:字体颜色。

在创建自定义的段落格式与字符格式时,两者的样式名称只能为2个字符。但是在使用时,会将样式的名称与描述同时显示出来。所以建议在设置自定义样式时写清楚描述内容。

(2)段落格式

① 缩进和空格

用来自定义控制文本段落样式的功能,和普通的Word文档的段落设置内容类似。可以用来设置段落的对齐方式,默认是居左对齐的方式,此外还有居中、右对齐和已调整的等对齐方式。

3.Style 段落样式界面
② 字体

字体的设置内容与上面介绍的字体样式内容一致,所以此处只展示一下界面。

4.Style 段落字体样式界面
③ 标签

当某个段落需要分为多个列,而需要设置每个列的宽度与对齐方式时,可以在此处设置。但是Smartform的段落格式可以通过模板或表格来定位,标签的应用一般较少。所以在实际使用过程中使用标签的需求很少,所以也不建议使用。

5.Style 段落标签样式界面

如上图所示,设置了三个列,均是左对齐,三个列总长为1cm + 2cm + 3cm = 6cm。

(3)字符格式

① 标准设置

在此处可以设置条形码,在名称处选择你上传或需要使用的条形码名称。此外还可以在此处设置字体的上标或下标样式。

6.Style 字段标准设置界面
② 字体

内容和上面的字体样式设置界面一致,所以此处就只展示一下界面。

7.Style 字段标准 字体设置界面

3.Text Module 文本模块

(1)介绍

文本模块主要用于设置一段固定的文本信息,如报表头名称,或者是报表附加条款说明等信息。

8.Text Module界面

(2)文本页签

进入后的界面和文本输入界面类似,在其中输入想要展示的文本内容即可。此外可以在后一个页签管理中设置该文本框中文本样式。

9.Text Module 文本输入框界面

(3)管理页签

在该页签主要用于设置前面文本输入框属性的样式设置,此处的样式也可以使用自己自定义的Style文本样式,若不设置则会使用系统默认的文本样式SYSTEM

10.Text Module管理页签界面

4.Form 表单

(1)介绍

打印报表内容的设置,可以在其中设置表格或循环打印数据等。

11.Form创建界面

在新建的Smartform界面中可以分为三个部分,左侧的部分是报表的各项属性与页内容的设置,中间则是Smartform内容的详细设置,而右侧部分则是Smartform内容的预览。

12.Form界面

(2)节点元素

Form中元素的输出顺序由Pages and Windows(页和窗口)中的后继节点结构和顺序来决定,导航树中的第一个页节点是Form处理的起始页,该节点在Form创建过程中被自动创建。导航树中的所有节点按照从上到下的顺序依次进行处理(包含页和窗口之间的节点)。

除了Pages and Windows(页和窗口)以外,其它所有节点都是可以加上执行条件属性设置的。只要满足的执行条件,则该节点才会被处理。

5.Form 全局设置

(1)表格属性

此处主要设置报表打印的格式,例如在输出选项中设置打印格式为A4纸的形式或设置报表文本的默认Style样式等。如果在此处设置了Style样式,则在后续的样式使用过程中会默认使用这个样式。

13.全局设置_表格属性_常规属性 14.全局设置_表格属性_输出选项

(2)表格接口

因为Smartform在最后调用时是通过Function Module的形式调用的,所以在表格接口处用于设置Funtion Module的参数。毕竟打印展示用的数据还需要通过这些参数进行获取和传递。

15.全局设置_表格接口

(3)全局定义

此处主要适用于定义Smartform全局变量、类型、初始化逻辑和映射货币或单位字段的位置。在此处设置的类型、变量和常量,在后续的所有节点和子结点中都是可以访问的。

16.全局设置_全局定义

6.页和窗口

(1)介绍

该功能模块就是用来设置Smartform展示内容的,所有的内容样式展示都是在这里进行设置的。可以在其中添加Page页节点、窗口、图形和地址等节点。然后在这些节点下再添加子元素节点用详细展示内容或进行逻辑处理。

17.页和窗口

(2)Page 节点

每一个Form都至少包含一个页节点。Page节点是Pages and Windows(页和窗口)的子节点,如果某个Page内容超出一页,则会将其他内容输出到Page节点的Next Page属性所指定的页面。每多出来一页内容就会产生分页,一般Next Page分页默认为自己。因为这样的Page节点格式类似,数据循环展示,所以只需要将数据重新加载进Page页自身即可。而如果需要有固定的报表头或报表页脚则需要重新新建Page节点。

此处的Page节点指代的是某一类页面的统称,而这个Page节点的内容则由其下的子节点确定。每Page页面除了通过Next Page静态属性来设置下一页,还可以再通过COMMAND节点的Go To New Page属性来设置。而设置页面跳转的条件则是通过CONDITION条件节点设置的。

(3)窗口节点

页面中包含主窗口(Main Windows)和子窗口(Secondary Windows)。其中,主窗口中的数据可以分页展示数据。每个Page节点中只能包含一个主窗口,但是可以有多个子窗口。在分页中,子窗口每次都会出现,就类似于页头和页脚。

  • 一个Smartform中只能顶一个主窗体;
  • 不同的Page上的主窗体必须宽度相同,但是高度可以不相同;
  • 一个没有主窗体的Page指向的下一个页面不能是自身;
  • 窗口中的模板宽度与高度不能超过窗口的宽度与高度,否则显示不出来;
  • 表格的宽度也不能比窗口的宽,否则编译会报错。

(4)图形节点

Smartform中可以使用SAP在SE78中上传的图片。

① 使用SE78上传图片

使用TCODE SE78上传图片时,需要先将图片使用系统自带的画图软件将其转化为bmp格式的图片。

19.SE78 图片格式

然后再使用TCODE SE78,点击上传按钮将图片上传到SE78。

18.SE78上传图片

上传成功后会在右侧显示图片的属性等信息。在上传图片时的一些设置也在可以右侧进行修改。

20.SE78图片上传成功
② Smartform添加图片

在Page页/窗口界面添加图形,然后拖动图形到界面上合适的位置。

21.Smartform添加航班Logo图片

创建完图片并填写完图片的名称等属性后,便可以在最右侧的Smartform预览窗口中看到添加的Image图片。然后可以自己将其拖动到合适的位置。

22.上传的图片

(5)地址节点

地址是经常出现在各种信函中的文本,在Smartform中与文本元素类似,所以可以在输出选项页签中设置样式等。通过地址的好处是保证地址是根据发信人国家的书写规范输出,使用地址节点有一个前提条件,即该用户必须具有SAP CAA的管理员权限,否则只有通过文本节点进行地址添加。

23.创建地址节点 24.地址节点属性

(6)文本节点

① 常规属性

当需要在Smartform中添加文字或文本内容时就需要使用到文本节点。

26.文本节点_文本类型

Smartform中包含下面类型的文本:

  • 文本元素:使用Smart Form中的PC Editor在Form创建过程中编辑的新文本。
  • 文本模块:独立于Smart Form,可以直接添加至Form,或参照文本模块生成Form文本元素。
  • 包含文本:已经插入设计好的SAPScript标准文本(在SO10中创建,可通过SE75查找),体现了二者之间的兼容性。
  • 动态文本:传入一个变量,展示的内容与变量值一致。可以参考这一片内容SMARTFORMS 输出动态文本(字符长度超出255)
② 输出选项

在输出选项中可以对当前文本节点的样式进行设置,此处设置的样式只会在当前文本节点生效。若此处不设置样式,则会使用之前在全局设置中表格属性的样式。

27.文本节点_输出选项

(7)字段列表

Smartform自身拥有很多的变量,而当我们在文本节点中需要使用这些变量时,可以通过打开字段列表然后将字段拖进文本节点的方式引入变量。

打开字段列表的方式有三种,一种是直接使用界面上的字段列表打开/关闭按钮;或是在最上侧的导航栏中 实用程序->字段列表打开/关闭;第三种则是直接使用快捷方式Crtl + Shift + F4。本片笔记就暂时记录最常使用的第一种方式。

28.打开字段列表

可以在左下角的小窗口中看到Smartform中系统变量、输入参数(导入接口)和输出参数(导出接口)。如果要在文本节点中使用下面的参数可以直接点击要使用的变量然后拖动到文本框中即可。

(8)模板节点

模板节点相较于表格节点要更为灵活,模板节点中的单元格可以添加图片和文本等子节点,用于展示图片内容或文本内容。此外模板节点的行高是可以自定义设置的。但是表格节点无法自定义行高或宽。

29.创建模板
① 表绘制器

默认为15TW。在实际工作中建议设置为20TW,用来适应针式打印机,激光打印机,喷墨打印机等。因为在实际工作中所使用的打印机不一样,导致有的边框线条打印不出来,所以建议设计成20TW(为临界值)。

30.模板界面
② 模板详细信息

例如上图所示,将上面的模板分成两列两行。然后进入详细信息界面对四个格子的列宽和行高进行设置。行定义中的Form和To选项用于指定当前的设置应用于哪些行。行号起始值为1,且行号不能出现间隔和重复。也可以指定Reference的值将其他行的设置应用到当前行。指定引用号后,系统将自动拷贝该行的行高和列宽等到当前行。

31.模板界面_详细信息
③ 表格与子节点的绑定

当你需要将子节点文本节点或图片节点绑定到模板对应的位置,则需要先将子节点放在模板节点下。之后可以在子节点的输出选项页签下通过输出结构设定子节点在模板表格中的位置。

例如我如果想将文本子节点放在模板的第一行第一个格子中,则在下图的行中输入1,列输入1。

32.填充子节点到模板节点

(9)表节点

表节点与模板类似,但是不同的地方是表节点本身就是为了展示数据而设置的。所以在创建完表节点后需要为表节点设置表头,表体和表的脚注(表头和表的脚注可选,不一定要有)。此外还需要设置表体中的数据源,用于获取展示的数据。

33.表节点创建

创建好表节点后,在子节点的表页签界面设置列。

35.表节点详细信息界面

在创建表的行子元素节点时会要求设置行类型,也就是上图中划分的列。此时选择好行类型后,会根据行类型中的列数自动生成列子节点,如下图所示。

36.表节点创建表行 37.表节点_表行绑定行类型 38.表节点_生成列子节点

(10)table和template的区别

以下内容是我从百度文库中找到的。

  • table可以动态添加行,数据输出时会根据列宽自动换行,可以固定列宽,但是默认情况下控制不了行高,如果要像template一样固定行高,需要将table的无换页属性打勾。
  • template是静态的,固定列宽、行高,当输出数据过长时会自动截断,通常被用于静态表单开发。template跟loop嵌套使用,可以实现固定行高、列宽的表单开发。
39.table和template区别_属性设置

三、Smartform实例

制作一个下图所示的Smartform,在OOALV的报表中选择想要展示的航班信息。然后进行预览,最后将其下载成PDF文件。

97.最终成果图

1.设置Style

(1)设置Style的默认格式

设置此处之后在进入文本节点时,会以该格式为默认的格式设置字体样式。

40.实例_Style的创建

(2)设置段落格式

此处的段落格式和Word中的段落设置内容类似。可以设置其对齐方式缩进间距字体样式等。在设置段落和字符格式时,最好在描述处写上这个段落或字符的样式简介,因为后续在使用时是通过段落与字符的描述对其设置样式的内容进行区分的。

然后我们分别设置左对齐格式、居中加粗(标题用)和普通大小的居中样式。

41.实例_Style 段落设置 42.实例_Style 段落字体设置

其他的两个段落样式节点设置原理相同,所以下面只列出节点的样式属性。

  • D2段落节点:
    • 描述:居中加粗标题
    • 缩进和空格:定中心(居中)
    • 字体:
      • 字体族:COURIER
      • 字体大小:14磅
      • 字体样式:粗体
  • D3段落节点:
    • 描述:正文居中格式
    • 缩进和空格:定中心(居中)
    • 字体:
      • 字体族:COURIER
      • 字体大小:12磅

(3)设置字符格式

想要单独设置字符的样式可以直接添加字符节点,当你只想设置墨迹个字符,或段落中的某一段字符的样式时,可以通古字符子节点实现。字符子节点只能设置字符的样式,所以页签属性相较于段落节点较少。

这次的案例只需要两种样式的字符格式,一种是正文的字符样式,另一种是正文字符的加粗样式。

43.实例_Style 字符设置 44.实例_Style 字符加粗正文设置

2.设置Smartform

(1)设置全局Style与纸张格式

将上面创建好的Style与Smartform的Style绑定。

45.实例_Form 全局属性设置

(2)设置接收展示数据接口变量

因为我们需要传递多条数据进来,所以需要在接口的表页签中添加一个表变量。用于传入Smartform展示和打印的数据。本次使用SAP的标准表SFLIGHT作为展示用的表和数据源。

46.实例_Form设置接口输入表参数

(3)设置全局变量

在上面设置了输入数据的表变量,为了能够遍历上面的表变量,所以还需要设置一个与表结构相同的结构体。而后续肯定在编写过程中肯定还会涉及到其他的全局变量。届时再在这里进行介绍。

47.实例_Form设置全局变量

全局变量介绍:

  • GS_SFLIGHT:IT_DATA相同结构的结构体,用于遍历数据时使用。
  • GV_FLAG:换页标记变量,当该变量值为X时,会控制主窗口进行换页。
  • GV_RUNFLAG:用来判断执行与否的标记,用来作为只执行一次逻辑的判断标记。
  • GV_COUNT:汇总统计展示的数据条数。

(4)创建TABLE(Table分页)

① 设置数据源

创建完表节点之后会需要你先设置表的数据来源。如下图所示,因为之前添加了一个用于传递输入参数的接口表变量和对应的结构体全局变量,所以此处将这两个变量填入下图所示的输入框,之后再主要区域中会对这个内表中的值进行循环展示。

56.实例_表节点数据源
② 设置列宽度

展开Page节点,在Main主窗口下新建一个Table节点。然后开始为Table节点设置行列属性。

48.实例_设置Table节点行列 49.实例_表行列详细信息
③ 设置表格边框
50.实例_设置表边框

设置好的带有边框的单元格四周不再是虚线,可以和上面的图片进行对比可以查看出两者的不同与区别。

52.实例_边框设置好之后的样子
④ 设置填充表头

设置表头内容,先设置表的标题,然后再设置打印输出的日期。最后将表头填充进去。

先设置表头,将航班信息四个子通过文本子节点填充进去。

实例_填充表标题

和上面的方式类似,设置表格表头的的第二行,打印时间。

54.实例_打印时间

最后再将字段列名设置好,这样表头就设置好了。

55.实例_Form行标题名称填充
⑤ 设置主要区域(分页逻辑)

此区域就是用来展示数据用的循环区域,此处只需要将第一步设置的结构体字段按照需求填入即可。因为在第一部设置的内表会将数据Loop进上面设置的结构体中,所以只此处只需要将结构体的字段变量填入即可自动实现数据的循环展示。但是本次是打算一页展示10条数据,所以还需要对其进行强制分页。

57.实例_设置主要区域内容

在开发Smartform的时候,有时候会遇上展示或打印的数据在最后一页不够10条的情况。此时会有需求将数据补齐到10条。这部分逻辑因为只执行一次,所以我将其放在了表头区域中的代码行中。并使用GV_RUNFLAG标记来限制其只执行一次。但是在这里的程序行中无法直接使用和访问全局变量,需要通过输入参数和输出参数将全局变量传入才可以使用。

本代码行的输出参数GV_RUNFLAG用来判断下面的逻辑是否只执行了一次。而IT_DATA则是用来获取数据条数的。

58.实例_补充数据条数

在上面设置好补充条数的逻辑之后,就可以在主要区域中设置用来分页的逻辑。在主窗口中的主要区域是数据的循环区域,所以将程序行放在主要区域中,当每展示一行数据就会执行一次在主要区域中设置的程序行和命令。所以可以在其中设置一个用于统计和汇总数据展示条数的变量GV_COUNT,然后使用该变量对10取余,等于0时就可以换页。

换页时将GV_FLAG变量设置为X,不换页时置为空。此外此处补充一点,输入和输出参数可以设置多个,不是只有界面上的两个。点击两个输入框右侧的下拉按钮,可以拉出来新的输入框,在其中设置其余需要设置的输入和输出参数即可。

59.实例_设置分页逻辑

设置完上面的两段逻辑之后,就可以在主要区域中设置翻页用的命令了。

60.实例_设置分页命令属性 61.实例_设置分页命令条件
⑥ 设置页码和总页数

此处因为一直在表格的最下侧,所以将其设置在表节点的脚标处即可。其中的当前页和总页数为系统变量。

因为脚标为一行单元格,所以在行类型处选择表头的TITLE类型即可。

62.实例_设置脚标行类型

在其中新建一个文本节点,然后将当前页和总页数的系统变量插入。

63.实例_设置脚标页码

(5)创建模板(模板分页)

此处只作为记录,将模板分页的核心内容和步骤记录如下。但后续的创建新窗口等操作依然是在上面的Table表格分页基础上进行的。即若第四项后续的操作是下面的第六项。

① 新建抬头窗口
88.实例_模板表格抬头

详细信息列表

89.实例_模板表格抬头详细信息

TABLELINE的详细数据如下:

1
2
   名称    从 至  高度  单位   1       2       3       4       5       6     
TABLELINE 3 3 10 MM 2.50 CM 2.50 CM 3.50 CM 2.50 CM 2.50 CM 2.50 CM

在实际效果图中为下图圈中的部分。

90.实例_表格抬头效果图
② 创建循环逻辑

循环逻辑和表的循环属性设置类似,都是填入循环用的内表和循环的结构体,之后可以在循环中使用结构体中的数据。

91.实例_新建循环逻辑
③ 创建行模板

行模板需要创建在LOOP循环节点下,且属性设置的内容与上面的TABLELINE属性内容一致。

92.实例_循环行模板
④ 编写初始化逻辑

和前面Table分页一样,在进入循环之前,编写一些设置初始值的逻辑。或是将数据补充和填充的逻辑写在里面。

其中输入参数为:

  • GV_RUNFLAG:用来判断执行次数的逻辑,主要是用来限制中间逻辑只执行一次
  • GV_LINES:接口传入的数据IT_DATA经过数据填充后的实际数据条数
  • IT_DATA:接口中Table页签中设置的用于接收传入展示数据的内表

输出参数和上面的一致。

93.实例_循环前初始值设置
⑤ 创建分页命令

此处分页命令和Table中的一样,一样是跳转到本页,使用GV_FLAG的作为分页的标记。此外需要注意的是,该命令是放在LOOP循环节点下的。

94.实例_分页命令参数设置
⑥ 编写分页逻辑

分页逻辑和上面的Table分页逻辑类似,但是不一样的是模板分页逻辑是放在Loop循环节点下的,不是放在模板行节点中。

输入参数为GV_COUNT、GV_FLAG和GV_LINES。除了GV_FLAG是分页的标记外,其余的变量上面都有介绍过,所以就不再介绍了。

输出参数为GV_COUNT和GV_FLAG。

95.实例_分页逻辑

进行完以上的操作后,通过模板实现的循环分页就完成了。最终的实际效果如下:

96.实例_效果图原图

(6)创建新窗口

创建一个新窗口,然后创建一个模板,将其分为两行,将打印的标题放进其中。创建好的模板不需要去设置边框,分成两行一列,然后将文本节点的内容放在第二行第一列即可。

64.实例_设置模板标题 65.实例_设置模板标题内容

设置两行一列的位置。

66.实例_模板标题内容位置

这个如果只是粗略的展示图片,则可以考虑将图片节点新建在Page节点下,之后可以在最右侧的预览界面将图片节点拖动到合适的位置即可。

67.实例_插入图片节点

(8)打印预览

设置完上面的内容之后就可以去预览界面对Smartform进行预览了。点击上面的执行按钮,系统会根据设计自动生成对应的功能Function,然后运行这个Function,选择打印预览。

68.实例_预览运行结果 69.实例_运行Function 70.实例_预览参数设置 71.实例_预览效果

预览效果如上图所示。

3.编写打印程序

(1)打印预览报表

先编写一个OOALV报表程序,展示用于打印的航班表数据。

OOALV报表相关的技术文档可以查看我写的这三篇技术笔记OOALV 基础知识OOALV 容器OOALV 事件类。他们介绍了如何创建一个OOALV的报表程序。

我们创建一个下面的报表,并添加两个按钮。一个按钮用于展示你在报表中选中的数据,另一个按钮是将选中的数据以Smartform的样式下载成PDF。

72.实例_Smartform数据报表

下面是两个按钮的部分逻辑。两个按钮都拥有公共的代码部分,分别是获取打印数据和通过Smartform的名称获取Smartform Function的调用名称。

① 按钮逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*--------------------------Variables-----------------------------------*
CONSTANTS:
LC_PRINT TYPE C LENGTH 6 VALUE 'PRINT',
LC_DOWPDF TYPE C LENGTH 6 VALUE 'DOWPDF'.
DATA:
LT_TABLE TYPE TABLE OF YSFLIGHT_CYH,
LV_FNAME TYPE RS38L_FNAM.
*----------------------------Logic-------------------------------------*
CLEAR: GV_MESSAGE.
"获取打印用数据
PERFORM GET_PRINT_DATA TABLES LT_TABLE.
CHECK GV_MESSAGE IS INITIAL.

"Get Smartform Function Name
PERFORM GET_SMARTFORM_NAME CHANGING LV_FNAME.
CHECK GV_MESSAGE IS INITIAL.

CASE PV_UCOMM.
WHEN LC_PRINT.
"预览Smartform
PERFORM UCOMMAND_PRINT TABLES LT_TABLE USING LV_FNAME.
WHEN LC_DOWPDF.
"下载成PDF
PERFORM UCOMMAND_DOWPDF TABLES LT_TABLE USING LV_FNAME.
WHEN OTHERS.
ENDCASE.

"Refresh ALV
PERFORM REFRESH_ALV.

FREE: LT_TABLE.
ENDFORM.
② 获取打印数据——GET_PRINT_DATA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
FORM GET_PRINT_DATA  TABLES PT_TABLE STRUCTURE YSFLIGHT_CYH.
*--------------------------Variables-----------------------------------*
DATA:
LT_ROWS TYPE LVC_T_ROW,
LS_ROWS TYPE LVC_S_ROW.
*----------------------------Logic-------------------------------------*
REFRESH: PT_TABLE.
"获取选行的索引
IF GO_ALV IS NOT INITIAL.
CALL METHOD GO_ALV->GET_SELECTED_ROWS
IMPORTING
ET_INDEX_ROWS = LT_ROWS.
IF SY-SUBRC NE 0.
GV_MESSAGE = GC_X.
"请选择要打印的数据
MESSAGE S000 WITH TEXT-E03 DISPLAY LIKE GC_E.
EXIT.
ENDIF.
ENDIF.

"获取选中的数据
LOOP AT LT_ROWS INTO LS_ROWS.
READ TABLE GT_TABLE INTO GS_TABLE INDEX LS_ROWS-INDEX.
IF SY-SUBRC EQ 0.
MOVE-CORRESPONDING GS_TABLE TO PT_TABLE.
APPEND PT_TABLE.
ENDIF.
CLEAR: LS_ROWS,GS_TABLE,PT_TABLE.
ENDLOOP.

IF PT_TABLE[] IS INITIAL.
GV_MESSAGE = GC_X.
"请选择要打印的数据
MESSAGE S000 WITH TEXT-E03 DISPLAY LIKE GC_E.
ENDIF.

FREE: LT_ROWS.
ENDFORM.
③ 获取Smartform Function名称——GET_SMARTFORM_NAME
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
FORM GET_SMARTFORM_NAME CHANGING VALUE(PV_FNAME) TYPE RS38L_FNAM.
*--------------------------Variables-----------------------------------*
CONSTANTS:
LC_SMARTNAME TYPE TDSFNAME VALUE 'YSMARTFORM0718_CYH'.
*----------------------------Logic-------------------------------------*
"Get Smartform Function
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
* FORMNAME = LC_SMARTNAME
FORMNAME = 'YSMARTFORM0718_CYH'
* VARIANT = ' '
* DIRECT_CALL = ' '
IMPORTING
FM_NAME = PV_FNAME
EXCEPTIONS
NO_FORM = 1
NO_FUNCTION_MODULE = 2
OTHERS = 3.
IF SY-SUBRC <> 0 OR PV_FNAME IS INITIAL.
GV_MESSAGE = GC_X.
"获取Smartform Function名称异常
MESSAGE S000 WITH TEXT-E01 DISPLAY LIKE GC_E.
EXIT.
ENDIF.
ENDFORM.

(2)展示表格逻辑

逻辑流程是选择想要在Smartform上展示的数据,然后通过Smartform的名称获取到动态的Function名称。通过这个名称调用展示Smartform。

73.实例_选择展示数据 74.实例_展示Smartform

调用Smartform的逻辑如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
FORM UCOMMAND_PRINT TABLES PT_TABLE STRUCTURE YSFLIGHT_CYH "展示用数据
USING VALUE(PV_FNAME) TYPE RS38L_FNAM. "Smartform Function名称
*--------------------------Variables-----------------------------------*
DATA:
LS_SSFCRESOP TYPE SSFCRESOP,
LS_SSFCRESCL TYPE SSFCRESCL,
LS_SSFCTRLOP TYPE SSFCTRLOP, "打印参数
LS_SSFCOMPOP TYPE SSFCOMPOP. "弹出框参数
*----------------------------Logic-------------------------------------*
"Set Printing Parameters
"No pop-up window 无弹窗
LS_SSFCTRLOP-NO_DIALOG = GC_X.
"预览
LS_SSFCTRLOP-PREVIEW = GC_X.

"Output参数
LS_SSFCOMPOP-TDDEST = 'SAP'.
"调用Smartform
CALL FUNCTION PV_FNAME
EXPORTING
* ARCHIVE_INDEX =
* ARCHIVE_INDEX_TAB =
* ARCHIVE_PARAMETERS =
CONTROL_PARAMETERS = LS_SSFCTRLOP
* MAIL_APPL_OBJ =
* MAIL_RECIPIENT =
* MAIL_SENDER =
OUTPUT_OPTIONS = LS_SSFCOMPOP
* USER_SETTINGS = 'X'
IMPORTING
* DOCUMENT_OUTPUT_INFO =
JOB_OUTPUT_INFO = LS_SSFCRESCL
JOB_OUTPUT_OPTIONS = LS_SSFCRESOP
TABLES
IT_DATA = PT_TABLE[]
EXCEPTIONS
FORMATTING_ERROR = 1
INTERNAL_ERROR = 2
SEND_ERROR = 3
USER_CANCELED = 4
OTHERS = 5.
IF SY-SUBRC <> 0.
"调用Smartform 异常
MESSAGE S000 WITH TEXT-E02 DISPLAY LIKE GC_E.
EXIT.
ENDIF.
ENDFORM.

(3)下载为PDF文件

下载为PDF的逻辑分为以下几个步骤。

  • 获取需要下载成PDF的数据(上面的GET_PRINT_DATA)
  • 获取Smartform的Function名称(上面的GET_SMARTFORM_NAME)
  • 调用Smartform的Function获取OTF数据
  • 将OTF数据转换为二进制数据
  • 获取下载PDF的路径
  • 下载成PDF文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
FORM UCOMMAND_DOWPDF  TABLES PT_TABLE STRUCTURE YSFLIGHT_CYH
USING VALUE(PV_FNAME) TYPE RS38L_FNAM.
*--------------------------Variables-----------------------------------*
DATA:
LV_SSFCRESPD TYPE SSFCRESPD,
LS_SSFCRESCL TYPE SSFCRESCL,
LS_SSFCRESOP TYPE SSFCRESOP,
LS_SSFCTRLOP TYPE SSFCTRLOP, "打印参数
LS_SSFCOMPOP TYPE SSFCOMPOP. "弹出框参数

"下载PDF数据
DATA:
LV_PDFDATA TYPE XSTRING,
LV_PDFLINE TYPE I,
LV_FILELENGTH TYPE I.

DATA:
LS_DOCTABLE TYPE DOCS,
LT_DOCTABLE TYPE TABLE OF DOCS, "DOC
LT_PDFTABLE TYPE TABLE OF TLINE. "转换为PDF数据

"下载地址
DATA:
LV_POST TYPE STRING.
*----------------------------Logic-------------------------------------*
"获取下载位置
PERFORM GET_DOWNLOAD_POST CHANGING LV_POST.
CHECK GV_MESSAGE IS INITIAL.

"设置打印参数
"无弹窗
LS_SSFCTRLOP-NO_DIALOG = GC_X.
"获取OTF数据,不print,fax,display
LS_SSFCTRLOP-GETOTF = GC_X.

"调用Smartform,生成PDF所需要的OTF数据
CALL FUNCTION PV_FNAME
EXPORTING
* ARCHIVE_INDEX =
* ARCHIVE_INDEX_TAB =
* ARCHIVE_PARAMETERS =
CONTROL_PARAMETERS = LS_SSFCTRLOP
* MAIL_APPL_OBJ =
* MAIL_RECIPIENT =
* MAIL_SENDER =
OUTPUT_OPTIONS = LS_SSFCOMPOP
* USER_SETTINGS = 'X'
IMPORTING
* DOCUMENT_OUTPUT_INFO =
JOB_OUTPUT_INFO = LS_SSFCRESCL
JOB_OUTPUT_OPTIONS = LS_SSFCRESOP
TABLES
IT_DATA = PT_TABLE[]
EXCEPTIONS
FORMATTING_ERROR = 1
INTERNAL_ERROR = 2
SEND_ERROR = 3
USER_CANCELED = 4
OTHERS = 5.
IF SY-SUBRC <> 0.
"OTF数据生成异常
MESSAGE S000 WITH TEXT-E04 DISPLAY LIKE GC_E.
EXIT.
ENDIF.

"OTF数据转换为PDF二进制文件
CALL FUNCTION 'CONVERT_OTF'
EXPORTING
FORMAT = 'PDF'
MAX_LINEWIDTH = 132
TABLES
OTF = LS_SSFCRESCL-OTFDATA[]
LINES = LT_PDFTABLE
EXCEPTIONS
ERR_MAX_LINEWIDTH = 1
ERR_FORMAT = 2
ERR_CONV_NOT_POSSIBLE = 3
ERR_BAD_OTF = 4
OTHERS = 5.
IF SY-SUBRC <> 0.
"OTF数据转换为PDF异常
MESSAGE S000 WITH TEXT-E05 DISPLAY LIKE GC_E.
EXIT.
ENDIF.

"下载PDF
CALL FUNCTION 'GUI_DOWNLOAD'
EXPORTING
BIN_FILESIZE = LV_PDFLINE
FILENAME = LV_POST
FILETYPE = 'DAT'
IMPORTING
FILELENGTH = LV_FILELENGTH
TABLES
DATA_TAB = LT_PDFTABLE
EXCEPTIONS
FILE_WRITE_ERROR = 1
NO_BATCH = 2
GUI_REFUSE_FILETRANSFER = 3
INVALID_TYPE = 4
NO_AUTHORITY = 5
UNKNOWN_ERROR = 6
HEADER_NOT_ALLOWED = 7
SEPARATOR_NOT_ALLOWED = 8
FILESIZE_NOT_ALLOWED = 9
HEADER_TOO_LONG = 10
DP_ERROR_CREATE = 11
DP_ERROR_SEND = 12
DP_ERROR_WRITE = 13
UNKNOWN_DP_ERROR = 14
ACCESS_DENIED = 15
DP_OUT_OF_MEMORY = 16
DISK_FULL = 17
DP_TIMEOUT = 18
FILE_NOT_FOUND = 19
DATAPROVIDER_EXCEPTION = 20
CONTROL_FLUSH_ERROR = 21
OTHERS = 22.
IF SY-SUBRC <> 0.
"PDF 下载失败
MESSAGE S000 WITH TEXT-E08 DISPLAY LIKE GC_E.
EXIT.
ENDIF.
ENDFORM.
① 获取下载PDF的路径
1
2
3
4
5
6
7
8
9
FORM GET_DOWNLOAD_POST  CHANGING VALUE(PV_FULLPATH) TYPE STRING.
CLEAR: GV_MESSAGE.
"Get download path
PERFORM GET_DOWNLOAD_FILE CHANGING PV_FULLPATH.
CHECK GV_MESSAGE IS INITIAL.

"Check that download files exist,and if they do,delete
"PERFORM CHECK_FILE_EXIS USING PV_FULLPATH.
ENDFORM.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
FORM GET_DOWNLOAD_FILE CHANGING VALUE(PV_PATH) TYPE STRING.
*---------------------------Variables----------------------------*
CONSTANTS:
LC__ TYPE C LENGTH 1 VALUE '_'.
DATA:
LV_FNAME TYPE STRING,
LV_PATH TYPE STRING,
LV_FILENAME TYPE STRING,
LV_TYPENAME TYPE STRING VALUE 'pdf',
LV_TITLE TYPE STRING VALUE 'PDF Downolad'.
*-----------------------------Logic------------------------------*
"Set Download file Name
CONCATENATE GV_TITLE SY-DATUM SY-UZEIT INTO LV_FILENAME
SEPARATED BY LC__.

"Gets the current default path.
CALL METHOD CL_GUI_FRONTEND_SERVICES=>DIRECTORY_GET_CURRENT
CHANGING
CURRENT_DIRECTORY = PV_PATH.

"Shell selection save path
CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_SAVE_DIALOG
EXPORTING
WINDOW_TITLE = LV_TITLE
DEFAULT_EXTENSION = LV_TYPENAME
DEFAULT_FILE_NAME = LV_FILENAME
FILE_FILTER = CL_GUI_FRONTEND_SERVICES=>FILETYPE_ALL
INITIAL_DIRECTORY = PV_PATH
CHANGING
FILENAME = LV_FNAME
PATH = LV_PATH
FULLPATH = PV_PATH
EXCEPTIONS
CNTL_ERROR = 1
ERROR_NO_GUI = 2
NOT_SUPPORTED_BY_GUI = 3
OTHERS = 5.
IF PV_PATH IS INITIAL.
GV_MESSAGE = GC_X.
"PDF下载路径获取失败
MESSAGE S000 WITH TEXT-E08 DISPLAY LIKE GC_E.
EXIT.
ENDIF.
ENDFORM.

四、Smartform其余内容汇总

1.Smartform系统参数

字段名称/SFSY 变量含义
PAGE 当前页号/页数
FORMPAGES 表格总页数
JOBPAGES 打印作业的总页数
COPYCOUNT 复制计数器(1=原文,2=第一个拷贝,…)
COPYCOUNT0 复制计数器(0=原文,1=第一个拷贝,…)
DATE 系统日期
TIME 系统时间
SUBRC 返回码
USERNAME 用户名
PAGENAME 页名称
WINDOWNAME 窗口名称
XSF XSF输出活动/未激活
XDF SAP Smart Forms:XDF输出活动
XDF2 SAP Smart Forms:XDF输出活动

2.常用打印参数介绍

(1)对话框参数

1
2
3
4
5
DATA:
LS_SSFCOMPOP TYPE SSFCOMPOP.
LS_SSFCOMPOP-TDDEST = 'LP01'. "打印设备
LS_SSFCOMPOP-TDPAGESLCT = '1,2,4'. "打印的页数,多页使用逗号进行分割
LS_SSFCOMPOP-TDNOPREV = 'X'. "隐藏打印预览按钮

(2)控制对话框参数

1
2
3
4
DATA:
LS_SSFCTRLOP TYPE SSFCTRLOP.
LS_SSFCTRLOP-NO_DIALOG = 'X'. "打印前不显示打印对话框
LS_SSFCTRLOP-PREVIEW = 'X'. "直接展示预览界面

3.一次性输出多张报表

有时候需要一次性打印多张不同的报表,直接调用Smartform时,每次打印一张报表后,会在循环中反复出现打印对话框,影响程序执行效率。SAP打印控制提供了假脱机功能,允许将多张需要打印的报表缓存。最后再一次性提交打印请求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
FORM CALL_SMARTFORM.
DATA:
LV_FNAME TYPE RS381_FNAM,
LS_SSFCTRLOP TYPE SSFCTRLOP.

DO 3 TIMES.
CASE SY-INDEX.
WHEN 1.
LS_SSFCTRLOP-NO_OPEN = SPACE. "首次运行时打开打印对话框
LS_SSFCTRLOP-NO_CLOSE = 'X'. "并且不关闭假脱机请求
WHEN 2.
LS_SSFCTRLOP-NO_OPEN = 'X'.
LS_SSFCTRLOP-NO_CLOSE = 'X'.
WHEN 3.
LS_SSFCTRLOP-NO_OPEN = 'X'.
LS_SSFCTRLOP-NO_CLOSE = SPACE."最后关闭假脱机准备打印
ENDCASE.

"调用Function通过SMartform Name获取Smartform Function
CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
EXPORTING
FORMNAME = 'Smartform Name'
IMPORTING
FM_NAME = LV_FNAME.

"调用Smartform
CALL FUNCTION LV_FNAME
EXPORTING
CONTROL_PARAMETERS = LS_SSFCTRLOP.
ENDDO.
ENDFORM.

4.转换PDF乱码问题

将Smartform转换为PDF文件时或许会出现乱码等问题。此时使用TCODE:SPAD(假脱机管理工具)设置打印设备类型为CN开头的类型即可。之后在程序和Smartform中使用这个设备即可。

75.补充_转PDF乱码事务 76.补充_转PDF乱码设备类型

5.自定义页格式

(1)设置纸张格式

对于Smartform打印的纸张等问题,除了可以使用SAP自带的国际上标准的A4等纸张格式外,还可以在TCODE:SPAD中设置打印纸张的格式。

先点击上面的完全管理按钮,调出剩下的设备管理页签。

77.补充_设置纸张格式

之后点击设备类型,在下方的页格式处设置页面格式。

79.补充_设置页格式

(2)设置格式类型

在上面设置完纸张格式并没办法直接调用使用,还需要设置该纸张格式的类型用于限制调用的程序类型。

在同一个页签中的格式类型中,输入格式类型名。然后选择类型。

其中S SAPscript的格式类型是在Smartform中使用的格式类型,L ABAP列表的格式类型则是在ALV报表中使用的格式。

80.补充_设置页格式具体步骤

(3)分配页格式到指定的设备

定义好上面的页格式和格式类型之后还需要将页格式分配到指定的设备,可以理解成是相互绑定。每个输出设备需要设定设备类型。所以当打印时,只有属于该打印设备的页格式才能被操作。若没有维护的话,预览不会存在问题,但在选择打印时,系统提示错误。

目前对中文输出所使用的设备类型大部分都默认为“CNSAPWIN”,在“设备类型”中输入“CNSAPWIN”,再点击“显示”,出现以下界面:

81.补充_绑定页格式与设备 82.补充_设备界面

进入下面的界面后,点击上面的创建按钮。将自己之前创建的格式类型填入,此处填入的是格式类型,这一点需要注意。

83.补充_绑定格式类型

点击上面的对勾按钮后进入下面的界面。之后需要对打印机操作维护基本的指令,没维护指令时,操作该类型的报表数据可能会出现打印机不切纸或者不执行打印问题。需维护的指令和打印机的驱动存在关系,可以参照CNSAPWIN下已经维护好的格式类型来维护。

86.补充_配置页格式

以SAP标准的A4纸张(DINA4)为例,一般需要维护操作包括:打印初始化、尾页、行结束,如:

85.补充_参照A4维护

之后就可以在Smartform中使用自己的页格式了。

87.补充_配置页格式效果展示

五、参考资料

Smart Forms&ScriptFrom

ABAP Smartforms

SAP中SmartForms报表工具的使用,一个简单的报表Demo

评论