Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

templates in ABAP

Former Member
0 Kudos

Hi,

I want a brief introduction to templates in ABAP.

I need to write a template which shall generate dynamic code. I am very new to this template concept in ABAP. Could some one please provide me good documents on how to write a template in ABAP or/and provide a simple sample program?

Regards,

Ravi

8 REPLIES 8

jayanthi_jayaraman
Active Contributor

Former Member
0 Kudos

Hi,

I am very badly in need of information regarding writing a template in ABAP.

Please provide me a simple sample program.

What is the meaning of *@ in a template????

Why is it used?

How do I generate code dynamically using a template?

Please answer and help me...

Regards,

Ravi

0 Kudos

Hi,

I am not sure whether you are looking for this.

Basically, to generate persistent programs you can use:

INSERT REPORT <prog> FROM <itab>.

e.g.

REPORT dynamic_program_generation .

DATA: lt_code TYPE TABLE OF rssource-line.

APPEND 'REPORT ZMY_DYN_PROG.' TO lt_code.

APPEND 'WRITE / ''Hello, I am dynamically created!''.' TO lt_code.

INSERT REPORT 'ZMY_DYN_PROG' FROM lt_code.

For temporary program generation, you can use

GENERATE SUBROUTINE POOL <itab> NAME <prog> [<options>].

For more information, you can refer to F1 help for GENERATE and INSERT statements.

Former Member
0 Kudos

Hi, not clear what's the template you mean here.

Can you explain the meaning in details for us?

Thanks a lot

0 Kudos

Hi Z gu,

The template I mean here is a program(generic code) which shall generate code dynmically.

Depending on the input that the program gets, it has to generate code dynamically.

Regards,

Ravi

0 Kudos

following is a template for example:

@--Template for generating CDS_READ_SERVICE--


*@

*@

*@ DATA: LT_SEGM TYPE SMMW_CDS_SEGM_TTYP.

*@ DATA: LT_MAPP TYPE SMMW_CDS_MAPP_TTYP.

*@ DATA: WA_SEGM TYPE SMMW_CDS_SEGM.

*@ DATA: WA_MAPP TYPE SMMW_CDS_MAPP.

*@ DATA: LS_HDR TYPE MSB_HEADER.

*@ DATA: LS_MBOINFO TYPE SMMW_CDS_MBO_INFO.

*@ DATA: META_OBJ TYPE SMMW_GUID.

*@ DATA: msg_strname(40) TYPE C.

*@ DATA: memodblbin(40) TYPE C,

*@ memodbltxt(40) TYPE C.

*@

*@ META_OBJ = I_META_OBJECT(32).

*@

*@

@ get MBO structure,version and sw component name

*@

*@ CALL FUNCTION 'MSB_GET_MBO_HEADER_INFO'

*@ EXPORTING

*@ IM_MBO_VERSION_ID = META_OBJ

*@ IMPORTING

*@ EX_MBO_HEADER = LS_HDR

*@ EXCEPTIONS

*@ MISSING_IMPORT_PARAMETER = 1

*@ NO_SUCH_MBO = 2

*@ MORE_THAN_ONE_MBO = 3

*@ OTHERS = 4

*@ .

*@ IF SY-SUBRC <> 0.

*@ MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

*@ WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

*@ ENDIF.

*@

@ get MBO information by calling API SMMW_CDS_GET_MBODATA

*@

*@ CALL FUNCTION 'MMW_CDS_GET_MBODATA'

*@ EXPORTING

*@ I_MBO_TRANS = META_OBJ

*@ IMPORTING

*@ SEGM_TAB = LT_SEGM

*@ MAPP_TAB = LT_MAPP

*@ MBO_INFO = LS_MBOINFO

*@ EXCEPTIONS

*@ MBO_ID_IS_INITIAL = 1

*@ PARENT_SEGMENT_NOT_FOUND = 2

*@ OTHERS = 3

*@ .

*@

*@ IF SY-SUBRC <> 0.

*@ MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

*@ WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

*@ ENDIF.

*@ msg_strname = LS_MBOINFO-MESGSTR_NAME.

*@ memodblbin = LS_MBOINFO-BMEMTABLE_NAME.

*@ memodbltxt = LS_MBOINFO-TMEMTABLE_NAME.

*----


  • CDS READ SERVICE

*----


  • This method has been generated

  • Never change it manually, please!!

*

  • Transaction: \LS_HDR-NAME\

  • Template : \I_TEMPLATE\

  • GenKey : CDS_READ_SERVICE

*

  • Generated on \SY-DATUM\ \SY-UZEIT\

  • by \SY-UNAME\

*----


CONSTANTS: LC_INSERT VALUE 'I',

LC_UPDATE VALUE 'U',

LC_DELETE VALUE 'D'.

DATA: LT_OBJ_LIST TYPE EXTRACTKEY_TT.

DATA: WA_OBJ_LIST TYPE SMMW_EXTRACTKEY.

DATA: LV_COUNT TYPE INT4.

DATA: RECORDS_NOT_FOUND TYPE BOOL VALUE ' '.

CONSTANTS: lv_sendbits(32) TYPE x VALUE

'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'.

*@ IF LS_HDR IS NOT INITIAL.

DATA: MBO_STR TYPE \msg_strname\.

*@ IF LT_SEGM IS NOT INITIAL.

*@ LOOP AT LT_SEGM INTO WA_SEGM.

  • declaring tables and workareas for segment : \WA_SEGM-SEGM_NAME\

DATA: LT_T\WA_SEGM-TABLENAME\ TYPE TABLE OF \WA_SEGM-TABLENAME\.

DATA: WA_T\WA_SEGM-TABLENAME\ TYPE \WA_SEGM-TABLENAME\.

DATA: WA_S\WA_SEGM-GEN_NUM\ TYPE \WA_SEGM-SEGM_STR\.

*@ ENDLOOP.

  • copy the extract key table to a local internal table.

LT_OBJ_LIST[] = OBJ_LIST[].

IF LT_OBJ_LIST IS INITIAL.

*...handle log here........

EXIT.

ELSE.

  • sort the table to delete adjacent duplicate entries

SORT LT_OBJ_LIST BY EXTRACTKEY.

  • delete the duplicate entries from the table before processing

DELETE ADJACENT DUPLICATES

FROM LT_OBJ_LIST

COMPARING EXTRACTKEY.

DESCRIBE TABLE LT_OBJ_LIST LINES LV_COUNT.

IF task EQ LC_DELETE OR task EQ LC_UPDATE.

IF LV_COUNT GT 1.

*.....bulk message is only for task 'I' not for task 'U' or 'D'.

*.....Hadle log here.....

OBJ_MISS[] = LT_OBJ_LIST[].

EXIT.

ENDIF.

ENDIF.

IF TASK EQ LC_DELETE.

  • prepare MBO message for the Extract keys whose task is DELETE

*@ LOOP AT LT_SEGM INTO WA_SEGM WHERE HIERARCHY EQ 1.

@ if the segment is root segment only.

LOOP AT LT_OBJ_LIST INTO WA_OBJ_LIST.

WA_S\WA_SEGM-GEN_NUM\-TASK = TASK.

WA_S\WA_SEGM-GEN_NUM\-\WA_SEGM-KEYFIELD\ =

WA_OBJ_LIST-EXTRACTKEY.

WA_S\WA_SEGM-GEN_NUM\-EXTRACTKEY =

WA_OBJ_LIST-EXTRACTKEY.

APPEND WA_S\WA_SEGM-GEN_NUM\ TO MBO_STR-\WA_SEGM-SEGM_NAME\.

ENDLOOP.

*@ ENDLOOP.

  • task is not 'D'.

ELSE.

*@ SORT LT_SEGM BY HIERARCHY.

*@ LOOP AT LT_SEGM INTO WA_SEGM.

*----


  • select statement to fill segment: \WA_SEGM-SEGM_NAME\

*----


*@ IF WA_SEGM-HIERARCHY NE 1.

IF RECORDS_NOT_FOUND IS INITIAL.

*@ ELSE.

DESCRIBE TABLE LT_OBJ_LIST LINES LV_COUNT.

*@ ENDIF.

SELECT * INTO TABLE LT_T\WA_SEGM-TABLENAME\

FROM \WA_SEGM-TABLENAME\

FOR ALL ENTRIES IN LT_OBJ_LIST

@ For root segment compare extractkey with synckey

*@ IF WA_SEGM-HIERARCHY = 1.

WHERE \WA_SEGM-KEYFIELD\ = LT_OBJ_LIST-EXTRACTKEY.

@ For other than root segments compare extractkey with

@ extractkey only.

*@ ELSE.

WHERE EXTRACTKEY = LT_OBJ_LIST-EXTRACTKEY.

*@ ENDIF.

*@ IF WA_SEGM-HIERARCHY = 1.

IF SY-SUBRC <> 0.

  • all the extractkeys are invalid hence send all to OBJ_MISS.

OBJ_MISS[] = LT_OBJ_LIST[].

RECORDS_NOT_FOUND = 'X'.

ELSEIF LV_COUNT NE SY-DBCNT.

  • Not all the keys are invalid.atleast one key is invalid.

*@ LOOP AT LT_MAPP INTO WA_MAPP

*@ WHERE SEGM_NAME = WA_SEGM-SEGM_NAME AND IS_SYNCKEY EQ 'X'.

LOOP AT LT_OBJ_LIST INTO WA_OBJ_LIST.

READ TABLE LT_T\WA_SEGM-TABLENAME\

WITH KEY \WA_MAPP-SFLD_NAME\ = WA_OBJ_LIST-EXTRACTKEY

TRANSPORTING NO FIELDS.

*@ ENDLOOP.

IF SY-SUBRC <> 0.

APPEND WA_OBJ_LIST TO OBJ_MISS.

ENDIF.

ENDLOOP.

ENDIF.

*@ ENDIF.

  • process all the records to set the value for task field.

IF LT_T\WA_SEGM-TABLENAME\ IS NOT INITIAL.

IF task EQ LC_UPDATE.

WA_S\WA_SEGM-GEN_NUM\-SENDBITS = lv_sendbits.

ENDIF.

WA_S\WA_SEGM-GEN_NUM\-TASK = TASK.

LOOP AT LT_T\WA_SEGM-TABLENAME\ INTO WA_T\WA_SEGM-TABLENAME\.

move-corresponding WA_T\WA_SEGM-TABLENAME\

to WA_S\WA_SEGM-GEN_NUM\.

*@ LOOP AT LT_MAPP INTO WA_MAPP

*@ WHERE SEGM_NAME = WA_SEGM-SEGM_NAME AND IS_MEMO NE SPACE.

IF wa_t\wa_segm-tablename\-\wa_mapp-sfld_name\ IS NOT INITIAL.

*@ IF WA_MAPP-IS_MEMO EQ 'T'.

  • select the text memo content from the db table

SELECT SINGLE CONTENT

FROM \memodbltxt\

INTO WA_S\WA_SEGM-GEN_NUM\-\WA_MAPP-SFLD_NAME\

WHERE tablename = '\WA_SEGM-TABLENAME\' AND

tablekey = WA_T\WA_SEGM-TABLENAME\-\WA_SEGM-KEYFIELD\ AND

tablefield = '\WA_MAPP-SFLD_NAME\'.

*@ ELSEIF WA_MAPP-IS_MEMO EQ 'B'.

  • select the binary memo content from the db table

SELECT SINGLE CONTENT

FROM \memodblbin\

INTO WA_S\WA_SEGM-GEN_NUM\-\WA_MAPP-SFLD_NAME\

WHERE tablename = '\WA_SEGM-TABLENAME\' AND

tablekey = WA_T\WA_SEGM-TABLENAME\-\WA_SEGM-KEYFIELD\ AND

tablefield = '\WA_MAPP-SFLD_NAME\'.

*@ ENDIF.

ENDIF.

*@ ENDLOOP.

APPEND WA_S\WA_SEGM-GEN_NUM\ TO MBO_STR-\WA_SEGM-SEGM_NAME\.

ENDLOOP.

ENDIF. " table LT_T\WA_SEGM-TABLENAME\ not initial.

*@ IF WA_SEGM-HIERARCHY NE 1.

ENDIF.

*@ ENDIF.

*@ ENDLOOP.

ENDIF.

ENDIF. " Object list not initial.

*@ LOOP AT LT_SEGM INTO WA_SEGM WHERE HIERARCHY EQ 1.

IF MBO_STR-\WA_SEGM-SEGM_NAME\ IS NOT INITIAL.

MBO_MESSAGE = MBO_STR.

  • Filling Header of the MBO message if it is not empty.

DESCRIBE TABLE MBO_STR-\WA_SEGM-SEGM_NAME\ LINES LV_COUNT.

*@ ENDLOOP.

CALL FUNCTION 'SYSTEM_UUID_C_CREATE'

IMPORTING

uuid = MBO_COMM_HEADER-MESSAGE_ID.

MBO_COMM_HEADER-SWCV_NAME = '\LS_HDR-SWCV_NAME\'.

MBO_COMM_HEADER-VERSION = '\LS_HDR-VERSION\'.

MBO_COMM_HEADER-MBO_NAME = '\LS_HDR-NAME\'.

  • GET TIME STAMP FIELD MBO_COMM_HEADER-SEND_TSTMP.

  • This vale SEND_TSTMP filling involves some problem...

MBO_COMM_HEADER-SEND_USR = SY-UNAME.

IF LV_COUNT EQ 1.

MBO_COMM_HEADER-MESSAGE_TYPE = 'I'.

READ TABLE OBJ_LIST INDEX 1 INTO WA_OBJ_LIST.

IF SY-SUBRC = 0.

MBO_COMM_HEADER-EXTRACT_KEY = WA_OBJ_LIST-EXTRACTKEY.

ENDIF.

ELSE.

MBO_COMM_HEADER-MESSAGE_TYPE = 'B'.

ENDIF.

ENDIF.

*@ ENDIF.

*@ ENDIF.

I dont understand the notation *@ here...

Why is it used??

Regards,

Ravi

Former Member
0 Kudos

Hi Ravi

I studied about dynamic program generation some time back in a book which i'm not currently having.

But as far as i remember, we add the code of the program that is to be generated at run time, in an internal table.

And, for generating the program, we use the statement with syntax:

GENERATE SUBROUTINE POOL <itab> NAME <prog> [<options>].

I found something helpful for you, have a look ate the following links:

http://help.sap.com/saphelp_47x200/helpdata/en/9f/db999535c111d1829f0000e829fbfe/frameset.htm

http://help.sap.com/saphelp_47x200/helpdata/en/9f/db996e35c111d1829f0000e829fbfe/content.htm

I hope it will solve your problem, if required i will send you a sample code (but i need a little bit time for it).

Regards

Ashish

andreas_mann3
Active Contributor
0 Kudos

Hi Ravi,

i think you mean <a href="http://help.sap.com/saphelp_47x200/helpdata/en/d1/801aaf454211d189710000e8322d00/frameset.htm">pattern</a>

here's another (only in german) <a href="http://www.tricktresor.de/content/index.php?navID=168&aID=96">tricktresor</a>

regards Andreas