GRC
HR
SCM
CRM
BI
Expand +


Article

 

Solve Simple Problems Using Simple Transformation

by Rehan Zaidi, Senior SAP Technical Consultant

June 4, 2018

Learn about the basics of Simple Transformation, the main Simple Transformation commands, and the steps required to create Simple Transformations for structures and internal tables. See how to download internal table ABAP data into a Microsoft Excel format using a sample Simple Transformation.

Simple Transformation is a meta-language allowing conversion of XML to ABAP and vice versa. If used wisely, it can solve requirements such as allowing developers to export data from an SAP system into Microsoft Excel in complex formats.

My aim is to provide an explanation of Simple Transformations and their benefits. I start with a brief overview of Simple Transformations and then describe the steps needed to create them and the syntax used for calling these transformations in ABAP. Included are transformations for structures and internal tables as well as serialization and de-serialization of ABAP and XML, and the graphical editor for defining transformations. An example of a transformation shows how to download data into a Microsoft Excel file in a sophisticated format.

The screenprints are from an SAP NetWeaver 7.50 system.

Simple Transformation: An Overview

The conversion of ABAP data into an XML format is known as serialization, and the reverse process of converting XML data into ABAP data objects is known as deserialization. You use the statement CALL TRANSFORMATION to call transformations from within ABAP programs. Simple Transformations are created using transaction code XSLT_TOOL.

To get an idea of how this would look, consider the Simple Transformation DEMO_ST_PROGRAM shown in Figure 1.


Figure 1
A sample Simple Transformation

On the first line, the SAP system adds a line <?sap.transform simple?> when a new transformation is created. The < and > contains the XML elements. There are two types of XML elements: namely Simple Transformation commands and literal XML elements.

Simple Transformation commands are meant to fulfill a specific purpose. Some examples of Simple Transformation commands are tt:template, tt:root, and tt:transform. As you see, these begin with the prefix tt.

Literal XML elements: Components of XML other than Simple Transformation commands are called literal elements. They have no meaning within the Simple Transformation language.

A Simple Transformation program contains the template tt:template, which specifies the block used for determining how to create the XML document from the ABAP data objects at the time of serialization or how to extract ABAP data from an XML document at the time of deserialization.

The template may also contain subtemplates. Within the Simple Transformation program, there are data roots. The data roots are interfaces for data transformation during serialization and deserialization. In order for data conversion to take place and ABAP data to be used, the transformation code must include at least one root element.

Now that you have an idea of how Simple Transformation works, let’s look at how the data is represented. There are three basic commands used for representing data: tt:value, tt:loop, and tt:template. The Simple Transformation command tt:value is used for representing data fields and field structures, and tt:loop lets you enable the serialization of internal tables.

A tt:template specifies a template within the transformation. This may or may not have a name.  A Simple Transformation program must have at least one template. There has to be a main template within the transformation. Simple Transformation commands and literal XML elements can be within the template. The main template within the program denotes the anatomy of the XML string into which the ABAP data is to be serialized, or from which the deserialization is to take place.

Create a Simple Transformation

Now I show you how to create a very “simple” Simple Transformation. In this example, there is no data root; instead, this transformation consists of only literal elements. You always need to have at least a single root element for the transformation to be able to receive data from an ABAP program and convert it to XML. Transformations can have no root elements, but in this case no ABAP data conversion is possible.  

Execute transaction code XSLT_TOOL. In the screen that appears (Figure 2), enter a name in the Transformation field. Click the Create button.


Figure 2
Enter a name in the Transformation field of the XSLT_TOOL screen

This action displays a dialog box (Figure 3).


Figure 3
The dialog box to create a Simple Transformation

Enter a short description and choose the transformation type Simple Transformation. Then press Enter. This action opens the screen in Figure 4. Click the SourceCde (source code) tab to see the editor containing the basic coding of the newly created transformation.


Figure 4
Create a transformation

Now let’s write some code in the newly created Simple Transformation. You delete the root element. By default there is a single root element added by the SAP system, but you need to delete it for my simple requirement, as it is not needed. Then add literal elements as well as two literal texts, one with identification and one without identification (Figure 5).

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

<tt:template>
  <Y0>
    <Y1> this line 1 </Y1>
    <Y2> <tt:text> this is line 2 </tt:text> </Y2>
  </Y0>
</tt:template>
Figure 5
A Simple Transformation

Here you have the literal element Y0, which has literal elements Y1 and Y2. The literal element Y1 has literal text without identification. On the other hand, the literal element Y2 has text with identification (using <tt:text> and </tt:text>).

This transformation now has no root element. This means that any data object (from the ABAP program) may be passed to it, but when the transformation is serialized, it will have no effect. Once you serialize the transformation, the XML looks like the code shown in Figure 6.

<Y0>

    <Y1> this is line 1 </Y1>

    <Y2> this is line 2 </Y2>

</Y0>

Figure 6
Serialized transformation

For a better example in which literal text has identification features, consider the Simple Transformation shown in Figure 7.

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

<tt:template>
  <Y0>
    <Y1> this line 1 </Y1>
    <Y2> <tt:text>           </tt:text> </Y2>
    <Y3>                                </Y3>
  </Y0>
</tt:template>

</tt:transform>

Figure 7
Another transformation example

You see elements Y2 and Y3. Y3 lacks identification, whereas Y2 has identification (i.e.,    tt:text). Both Y2 and Y3 contain blank spaces. However, the resulting XML string shows different content for Y2 and Y3 within the debugger as shown in Figure 8. For element Y3, the blank spaces are retained, but for Y2, they are not.


Figure 8
The resulting XML string

Structure Transformations

Now let’s look at the steps needed to create a Simple Transformation that is based on a nested structure declared in an ABAP program. In this section, I first create the structure transformation and then call it within an ABAP program using the CALL TRANSFORMATION statement. I pass a filled ABAP structure that corresponds to the root element defined in the transformation. This then converts the SAP data to XML.

Follow these steps:

1. Execute transaction code XSLT_TOOL. In the screen that the system opens (refer back to Figure 2), enter a suitable name in the Transformation field (in my example, ZST1_TEST) and click the Create button. In the dialog box that appears (refer to Figure 3), choose Simple Transformation and press Enter. Type the code shown in the Transformation Editor (Figure 9).

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
<tt:root name="OUTER_STRUCT"/>
<tt:template>
  <Y0>
    <Y1>
        <tt:value ref ="OUTER_STRUCT.COL1"/>
    </Y1>

    <Y2>
       <Y3>
        <tt:value ref ="OUTER_STRUCT.INNER_STRUCT.COL1"/>
       </Y3>

       <Y4>
        <tt:value ref ="OUTER_STRUCT.INNER_STRUCT.COL2"/>
       </Y4>

    </Y2>
   </Y0>
</tt:template>
</tt:transform>
Figure 9
Structure transformation

2. Enter the code on the Source Code tab, then activate it using the Activate button.

3. Now create the ABAP program to call the Simple Transformation. The code of this program is shown in Figure 10.

data xml type string.

data : begin of outer_struct ,
         col1 type c length 20,
         begin of inner_struct,
           col1 type c length 20,
           col2 type c length 20,
         end of inner_struct,
       end of outer_struct.

Figure 10
Declaration of the structure

Here, there is a nested structure OUTER_STRUCT that contains field COL1. It also contains an inner structure that consists of two fields, COL1 and COL2.

4. Now, write the code to fill the structure with data (Figure 11). 

outer_struct-col1 = 'John'.
outer_struct-inner_struct-col1 = 'will'.
outer_struct-inner_struct-col2 = 'come'.
Figure 11
Add data to OUTER_STRUCT

5. Declare a string by the name xml and use the CALL transformation statement. You pass the structure OUTER_STRUCT to the transformation and get the resulting XML in the string XML (Figure 12).

call transformation zst1_test
source outer_struct = outer_struct
result xml = xml.
Figure 12
Call transformation statement

The structure of the program (OUTER_STRUCT) is passed during serialization to the transformation via the root element outer_struct. The Y2 literal element of the transformation corresponds to the inner_struct structure in outer_struct. (Note that there is an inner_struct in a transformation and an INNER_STRUCT in a program.)

You have passed the filled ABAP structure OUTER_STRUCT as the SOURCE structure. This is serialization. The string XML can then be displayed in the ABAP debugger (Figure 13).


Figure 13
Generated XML file

Transformations for Internal Tables

So far, you have seen transformations pertaining to structures as well as to single fields. You can also create a transformation for an internal table using the Transformation Editor. To demonstrate, I first create a transformation (based on an internal table) and then create a program to call the internal table transformation and pass the data to generate an XML string. You have an internal table called MYITAB that comprises two fields, MYFIELD1 and MYFIELD2.

First, create a Simple Transformation using the procedure shown earlier in the article. Enter code in the editor as shown in Figure 14.

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

  <tt:root name="MYITAB"/>
  <tt:template>
    <int_table>
      <tt:loop ref=".MYITAB">
        <row>
          <column1>
            <tt:value ref="MYFIELD1"/>
          </column1>
          <column2>
            <tt:value ref="MYFIELD2"/>
          </column2>
        </row>
      </tt:loop>
    </int_table>
  </tt:template>
</tt:transform>
Figure 14
Internal table transformation

So far, the transformation has a root element denoting the internal table MYITAB. The XML element <int_table> is used inside a template. Use the tt:loop command to loop at each line of the internal table MYITAB and use ref=".MYITAB" to address the current node.

For each internal table line, the XML element <row> is included in the generated XML.

The XML element <row> is used to denote a single line. Within <row>, there are XML elements column1 and column2, within which the MYFIELD1 and MYFIELD2 fields of the internal table of a particular line of the table are written.

Now create a simple program that declares an internal table based on the transformation you have just created. This program also calls the transformation and supplies it with the internal table data. The internal table it_emp is composed of the fields field1 and field2. It is filled with the relevant data as shown in Figure 15.

data : begin of myitab occurs 0,
         myfield1 type c length 20,
         myfield2 type c length 20,
       end of myitab.

myitab-myfield1 = 'John'.
myitab-myfield2 = 'Terry'.
append myitab.

myitab-myfield1 = 'James'.
myitab-myfield2 = 'Fernando'.
append myitab.
Figure 15
Internal table declaration and population of data

Finally, call the CALL TRANSFORMATION statement, and the internal table is passed as a value. As you can see, the result is stored in the string my_xml_string (Figure 16).

data xml type string.
call transformation zst1_test
source myitab = myitab[]
result xml xml.
break student001.
Figure 16
CALL TRANSFORMATION statement

After the serialization, the XML string is as shown in Figure 17.


Figure 17
Serialized internal table data

Graphical Generation of Transformation of Dictionary Types

You can also create or generate transformations for table types or structures found in the ABAP Dictionary, using the graphical Transformation Editor in the XSLT_TOOL. The advantage of the graphical editor is that it allows quick generation of a transformation via simple drag-and-drop operations, and it saves you from writing lengthy Simple Transformation code.

First, create a table type via transaction code SE11 and name this table ZST1_TT_EMP. It consists of an employee number (PERNR), employee name (NAME), and city (CITY). The line type for this table type is ZST1_ST_EMP. Enter this name in the Data Type field and click the Create button. Choose the Structure option from the box that appears.

Specify the fields of the line type. These are PERNR, NAME, and CITY, based on the data elements PERSNO, EMNAM, and ORT01, respectively.

Next, create a table type by the name ZST1_TT_EMP. It is important that you specify the line type created earlier as the line type for this table type.

Now that you have created the line type, use the XSLT_TOOL and generate a corresponding transformation. To do this:

1. Execute transaction code XSLT_TOOL and create a Simple Transformation as shown earlier.

2. In the transformation Edit mode, click the edit transformation graphically icon ( ) on the toolbar. This action takes you to the Transformation Editor (Figure 18).


Figure 18
The graphical Transformation Editor

3. From the left pane, click the ROOT node, and from the context menu, choose Insert New Root. This action displays the dialog box shown in Figure 19.


Figure 19
Insert a new root

4. Enter ITAB1 and ZST1_TT_EMP in the Root-Name and Type-Name fields, respectively. (You can also enter the line type ZST1_ST_EMP created in the Type-Name field and click the Line-Type? check box.) Press Enter. This adds an ITAB1 table to the DATA roots (Figure 20).


Figure 20
Data roots

Drag and drop the ITAB1 node to the right pane.

An ITAB1 node (along with components) now appears in the right pane, as shown in Figure 21.


Figure 21
The ITAB1 node

5. Make slight adjustments to the nodes. Delete the ROOT node from the left pane so that only ITAB1 remains.

To summarize: You created a new Simple Transformation and then inserted a root element named ITAB1 based on the dictionary type ZST1_TT_EMP. You then dragged and dropped it to include the table type and components in the transformation. This step generated the transformation, the code of which is shown in Figure 22.

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates" xmlns:ddic="http://www.sap.com/abapxml/types/dictionary" xmlns:def="http://www.sap.com/abapxml/types/defined">
  <tt:root name="ITAB1" type="ddic:ZST1_TT_EMP"/>
  <tt:template>
    <ITAB1>
      <tt:loop ref=".ITAB1">
        <ZST1_ST_EMP>
          <PERNR tt:value-ref="PERNR"/>
          <NAME tt:value-ref="NAME"/>
          <CITY tt:value-ref="CITY"/>
        </ZST1_ST_EMP>
      </tt:loop>
    </ITAB1>
  </tt:template>
</tt:transform>
Figure 22
Generated transformation code

As you will see, within the template a loop is executed for each line of table ITAB1. The data content of the PERNR, NAME, and CITY are valid in the XML element ZT1_ST_EMP (the line type you created earlier). The complete graphical format of the transformation is shown in Figure 23.


Figure 23
The completed visual transformation

This transformation can then be called from ABAP programs using CALL TRANSFORMATION. 

Downloading into Excel—Simplified

In this final section, you see how to use Simple Transformation to download data residing in internal tables into an Excel format. You can create an Excel file with colored headings having a number of fonts and font sizes. 

(Note: The focus of this section is to create an XML string corresponding to the Excel data in XML format. The transformation serves as a template for downloading data from the SAP system into an Excel file format. Suppose you need to download the fields shown in Figure 24 into Excel.)


Figure 24
A sample download file

The transformation provided in the code shown in Figure 25 is based on this example, but you can change it to tailor it to any of your requirements or fields and columns. The fields used here are personnel number, employee name, and country of birth.

<?sap.transform simple?>

<tt:transform xmlns:tt="http://www.sap.com/transformation-templates">

  <?mso-application progid="Excel.Sheet"?>

  <tt:root name="table"/>

  <tt:template>

    <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html=

"http://www.w3.org/TR/REC-html40">

      <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">

        <Created>2006-09-16T00:00:00Z</Created>

        <LastSaved>2016-10-03T13:49:23Z</LastSaved>

        <Version>15.00</Version>

      </DocumentProperties>

      <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">

        <AllowPNG/>

        <RemovePersonalInformation/>

      </OfficeDocumentSettings>

      <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">

        <WindowHeight>8010</WindowHeight>

        <WindowWidth>14805</WindowWidth>

        <WindowTopX>240</WindowTopX>

        <WindowTopY>105</WindowTopY>

        <ProtectStructure>False</ProtectStructure>

        <ProtectWindows>False</ProtectWindows>

      </ExcelWorkbook>

      <Styles>

        <Style ss:ID="Default" ss:Name="Normal">

          <Alignment ss:Vertical="Bottom"/>

          <Borders/>

          <Font ss:Color="#000000" ss:FontName="Calibri" ss:Size="11" x:Family="Swiss"/>

          <Interior/>

          <NumberFormat/>

          <Protection/>

        </Style>

        <Style ss:ID="s62">

          <Font ss:Color="#FF0000" ss:FontName="Calibri" ss:Size="11" x:Family="Swiss"/>

        </Style>

        <Style ss:ID="s77">

          <Font ss:Bold="1" ss:Color="#FFFFFF" ss:FontName="Arial" ss:Size="13" x:Family="Swiss"/>

          <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>

        </Style>

        <Style ss:ID="s78">

          <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>

          <Font ss:Bold="1" ss:Color="#FFFFFF" ss:FontName="Arial" ss:Size="13" x:Family="Swiss"/>

          <Interior ss:Color="#FF0000" ss:Pattern="Solid"/>

        </Style>

        <Style ss:ID="s79">

          <Font ss:Color="#000000" ss:FontName="Calibri" ss:Size="13" x:Family="Swiss"/>

        </Style>

      </Styles>

      <Worksheet ss:Name="Sheet1">

 

        <Table ss:DefaultRowHeight="15" ss:ExpandedColumnCount="6"  x:FullColumns="1" x:FullRows="1">

          <Column ss:Index="2" ss:Width="84.75"/>

          <Column ss:AutoFitWidth="0" ss:Width="109.5"/>

          <Column ss:Span="1" ss:Width="104.25"/>

          <Row ss:Height="16.5" ss:Index="2">

            <Cell ss:Index="1" ss:StyleID="s78">

              <Data ss:Type="String">Staff Number</Data>

            </Cell>

            <Cell ss:StyleID="s78">

              <Data ss:Type="String">Name</Data>

            </Cell>

            <Cell ss:StyleID="s77">

              <Data ss:Type="String">Country of Birth</Data>

            </Cell>

          </Row>

 

          <tt:loop ref=".table">

 

            <Row ss:Height="17.25">

              <Cell>

                <Data ss:Type="Number">

                  <tt:value ref="PERNR"/>

                </Data>

              </Cell>

              <Cell>

                <Data ss:Type="String">

                  <tt:value ref="NAME"/>

                </Data>

              </Cell>

              <Cell>

                <Data ss:Type="String">

                  <tt:value ref="COUNTRY"/>

                </Data>

              </Cell>

            </Row>

 

          </tt:loop>

 

        </Table>

        <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">

          <PageSetup>

            <Header x:Margin="0.3"/>

            <Footer x:Margin="0.3"/>

            <PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>

          </PageSetup>

          <Print>

            <ValidPrinterInfo/>

            <HorizontalResolution>-3</HorizontalResolution>

            <VerticalResolution>0</VerticalResolution>

          </Print>

          <Selected/>

          <Panes>

            <Pane>

              <Number>3</Number>

              <ActiveRow>12</ActiveRow>

              <ActiveCol>2</ActiveCol>

            </Pane>

          </Panes>

          <ProtectObjects>False</ProtectObjects>

          <ProtectScenarios>False</ProtectScenarios>

        </WorksheetOptions>

      </Worksheet>

    </Workbook>

  </tt:template>

</tt:transform>

Figure 25
Simple Transformation for an employee sample file

To use this transformation, create a Simple Transformation using transaction code XSLT_TOOL. Then, paste the code of the transformation at the link. The transformation at the link is shown in Figure 26.


Figure 26
Downloaded Simple Transformation

Save and activate the transformation by pressing Ctrl F3.

Let’s take a careful look at the downloaded transformation to understand its major parts. A root element table is at the beginning of the transformation, prior to the tt:template command. The transformation contains tt:loop. As mentioned earlier, the loop iterates over every line of the internal table "table". The contents of the fields PERNR, NAME, and COUNTRY are displayed in the element <Cell> for each <Row> (Figure 27).

……..

          <tt:loop ref=".table">
            <Row ss:Height="17.25">
              <Cell>
                <Data ss:Type="Number">
                  <tt:value ref="PERNR"/>
                </Data>
              </Cell>
              <Cell>
                <Data ss:Type="String">
                  <tt:value ref="NAME"/>
                </Data>
              </Cell>
              <Cell>
                <Data ss:Type="String">
                  <tt:value ref="COUNTRY"/>
                </Data>
              </Cell>
            </Row>

          </tt:loop>

        </Table>

Figure 27
Transformation loop

Now that the transformation is in place, create a simple program that populates an internal table corresponding to the root element table.

1. Define an internal table and work area, and then assign a few rows to the table. This internal table corresponds to that used in the transformation (Figure 28).

types : begin of ty_itab,
          pernr type persno,
          name(40),
          country(40),
        end of ty_itab.

data wa type ty_itab.
data itab type standard table of ty_itab.
wa-pernr = '10'.
wa-name = 'Ted Jones'.
wa-country = 'United States'.
append wa to itab.

wa-pernr = '22'.
wa-name = 'Paul Adam'.
wa-country = 'United Kingdom'.
append wa to itab.

Figure 28
Fill an internal table

2. Here, you have defined an internal table ITAB and work area. Within the program, call the CALL TRANSFORMATION and pass the internal table IT_EMP to it.

3. The CALL transformation statement returns the XML in the string variable XML. This contains the Excel data in XML format (Figure 29).

call transformation zst1_test2
source table = itab[]
result xml xml.
Figure 29
Call the transformation

The template has a section in which an internal table is declared along with the necessary fields. There is a loop running on internal table ITAB and displaying the fields of the table as columns. The transformation generates the XML string. The internal table ITAB is passed for the root element table defined in the transformation. Upon serialization, the loop shown in the transformation is executed and the content of the internal table ITAB is included in the generated XML string. The XML can be saved on a local PC or sent as an email. The code pertaining to the download is shown in Figure 30.

data xml_tab type standard table of string.
append xml to xml_tab.
call method cl_gui_frontend_services=>gui_download
  exporting
    filename              = 'C:\Users\User\Desktop\test.xls'
    filetype              = 'ASC'
    write_field_separator = 'X'
  changing
    data_tab              = xml_tab.
Figure 30
Download the file to the desktop

When this file is opened using Excel, it shows the data of internal table ITAB in the same format (i.e., heading font and colors) as the sample file shown in Figure 24.

An email has been sent to:





 

Rehan Zaidi

Rehan Zaidi (erpdomain@gmail.com) is a consultant for several international SAP clients (both on-site and remotely) on a wide range of SAP technical and functional requirements, and also provides writing and documentation services for their SAP- and ABAP-related products. He started working with SAP in 1999 and writing about his experiences in 2001.



COMMENTS

Please log in to post a comment.

No comments have been submitted on this article. Be the first to comment!


SAPinsider
FAQ