ABAP:SmartForms--设计
要求:
1、不是套打,表格線也需要輸出
2、每張報表打印8行記錄,不足的空白行也需要輸出
3、按憑證號打印單據(jù),可以連續(xù)打印多張報表。
?一、創(chuàng)建樣式:
在創(chuàng)建Form之前,需要創(chuàng)建多種段落和字體樣式,供Form中的文字使用。需要設置多種“段落格式”,并且必須在“表頭數(shù)據(jù)”中設定“標準段落”
1.創(chuàng)建段落格式,一般有RH(Report Header),PD(Page Header), PB(Page Bottom),LD(Line Header and Details),字體:CNSONG,9pt。注意最好在各段落的“首行縮”中設定1mm的縮進,否則,在Form中表格線和文字之間會沒有任何間隙。
2.設置“表頭數(shù)據(jù)”中“標準段落”
3、保存并激活樣式文件。
二、創(chuàng)建SmartForm
1、在“全局設置”-〉“表格屬性”-〉“輸出選項”中
設定“頁格式”:即紙張的大小
“樣式”:設定本Form使用的默認樣式文件,這里指定為第一步創(chuàng)建的樣式文件。
2、在“全局設置”-〉“表格接口”-〉“導入”
設置兩個參數(shù):
ptr_header type c
ptr_items? type c
這兩個參數(shù)用來傳入我們在Report中Export內(nèi)表數(shù)據(jù)的句柄(ID key)。
3、在“全局設置”-〉“全局定義”中進行多項設定
a、“類型”設定,在這里需要定義4個類型,一個用來保存表頭數(shù)據(jù)的工作區(qū)和內(nèi)表,一個用來保存明細數(shù)據(jù)的工作區(qū)和內(nèi)表,它們的結構必須與Report中Export到數(shù)據(jù)庫中的內(nèi)表的結構完全對應一致,否則,我們將不能從傳入的句柄(ID key)中恢復內(nèi)表數(shù)據(jù)。
TYPES:
BEGIN?OF?TYP_header_ROW?,
????????mblnr??????????LIKE?mseg-mblnr,????"?憑證號
????????bldat??????????LIKE?rkpf-rsdat,????"?憑證日期
????????c_so(16)???????TYPE?c,?????????????"?銷售訂單號
????????c_issdt????????LIKE?sy-datum,??????"?發(fā)貨日期
????????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,?????????????"?移動類型次數(shù)
????????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,??????"?計劃數(shù)量(手工填寫)
????????c_outc??????LIKE?mseg-erfmg,??????"?實發(fā)數(shù)量
????????c_count(6)??TYPE?c,???????????????"?件數(shù)(手工填寫)
????????lgort???????LIKE?mseg-lgort,??????"?倉儲地點
????????charg???????LIKE?mseg-charg,??????"?備注
END?OF?TYP_ITEMS_ROW.
TYPES:?TYP_ITEMS_TABLE?TYPE?TYP_ITEMS_ROW?OCCURS?0.
b、在“全局數(shù)據(jù)”中,定義全局的變量,我們需要定義如下幾個變量
? wa_header type typ_header_row??? "表頭數(shù)據(jù)工作區(qū),由于SmartForms中的內(nèi)表不能有HeaderLine,因此必須定義一個與內(nèi)表結構一樣的工作區(qū)
??wa_items??type?typ_items_row?????"表單明細工作區(qū)
??ig_items??type?typ_items_table???"表單明細內(nèi)表
??wa_blanks?type?typ_items_row?????"空白行工作區(qū)
??ig_blanks?type?typ_items_table???"空白行內(nèi)表
??g_count???type?i?????????????????"記錄一張報表的明細的記錄數(shù)量
??G_CURRLINE?type?i????????????????"記錄所有報表共計打印了多少行,用于判斷最后一頁
??G_TOTALLINES?type?i??????????????"記錄內(nèi)表ig_items總行數(shù),用于判斷最后一頁
??G_CURRPAGE?type?i????????????????"一個憑證的當前頁碼
??G_TOTALPAGE?type?i???????????????"一個憑證的總頁碼
c、在“初始化”中,將數(shù)據(jù)句柄中的內(nèi)表恢復到剛設定的全局變量中
輸入?yún)?shù):ptr_header,ptr_items,ig_header,ig_items,g_totallines
perform?Restor_buffer?using?ptr_items??changing?ig_items.
DESCRIBE?TABLE?IG_ITEMS?LINES?G_TOTALLINES.
d、在Freecode"格式化程序"中,定義Form Restor_buffer函數(shù)
??import?t?from?database?indx(hk)?id?typeid.
endform.
至此,我們已經(jīng)得到了表頭和明細這2個內(nèi)表的數(shù)據(jù),下面準備畫報表并輸出數(shù)據(jù)。
4、在“頁和窗口”中,在“%Page1”頁下,添加3個窗口
"MAIN主窗口": 在SmartForm中,只有窗口類型為“主窗口”的窗口,才能被循環(huán)。例如,在最前面的樣表中,明細數(shù)據(jù)有20條,不能在一頁中打印輸出完畢,需要輸出4頁才能打印完一張單據(jù)的數(shù)據(jù),在這4張單據(jù)中,表頭和表尾是不變的,但是表中間部分數(shù)據(jù)卻是變化的,中間這個窗口需要被循環(huán)輸出4次。因此需要將這個窗口類型設定為“主窗口”。在本例中為現(xiàn)實明細數(shù)據(jù)的這部分。
“窗口1”:從表最上面到明細欄的標題欄(包括標題欄)
“窗口2”:最底下2行。
注意:窗口的寬度加上遍距不能大于紙張寬度。
創(chuàng)建好這三個窗口,設定好窗口的寬度,高度,以及位置信息。下圖是整個SmartForm的結構
注意,我將輸出表頭的窗口“%windows1 頁頭”放在了輸出明細數(shù)據(jù)的窗口“主窗口”的下面,這是必須的,因為表頭中的數(shù)據(jù)需要從表頭內(nèi)表ig_header中來。loop1是循環(huán)內(nèi)表ig_header,將數(shù)據(jù)放到表頭工作區(qū)wa_header中。因此,%windows1 頁頭窗口就可以直接使用工作區(qū)wa_header中的數(shù)據(jù)。如果該窗口放在了主窗口的前面,那么至少第一頁中表頭會沒有數(shù)據(jù),而且后面每一頁的表頭顯示的都是下一個表頭的內(nèi)容。
注:雖然打印機輸出時,現(xiàn)打印%WINDOWS1 頁頭,再打印MAIN主窗口,最后打印%WINDOW2頁尾窗口,但是程序執(zhí)行時,卻是按照上圖中樹結構從上到下進行處理的,是先處理MAIN主窗口,其次%WINDOWS1 頁頭,最后%WINDOW2頁尾窗口的邏輯順序,可以從跟蹤SMARTFORMS程序得知。
下面詳細介紹整個邏輯流程和代碼:
1、%LOOP1表頭循環(huán)
設置:數(shù)據(jù)-〉loop循環(huán)-〉操作數(shù):ig_header into wa_header
作用:循環(huán)表頭內(nèi)表中的數(shù)據(jù),每次打印一個憑證的行項目數(shù)據(jù)。由于內(nèi)表在這里不能有工作區(qū),因此將每個表頭數(shù)據(jù)放置到另外的工作區(qū)。
2、%LOOP4計算單個憑證總頁碼
設置:數(shù)據(jù)-〉loop循環(huán)-〉操作數(shù):IG_ITEMS INTO WA_ITEMS
????? WHERE條件:IBLNR = WA_HEADER-IBLNR
作用:由于在打印每張憑證及行項目之前,需要知道該憑證的總頁數(shù),因此需要首先計算IG_ITEMS內(nèi)表中有多少條當前憑證的行記錄數(shù)。
3、%CODE4累計單個憑證的行項目數(shù)
輸入?yún)?shù):G_COUNT
代碼:
作用:累計當前憑證的行項目數(shù)。
4、%CODE1計算當前憑證總頁碼
輸入?yún)?shù):G_TOTALPAGE,G_COUNT
代碼:
*計算單個憑證的總頁碼
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.
作用:根據(jù)第三步累計的單個憑證的總行項目數(shù),以及每頁打印的行記錄數(shù)(8),計算該憑證需要打印的總頁數(shù)。計算完畢以后,G_COUNT重新置0。
6、%LOOP2循環(huán)輸出明細
設置:數(shù)據(jù)-〉loop循環(huán)-〉操作數(shù):IG_ITEMS INTO WA_ITEMS
????? WHERE條件:IBLNR = WA_HEADER-IBLNR
作用:這里的循環(huán)條件與第2步的條件完全一致,準備循環(huán)打印當前憑證的所有行項目。
7、%CODE2記錄行數(shù)加1
輸入?yún)?shù):G_COUNT,G_CURRLINE
代碼:
G_COUNT?=?G_COUNT?+?1.
G_CURRLINE?=?G_CURRLINE?+?1.
作用:每循環(huán)一次,當前憑證打印的行記錄數(shù)加1,所有憑證打印的總行記錄數(shù)加1。
8、%TEMPLATE4數(shù)據(jù)明細
作用:模板,行記錄的表格,以及相關文本內(nèi)容。LOOP2每循環(huán)一次,就打印輸出一行該模板以及文本內(nèi)容。行高一般為5mm(根據(jù)實際調整),注意模板的寬度不能超過窗口的寬度。在“細節(jié)”中可以調整模板的每個單元格的寬度,以及每行的高度。
9、%TEXT22 - %TEXT30文本內(nèi)容
%TEXT22??? 序號:&G_COUNT(CZT4R)&? 輸出選項-〉輸出結構:第1行第1列?
%TEXT23物料號碼:&WA_ITEMS-MATNR&? 輸出選項-〉輸出結構:第1行第2列
依此類推。
10、%CODE5計算當前頁碼
輸入?yún)?shù):G_COUNT,G_CURRPAGE
代碼:
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計算空行
輸入?yún)?shù):G_COUNT,IG_BLANKS,WA_BLANKS
代碼:
*?需要的空記錄行數(shù)
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.
作用:在當前憑證的所有有效數(shù)據(jù)行打印完畢以后,還需要計算需要打印多少空行,才能剛好打印滿一張紙。用計算的數(shù)量,填充內(nèi)表IG_BLANKS,計算完畢以后,G_COUNT必須清0。
12、%LOOP3 補充打印空行
設置:數(shù)據(jù)-〉loop循環(huán)-〉操作數(shù):IG_BLANKSS INTO WA_BLANKS
????? WHERE條件:無
作用:循環(huán)內(nèi)表IG_BLANKS,次數(shù)為內(nèi)表中的記錄數(shù),即空行數(shù),打印輸出空行。
13、%TEMPLATE5空數(shù)據(jù)明細
作用:該模板與第8步的TEMPLATE4完全一樣,只是該模板下不需要有文本TEXT,只序號輸出模板的表格線即可。
到此步驟,已經(jīng)打印完畢了當前憑證的所有有效數(shù)據(jù)行和補充的空行,如果當前憑證需要打印多頁,例如有30條行記錄,需要打印3個滿頁,第4頁數(shù)出6行數(shù)據(jù),補充2個空行,這3次分頁是系統(tǒng)自動分頁的,分也之前,自動處理頁頭和頁尾窗口,輸出這兩個窗口的內(nèi)容。自動分頁的條件是“MAIN主窗口”的高度被打印滿了,因此一定要注意,主窗口的高度必須等于你需要的高度,不要多,也不要少,在本例中,高度為8行 x 5mm = 40mm
14、%CONDITION1分頁
設置:一般屬性-〉節(jié)點條件:G_CURRLINE <> G_TOTALLINES
作用:在一個憑證打印完畢以后,將要進入打印下一個憑證之前,需要分頁,但是在打印完最后一個憑證的最后一頁以后,卻不能有分頁,否則最后會多一個空行。
15、%COMMAND1強制分頁
設置:一般屬性-〉轉到新頁:%PAGE1
作用:在G_CURRLINE <> G_TOTALLINES 條件成立(不是最后一行)的情況下,強制分頁。
你也許會說,這里不強制分頁,系統(tǒng)也會自動分頁,因為前面輸出的高度正好都滿足的各窗口的高度,會自動進行分頁,確實如此,系統(tǒng)會自動進行分頁,但是在這里強調:強制分頁是必須的,不能使用自動分頁,原因是:自動分頁發(fā)生的時間不是我們預想的,我們需要在第13步執(zhí)行完畢以后,馬上進行分頁,這時,WA_HEADER中的內(nèi)容還是當前憑證的數(shù)據(jù),這樣,在處理頁頭和頁尾窗口時,數(shù)據(jù)是正確的。而自動分頁卻不在此時發(fā)生,而是在第1步LOOP1循環(huán)再次執(zhí)行以后,也就是WA_HEADER之中的內(nèi)容變成下一條以后才發(fā)生,這樣我們就不能輸出正確的表頭和表尾數(shù)據(jù),因此必須使用強制的分頁命令。
16、表頭和表尾窗口
由于這兩個窗口非常簡單,僅輸出文字描述和WA_HEADER中的內(nèi)容,因此不詳細說明。
Q&A
1.打印預覽表格線都正常,但是用針式打印機輸出出現(xiàn)部分表格線無法輸出。
答:這個可能是由于針式打印機的分辨率較小的緣故,使用激光或者噴墨打印機可以正常輸出,或者在SmartForms中加粗表格線,使用30TW。
2.在使用穿孔紙連續(xù)打印時,后面的紙張出現(xiàn)錯位現(xiàn)象。
答:原因不是很清楚,需要設置打印機中的紙張格式,將紙張高度根據(jù)錯位的距離進行加或者減,多次調整以后可以達到?jīng)]有錯位。
總結
以上是生活随笔為你收集整理的ABAP:SmartForms--设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Smartform中如何设置背景阴影色(
- 下一篇: T001W更新逻辑