报表要求:(见下表)

要求:
1、不是套打,表格线也需要输出
2、每张报表打印8行记录,不足的空白行也需要输出
3、按凭证号打印单据,可以连续打印多张报表。

一、创建样式:
在创建Form之前,需要创建多种段落和字体样式,供Form中的文字使用。需要设置多种“段落格式”,并且必须在“表头数据”中设定“标准段落”

1.创建段落格式,一般有RH(Report Header),PD(Page Header), PB(Page Bottom),LD(Line Header and Details),字体:CNSONG,9pt。注意最好在各段落的“首行缩”中设定1mm的缩进,否则,在Form中表格线和文字之间会没有任何间隙。
2.设置“表头数据”中“标准段落”
3、保存并激活样式文件。

二、创建SmartForm

1、在“全局设置”-〉“表格属性”-〉“输出选项”中
设定“页格式”:即纸张的大小
“样式”:设定本Form使用的默认样式文件,这里指定为第一步创建的样式文件。

2、在“全局设置”-〉“表格接口”-〉“导入”
设置两个参数:
ptr_header type c
ptr_items  type c
这两个参数用来传入我们在Report中Export内表数据的句柄(ID key)。

3、在“全局设置”-〉“全局定义”中进行多项设定
a、“类型”设定,在这里需要定义4个类型,一个用来保存表头数据的工作区和内表,一个用来保存明细数据的工作区和内表,它们的结构必须与Report中Export到数据库中的内表的结构完全对应一致,否则,我们将不能从传入的句柄(ID key)中恢复内表数据。

* 领料单抬头信息
TYPES:
BEGIN OF TYP_header_ROW ,
        mblnr          LIKE mseg-mblnr,    " 凭证号
        bldat          LIKE rkpf-rsdat,    " 凭证日期
        c_so(16)       TYPE c,             " 销售订单号
        c_issdt        LIKE sy-datum,      " 发货日期
        werks          LIKE mseg-werks,    " 地点
        PLNAT_NAME     LIKE t001w-name1,   " 出货单位名称
        kokrs          LIKE mseg-kokrs,    " 控制范围
        kostl          LIKE mseg-kostl,    " 成本中心
        cc_name        LIKE cskt-ktext,    " 成本中心名称名称
        c_depart(45)   TYPE c,             " 领料部门
        bwart          LIKE mseg-bwart,    " 移动类型代码
        btext_mt       LIKE t156t-btext,   " 移动类型描述
        c_btext_mt(60) TYPE c,             " 移动类型次数
        C_TOTAL(17)    TYPE C,             "合计输出时由用户手工填写
END OF TYP_header_ROW .

TYPES: TYP_HEADER_TABLE TYPE TYP_HEADER_ROW OCCURS 0.

* 领料单明细信息
TYPES:
BEGIN OF TYP_ITEMS_ROW ,
        mblnr       LIKE mseg-mblnr,      " 物料凭证编号 : 物料凭证
        rsnum       LIKE rkpf-rsnum,      " 凭证号 : 预留单
        mjahr       LIKE mseg-mjahr,      " 物料凭证年度
        zeile       LIKE mseg-zeile,      " 序号
        bwart       LIKE mseg-bwart,      " 移动类型代码
        werks       LIKE mseg-werks,      " 地点
        kokrs       LIKE mseg-kokrs,      " 控制范围
        kostl       LIKE mseg-kostl,      " 成本中心
        matnr       LIKE mseg-matnr,      " 物料号码
        maktx       LIKE makt-maktx,      " 物料描述
        erfme       LIKE mseg-erfme,      " 计量单位
        c_planc     LIKE resb-bdmng,      " 计划数量(手工填写)
        c_outc      LIKE mseg-erfmg,      " 实发数量
        c_count(6)  TYPE c,               " 件数(手工填写)
        lgort       LIKE mseg-lgort,      " 仓储地点
        charg       LIKE mseg-charg,      " 备注
END OF TYP_ITEMS_ROW.

TYPES: TYP_ITEMS_TABLE TYPE TYP_ITEMS_ROW OCCURS 0.

b、在“全局数据”中,定义全局的变量,我们需要定义如下几个变量
  wa_header type typ_header_row    "表头数据工作区,由于SmartForms中的内表不能有HeaderLine,因此必须定义一个与内表结构一样的工作区

  ig_header type typ_header_table  "表头数据内表
  wa_items  type typ_items_row     "表单明细工作区
  ig_items  type typ_items_table   "表单明细内表
  wa_blanks type typ_items_row     "空白行工作区
  ig_blanks type typ_items_table   "空白行内表
  g_count   type i                 "记录一张报表的明细的记录数量
  G_CURRLINE type i                "记录所有报表共计打印了多少行,用于判断最后一页
  G_TOTALLINES type i              "记录内表ig_items总行数,用于判断最后一页
  G_CURRPAGE type i                "一个凭证的当前页码
  G_TOTALPAGE type i               "一个凭证的总页码

c、在“初始化”中,将数据句柄中的内表恢复到刚设定的全局变量中
输入参数:ptr_header,ptr_items,ig_header,ig_items,g_totallines

perform Restor_buffer using ptr_header changing ig_header.
perform Restor_buffer using ptr_items  changing ig_items.

DESCRIBE TABLE IG_ITEMS LINES G_TOTALLINES.

d、在Freecode"格式化程序"中,定义Form Restor_buffer函数

form Restor_buffer using typeid type c changing t type table.
  import t from database indx(hk) id typeid.
endform.

至此,我们已经得到了表头和明细这2个内表的数据,下面准备画报表并输出数据。

4、在“页和窗口”中,在“%Page1”页下,添加3个窗口
"MAIN主窗口": 在SmartForm中,只有窗口类型为“主窗口”的窗口,才能被循环。例如,在最前面的样表中,明细数据有20条,不能在一页中打印输出完毕,需要输出4页才能打印完一张单据的数据,在这4张单据中,表头和表尾是不变的,但是表中间部分数据却是变化的,中间这个窗口需要被循环输出4次。因此需要将这个窗口类型设定为“主窗口”。在本例中为现实明细数据的这部分。
“窗口1”:从表最上面到明细栏的标题栏(包括标题栏)
“窗口2”:最底下2行。
注意:窗口的宽度加上遍距不能大于纸张宽度。

创建好这三个窗口,设定好窗口的宽度,高度,以及位置信息。下图是整个SmartForm的结构

注意,我将输出表头的窗口“%windows1 页头”放在了输出明细数据的窗口“主窗口”的下面,这是必须的,因为表头中的数据需要从表头内表ig_header中来。loop1是循环内表ig_header,将数据放到表头工作区wa_header中。因此,%windows1 页头窗口就可以直接使用工作区wa_header中的数据。如果该窗口放在了主窗口的前面,那么至少第一页中表头会没有数据,而且后面每一页的表头显示的都是下一个表头的内容。
注:虽然打印机输出时,现打印%WINDOWS1 页头,再打印MAIN主窗口,最后打印%WINDOW2页尾窗口,但是程序执行时,却是按照上图中树结构从上到下进行处理的,是先处理MAIN主窗口,其次%WINDOWS1 页头,最后%WINDOW2页尾窗口的逻辑顺序,可以从跟踪SMARTFORMS程序得知。

下面详细介绍整个逻辑流程和代码:

1、%LOOP1表头循环
设置:数据-〉loop循环-〉操作数:ig_header into wa_header
作用:循环表头内表中的数据,每次打印一个凭证的行项目数据。由于内表在这里不能有工作区,因此将每个表头数据放置到另外的工作区。

2、%LOOP4计算单个凭证总页码
设置:数据-〉loop循环-〉操作数:IG_ITEMS INTO WA_ITEMS
      WHERE条件:IBLNR = WA_HEADER-IBLNR
作用:由于在打印每张凭证及行项目之前,需要知道该凭证的总页数,因此需要首先计算IG_ITEMS内表中有多少条当前凭证的行记录数。

3、%CODE4累计单个凭证的行项目数
输入参数:G_COUNT
代码:

G_COUNT = G_COUNT + 1.

作用:累计当前凭证的行项目数。

4、%CODE1计算当前凭证总页码
输入参数:G_TOTALPAGE,G_COUNT
代码:

G_TOTALPAGE = 0.

*计算单个凭证的总页码
G_TOTALPAGE = G_COUNT MOD 8.

IF G_TOTALPAGE = 0.
  G_TOTALPAGE = G_COUNT DIV 8.
ELSE.
  G_TOTALPAGE = G_COUNT DIV 8 + 1.
ENDIF.

G_COUNT = 0.

作用:根据第三步累计的单个凭证的总行项目数,以及每页打印的行记录数(8),计算该凭证需要打印的总页数。计算完毕以后,G_COUNT重新置0。

6、%LOOP2循环输出明细
设置:数据-〉loop循环-〉操作数:IG_ITEMS INTO WA_ITEMS
      WHERE条件:IBLNR = WA_HEADER-IBLNR
作用:这里的循环条件与第2步的条件完全一致,准备循环打印当前凭证的所有行项目。

7、%CODE2记录行数加1
输入参数:G_COUNT,G_CURRLINE
代码:

* 每打印一行行记录,记录数量加1
G_COUNT = G_COUNT + 1.

G_CURRLINE = G_CURRLINE + 1.

作用:每循环一次,当前凭证打印的行记录数加1,所有凭证打印的总行记录数加1。

8、%TEMPLATE4数据明细
作用:模板,行记录的表格,以及相关文本内容。LOOP2每循环一次,就打印输出一行该模板以及文本内容。行高一般为5mm(根据实际调整),注意模板的宽度不能超过窗口的宽度。在“细节”中可以调整模板的每个单元格的宽度,以及每行的高度。

9、%TEXT22 - %TEXT30文本内容
%TEXT22    序号:&G_COUNT(CZT4R)&  输出选项-〉输出结构:第1行第1列 
%TEXT23物料号码:&WA_ITEMS-MATNR&  输出选项-〉输出结构:第1行第2列
依此类推。

10、%CODE5计算当前页码
输入参数:G_COUNT,G_CURRPAGE
代码:

DATA: L_LINE TYPE I.
L_LINE = G_COUNT MOD 8.

IF L_LINE = 0.
  G_CURRPAGE = G_COUNT / 8.
ELSE.
  G_CURRPAGE = G_COUNT DIV 8 + 1.
ENDIF.

作用:每输出一行,计算当前行所在的页码,即为当前页

11、%CODE3计算空行
输入参数:G_COUNT,IG_BLANKS,WA_BLANKS
代码:

G_COUNT = G_COUNT MOD 8.

* 需要的空记录行数
IF G_COUNT <> 0.
  G_COUNT = 8 - G_COUNT.
ENDIF.

CLEAR IG_BLANKS[].
DO G_COUNT TIMES.
  APPEND wa_blanks to ig_blanks.
ENDDO.

G_COUNT = 0.

作用:在当前凭证的所有有效数据行打印完毕以后,还需要计算需要打印多少空行,才能刚好打印满一张纸。用计算的数量,填充内表IG_BLANKS,计算完毕以后,G_COUNT必须清0。

12、%LOOP3 补充打印空行
设置:数据-〉loop循环-〉操作数:IG_BLANKSS INTO WA_BLANKS
      WHERE条件:无
作用:循环内表IG_BLANKS,次数为内表中的记录数,即空行数,打印输出空行。

13、%TEMPLATE5空数据明细
作用:该模板与第8步的TEMPLATE4完全一样,只是该模板下不需要有文本TEXT,只序号输出模板的表格线即可。
到此步骤,已经打印完毕了当前凭证的所有有效数据行和补充的空行,如果当前凭证需要打印多页,例如有30条行记录,需要打印3个满页,第4页数出6行数据,补充2个空行,这3次分页是系统自动分页的,分也之前,自动处理页头和页尾窗口,输出这两个窗口的内容。自动分页的条件是“MAIN主窗口”的高度被打印满了,因此一定要注意,主窗口的高度必须等于你需要的高度,不要多,也不要少,在本例中,高度为8行 x 5mm = 40mm

14、%CONDITION1分页
设置:一般属性-〉节点条件:G_CURRLINE <> G_TOTALLINES
作用:在一个凭证打印完毕以后,将要进入打印下一个凭证之前,需要分页,但是在打印完最后一个凭证的最后一页以后,却不能有分页,否则最后会多一个空行。

15、%COMMAND1强制分页
设置:一般属性-〉转到新页:%PAGE1
作用:在G_CURRLINE <> G_TOTALLINES 条件成立(不是最后一行)的情况下,强制分页。
你也许会说,这里不强制分页,系统也会自动分页,因为前面输出的高度正好都满足的各窗口的高度,会自动进行分页,确实如此,系统会自动进行分页,但是在这里强调:强制分页是必须的,不能使用自动分页,原因是:自动分页发生的时间不是我们预想的,我们需要在第13步执行完毕以后,马上进行分页,这时,WA_HEADER中的内容还是当前凭证的数据,这样,在处理页头和页尾窗口时,数据是正确的。而自动分页却不在此时发生,而是在第1步LOOP1循环再次执行以后,也就是WA_HEADER之中的内容变成下一条以后才发生,这样我们就不能输出正确的表头和表尾数据,因此必须使用强制的分页命令。

16、表头和表尾窗口
由于这两个窗口非常简单,仅输出文字描述和WA_HEADER中的内容,因此不详细说明。

Q&A
1.打印预览表格线都正常,但是用针式打印机输出出现部分表格线无法输出。
答:这个可能是由于针式打印机的分辨率较小的缘故,使用激光或者喷墨打印机可以正常输出,或者在SmartForms中加粗表格线,使用30TW。

2.在使用穿孔纸连续打印时,后面的纸张出现错位现象。
答:原因不是很清楚,需要设置打印机中的纸张格式,将纸张高度根据错位的距离进行加或者减,多次调整以后可以达到没有错位。

转载于:https://www.cnblogs.com/zhumk/archive/2005/06/04/167904.html

ABAP:SmartForms 之二--设计相关推荐

  1. ABAP SMARTFORMS打印二维码

    此方法需要SAP_BASIS版本在731以上 TCODE-SE73 创建系统条形码 Module Size 调节二维码的尺寸 Mode:这个参数控制了生成二维码数据的编码格式,有以下几种常用选择: A ...

  2. 【ABAP系列】SAP ABAP smartforms设备类型CNSAPWIN不支持页格式ZXXX

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP smartfo ...

  3. ABAP SMARTFORMS 连续打印(套打功能)

    ABAP SMARTFORMS套打功能 对于SAP打印的功能,如果对于纸张有要求或者需要同时打印好几种类型单据,就需要套打了.单个打印轻车熟路,套打需要用OPEN 和 CLSOE 两个函数控制. 先获 ...

  4. kettle对字符串去除空格_整理|ABAP基础知识二:常用字符串处理

    常用字符串处理 上一期整理了ABAP的数据类型和定义,今天我们整理一下开发过程中常见的字符串处理命令.虽然说这些基础知识对于已经熟练使用Ctrl c + Ctrl v的资深码农来说过于简单.但是对于一 ...

  5. [Unity] 状态机事件流程框架 (二) 设计游戏状态的保存框架,存档功能 ScriptableObject、EasySave

    前文 : ​​​​​​​[Unity] 状态机事件流程框架 (一) 本期来设计一个游戏状态的怎么在游戏中表示和存储.保存游戏状态的目的一是方便根据玩家当前的游戏进度实行各种各样的逻辑分支,二是在存档时 ...

  6. 计算机组成原理-附加实验二-设计微程序

    一.实验要求 1.编写程序和微程序实现反复r0+1,并求和的功能 指令助记符 指令功能 A: ADD R0,#01H 相加 JMP A 跳转到A标号处 2.系统支持的基本指令格式有三种,本题选用格式一 ...

  7. 扁平化设计学习之二 设计原则

    扁平化设计原则 13-06-08 oooceo 没有评论 设计美化 1604 浏览 设计社区不停讨论关于扁平风格. 这种风格很带感.但大多数设计师不能彰显这种风格,或者直接讨厌这种风格. 我很现实,创 ...

  8. 后端开发如何设计数据库系列文章(二)设计大数据量表结构

    上篇文章讲解了传统数据库的一些设计注意点. 本篇为第二篇,在大数据量的情况下,如何去提前设计这个表结构,来达到一个比较好的效果.对于团队,对于后续的维护和扩展都带来更大的便利. 自增id 自增id还是 ...

  9. SQLite入门与分析(二)---设计与概念

    写在前面:谢谢各位的关注,没想到会有这么多人关注.高兴的同时,也感到压力,因为我接触SQLite也就几天,也没在实际开发中用过,只是最近项目的需求才来研究它,所以我很担心自己的文章是否会有错误,误导别 ...

  10. ABAP实例:如何设计和使用自定义的权限对象

    调用的方法     *&---------------------------------------------------------------------*     *&    ...

最新文章

  1. tensorflow 使用CPU而不使用GPU的问题解决
  2. 基于java 的websocket的聊天功能,一开始初始化websocket,执行打开连接之后就直接关闭连接了。...
  3. QT:触摸屏支持手指触摸,增加touch事件touchevent,记录前后touch坐标并处理
  4. 如何用好 Chrome devtools
  5. Autodesk Revit DB Link 中文理解
  6. 【Windows】DACL SACL
  7. 中专计算机网络技术试卷,2018年中职对口升学计算机网络技术模拟试题
  8. IDM下载百度资源出现403的解决方法
  9. webx mysql_Webx项目的获取与验证
  10. 【HUSTOJ】1046: 字符图形2-星号直角
  11. 使用u盘量产工具修复写保护的u盘
  12. 2019年9月中国编程语言排行榜
  13. 给本本K46C升级内存并升级64位WIN7
  14. 手机分辨率Android教程(十二)-- 使用DisplayMetrics获取手机分辨率
  15. HTML 之 块级元素、行内元素和行内块元素之间的嵌套规则
  16. python (ploit)
  17. 同构图异构图二部图区别
  18. 【Restful接口】restful接口的两种使用方式
  19. 计算机网络(中科大郑烇)第二章笔记
  20. Configuring Linphone

热门文章

  1. 机器学习中的混淆矩阵,准确率,精确率,召回率,F1,ROC/AUC,AP/MAP
  2. 易筋SpringBoot 2.1 | 第三十六篇:Spring Boot RestTemplate超时配置示例
  3. 算法:Validate Binary Search Tree(验证二叉查找树)
  4. hive出现内存溢出_hive问题处理
  5. php $stomp write byte message,PHP通过Stomp协议与,ActiveMQ,通信所遇到的问题
  6. 合法的括号序列匹配数
  7. python程序运行原理
  8. shell2 for linux,Linux Shell编程(2): for while
  9. Lucene创建索引与搜索索引试手
  10. 最新回归算法理解、实现及应用(2)logistic回归