SAP Archiving(1)--OverView
所谓的SAP Archiving中文解释就是归档。这是一个什么样的概念呢?就比如,纸质办公的企业,它每年都会有很多的资料和数据,过几年就需要把一些用不着的文件 整理处理,由专门的人员管理和保存,不再或很少拿出来使用(仅供特殊用途)。这是为了保证这些过时的文件,不影响到现有的业务,以免混在一起,降低现时文 件的查找效率、造成管理混乱。那么现在SAP的归档,你可以理解成把纸质变成了硬盘和磁碟机,它们也有存满的一天,它们也存在着效率问题,所以对于运行大 量业务的公司,定期的Archiving是必不可少的。
下面谈一下Archiving几大优点。
- 减少数据库的压力,提高系统性能
- 有些数据由于财务审计、税务要求必须保留,不能删除,就只能通过Archiving的形式保留
- 减少备份,恢复,升级的时间
- 节约存储空间
- 可以通过SAP提供的工具访问Archiving的数据
- 由于数据量的减少,从而提高了系统管理效率
SAP Archiving就是为了解决公司业务增长过快,原有数据库中数据海量增长,系统效率降低,而导致业务受到影响等情况的。虽然说现在有BI,可以方便用 来出报表,但是不管出报表速度多快,如果数据量无限膨胀的话,哪个数据库,哪个系统都是吃不消的,所以Archiving还是必须的。
下面是一些在Archving时常用的T-code,总的来说分为数据容量分析和归档具体应用两块。着颜色的几个T-code是几个主要的归档事务。以后 的总结中,会慢慢讲解其中一些T-code的应用。
Transaction Code |
Short text |
Package |
|
|
|
ACLA |
Define Archiving Classes |
SARC |
AOBJ |
Archiving object definition |
SARC |
DB15 |
Data Archiving: Database Tables |
SARC |
SARA |
Archive Administration |
SARC |
SAR_DA_STAT_ANALYSIS |
Analysis of DA Statistics |
SARC |
SAR_OBJ_IND_CUS |
Cross-Archiving-Obj. Customizing |
SARC |
SAR_SHOW_MONITOR |
Data Archiving Monitor |
SARC |
SAR_SYNC_HOME_PATH |
Synchornization of Home Paths |
SARC |
|
|
|
AS_ADMIN |
SAP AS: Administration |
SARCIS |
SARE |
Archive Explorer |
SARCIS |
SARI |
Archive Information System |
SARCIS |
SARJ |
Archive Retrieval Configurato |
SARCIS |
SAP Archiving(2)--项目介绍
上文介绍了一下Archiving,下面来介绍我参与的那个项目。
一般来说Archiving只要Basis去做就可以了,但是由于上线一段时间后客户会做很多的定制和增强,那么原有的Archiving程序就不能再用 了,需要重新编写。
Archiving运行界面:
我们需要用T-code: AOBJ来定义一个Archiving Object。其中有四个主要的地方需要ABAPer来参与,Preprocess,Write,Delete,Read,这四个步骤分别代表4个程序, 在AOBJ里需要配置给相应的自定义的Archiving Object。
其中,Archiving Object中需要Write Program, Delete Program, Preprocessing Program等,这三个一般都要重写,其他的视情况而定。Stucture Definition要定义哪些表要Archiving,最好这些表都是相关联的。Customizing Settings,就是定义一些Archive文件的容量,提交的频率等。Read Program就是用来读取已经Archiving数据的程序。其余的就是一些选择性的内容,根据Archiving Object来定。
配置完毕后,用T-code: SARA进行Archiving 就行。
对于这个Archiving Project原来有两个方案,一个针对Oracle数据库的优化软件LiveReorg,另一个是日立的IXOS。介绍一下这各工具:
Oracle数据库应用的大量实施,使数据库碎片重组成为保持应用高性能运行的关键。常规重组方法需要中断应用运行,对企业造成严重的影响。
LiveReorg是一种联机数据库性能优化工具,在不影响关键业务系统运行的情况下,对Oracle数据库进行碎片重组。
LiveReorg 采用了基于日志的复制技术。通过读取Oracle 日志,可以跟踪重组期间发生的用户活动,保证应用系统的数据库保持持续可用的状态。
LiveReorg包括快速、灵活的数据移动选项,支持通过实时和常规方式进行重组。重组过程既可以完全在数据库内,通过 SQL语句来实现,也可以利用该主品的FastCopy功能通过文件系统实现。FastCopy功能可以将数据卸载到文件系统,再利用Oracle的直接 路径技术对其进行重载,这种方式对较大的Long和Long Raw数据类型有很好的支持。
IXOS,是一个文档管理系统,数据是存在光存储器上的,专门用来管理Archiving文档的工具,具有简单好用等特点。
最后,公司选择了IXOS,理由就是简单好用,越是牛比复杂的技术,日后出现问题的概率就越大,维护起来就越麻烦。
由于选择了IXOS,所有有了Archiving项目,才有了机会把Archiving好好搞一遍。
SAP Archiving(3)--代码举例
SAP Archiving中对于一些增强过的表及特殊要求,我们要重写一些PreProcessing, Write, Delete, Read等程序。由于PreProcessing就是在Archiving前做一些检查和处理,每个表都有不同。所以下面就举Write, Delete, Read等比较通用的程序。(其实还是按照我之前的方法,把例子看懂了,逻辑清楚了,就可以拿来重用了。不然每次都重头写,不要累死的)。
Write Program
SPAN { font-family: "Courier New"; font-size: 10pt; color: #000000; background: #FFFFFF; } .L1S31 { font-style: italic; color: #808080; } .L1S32 { color: #3399FF; } .L1S33 { color: #4DA619; } .L1S52 { color: #0000FF; }
*----------------------------------------------------------------------*
* Program Name: ZKEVINA_WRI
* Project : N/A
* Author : Kevin.Zhang
* Date : 2007.1.1
* Module : N/A
* Description : Template of Program
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author Date Commented as Description
*----------- -------- ----------- ----------------------------------*
*
*----------------------------------------------------------------------*
REPORT ZKEVINA_WRI.
*$*$----------------------------------------------------------------$*$*
*$*$ Global Types, Data Statements, Ranges, Constants $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Tables
*-----------------------------------------------------------------------
TABLES : ZKEVINA.
*-----------------------------------------------------------------------
* Constants
*-----------------------------------------------------------------------
* data declaration
CONSTANTS : LC_OBJECT
TYPE ARCH_OBJ-OBJECT
VALUE
'ZKEVIN' .
*-----------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------
DATA : LV_FILES_CREATE(
1 )
TYPE
C ,
LV_DELETE_TESTMODE(
1 )
TYPE
C ,
LV_HANDLE
LIKE SY-TABIX,
LV_SESSION_INTERRUPTED(
1 )
TYPE
C
VALUE
' ' ,
LV_OBJECT_IDENTIFIER
TYPE STRING,
LV_TOTAL_OBJECT_NUMBER
TYPE
I ,
LV_OBJECTS_PROCESSED
TYPE
I ,
LV_PROGRESS_SEND(
1 )
TYPE
C .
*-----------------------------------------------------------------------
* Internal Tables and Work Areas
*-----------------------------------------------------------------------
DATA : LS_ZKEVINA
LIKE ZKEVINA,
LW_CALLBACK_PARAM
TYPE BAL_S_PARM,
* lt_callback_param TYPE bal_t_par,
LT_ZKEVINA
LIKE
TABLE
OF ZKEVINA.
* optional e.g. for the old index solution (ADK index, not SAP AS)
* DATA: lv_data_object_id LIKE arch_idx_s-obj_id.
*$*$----------------------------------------------------------------$*$*
*$*$ Selection Screen $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Selection Screen
*-----------------------------------------------------------------------
* selection criteria and parameters
SELECTION-
SCREEN
BEGIN
OF
BLOCK ARCH_ZKEVINA
WITH
FRAME .
SELECT -OPTIONS: S_ID
FOR ZKEVINA-
ID ,
S_NAME
FOR ZKEVINA-NAME.
SELECTION-
SCREEN
END
OF
BLOCK ARCH_ZKEVINA.
*-----------------------------------------------------------------------
* At Selection Screen
*-----------------------------------------------------------------------
INCLUDE ARCH_WRITE_PRG_STANDARD2.
" flow control
*--------- INITIALIZATION ----------
INITIALIZATION .
PERFORM STANDARD_OPT_WRITEPRG_INIT.
" flow contol: frame titel
*--------- AT SELECTION-SCREEN OUTPUT ----------
AT SELECTION-
SCREEN
OUTPUT .
PERFORM STANDARD_OPT_WRITEPRG_ATOUTPUT
USING LC_OBJECT.
" options for start of delete program
*$*$----------------------------------------------------------------$*$*
*$*$ Main Program $*$*
*$*$----------------------------------------------------------------$*$*
*--------- START-OF-SELECTION ----------
START-
OF -SELECTION.
* set parameters for 'ARCHIVE_OPEN_FOR_WRITE' from selection screen
LV_DELETE_TESTMODE =
'X' .
IF P_WRITST =
'X' .
LV_FILES_CREATE = SPACE.
ELSE .
LV_FILES_CREATE =
'X' .
IF P_DELTST
IS
INITIAL .
LV_DELETE_TESTMODE = SPACE.
ENDIF .
ENDIF .
* select data from the database
SELECT *
FROM ZKEVINA
INTO
TABLE LT_ZKEVINA
WHERE
ID
IN S_ID
AND
NAME
IN S_NAME.
LV_TOTAL_OBJECT_NUMBER = SY-DBCNT.
* open a new archiving session to archive data
CALL
FUNCTION
'ARCHIVE_OPEN_FOR_WRITE'
EXPORTING
CALL_DELETE_JOB_IN_TEST_MODE = LV_DELETE_TESTMODE
COMMENTS = P_COMENT
CREATE_ARCHIVE_FILE = LV_FILES_CREATE
OBJECT = LC_OBJECT
OUTPUT_SEL_SCREEN_WHEN_DIALOG =
''
IMPORTING
ARCHIVE_HANDLE = LV_HANDLE.
* optional: set call back parameter for object and message details
* lw_callback_param-callback-userexitp = sy-repid.
* lw_callback_param-callback-userexitf = 'CALLBACK_AT_LINE_SELECTION'.
* lw_callback_param-callback-userexitt = space.
* "or:
* lw_callback_param-callback-userexitf = ''.
* lw_callback_param-callback-userexitt = 'F'.
* init protocoll
CALL
FUNCTION
'ARCHIVE_PROTOCOL_INIT'
EXPORTING
I_DETAILPROTOCOL = P_PROT
I_PROTOCOL_OUTPUT = P_PROT_O.
* optional: set call back parameter for object and message details
* I_CALLBACK_PARAMETER = lw_callback_param.
LOOP
AT LT_ZKEVINA
INTO LS_ZKEVINA.
* if necessary, process checks whether records can be archived or not
* (residence time etc.)
* ...
* get/check records from all dependig/further tables
* SELECT * FROM INTO TABLE lt_depending_table1
* WHERE ...
* AND ...
* ...
* optional e.g. for the old index solution (ADK index, not SAP AS)
* if possible use SAP AS instead
* CONCATENATE sy-mandt ls_sbook-carrid ls_sbook-bookid
* INTO lv_data_object_id.
* initialize a new data object
CALL
FUNCTION
'ARCHIVE_NEW_OBJECT'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE.
* object_id = lv_data_object_id. " optional: ADK index
* put data records into ADK's data container
CALL
FUNCTION
'ARCHIVE_PUT_RECORD'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
RECORD_STRUCTURE =
'ZKEVINA'
RECORD = LS_ZKEVINA.
* further (depending) records from other tables usually follow
* CALL FUNCTION 'ARCHIVE_PUT_TABLE'
* EXPORTING
* archive_handle = lv_handle
* record_structure = 'DEPENDING_TABLE1'
* TABLES
* table = lt_depending_table1.
* .......
* (or alternatively
* loop at where ...
* call function 'ARCHIVE_PUT_RECORD' ...
* endloop...)
* write data object into the archive file
CALL
FUNCTION
'ARCHIVE_SAVE_OBJECT'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
EXCEPTIONS
TERMINATION_REQUESTED =
1 .
IF SY-SUBRC =
1 .
LV_SESSION_INTERRUPTED =
'X' .
EXIT .
ENDIF .
* collect protocol messages
CONCATENATE LS_ZKEVINA-
ID LS_ZKEVINA-NAME
INTO LV_OBJECT_IDENTIFIER
SEPARATED
BY SPACE.
* optional: parameter needed in order to display object details
* REFRESH lt_callback_param.
* APPEND INITIAL LINE TO lt_callback_param ASSIGNING .
* -parname = '...'.
* -parvalue = '...'.
CALL
FUNCTION
'ARCHIVE_PROTOCOL_COLLECT'
EXPORTING
I_OBJECT = LV_OBJECT_IDENTIFIER
I_TEXT =
'Einzelflugbuchung archiviert' (
001 )
I_MSGTYPE =
1 .
* I_CALLBACK_PARAMETER = lt_callback_param[].
LV_OBJECTS_PROCESSED = LV_OBJECTS_PROCESSED +
1 .
* send progress indicator
CALL
FUNCTION
'PROGRESS_INDICATOR'
EXPORTING
I_TEXT =
'&1% (&2 von &3) der Einzelflugbuchungen archiviert' (
002 )
I_PROCESSED = LV_OBJECTS_PROCESSED
I_TOTAL = LV_TOTAL_OBJECT_NUMBER
IMPORTING
E_PROGRESS_SENT = LV_PROGRESS_SEND.
IF
NOT LV_PROGRESS_SEND
IS
INITIAL .
CALL
FUNCTION
'DB_COMMIT' .
ENDIF .
* send progress indicator if all objects are processed
IF LV_OBJECTS_PROCESSED = LV_TOTAL_OBJECT_NUMBER.
CALL
FUNCTION
'PROGRESS_INDICATOR'
EXPORTING
I_TEXT =
'&1% (&2 von &3) der Einzelflugbuchungen archiviert' (
002 )
I_PROCESSED = LV_OBJECTS_PROCESSED
I_TOTAL = LV_TOTAL_OBJECT_NUMBER
I_OUTPUT_IMMEDIATELY =
'X' .
ENDIF .
ENDLOOP .
IF LV_SESSION_INTERRUPTED =
'X' .
* This means the last data object has not been saved.
* -> Clean-up and/or update status specific to interrupted sessions,
* but also write a detailed or standard log + close session as usual:
ENDIF .
* create the default spool list
CALL
FUNCTION
'ARCHIVE_WRITE_STATISTICS'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE.
* close the archiving session
CALL
FUNCTION
'ARCHIVE_CLOSE_FILE'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE.
* write protocol
CALL
FUNCTION
'ARCHIVE_PROTOCOL_WRITE' .
*************
* optional - only for online programs with protocol output into the spool:
* show details on chosen object or message
* AT LINE-SELECTION.
* CALL FUNCTION 'ARCHIVE_PROTOCOL_LINE_DETAIL'.
*************
* optional - only for online programs with protocol output into the spool:
* call back for showing details on chosen object
* FORM callback_at_line_selection USING lv_object TYPE string
* lt_param TYPE bal_t_par.
* ...
** !!! if CALL SCREEN is needed, it has to be called in a function module.!!!
*
* ENDFORM.
Delete Program
SPAN { font-family: "Courier New"; font-size: 10pt; color: #000000; background: #FFFFFF; } .L1S31 { font-style: italic; color: #808080; } .L1S32 { color: #3399FF; } .L1S33 { color: #4DA619; } .L1S52 { color: #0000FF; }
*----------------------------------------------------------------------*
* Program Name: ZKEVIN_DEL
* Project : N/A
* Author : Kevin.Zhang
* Date : 2007.1.1
* Module : N/A
* Description : Template of Program
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author Date Commented as Description
*----------- -------- ----------- ----------------------------------*
*
*----------------------------------------------------------------------*
REPORT ZKEVINA_DEL.
*$*$----------------------------------------------------------------$*$*
*$*$ Global Types, Data Statements, Ranges, Constants $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Constants
*-----------------------------------------------------------------------
* data declaration
CONSTANTS : LC_OBJECT
LIKE ARCH_OBJ-OBJECT
VALUE
'ZKEVIN' .
*-----------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------
DATA : LV_HANDLE
LIKE SY-TABIX,
LV_COMMIT_CNT
LIKE ARCH_USR-ARCH_COMIT,
LV_OBJECT_CNT
TYPE
I ,
LV_DELCNT
TYPE
I ,
LV_CNT
TYPE
I .
DATA : LV_DOCUMENT
TYPE ADMI_RUN-DOCUMENT,
LV_ARCHIVE_KEY
TYPE ADMI_FILES-ARCHIV_KEY,
LV_OBJECTS_TO_DELETE
TYPE
I .
*-----------------------------------------------------------------------
* Tables
*-----------------------------------------------------------------------
DATA : LT_ZKEVINA
TYPE
TABLE
OF ZKEVINA,
LT_ZKEVINA_DELETE
TYPE
TABLE
OF ZKEVINA.
*$*$----------------------------------------------------------------$*$*
*$*$ Selection Screen $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* At Selection Screen
*-----------------------------------------------------------------------
*--------- INITIALIZATION ----------
INCLUDE ARCH_DELETE_PRG_STANDARD1.
"<<< flow control
INITIALIZATION .
PERFORM STANDARD_OPT_DELETEPRG_INIT.
"<<< flow control: frame titel
*$*$----------------------------------------------------------------$*$*
*$*$ Main Program $*$*
*$*$----------------------------------------------------------------$*$*
START-
OF -SELECTION.
* open a new archiving session to delete data
CALL
FUNCTION
'ARCHIVE_OPEN_FOR_DELETE'
EXPORTING
OBJECT = LC_OBJECT
TEST_MODE = P_DELTST
IMPORTING
ARCHIVE_HANDLE = LV_HANDLE.
* get Customizing data from the archiving object
CALL
FUNCTION
'ARCHIVE_GET_CUSTOMIZING_DATA'
EXPORTING
OBJECT = LC_OBJECT
IMPORTING
COMMIT_COUNT_FOR_DELETE_PRG = LV_COMMIT_CNT.
* get total number of objects to be deleted
CALL
FUNCTION
'ARCHIVE_GET_INFORMATION'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
IMPORTING
ARCHIVE_DOCUMENT = LV_DOCUMENT
ARCHIVE_NAME = LV_ARCHIVE_KEY.
SELECT
SINGLE OBJ_COUNT
FROM ADMI_FILES
INTO LV_OBJECTS_TO_DELETE
WHERE DOCUMENT = LV_DOCUMENT
AND ARCHIV_KEY = LV_ARCHIVE_KEY.
* loop to get the next data object from the archive file(s)
CLEAR LV_OBJECT_CNT.
DO .
CALL
FUNCTION
'ARCHIVE_GET_NEXT_OBJECT'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
EXCEPTIONS
END_OF_FILE =
01 .
IF SY-SUBRC =
1 .
EXIT .
ENDIF .
ADD
1
TO LV_OBJECT_CNT.
REFRESH LT_ZKEVINA.
CALL
FUNCTION
'ARCHIVE_GET_TABLE'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
RECORD_STRUCTURE =
'ZKEVINA'
ALL_RECORDS_OF_OBJECT =
'X'
TABLES
TABLE = LT_ZKEVINA.
APPEND
LINES
OF LT_ZKEVINA
TO LT_ZKEVINA_DELETE.
* for dependig/further tables
* call function 'ARCHIVE_GET_TABLE'
* exporting
* archive_handle = lv_handle
* record_structure = 'DEPENDING_TABLE1'
* all_records_of_object = 'X'
* tables
* table = lt_depending_table1.
* APPEND LINES OF lt_depending_table1 TO lt_depending_table1_to_del.
* in case of archiving classes
* call function 'ARCHIVE_DELETE_OBJECT_DATA'
* exporting
* archive_handle = lv_handle
IF LV_OBJECT_CNT = LV_COMMIT_CNT.
* delete data (if running in production mode) or simulate deletion (if
* running in test mode) and collect statistics
PERFORM DELETE_FROM_TABLE
USING LV_HANDLE
P_DELTST
LV_OBJECT_CNT
LT_ZKEVINA_DELETE.
DESCRIBE
TABLE LT_ZKEVINA_DELETE
LINES LV_CNT.
ADD LV_OBJECT_CNT
TO LV_DELCNT.
CLEAR LV_OBJECT_CNT.
REFRESH LT_ZKEVINA_DELETE.
".. dependig/further tables
ENDIF .
" value of commit counter
* send progress indicator
CALL
FUNCTION
'PROGRESS_INDICATOR'
EXPORTING
I_TEXT =
'&1 (&2 von &3) der Einzelflugbuchungen bearbeitet' (
003 )
I_PROCESSED = LV_DELCNT
I_TOTAL = LV_OBJECTS_TO_DELETE.
ENDDO .
IF LV_OBJECT_CNT >=
1 .
PERFORM DELETE_FROM_TABLE
USING LV_HANDLE
" deleting last package
P_DELTST
LV_OBJECT_CNT
LT_ZKEVINA_DELETE.
ADD LV_OBJECT_CNT
TO LV_DELCNT.
CLEAR LV_OBJECT_CNT.
".. dependig/further tables
ENDIF .
IF LV_DELCNT = LV_OBJECTS_TO_DELETE.
* send progress indicator at the end
CALL
FUNCTION
'PROGRESS_INDICATOR'
EXPORTING
I_TEXT =
'&1 (&2 von &3) der Einzelflugbuchungen bearbeitet' (
003 )
I_PROCESSED = LV_DELCNT
I_TOTAL = LV_OBJECTS_TO_DELETE
I_OUTPUT_IMMEDIATELY =
'X' .
ENDIF .
* create statistics list
CALL
FUNCTION
'ARCHIVE_WRITE_STATISTICS'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE
STATISTICS_ONLY_PER_FILE =
'X' .
* close the archiving session
CALL
FUNCTION
'ARCHIVE_CLOSE_FILE'
EXPORTING
ARCHIVE_HANDLE = LV_HANDLE.
*---------------------------------------------------------------------*
* FORM DELETE_FROM_TABLE *
*---------------------------------------------------------------------*
* --> P_HANDLE ADK handle
* --> P_TESTMODE X = deleting in test mode
* --> P_OBJECT_CNT number of deleted data objects
* --> PT_SBOOK_DELETE records to delete from SBOOK
* --> PT_... records to delete from further tables
*---------------------------------------------------------------------*
FORM DELETE_FROM_TABLE
USING
VALUE (P_HANDLE)
LIKE SY-TABIX
VALUE (P_TESTMODE)
LIKE P_DELTST
VALUE (P_OBJECT_CNT)
LIKE SY-DBCNT
VALUE (PT_ZKEVINA_DELETE)
LIKE LT_ZKEVINA_DELETE.
DATA : LS_STAT_ITAB
TYPE ARCH_STAT,
LT_STAT_ITAB
TYPE
TABLE
OF ARCH_STAT,
LT_ZKEVINA_AUX
TYPE
TABLE
OF ZKEVINA,
"#EC NEEDED
LV_DBCNT
TYPE SY-DBCNT.
REFRESH LT_STAT_ITAB.
IF P_TESTMODE
IS
INITIAL .
* delete data on DB if running in production mode
DELETE ZKEVINA
FROM
TABLE PT_ZKEVINA_DELETE.
" delete job restartable
LV_DBCNT = SY-DBCNT.
".. dependig/further tables
ELSE .
* select data from DB if running in test mode
SELECT *
FROM ZKEVINA
INTO
TABLE LT_ZKEVINA_AUX
FOR
ALL ENTRIES
IN PT_ZKEVINA_DELETE
WHERE
ID = PT_ZKEVINA_DELETE-
ID
AND NAME = PT_ZKEVINA_DELETE-NAME.
LV_DBCNT = SY-DBCNT.
".. dependig/further tables
ENDIF .
LS_STAT_ITAB-TABNAME =
' ' .
LS_STAT_ITAB-
COUNT = P_OBJECT_CNT.
APPEND LS_STAT_ITAB
TO LT_STAT_ITAB.
LS_STAT_ITAB-TABNAME =
'ZKEVINA' .
LS_STAT_ITAB-
COUNT = LV_DBCNT.
APPEND LS_STAT_ITAB
TO LT_STAT_ITAB.
* provide ADK with statistics data (before every COMMIT WORK!)
CALL
FUNCTION
'ARCHIVE_GIVE_STATISTICS'
EXPORTING
ARCHIVE_HANDLE = P_HANDLE
TABLES
TABLE = LT_STAT_ITAB.
COMMIT
WORK .
ENDFORM .
" DELETE_FROM_TABLE
Read Program
SPAN { font-family: "Courier New"; font-size: 10pt; color: #000000; background: #FFFFFF; } .L1S31 { font-style: italic; color: #808080; } .L1S32 { color: #3399FF; } .L1S33 { color: #4DA619; } .L1S52 { color: #0000FF; }
*----------------------------------------------------------------------*
* Program Name: ZKEVINA
* Project : N/A
* Author : Kevin.Zhang
* Date : 2007.1.1
* Module : N/A
* Description : Template of Program
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author Date Commented as Description
*----------- -------- ----------- ----------------------------------*
*
*----------------------------------------------------------------------*
REPORT ZKEVINA.
*$*$----------------------------------------------------------------$*$*
*$*$ Global Types, Data Statements, Ranges, Constants $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------
* data declaration
DATA : HANDLE
LIKE SY-TABIX,
BUFFER
TYPE ARC_BUFFER,
ZKEVINA_WA
LIKE ZKEVINA,
NUMBER_OF_RECORDS_READ
TYPE
I .
*$*$----------------------------------------------------------------$*$*
*$*$ Main Program $*$*
*$*$----------------------------------------------------------------$*$*
* open existing archive files
CALL
FUNCTION
'ARCHIVE_OPEN_FOR_READ'
EXPORTING
OBJECT =
'ZKEVIN'
IMPORTING
ARCHIVE_HANDLE = HANDLE
EXCEPTIONS
OTHERS =
1 .
IF SY-SUBRC <>
0 .
WRITE : /
'No file can be accessed' (
001 ).
STOP .
ENDIF .
CLEAR NUMBER_OF_RECORDS_READ.
* loop to get the next data object from the archive file(s)
DO .
CALL
FUNCTION
'ARCHIVE_GET_NEXT_OBJECT'
EXPORTING
ARCHIVE_HANDLE = HANDLE
EXCEPTIONS
END_OF_FILE =
1
OTHERS =
2 .
IF SY-SUBRC <>
0 .
EXIT .
ENDIF .
* get data records from the data container
DO .
CALL
FUNCTION
'ARCHIVE_GET_NEXT_RECORD'
EXPORTING
ARCHIVE_HANDLE = HANDLE
IMPORTING
RECORD =
BUFFER -SEGMENT
RECORD_STRUCTURE =
BUFFER -RNAME
EXCEPTIONS
END_OF_OBJECT =
1
OTHERS =
2 .
IF SY-SUBRC <>
0 .
EXIT .
ENDIF .
ADD
1
TO NUMBER_OF_RECORDS_READ.
ENDDO .
ENDDO .
WRITE : /
'Total number of records read: ' (
002 ), NUMBER_OF_RECORDS_READ.
SKIP .
WRITE /
'Last record read: ' (
003 ).
SKIP .
CASE
BUFFER -RNAME.
WHEN
'ZKEVINA' .
FIELD -SYMBOLS:
TYPE
X ,
TYPE
X .
ASSIGN ZKEVINA_WA
TO CASTING.
ASSIGN
BUFFER -SEGMENT
TO CASTING.
= .
* sbook_wa = buffer-segment.
WRITE : /
'ID :' , ZKEVINA_WA-
ID ,
/
'NAME :' , ZKEVINA_WA-NAME,
/
'...' .
* when ...
* If the archive object contained more than one table
* (different buffer-rname), more cases would be needed.
ENDCASE .
* close the archive session
CALL
FUNCTION
'ARCHIVE_CLOSE_FILE'
EXPORTING
ARCHIVE_HANDLE = HANDLE.
SAP Archiving(4)--重点
你说SAP Archiving的重点和难点是什么?是技术么?显然不是,SAP已经提供了一套相当简便的方法,还有也有很多例子可供参考。有一个很Senior的 BASIS和我说过,BASIS做多了,就成了体力活,我想这句话应该是真的。很多BASIS的活不难,但是很需要熟练度,像这个Archiving的项 目,看上去,主力是BASIS,但实际上,你只要会用几个T-code(DB02,DB15等)和一些DB上的知识,你也行。关键是人家比你更熟练,更精 通,更有经验。
虽说主要任务还是由BASIS和ABAP来承担,但是项目成败的关键还是业务,能对业务准确地分析,多久的数据是可以Archiving的?什么类型的凭 证是不能Archiving的?
我要先要把业务搞清楚了,才能往下做,我们当时做的时候就是在这方面花了很大力气。
后面就是BASIS分析好,那些表由于技术上的考虑(DB容量,系统性能等),需要Archiving。最后才是ABAP来进行实现。
可是,一个项目要成功,就需要业务、BASIS、ABAP同事做好才能行。不然,就会导致以下几种情况:
1.业务弄错了,后面都是白做
2.BASIS没分析好,该Archiving的没有做,不该做的倒做了
3.ABAP最后没有把实现好,导致最后数据错误地被Archiving,这个后果也是很严重的!
所以,一个实施好的项目,就是把一系列的做好的事情串联而成的,要重视每一个环节!
SAP Archiving(5)--很好的架构
由于这边的业务比较复杂,对需要Archiving数据做的处理也就很多。
这里我就要提到架构问题。之前写程序也没考虑到架构问题,因为大家都知道,国内做ABAP开发,程序的规模都不是很大。能在一个程序里写完的,绝对不放在 两个程序里搞定。
刚看到把一个程序搞那么复杂时,我真觉得那个美国的架构师是不是闲得没事做了,特意把简单东西复杂化了。
但实则不然。
后来在做项目过程中,慢慢发现,那样架构的优势,真的是很不错,值得国内的一些项目借鉴。下面就先写几点。
先是一个自己写的Archiving Main Menu,User Menu上挂了很多T-code,包括SAP标准的那些Archiving 工具,还有自己定制的一些工具,用起来很方便。
大量使用了function group,主程序代码量相对很少,大量地模块化。注:一个function group是可以共享全局变量的,这样每个function之间就有了联系。
使用了动态调用及Mapping技术,真的很动态,减少很多冗余代码。
......
突然觉得这种东西,还是挺值得写写的。看看人家几百个程序是怎么整合成一个应用的,我后面会慢慢总结,好东西要一口口吃,不然会噎着 的。
SAP Archiving(6)--一些补充
对之前的Archiving 做一 下补充
T-code: AOBJ ,Customizing Setting 里,有一块是’Place File in Storage System’ ,是将在SAP 文件系统中的Archive 文 件,移送到外围的Storage System 中。但是,在我参与的项目中没 有使用这个选项,而是由人工去实现移送。
Content Repository 需 要根据情况自己定义。
T-code
OAC0 定义Content Repository
OAC2 定义Document types
OAC3 定义Content Repository 的Link
SM59 定义RFC Destination for Content Sever
SAP 官方有详细的介绍:
http://help.sap.com/saphelp_47x200/helpdata/en/8d/3e4ef6462a11d189000000e8323d3a/frameset.htm
T-code SARI , 这是对Archiving 后的数据进行浏览使用的。
进入SARI 界面后Customizing->Environment->Field Catalogs 定 义与Archiving data 相应的Field Catalogs-> 回到Customizing 界 面,建立Archive Infostructure-> 回到SARI 界面,Status-> Status Per Archive/Status Per Infostructure->Fill Structures->SARI 界面,Archive Explorer-> 输入相应的选择条件,就能查询到相关Archived 数据-> 回 到SARI 界面,Status-> Status Per Archive/Status Per Infostructure->Delete Structures-> 完成一次Archive Data Explorer 。
对之前的Archiving 做 一下补充。
由于数据库中的数据做完Archiving 后, 会暂时存在SAP 服务器中,之后才会移到相应的Storage System 。
所以要对Archiving 数 据的存储路径和命名规则进行定义。
你在AOBJ->Customizing Settings 中要输入Logical File Name , 那个是在T-code: FILE 里定义的。
同时,你也可以查看Archiving 数 据是否生成在指定目录,这个T-code 是AL11
还有两个比较有用的T-code :
CG3Y 下 载服务器文件
CG3Z 上 传服务器文件
至于FILE 中如何设置的 话,大家可以参看黄佳的《SAP 业务数据传输指南》,那里讲得比较详细。
还有就是建议大家学一些BASIS的知识,这个对SAP从业人员还是很有用的。
SAP Archiving(7)--再谈架构01
之前说过一个Main Menu 的 架构,虽然实现难度不是很大,但是却可以省去用户很多麻烦。所有的T-code 都 集中在一个屏幕上,再也不用记那么多繁杂的T-code 了。
主要是在Menu Bar 里 加上相应的T-code 和描述,下面是代码的实现。很简单吧!但很实用!
*----------------------------------------------------------------------*
* Program Name: ZARCH_MAINMENU
* Project : N/A
* Author : Kevin.Zhang
* Date : 2007.1.1
* Module : N/A
* Description : Template of Program
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author Date Commented as Description
*----------- -------- ----------- ----------------------------------*
*
*----------------------------------------------------------------------*
REPORT ZARCH_MAINMENU.
*$*$----------------------------------------------------------------$*$*
*$*$ Global Types, Data Statements, Ranges, Constants $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Variables
*-----------------------------------------------------------------------
DATA : GV_TCODE
LIKE SY-TCODE.
*$*$----------------------------------------------------------------$*$*
*$*$ Main Program $*$*
*$*$----------------------------------------------------------------$*$*
*--------- START-OF-SELECTION ----------
START-
OF -SELECTION.
* Empty screen used just to display the GUI status.
CALL
SCREEN
001 .
*--------- END-OF-SELECTION ----------
END -
OF -SELECTION.
*&---------------------------------------------------------------------*
*& Module STATUS_0001 OUTPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE STATUS_0001
OUTPUT .
* Archiving Area Menu
SET
TITLEBAR
'001' .
SET PF-STATUS
'ARCHMENU' .
ENDMODULE .
" STATUS_0001 OUTPUT
*&---------------------------------------------------------------------*
*& Module USER_COMMAND_0001 INPUT
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
MODULE USER_COMMAND_0001
INPUT .
IF ( SY-UCOMM =
'BACK' )
OR ( SY-UCOMM =
'EXIT' )
OR
( SY-UCOMM =
'CANCEL' )
OR ( SY-UCOMM =
'SE38' ).
LEAVE
PROGRAM .
ELSEIF ( SY-UCOMM = SPACE ).
EXIT .
ELSE .
GV_TCODE = SY-UCOMM.
CALL
TRANSACTION GV_TCODE.
ENDIF .
ENDMODULE .
" USER_COMMAND_0001 INPUT
SAP Archiving(8)--再谈架构02
将一个功能或者模块的开发放在一个Package 里, 这是一个习惯。就如,我们把SAP Archiving 中所有的字典对象, 类,程序等都会放在一个Package 里。国内有些项目放得很随意,有根据开 发人员分Package 的,有分得很宽泛的,更有甚者随便拿了个Package 就可以你放,以为只要能传输就可以了…… 但是为了方便项目的管理和维护,我觉得还是以项目为单位比较好。特别是当一个公司模块很多,错综复杂的时候,这 样分更易维护和升级。
关于用Function Group 的 好处。前面提到要把一个项目相关的开发都要放到一个Package 以便维护, 这里有一个更进一步的,就是把相关联的Function 都放到一个Function Group 里,因为这样可以共享全局的参数,而且方便管理。
可以用以下路径访问到Function 的Function Pool: se37->function 名->Goto->Global Data/MainProgram
Global Data 是全局有效 的,Function 之间是共享的。比如一个程序调用一个function group 里的两个function ,如果这两个function 都 对一个参数进行了操作,那么这个参数会顺序改变。
如:Global Data: A = 1.
FM1: A = A + 1.
FM2: A = A + 2.
在主程序中Call FM1 : A = 1 + 1 = 2
Call FM2 : A = 2 + 2 = 4
所以使用这种方式写的话,要当心全局变量的赋值。
SAP Archiving(9)--再谈架构03
这里我们聊一下动态调用和Mapping 。
作为一个比较大型的应用,动态调用和Mapping 是 必不可少的,有了这两样法宝,可以减少很多冗余代码,同时也简化日后维护。
下面给一个例子:分两部分,一个是function group ,另一个运行用的report
Function pool: SAPLZKEVIN_A
*******************************************************************
* System-defined Include-files. *
*******************************************************************
INCLUDE LZKEVIN_ATOP. " Global Data
INCLUDE LZKEVIN_AUXX. " Function Modules
*******************************************************************
* User-defined Include-files (if necessary). *
*******************************************************************
* INCLUDE LZKEVIN_AF. " Subprograms
* INCLUDE LZKEVIN_AO... " PBO-Modules
* INCLUDE LZKEVIN_AI... " PAI-Modules
INCLUDE LZKEVIN_AF01.
*INCLUDE LZKEVIN_AF02.
INCLUDE LZKEVIN_AF02.
LZKEVIN_AF01
*----------------------------------------------------------------------*
***INCLUDE LZKEVIN_AF01 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form CHECK_02
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM CHECK_02 .
WRITE / 'CHECK_02' .
ENDFORM . " CHECK_02
*&---------------------------------------------------------------------*
*& Form CHECK_03
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM CHECK_03 .
WRITE / 'CHECK_03' .
ENDFORM . " CHECK_03
LZKEVIN_AF02
*----------------------------------------------------------------------*
***INCLUDE LZKEVIN_AF02 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*& Form CHECK_01
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
* --> p1 text
* <-- p2 text
*----------------------------------------------------------------------*
FORM CHECK_01 .
WRITE / 'CHECK_01' .
ENDFORM . " CHECK_01
Report
*----------------------------------------------------------------------*
* Program Name: Z_KEVIN_ARCH
* Project : N/A
* Author : Kevin.Zhang
* Date : 2007.1.1
* Module : N/A
* Description : Template of Program
*
*
*
* Special features: N/A
*
*
*----------------------------------------------------------------------*
* Modifications:
* Author Date Commented as Description
*----------- -------- ----------- ----------------------------------*
*
*----------------------------------------------------------------------*
REPORT Z_KEVIN_ARCH.
*$*$----------------------------------------------------------------$*$*
*$*$ Global Types, Data Statements, Ranges, Constants $*$*
*$*$----------------------------------------------------------------$*$*
*-----------------------------------------------------------------------
* Internal Tables and Work Areas
*-----------------------------------------------------------------------
DATA GS_CHECK TYPE ZCHECK.
DATA GT_CHECK TYPE TABLE OF ZCHECK.
DATA GS_ZKEVINA TYPE ZKEVINA.
DATA GT_ZKEVINA TYPE TABLE OF ZKEVINA.
*$*$----------------------------------------------------------------$*$*
*$*$ Main Program $*$*
*$*$----------------------------------------------------------------$*$*
SELECT * FROM ZKEVINA
INTO TABLE GT_ZKEVINA
WHERE ID = '1' .
SELECT * FROM ZCHECK
INTO TABLE GT_CHECK.
SORT GT_CHECK BY SEQ.
LOOP AT GT_ZKEVINA INTO GS_ZKEVINA.
READ TABLE GT_CHECK INTO GS_CHECK WITH KEY ID = GS_ZKEVINA-ID .
IF ( SY-SUBRC = 0 ).
LOOP AT GT_CHECK INTO GS_CHECK WHERE ID = GS_ZKEVINA-ID .
PERFORM (GS_CHECK-CHECK_ROUTINE) IN PROGRAM SAPLZKEVIN_A.
ENDLOOP .
ENDIF .
ENDLOOP .
表结构:
ZCHECK
MANDT MANDT CLNT 3 0 Client
ID CHAR 4 0
SEQ NUMC3 NUMC 3 0 Numc3, internal use
CHECK_ROUTINE CHAR30 CHAR 30 0 30 Characters
ZKEVINA
ID CHAR 4 0 ID
NAME CHAR 20 0 Name