logo资料库

abap自学的好教材:SmartForms 之一--设计.doc

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
SmartForms 之二--设计 要求: 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 这两个参数用来传入我们在 Report 中 Export 内 type c 和 ptr_items 表数据的句柄(ID key)。 3、在“全局设置”-〉“全局定义”中进行多项设定 a、“类型”设定,在 这里需要定义 4 个类型,一个用来保存表头数据的工作区和内表,一个用来保存 明细数据的工作区和内表,它们的结构必须与 Report 中 Export 到数据库中的内 表的结构完全对应一致,否则,我们将不能从传入的句柄(ID key)中恢复内表数 据。 * 领料单抬头信息 TYPES: BEGIN TYP_header_ROW OF , LIKE LIKE mblnr bldat c_so(16) c_issdt werks mseg-mblnr, rkpf-rsdat, TYPE LIKE LIKE c, sy-datum, mseg-werks, " 凭证号 " 凭证日期 " 销售订单号 " 发货日期 " 地点
PLNAT_NAME kokrs kostl cc_name c_depart(45) bwart btext_mt c_btext_mt(60) C_TOTAL(17) OF LIKE LIKE LIKE LIKE TYPE LIKE LIKE TYPE TYPE t001w-name1, mseg-kokrs, mseg-kostl, cskt-ktext, c, mseg-bwart, t156t-btext, c, C, " 出货单位名称 " 控制范围 " 成本中心 " 成本中心名称名称 " 领料部门 " 移动类型代码 " 移动类型描述 " 移动类型次数 " 合计输出时由用户手工填写 TYP_header_ROW TYP_HEADER_TABLE . TYPE TYP_HEADER_ROW OCCURS 0. OF LIKE LIKE LIKE LIKE LIKE LIKE LIKE LIKE LIKE LIKE END TYPES: * 领料单明细信息 TYPES:BEGIN mblnr rsnum mjahr zeile bwart werks kokrs kostl matnr maktx erfme c_planc c_outc c_count(6) lgort charg OF END TYPES: TYPE LIKE LIKE TYP_ITEMS_ROW. TYP_ITEMS_TABLE , TYP_ITEMS_ROW mseg-mblnr, rkpf-rsnum, mseg-mjahr, mseg-zeile, mseg-bwart, mseg-werks, mseg-kokrs, mseg-kostl, mseg-matnr, makt-maktx, " 物料凭证编号 : 物料凭证 " 凭证号 : 预留单 " 物料凭证年度 " 序号 " 移动类型代码 " 地点 " 控制范围 " 成本中心 " 物料号码 " 物料描述 LIKE LIKE LIKE mseg-erfme, resb-bdmng, mseg-erfmg, " 计量单位 " 计划数量(手工填写) " 实发数量 " 件数(手工填写) c, mseg-lgort, " 仓储地点 mseg-charg, " 备注 TYPE TYP_ITEMS_ROW OCCURS 0. a、在“全局数据”中,定义全局的变量,我们需要定义如下几个变量 wa_header type typ_header_row "表头数据工作区,由于 SmartForms 中的内表 不能有 HeaderLine,因此必须定义一个与内表结构一样的工作区。 type type type type type type ig_header wa_items ig_items wa_blanks ig_blanks g_count G_CURRLINE G_TOTALLINES G_CURRPAGE G_TOTALPAGE typ_header_table typ_items_row typ_items_table typ_items_row typ_items_table i "表头数据内表 "表单明细工作区 "表单明细内表 "空白行工作区 "空白行内表 "记录一张报表的明细的记录数量 type I "记录所有报表共计打印了多少行,用于判断最后一页 type i"记录内表 ig_items 总行数,用于判断最后一页 type i "一个凭证的当前页码 type i "一个凭证的总页码
b、在“初始化”中,将数据句柄中的内表恢复到刚设定的全局变量中输入 Restor_buffer Restor_buffer 参数:ptr_header,ptr_items,ig_header,ig_items,g_totallines。 perform perform DESCRIBE d、在 Freecode"格式化程序"中,定义 Form Restor_buffer 函数 form t ptr_header ptr_items G_TOTALLINES. using using TABLE IG_ITEMS typeid type changing changing LINES ig_header. ig_items. Restor_buffer from import t using database indx(hk) c id changing typeid. type table. 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. 5、*计算单个凭证的总页码 G_TOTALPAGE G_COUNT = MOD 8. IF G_TOTALPAGE = G_TOTALPAGE 0. = ELSE. G_COUNT DIV 8. 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_CURRLINE G_COUNT = + 1. G_CURRLINE + 1. 作用:每循环一次,当前凭证打印的行记录数加 1,所有凭证打印的总行记 录数加 1。 8、%TEMPLATE4 数据明细,作用:模板,行记录的表格,以及相关文本内容。 LOOP2 每循环一次,就打印输出一行该模板以及文本内容。行高一般为 5mm(根 据实际调整),注意模板的宽度不能超过窗口的宽度。在“细节”中可以调整模 板的每个单元格的宽度,以及每行的高度。 9、%TEXT22 - %TEXT30 文本内容 %TEXT22 序号:&G_COUNT(CZT4R)& 输 出选项-〉输出结构:第 1 行第 1 列 %TEXT23 物料号码:&WA_ITEMS-MATNR& 输 出选项-〉输出结构:第 1 行第 2 列 依此类推。 L_LINE 10、%CODE5 计算当前页码,输入参数:G_COUNT,G_CURRPAGE DATA: L_LINE IF G_COUNT I. MOD TYPE 8. = L_LINE G_CURRPAGE = 0. = G_COUNT / 8. 代码: ELSE. G_CURRPAGE = G_COUNT DIV 8 + 1. ENDIF. 作用:每输出一行,计算当前行所在的页码,即为当前页 11、%CODE3 计算空行:输入参数:G_COUNT,IG_BLANKS,WA_BLANKS 代码: G_COUNT G_COUNT * 需要的空记录行数 IF 0. MOD 8. = G_COUNT G_COUNT <> = 8 - G_COUNT. ENDIF.
CLEAR DO IG_BLANKS[]. TIMES. G_COUNT APPEND wa_blanks to ig_blanks. = 0. ENDDO. G_COUNT 作用:在当前凭证的所有有效数据行打印完毕以后,还需要计算需要打印多 少空行,才能刚好打印满一张纸。用计算的数量,填充内表 IG_BLANKS,计算完 毕以后,G_COUNT 必须清 0。 12、%LOOP3 补充打印空行:设置:数据-〉loop 循环-〉操作数:IG_BLANKSS WHERE 条件:无;作用:循环内表 IG_BLANKS,次数为内表中 INTO WA_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 中的内容,因此不详细说明。 17、打印预览表格线都正常,但是用针式打印机输出出现部分表格线无法输 出。答:这个可能是由于针式打印机的分辨率较小的缘故,使用激光或者喷墨打 印机可以正常输出,或者在 SmartForms 中加粗表格线,使用 30TW。 18、在使用穿孔纸连续打印时,后面的纸张出现错位现象。 答:原因不是很清楚,需要设置打印机中的纸张格式,将纸张高度根据错位的距 离进行加或者减,多次调整以后可以达到没有错位。
分享到:
收藏