Skip to Content
Technical Articles
Author's profile photo Arnab Datta

Tutorial: Save and display text field more than 255 characters from Table Maintenance (SM30)

Hi folks,

I know SM30 is very old and not relevant anymore. But from SAP functional person perspective, it is very useful and important tool. Sometime scenario comes that we need to store more than 255-characters text in table and want to maintain it from SM30 as it is very easy and quick to develop. But SAP only allows 255 characters to save and display in table maintenance.

While solving this I thought that I will add a button to SM30 and clicking on that button will display a text edit box in which user can enter the text up to 1000 characters or more.

****** GitHub repo: https://github.com/arnabdatta/abap-sm30-text-input/ **********

Lets create a table SM30_DEMO

Once you generate the table maintenance, you will get a warning message like this.

Now let’s begin the solution.

Double click on the screen number to open the screen painter. Then click on “Layout” button on the toolbar.

In screen painter take the button and draw it at the end of the table.me it “Edit Text”

Save and activate it, go back to flow logic and go to “Element List” tab.

Click on attributes icon at the top to open and give the icon and function code as shown.

 

In the flow logic add one module in the end and double click to create it.

PROCESS BEFORE OUTPUT.
 MODULE LISTE_INITIALISIEREN.
 LOOP AT EXTRACT WITH CONTROL
  TCTRL_ZSM30_DEMO CURSOR NEXTLINE.
   MODULE LISTE_SHOW_LISTE.
 ENDLOOP.
*
PROCESS AFTER INPUT.
 MODULE LISTE_EXIT_COMMAND AT EXIT-COMMAND.
 MODULE LISTE_BEFORE_LOOP.
 LOOP AT EXTRACT.
   MODULE LISTE_INIT_WORKAREA.
   CHAIN.
    FIELD ZSM30_DEMO-VALUE .
    FIELD ZSM30_DEMO-TEXT .
    MODULE SET_UPDATE_FLAG ON CHAIN-REQUEST.
   ENDCHAIN.
   FIELD VIM_MARKED MODULE LISTE_MARK_CHECKBOX.
   CHAIN.
    FIELD ZSM30_DEMO-VALUE .
    MODULE LISTE_UPDATE_LISTE.
   ENDCHAIN.
 ENDLOOP.
 MODULE LISTE_AFTER_LOOP.
 MODULE BTN_EDIT_TEXT.   " <====== Add here

Write the below code in the module.

*&---------------------------------------------------------------------*
*&      Module  BTN_EDIT_TEXT  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE btn_edit_text INPUT.
  TYPES BEGIN OF lty_tab.
  INCLUDE STRUCTURE zsm30_demo. " Incident Sub types
  INCLUDE STRUCTURE vimtbflags. " Flag structure for view maint. tool: Flags for tables
  TYPES END OF lty_tab.

  DATA: lt_tab TYPE STANDARD TABLE OF lty_tab,
        ls_tab TYPE lty_tab.

  DATA: lv_line         TYPE i,                    " Line of type Integers
        lt_text         TYPE catsxt_longtext_itab, " Text editor text line
        ls_line_struc   TYPE lty_tab,
        lv_old_text     TYPE text1000,             " Explanation
        lv_changed_text TYPE text1000.             " Explanation

  FIELD-SYMBOLS: <fs_line_struc>   TYPE lty_tab, " Incident Sub types
                 <fs_explaination> TYPE any.

  CASE function.
    WHEN 'EDIT_TXT'.

      GET CURSOR LINE lv_line.

      LOOP AT extract .
        IF sy-tabix EQ lv_line.
          ASSIGN extract TO <fs_line_struc> CASTING.
          EXIT.
        ENDIF. " IF sy-tabix EQ lv_line
      ENDLOOP. " LOOP AT extract

      ls_line_struc = <fs_line_struc>.

      lv_old_text = <fs_line_struc>-text.

      CLEAR lt_text.
      CALL FUNCTION 'RKD_WORD_WRAP'
        EXPORTING
          textline            = <fs_line_struc>-text
          outputlen           = 72
        TABLES
          out_lines           = lt_text
        EXCEPTIONS
          outputlen_too_large = 1
          OTHERS              = 2.
      IF sy-subrc <> 0.
* Implement suitable error handling here
      ENDIF. " IF sy-subrc <> 0


      CALL FUNCTION 'CATSXT_SIMPLE_TEXT_EDITOR'
        EXPORTING
          im_title = 'Explanation Text'
        CHANGING
          ch_text  = lt_text.

      CLEAR lv_changed_text.
      LOOP AT lt_text INTO DATA(ls_text).
        CONCATENATE lv_changed_text ls_text INTO lv_changed_text SEPARATED BY space.
      ENDLOOP. " LOOP AT lt_text INTO DATA(ls_text)

      CONDENSE lv_changed_text.

      IF lv_old_text NE lv_changed_text.
        <fs_line_struc>-text = lv_changed_text.
        <fs_line_struc>-vim_action = aendern.

        MODIFY extract INDEX lv_line.
        <status>-upd_flag = 'X'.
        total[] = extract[].
      ENDIF. " IF lv_old_text NE lv_changed_text

  ENDCASE.
ENDMODULE.

 

Now you have fully functional Sm30 with a popup taking more than 255 characters. The last touch , you can also make the text field read only so that user will only use the popup to enter the long text.

Demo:

 

Hope this helps! Let me know in your comments any improvement I can do to this.

 

To know more about SM30 events and variables please check the SAP Help site.

Extended Table Maintenance Events | SAP Help Portal

Happy coding!! ๐Ÿ™‚

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Dominik Tylczynski
      Dominik Tylczynski

      Nice blog really!

      One comment though - your long text field is still limited to 1000 chars. However you don't respect that limitation anywhere in your code or in the long text editor.

      Have you checked how you design works if more than 1000 chars are put in the long text edit pop up?

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Thanks Dominik Tylczynski for your comment!

      Yeah I should have given a error message when taking the input more than 1000 characters. In the current solution it just truncates after 1000 characters. I will post any improved solution if I find.

      Author's profile photo Ram Kumar
      Ram Kumar

      Hi Arnab Datta ,

      Great Blog!!

      I have tried doing the same, but its not working for me. Can you please help me out...

      ย 

      In TMG, If I Click EDIT TEXT, the Editable text popup isn't coming up.

      ย 

      Here is what an all I have done.

      I have created a Table 'ZTEXT_MAINTAIN' with the following fields and also generated the TMG for the same.

      Added a Pushbutton on Screen Painter in end of my table.

      Added the Function Code for the Pushbutton attribute.

      I have added the new module in my flow logic.

      PROCESS BEFORE OUTPUT.
        MODULE LISTE_INITIALISIEREN.
        LOOP AT EXTRACT WITH CONTROL
         TCTRL_ZTEXT_MAINTAIN CURSOR NEXTLINE.
          MODULE LISTE_SHOW_LISTE.
        ENDLOOP.
      *
      PROCESS AFTER INPUT.
        MODULE LISTE_EXIT_COMMAND AT EXIT-COMMAND.
        MODULE LISTE_BEFORE_LOOP.
        LOOP AT EXTRACT.
          MODULE LISTE_INIT_WORKAREA.
          CHAIN.
            FIELD ZTEXT_MAINTAIN-BUKRS .
            FIELD ZTEXT_MAINTAIN-TEXT .
            MODULE SET_UPDATE_FLAG ON CHAIN-REQUEST.
          ENDCHAIN.
          FIELD VIM_MARKED MODULE LISTE_MARK_CHECKBOX.
          CHAIN.
            FIELD ZTEXT_MAINTAIN-BUKRS .
            MODULE LISTE_UPDATE_LISTE.
          ENDCHAIN.
        ENDLOOP.
        MODULE LISTE_AFTER_LOOP.
        MODULE BTN_EDIT_TEXT.

      And Created a new Include for this module.

      *----------------------------------------------------------------------*
      ***INCLUDE LZTEXT_MAINTAINI01.
      *----------------------------------------------------------------------*
      *&---------------------------------------------------------------------*
      *&      Module  BTN_EDIT_TEXT  INPUT
      *&---------------------------------------------------------------------*
      *       text
      *----------------------------------------------------------------------*
      MODULE BTN_EDIT_TEXT INPUT.
      
        TYPES BEGIN OF lty_tab.
        INCLUDE STRUCTURE ZTEXT_MAINTAIN. " Incident Sub types
        INCLUDE STRUCTURE vimtbflags. " Flag structure for view maint. tool: Flags for tables
        TYPES END OF lty_tab.
      
        DATA: lt_tab TYPE STANDARD TABLE OF lty_tab,
              ls_tab TYPE lty_tab.
      
        DATA: lv_line         TYPE i,                    " Line of type Integers
              lt_text         TYPE catsxt_longtext_itab, " Text editor text line
              ls_line_struc   TYPE lty_tab,
              lv_old_text     TYPE text1000,             " Explanation
              lv_changed_text TYPE text1000.             " Explanation
      
        FIELD-SYMBOLS: <fs_line_struc>   TYPE lty_tab, " Incident Sub types
                       <fs_explaination> TYPE any.
      
        CASE function.
          WHEN 'EDIT'.
      
            GET CURSOR LINE lv_line.
      
            LOOP AT extract .
              IF sy-tabix EQ lv_line.
                ASSIGN extract TO <fs_line_struc> CASTING.
                EXIT.
              ENDIF. " IF sy-tabix EQ lv_line
            ENDLOOP. " LOOP AT extract
      
            ls_line_struc = <fs_line_struc>.
      
            lv_old_text = <fs_line_struc>-text.
      
            CLEAR lt_text.
            CALL FUNCTION 'RKD_WORD_WRAP'
              EXPORTING
                textline            = <fs_line_struc>-text
                outputlen           = 72
              TABLES
                out_lines           = lt_text
              EXCEPTIONS
                outputlen_too_large = 1
                OTHERS              = 2.
            IF sy-subrc <> 0.
      * Implement suitable error handling here
            ENDIF. " IF sy-subrc <> 0
      
      
            CALL FUNCTION 'CATSXT_SIMPLE_TEXT_EDITOR'
              EXPORTING
                im_title = 'Explanation Text'
              CHANGING
                ch_text  = lt_text.
      
            CLEAR lv_changed_text.
            LOOP AT lt_text INTO DATA(ls_text).
              CONCATENATE lv_changed_text ls_text INTO lv_changed_text.
            ENDLOOP. " LOOP AT lt_text INTO DATA(ls_text)
      
            CONDENSE lv_changed_text.
      
            IF lv_old_text NE lv_changed_text.
              <fs_line_struc>-text = lv_changed_text.
              <fs_line_struc>-vim_action = aendern.
      
              MODIFY extract INDEX lv_line.
              <status>-upd_flag = 'X'.
              total[] = extract[].
            ENDIF. " IF lv_old_text NE lv_changed_text
      
        ENDCASE.
      
      ENDMODULE.

      Did these things, but couldn't get that Editable popup.

      Is it because of the new Include or did I leave any step in between?

      ย 

      Need your help!!

      ย 

      Reagrds,

      Ram Kumar

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Hi Ram,

      Did you put a debugger in the line from where module is called and inside the module? Is program control coming there when you click edit text button? Please check if there are any errors happening while calling the FM in debug mode. You can connect with me if needed.

      Thanks.

      Arnab

      Author's profile photo Ram Kumar
      Ram Kumar

      Hi Arnab,

      I tried to put a breakpoint inside the module, but It gives this error:

      So, I added a breakpoint in the standard FM's ( RKD_WORD_WRAP, CATSXT_SIMPLE_TEXT_EDITOR ). and while clicking the Edit textย button the breakpoints weren't triggered.

      I guess this module isn't getting called.

      Yes, can we connect if possible to get this resolved?

      ย 

      Regards,

      Ram Kumar

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Hi Ram,

      Please try to activate all your code. If possible try to use function code anything other than 'EDIT'. Which version of ECC/S4 system you are using?

      Thanks,

      Arnab

      Author's profile photo Ram Kumar
      Ram Kumar

      HI Arnab,

      My codes are in active state, I have already given a try on function code - EDIT_TXT, but no luck.My current version is S4HANA on Premise(2020).

      Thanks,

      Ram Kumar.

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      The code needed to be correctly activated. the issue is resolved. ๐Ÿ™‚

      Author's profile photo Matthew Billingham
      Matthew Billingham

      If you regenerate, won't you lose all those changes?

      How can you mitigate that?

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Hi Matthew Billingham ,

      Thanks for this question. I think f you don't check the option 'Create Module' while regenerating, the code will be there. Do you have any other better idea to mitigate this?

       

      Author's profile photo Matthew Billingham
      Matthew Billingham

      I believe the screens get recreated anyway. But even if they're not, it's risky to rely on the next developer (which could be you!) remembering not to check certain boxes.

      I always move code out of the function group into their own classes. That means if I have to rebuild, it's quite simple. I'd suggest adding in the comments, in the bits that don't get deleted, exactly how to rebuild.

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Yeah, we can move the code into our own FM or class which will be called from the module but the global field symbol and internal table will be tough to pass and access. Good suggestions, thanks! Learning a lot from this. ๐Ÿ™‚

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for sharing! I think you could add this to the list of Enno's rants about SM30 here. ๐Ÿ™‚

      Author's profile photo Florian Pichler
      Florian Pichler

      Praise the lord, you saved my day!

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      I am glad it helped you.

      Author's profile photo Alexandre Ourth
      Alexandre Ourth

      Well sir thank you for sharing this.

      I used it and with very few rewriting to meet my needs, it's working perfectly.

      Have a good day and good luck on your journey!

      ย 

      Regards,

      Alexandre

      Author's profile photo Arnab Datta
      Arnab Datta
      Blog Post Author

      Thanks Alexandre. I am happy it helped you ๐Ÿ™‚