SMARTFORMS分页

原贴地址:http://space.itpub.net/166523/viewspace-374701

报表要求:(见下表)

要求:ITPUB个人空间4C�~Ow.o2VPp
1、 不是套打,表格线也需要输出ITPUB个人空间UvT;@9ok.G
2、 每张报表打印8行记录,不足的空白行也需要输出
qPddf#q0 3、 按凭证号打印单据,可以连续打印多张报表。

 、创建样式 :
8v9k](rXu�W _0
在创建Form之前,需要创建多种段落和字体样式,供Form 中的文字使用。需要 设置多种“段落格 式”,并且必须在“表头数据”中设定“标准段落”ITPUB个人空间%N*u_3{s l1H@P

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

二、创建SmartForm ITPUB个人空间#w{8Y4T"l;QL1t

1、在“全局设置”-〉“表格属性”-〉“输出选项”中ITPUB个人空间;IQ9Iy+^
设定“页格式”:即纸张的大小
K2@8{lZ)d?-Zp4{0
“样式”:设定本Form使用的默认样式文件,这里指定为第一步 创建的样式文件。ITPUB个人空间 ?-[h+tgl.i

2、在“全局设置”-〉“表格接口”-〉“导入”
oNRF1UsB Ta0
设置两个参数:ITPUB个人空间 ]P2OK"j
ptr_header type c
g*H"BX?ZEd0
ptr_items  type c
Q3dm6wL2}(L0
这两个参数用来传入我们在Report中Export内表数据的 句柄(ID key)。ITPUB个人空间zZo/]7X*YUi

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

*  领 料单抬头信息ITPUB个人空间!Cf!q0Ba�M6X X+|
TYPES:
2/EW7U/h)T1v+xk&M0 BEGIN OF TYP_header_ROW ,ITPUB个人空间cDSc!OMt2_
        mblnr          LIKE mseg
- mblnr,     "  凭 证号
vm wu.M[0
        bldat          LIKE rkpf - rsdat,     "  凭 证日期 ITPUB个人空间4XRYHUf7_
        c_so( 16 )       TYPE c,              "  销 售订单号
(_#W1^Y(C)Z[(s{*]%_0
        c_issdt        LIKE sy - datum,       "  发 货日期
n@)YA-r5y L0
        werks          LIKE mseg - werks,     "  地 点
`n�R uO~#zC0
        PLNAT_NAME     LIKE t001w - name1,    "  出 货单位名称 ITPUB个人空间 fkV8D/A
        kokrs          LIKE mseg - kokrs,     "  控 制范围 ITPUB个人空间w5x p0Ly/F7F&{"y{
        kostl          LIKE mseg - kostl,     "  成 本中心 ITPUB个人空间4k&]7c-n1V v
        cc_name        LIKE cskt - ktext,     "  成 本中心名称名称
wvT T�C(l'/'O0
        c_depart( 45 )   TYPE c,              "  领 料部门 ITPUB个人空间2VlES g C&?-AN
        bwart          LIKE mseg - bwart,     "  移 动类型代码
1A4PFW/@n0
        btext_mt       LIKE t156t - btext,    "  移 动类型描述
^:V)v J{o_+Yu0
        c_btext_mt( 60 ) TYPE c,              "  移 动类型次数
i.r"mls0
        C_TOTAL( 17 )    TYPE C,              " 合计输出时由用户手工填写
3Mi8a$Xrj3A'r1Q0
END  OF TYP_header_ROW .ITPUB个人空间Q,wA }.~q*^a
ITPUB个人空间:m"o&Z" {/lUBG jx
TYPES: TYP_HEADER_TABLE TYPE TYP_HEADER_ROW OCCURS 
0 .ITPUB个人空间S"gJsd;eor

:t|E)M9]A0
*  领料单明细信息
DT/U.j3o:O/V"L_;G0 TYPES:
u4S`!Z/L2^0 BEGIN OF TYP_ITEMS_ROW ,
[*urkEp[sg0         mblnr       LIKE mseg
- mblnr,       "  物 料凭证编号 : 物料凭证 ITPUB个人空间1/CAJfw
        rsnum       LIKE rkpf - rsnum,       "  凭 证号 : 预留单
k4Bl%]uB:r0
        mjahr       LIKE mseg - mjahr,       "  物 料凭证年度
Ej:z�L-d P4G uun0
        zeile       LIKE mseg - zeile,       "  序 号
a.q.? h?0
        bwart       LIKE mseg - bwart,       "  移 动类型代码
p T:Z7U7?]v0
        werks       LIKE mseg - werks,       "  地 点 ITPUB 个人空间 nP^Z!^R
        kokrs       LIKE mseg - kokrs,       "  控 制范围 ITPUB个人空间8BM|V.[jG O/["u
        kostl       LIKE mseg - kostl,       "  成 本中心
.SnnXV0
        matnr       LIKE mseg - matnr,       "  物 料号码 ITPUB个人空间~I4]w7r m tu
        maktx       LIKE makt - maktx,       "  物 料描述
j uyZph'/!t1E0
        erfme       LIKE mseg - erfme,       "  计 量单位
#K/fo�Y!mG'e0
        c_planc     LIKE resb - bdmng,       "  计 划数量(手工填写)
(~[[REa_S0
        c_outc      LIKE mseg - erfmg,       "  实 发数量
8@x%rRi2Ed+ed8@0
        c_count( 6 )  TYPE c,                "  件 数(手工填写) ITPUB个人空间&U3Vu?,}x:A#l-u
        lgort       LIKE mseg - lgort,       "  仓 储地点 ITPUB个人空间yE$jOT(K#Yw
        charg       LIKE mseg - charg,       "  备 注 ITPUB 个人空间.a"Kz*PgI
END  OF TYP_ITEMS_ROW.ITPUB个人空间SJG.^:Xpf
ITPUB 个人空间&y,_#/8g2K�i
TYPES: TYP_ITEMS_TABLE TYPE TYP_ITEMS_ROW OCCURS 
0 .


;`v^ ev,B0 b、在“全局数据”中,定义全局的变量,我们需要定义如下几 个变量ITPUB个人空间/"[&h-ig E^T
  wa_header type typ_header_row    "表头数据工作区,由于SmartForms中的内表不能有HeaderLine,因此必须定义一个与内表结构一样的工作区
&Z:o T1q4fP g]]+y0

  ig_header type typ_header_table   " 表 头数据内表
~:b#_M'D_#d7~0
  wa_items  type typ_items_row      " 表单明细工作区
P Nt+d*D%vR._+})Ms0
  ig_items  type typ_items_table    " 表 单明细内表 ITPUB个人空间+oC v;}&T$gshQ H)t
  wa_blanks type typ_items_row      " 空 白行工作区
bKT8O7D%U0
  ig_blanks type typ_items_table    " 空 白行内表 ITPUB个人空间:`CXC7`6Ax7SVz
  g_count   type i                  " 记 录一张报表的明细的记录数量 ITPUB个人空间Z"It*a+IL'Iv
  G_CURRLINE type i                 " 记 录所有报表共计打印了多少行,用于判断最后一页 ITPUB个人空间4` x5t4i'O
  G_TOTALLINES type i               " 记 录内表ig_items总行数,用于判断最后一页 ITPUB个人空间2eG;t*pn_y3_;x)G
  G_CURRPAGE type i                 " 一 个凭证的当前页码 ITPUB个人空间6B n7@8m:m8V?
  G_TOTALPAGE type i                " 一 个凭证的总页码


1N`be HSg5Z0
*}D V7l e0 c、在“初始化”中,将数据句柄中的内表恢复到刚设定的全局变量中ITPUB 个人空间+H0v%R9``4Af
输入参 数:ptr_header,ptr_items,ig_header,ig_items,g_totallines

perform Restor_buffer using ptr_header changing ig_header.
!U4t y ]5x!Id*F2Z0 perform Restor_buffer using ptr_items  changing ig_items.ITPUB个人空间])z"b^/t
ITPUB个人空间 sa-I|f
DESCRIBE TABLE IG_ITEMS LINES G_TOTALLINES.

d、 在Freecode"格式化程序"中,定义Form. Restor_buffer函数
7v3F+a @l$rx}0

form Restor_buffer using typeid type c changing t type table.ITPUB个人空间Ks�H[b'q cq�R
  import t from database indx(hk) id typeid.ITPUB个人空间 f / I B#eD(`;B%A0D
endform.

ITPUB个人空间^}W3c$R
ITPUB个人空间sZ#Wj c!n1x
至此,我们已经得到了表头和明细这2个内表的数据,下面准备画报表并输出数据。
U R&gN {)V%B0

4、在“页和窗口”中,在“%Page1”页下,添加3个窗口
|(J v6l_?l0 "MAIN主窗口": 在SmartForm中,只有窗口类型为“主窗口”的窗口,才能被循环。例如,在最前面的样表中,明细数据有20条,不能在一页中打印输出完毕,需要输出 4页才能打印完一张单据的数据,在这4张单据中,表头和表尾是不变的,但是表中间部分数据却是变化的,中间这个窗口需要被循环输出4次。因此需要将这个窗 口类型设定为“主窗口”。在本例中为现实明细数据的这部分。
0fS(/]X+u;] s0 “窗口1”:从表最上面到明细栏的标题栏(包括标题栏)
TC(Fz|9A*`#o/h"Q-V0 “窗 口2”:最底下2行。
8t//+_3m0x0 注意:窗口的宽度加上遍 距不能大于纸张宽度。
;q�?O:Mxy hu0 ITPUB个人空间[]b#F4~
创建好这三个窗口,设定好窗口的宽度, 高度,以及位置信息。下图是整个SmartForm的结构

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

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

1、%LOOP1表头循环
F(]#k4UA'O /0 设置:数据-〉loop循环-〉操作数:ig_header into wa_headerITPUB个人空间3a6A+n`8t'X!Y
作用:循环表头内表中的数据,每 次打印一个凭证的行项目数据。由于内表在这里不能有工作区,因此将每个表头数据放置到另外的工作区。ITPUB个人空间Z6l C~N/H_`'u)W}:S

pq1Q|,R^E"i0 2、%LOOP4计算单个凭证总页码ITPUB个人空间FKb|/Jg
设置:数据-〉loop循环-〉操作 数:IG_ITEMS INTO WA_ITEMSITPUB个人空间1fn:k q&^tN2]$[p
      WHERE条件:IBLNR = WA_HEADER-IBLNR
DEs3`x S$e0 作用:由于在打印每张凭证及行项目之前,需要知道该凭证的总页数,因此需要首先计算IG_ITEMS内表中有多少条当前凭证的行记 录数。
:Kxj[O"I I0 ITPUB个人空间t(B#EM5Oe Oa7e
3、%CODE4 累计单个凭证的行项目数
dP;dB{'ml2W0 输入参 数:G_COUNTITPUB个人空间G#^]s3I;lZ
代 码:

G_COUNT  =  G_COUNT  +   1 .

作 用:累计当前凭证的行项目数。ITPUB个人空间e9L1FcG4}�|*j#~

D;dH`i;_0 4、%CODE1计算当前凭证总页码
0}D-o.pQBh&D0 输入参 数:G_TOTALPAGE,G_COUNTITPUB个人空间3H%}e0S] i&nDd"]
代码:

G_TOTALPAGE  =   0 .ITPUB个人空间3Rw!~6w4d;@

mh;r Y:X&k4W0
* 计 算单个凭证的总页码ITPUB个人空间 EH,^*_0H6z+J
G_TOTALPAGE 
=  G_COUNT  MOD  8 .
d?oMD(]+Z`(h)c0
FKy }7e!a#u0
IF  G_TOTALPAGE  =   0 .
[5Trr$DU9S"y?0   G_TOTALPAGE 
=  G_COUNT DIV 8 .ITPUB个人空间"N W Ml7D'u^�Y4X9o,t(~ t
ELSE .
1E;r1H2Z j2G.A:z0   G_TOTALPAGE 
=  G_COUNT DIV 8   +   1 .ITPUB个人空间 S2S'o�lym
ENDIF.
Z$QW/R?0
:}s(U h%C~0 G_COUNT 
=   0 .

作用:根据第三步累计的单个凭证的总行项 目数,以及每页打印的行记录数(8),计算该凭证需要打印的总页数。计算完毕以后,G_COUNT重新置0。ITPUB个人空间9ehA%^Ib*K'l
ITPUB 个人空间.Moc_;lu0qF)|
6、%LOOP2循环输出明细ITPUB个人空间9{Ic:ZvJr7|,u$z
设置:数据-〉loop循环-〉操作 数:IG_ITEMS INTO WA_ITEMSITPUB个人空间,h y�M/?7j+p(LQr
      WHERE条件:IBLNR = WA_HEADER-IBLNRITPUB个人空间:e%Khw Q7zru
作用:这里的循环条件与第2步的条件完全一致,准备循环打印当前凭证的所有行项目。ITPUB个人空间![&p Lq)^s;VS

d f#Dj V-K0 7、%CODE2记录行数加1
(}*OL[{1u w0 输入参数:G_COUNT,G_CURRLINEITPUB个人空间:i |MZYz3p
代码:

*  每打印一行行记录,记录数量加1ITPUB个人空间9T8Rw;mD[(q
G_COUNT 
=  G_COUNT  +   1 .
!@ U7x}n0 ITPUB 个人空间;]v.Ba7NQ5Jv
G_CURRLINE 
=  G_CURRLINE  +   1 .

作 用:每循环一次,当前凭证打印的行记录数加1,所有凭证打印的总行记录数加1。
Pq1mn!r i;t0 ITPUB个人空间9RS7[�S y6U
8、%TEMPLATE4数据明细
2LTJsUM Y;P0 作用:模板,行记录的表格,以及相关文本内容。LOOP2每循环一次,就打印输出一行该模板以及文本内容。行高一般为5mm(根据 实际调整),注意模板的宽度不能超过窗口的宽度。在“细节”中可以调整模板的每个单元格的宽度,以及每行的高度。ITPUB个人空间f-YBf)`*B{�A
ITPUB个人空间)AfHBE0x iX uVJ
9、%TEXT22 - %TEXT30文本内容
q6Yr^C1YK0 %TEXT22    序号:&G_COUNT(CZT4R)&  输出选项-〉输出结构:第1行第1列 
4h#/Y#n/XHxU0 %TEXT23 物料号码:&WA_ITEMS-MATNR&  输出选项-〉输出结构:第1行第2列ITPUB个人空间Uea5V6/(`
依此类推。
Go I/l O+w{e0 ITPUB个人空间5~F9XYhSz$RZ
10、%CODE5 计算当前页码ITPUB个人空间-A^-gyj P H
输入参数:G_COUNT,G_CURRPAGEITPUB个人空 间*a]/O*U:l)| OZ
代码:

DATA: L_LINE TYPE I.ITPUB个人空间wG3jz|!~.yW
L_LINE 
=  G_COUNT  MOD  8 .ITPUB个人空间Ug8r'L6~h*/J m

;ub(}R-[P0
IF  L_LINE  =   0 .ITPUB个人空间w7p o+[(d*EM
  G_CURRPAGE 
=  G_COUNT  /  8 .
#{_M+~c`f6K A0
ELSE .
l NhbzW]#K0   G_CURRPAGE 
=  G_COUNT DIV 8   +   1 .ITPUB个人空间%/ n%m9shV o r
ENDIF.

作用:每输出一行,计算当前行所在的页码,即为当前页
.bz.o)_3u(a0 ITPUB 个人空间3j2n8M6v)t
11、%CODE3计算空行
(/Xh6d4|4ce0 输 入参数:G_COUNT,IG_BLANKS,WA_BLANKSITPUB个人空间V XT.MB2xURn
代码:

G_COUNT  =  G_COUNT  MOD  8 .
Gg+q1ET k&w*j8R0
S2x(ZZH8~0
*  需 要的空记录行数ITPUB个人空间l&IW9Qmxq
IF  G_COUNT  <>   0 .
Bh-{f(r4W"?}y6I0   G_COUNT 
=  8   -  G_COUNT.
zZEGW0 ENDIF.ITPUB个人空间)aJ Z9L C||^?

*[-yH u'jn-c0 CLEAR IG_BLANKS[].ITPUB个人空间W ?/2U!k$P$E0B${ vxLE
DO  G_COUNT TIMES.ITPUB个人空间4F3j4o/V-J
  APPEND wa_blanks 
to  ig_blanks.ITPUB个人空间#m2q:JU+/L
ENDDO.ITPUB个人空间dW~&s)w${K7C

b#] F7X�j8G%N0 G_COUNT 
=   0 .

作用:在当前凭证的所有有效数据行打印完 毕以后,还需要计算需要打印多少空行,才能刚好打印满一张纸。用计算的数量,填充内表IG_BLANKS,计算完毕以后,G_COUNT必须清0。
7/)~gX'B pN0
!~(I-~TZl:W0 12、%LOOP3 补充打印空行
oU Y-|8MM ]ocY f0 设置:数据-〉loop循环-〉操作数:IG_BLANKSS INTO WA_BLANKS
'L@-b.X)^/g9|%g6M(k0       WHERE条件:无ITPUB个人空间c"a-j9{g#i#x6}
作用:循环内表 IG_BLANKS,次数为内表中的记录数,即空行数,打印输出空行。
|!P4L-_)q#t0 ITPUB个人空间%kT&FFN-jPf _~
13、%TEMPLATE5 空数据明细ITPUB个人空间)v8S?+r,v*| {(e
作 用:该模板与第8步的TEMPLATE4完全一样,只是该模板下不需要有文本TEXT,只序号输出模板的表格线即可。ITPUB个人空间9l"k$fZ-nI
到此步骤,已经打印完毕了当前凭证的 所有有效数据行和补充的空行,如果当前凭证需要打印多页,例如有30条行记录,需要打印3个满页,第4页数出6行数据,补充2个空行,这3次分页是系统自 动分页的,分也之前,自动处理页头和页尾窗口,输出这两个窗口的内容。自动分页的条件是“MAIN主窗口”的高度被打印满了,因此一定要注意,主窗口的高 度必须等于你需要的高度,不要多,也不要少,在本例中,高度为8行 x 5mm = 40mmITPUB 个人空间 N Ds:b ph
ITPUB个人空间5XJ&XJ rf:Q.eV-P

6Sq1j7W /&s0 14、%CONDITION1分页
rg/m tz+y;S OM0 设置:一般属性-〉节点条件:G_CURRLINE <> G_TOTALLINES
p0Tw�N{G$@7[0 作用:在一个凭证打印完毕以后,将要进入打印下一个凭 证之前,需要分页,但是在打印完最后一个凭证的最后一页以后,却不能有分页,否则最后会多一个空行。
?~$Q#uw/ sO0
7m@vw2U#]/0 15、%COMMAND1 强制分页
'QCDe_0 设置:一般属性-〉转到新 页:%PAGE1ITPUB个人空间 @#Z(H0T/A~x
作 用:在G_CURRLINE <> G_TOTALLINES 条件成立(不是最后一行)的情况下,强制分页。
.mE b W&{ v0x"?0 你也许会说,这里不强制分页,系统也会自动分页,因为前面输出的高度正好都满足的各窗口的高度,会自动进行分页,确实如此,系 统会自动进行分页,但是在这里强调:强制分页是必须的,不能使用自动分页,原因是:自动分页发生的时间不是我们预想的,我们需要在第13步执行完毕以后, 马上进行分页,这时,WA_HEADER中的内容还是当前凭证的数据,这样,在处理页头和页尾窗口时,数据是正确的。而自动分页却不在此时发生,而是在第 1步LOOP1循环再次执行以后,也就是WA_HEADER之中的内容变成下一条以后才发生,这样我们就不能输出正确的表头和表尾数据,因此必须使用强制 的分页命令。ITPUB个人空间 Zz7j?,/:~7i4{)[
ITPUB个人空间H/ K*`!Gr ?c-ee
16、表头和表尾窗口
g9DSB2J,KR!T0 由 于这两个窗口非常简单,仅输出文字描述和WA_HEADER中的内容,因此不详细说明。ITPUB 个人空间&a#fS B0o6Ga2{/L0[

u2f~(HZn0
:Y0z�n tY H#|e~0 Q&A
3W+u tuGm G8V0 1.打印预览表格线都正常,但是用针式打印机输出出现部分表格线无法输出。ITPUB个人空间(/WU+O/G
答:这个可能是由于针式打印机的分辨率较 小的缘故,使用激光或者喷墨打印机可以正常输出,或者在SmartForms中加粗表格线,使用30TW。
3S4yu%Sv[b�?k0
'Y0Z9p.@L}0 2.在使用穿孔纸连续打印时,后面的纸张出现错位现象。
`[? j;SoQB0 答:原因不是很清楚,需要设置打印机中的纸张格式,将纸张高度根据错位的距离进行加或者减,多次调整以后可以达到没有 错位。

ITPUB个人空间_+Pq v;~)]{&I/f1R

ITPUB个人空间(Nb3FBT/u

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值