Preparing Long Texts to be Loaded in a Batch

Jimbo's picture

Longhorn goatLoading long texts to objects can be a daunting task because of the way that SAP breaks up the texts to be stored in blocks. When the object with the long texts is opened in SAP, the system knits the blocks back together into the long text to be displayed to the user.

For this example, long texts for Service Notifications will be loaded using the IW51 transaction in batch mode. The long text is passed in as a series of lines populating the individual fields of the long text editor screen.

The sample text is a description of Isaac Asimov's "The Naked Sun" and is a single line with no carriage returns. This text will be broken down into individual words and then knit back together into blocks of 73 characters or less.
A millennium into the future, two advancements have altered the course of human history: the colonization of the Galaxy and the creation of the positronic brain. On the beautiful Outer World planet of Solaria, a handful of human colonists lead a hermit-like existence, their every need attended to by their faithful robot servants.

Start by creating a new recording in LSMW. Click the Create Text button and then touch all of the fields below.

After saving the document, click the "Default All" button so that the fields to be populated in the batch will be automatically named. Only ten lines have been selected for this example, but more can be added; pressing PgDn twice positions the cursor at the next blank line while the recording is running, so some clever editing can be done.

The code starts by defining the variables that will store the long text as it is transformed. The structure BAPI2080_NOTFULLTXTE is used here because this was originally planned to be loaded as a BAPI.

data: it_split type table of char128,
      wa_split type char128,
      cTemp type string, nLength type i,
      it_NOTFULLTEXT type table of BAPI2080_NOTFULLTXTE,
 it_QMEL type standard table of QMEL,
 wa_QMEL like QMEL.

Before attempting to load any data, the records from the QMEL table associated with Service Notifications from the legacy system is used to populate an internal table in order to expedite lookups. This takes a lot of memory because the client had more than one million legacy Service Notifications and, because it occurs in the BEGIN_OF_PROCESSING code block of the LSMW object, it only has to run once.

* Pre-load the QMEL table into memory for speed.
select * from QMEL into wa_QMEL
 where QMART eq 'Z5'.
  append wa_QMEL to it_QMEL.

A quick loop through the internal table kicks out any records that have already been loaded. This prevents duplicates and allows for delta loads to be easily run.

loop at it_QMEL into wa_QMEL
 where QMNUM eq IW51B-QMNUM
   and QMART eq IW51B-QMART.
  if p_Verbos eq 'X'.
    write: / IW51S-QMNUM color col_positive, 'Already loaded.'.
endloop .

Now the boring code that validates all of the equipment, customers, dealers and servicing customers is skipped. The point of this whitepaper is to break up long text so that it can be loaded into SAP using a batch.

The work area structure is populated with the appropriate values. The first record is appended to the internal table so that the first line of the long text is "1-FINAL RESOLUTION"; the asterisk at the beginning represents the beginning of a new line.


Here the text is split on space into individual words. These words are then used to populate an internal table and are then knit back together into blocks that are 72 characters or less and the fist line starts with an asterisk followed by a space so that it will begin on a new line when displayed instead of starting after the previous line. Notice how the odometer reading has a blank line added above and after it per the client's wishes.

shift IW51S-RESOLUTION left deleting leading space.
split IW51S-RESOLUTION at space into table it_split.
cTemp = ''.
loop at it_split into wa_split.
  concatenate cTemp wa_split into cTemp separated by space.
  shift cTemp left deleting leading space.
  nLength = strLen( ctemp ).
  if nLength gt 71. "Leave enough for a space.
    append wa_NOTFULLTEXT to it_NOTFULLTEXT.
    cTemp = wa_split.
append wa_NOTFULLTEXT to it_NOTFULLTEXT.  "This was the last line.
*** Add another line if any odometer data is provided. ***
if IW51S-ODOMETER ne ''.
  concatenate 'Odometer Reading =' IW51S-ODOMETER
   into wa_NOTFULLTEXT-TEXT_LINE separated by space.

Eventually, the blocks are appended one after the other into the internal table containing the blocks to be loaded as long text. Notice the asterisks for new lines.

Finally, the program loops through the internal table and assigns the values in those records to the appropriate fields of the batch. The form in this code is stored in the FORM_ROUTINES code block of the LSMW object.

nLength = 2.  "Start assuming that the first two lines are populated.
  add 1 to nLength.
  perform FillLongText.

During the processing, the batch calls the long text editor and automatically populates all of the fields. The lines with asterisks will be represented as new paragraphs.

When the document is viewed in transaction IW53, the text appears as below. Notice how the blocks have been knit back into cogent sentences and the blank lines before and after the odometer reading have been preserved.

Update: The code above was adjusted when it was discovered that filling one line clear to the end causes the words to be concatenated instead of joined with a space between. Notice in the IW53 displayed text where the text says, "...Solaria, ahandful of human...".

Because the length of the line was allowed to run all the way to 72 characters, the "a" at then end was added to the beginning of the next word, "handful". By changing the code to if nLength gt 71., the last character is no longer populated with a letter or punctuation.