Sunday, August 22, 2010

Enhance your ABAP Pretty Printer

I like my code to have TYPE statements lined up, and assignments as well. So I've enhanced the PRETTY_PRINTER function (yes it is a funciton module) to do that, and insert a comment block at the top as well.

If you don't know how to enhance the pretty printer function to call this code then you probably shouldn't be messing with it. 

Note that after enhancing the PRETTY_PRINTER function SAP will dump any open ABAP source that other programmers may be working on.  Best to do this early or late in the day or you will hear a lot of complaining... :-)

*--------------------------------------------------------------------------
* Developer:        Peter Chapman
* Created:          Thursday, 15. July 2010
* Modified:         Thursday, 12. August 2010
*-----------------------------------------------------------------------


function zpretty_printer.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  CHANGING
*"     REFERENCE(CT_CODE) TYPE  SWBSE_MAX_LINE_TAB
*"----------------------------------------------------------------------

*-- Indent                   type statements nicely during pretty print
  data zf                    type i.
  data zi                    type i.
  data lv_date               type string.
  data lt_days               type table of casdayattr.
  data zs(29).

  field-symbols:
                        type casdayattr,
                       type swbse_max_line.

  check sy-uname = 'PCHAPMAN'.

*-- make sure it is a program
  find first occurrence of regex '^(function|method|report|class)' in table ct_code match line zi.
  check zi > 0.

*-- Handle coding block
  call function 'DAY_ATTRIBUTES_GET'
    tables
      day_attributes         = lt_days.
  read table lt_days index 1 assigning .

  find first occurrence of regex 'Peter Chapman' in table ct_code match line zi.
  if sy-subrc <> 0 or zi > 3.
    insert initial line into ct_code index 1 assigning .
                       = '*-----------------------------------------------------------------------'.
    insert initial line into ct_code index 2 assigning .
                       = '* Developer:        Peter Chapman'.
    insert initial line into ct_code index 3 assigning .
                       = '* Created:'.
    +20                = -day_string.
    insert initial line into ct_code index 4 assigning .
                       = '* Modified:'.
    +20                = -day_string.
    insert initial line into ct_code index 5 assigning .
                       = '*-----------------------------------------------------------------------'.
    insert initial line into ct_code index 6 assigning .
  endif.

  find first occurrence of regex 'Modified' in table ct_code match line zi.
  if sy-subrc = 0 and zi < 6.
    read table ct_code index zi assigning .
                       = '* Modified:'.
    +20                = -day_string.
  endif.

  loop at ct_code assigning .

    clear: zf, zi.

*-- Handle TYPE indentation
    find first occurrence of regex '\btype\b' in  match offset zf.
    if zf > 0 and zf < 29.
      zi                     = 29 - zf.
      +29              = +zf.
      +zf(zi)          = zs.
      modify ct_code from .
    endif.

*-- Handle = indentation
    find first occurrence of regex '^\s*\S*\s*(=)[^=]*$' in .
    " start of line, blanks, alphas, blanks = no more \= end of line
    if sy-subrc = 0.
      find first occurrence of regex '=' in  match offset zf.

      if zf > 0 and zf < 29.
        zi                   = 29 - zf.
        +29            = +zf.
        +zf(zi)        = zs.
      endif.

      zs                     = 5.

    endif.

  endloop.

endfunction.

Monday, February 1, 2010

Text descriptions for object types

Where does SAP store the text for object descriptions in SE10 - TRE071X-OBJ_DESCRI ?

Not in a table. By analysing the search help SCTSOBJECT I found a form called GET_SYSTEM_TYPES in program SAPLTR_OBJECTS. Here all the object texts are hard coded and populated into an internal table with the KO100 structure.

Monday, March 23, 2009

How to print PDF forms from the SAP spooler

As of SAP Web Application Server 6.40, you can create a form in the new PDF-based form solution, which is integrated into the ABAP Workbench (SE80) and the SAP NetWeaver Developer Studio... more

Sunday, March 22, 2009

Embedding paint.exe in SAP GUI transactions

Here is some code to embed the paint application into a GUI application. Tablet signatures, anyone? However, my preferred approach is using a Flex components in web dynpros - much slicker but you will need EP1 for NW.



report zzzzzzzz.

include ole2incl.

selection-screen begin of screen 1100.
selection-screen end of screen 1100.

*----------------------------------------------------------------------*
* CLASS cl_paint DEFINITION
*----------------------------------------------------------------------*
class cl_paint definition.

public section.

methods:
constructor,

on_close_document
for event on_close_document of i_oi_document_proxy
importing document_proxy has_changed.

private section.

data:
go_control type ref to i_oi_container_control,
go_proxy type ref to i_oi_document_proxy.


endclass. "cl_paint DEFINITION

*----------------------------------------------------------------------*
* CLASS cl_paint IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class cl_paint implementation.

method constructor.

data:
retcode type soi_ret_string.

*-- Create the OLE control
call method c_oi_container_control_creator=>get_container_control
importing
control = go_control
retcode = retcode.
call method c_oi_errors=>raise_message
exporting
type = 'E'.

*-- Attach the OLE control to the screen container
call method go_control->init_control
exporting
r3_application_name = 'Signature Pad'(000)
inplace_enabled = 'X'
inplace_scroll_documents = 'X'
parent = cl_gui_container=>screen0
register_on_close_event = 'X'
register_on_custom_event = 'X'
importing
retcode = retcode.
call method c_oi_errors=>raise_message
exporting
type = 'E'.

*-- Create a proxy to the Paint application in the OLE container
call method go_control->get_document_proxy
exporting
document_type = 'Paint.Picture'
document_format = 'OLE'
importing
document_proxy = go_proxy
retcode = retcode.
if retcode ne c_oi_errors=>ret_ok.
exit.
endif.

*-- Create a new paint document
call method go_proxy->create_document
exporting
create_view_data = 'X'
open_inplace = 'X'
importing
retcode = retcode.
if retcode ne c_oi_errors=>ret_ok.
exit.
endif.

set handler me->on_close_document for go_proxy.

endmethod. "constructor


method on_close_document.

" Save the signature here

endmethod.

endclass. "cl_paint IMPLEMENTATION


start-of-selection.

data:
go_picture type ref to cl_paint.

create object go_picture.

call selection-screen 1100.

Tuesday, March 17, 2009

Substitutions: accessing values that should be out of scope

A lot of dodgy code has been written to get at required data which is not visible in user exits and substitutions. A common strategy is to EXPORT the desired value to memory in one exit, and IMPORT from memory in another. Such code is hard to write reliably, and even harder to maintain.

The trick illustrated below provides direct access to any data in any program in the global memory of a session. It is clean, reliable and easy to maintain. Go wild.


*&-----------------------------------*
*& Form u113
*&-----------------------------------*
** Customer number into assignment field
** Peter Chapman - March 2009 - Final
*------------------------------------*
FORM u113.

FIELD-SYMBOLS: <k> TYPE kunnr.

DATA:
lv_kunnr_field TYPE fieldname VALUE '(SAPMF05A)KNA1-KUNNR'.

ASSIGN (lv_kunnr_field) TO <k>.

bseg-zuonr = <k>.

ENDFORM.

Sunday, March 15, 2009

Email from SAP - class replaces SO_OBJECT_SEND

SO_OBJECT_SEND has been replaced by CL_BCS and CL_DOCUMENT_BCS. Less code is required to create and send email messages through Business Communication Services aka SAPOffice and SAPconnect. Here is a simple example of sending an email message from NetWeaver using the classes.

Full documentation is available on SDN here.

Note: to send email from SAP your user profile (system > user profile > own data) must have an email address set up so the return address can be detemined.


* Send email from SAP using BCS classes
* Peter Chapman - March 2009 - Final

REPORT zr_email.

DATA:
lv_message TYPE bcsy_text,
lv_send_result TYPE c,

lo_receiver TYPE REF TO if_recipient_bcs,

lo_email TYPE REF TO cl_bcs,
lo_email_body TYPE REF TO cl_document_bcs,

lx_exception TYPE REF TO cx_bcs.

APPEND '<font color="#0000FF">Your message is reddy!</font>' TO lv_message.

TRY.
lo_email = cl_bcs=>create_persistent( ).

lo_email_body = cl_document_bcs=>create_document(
i_type = 'HTM'
i_text = lv_message
i_subject = 'Message from SAP BCS' ).

PERFORM add_attachment USING lo_email_body.

lo_email->set_document( lo_email_body ).

lo_receiver = cl_cam_address_bcs=>create_internet_address( 'someone@somewhere.com' ).
lo_email->add_recipient( i_recipient = lo_receiver
i_express = 'X' ).

lo_email->set_send_immediately( 'X' ).

lo_email->send( EXPORTING
i_with_error_screen = 'X'
RECEIVING
result = lv_send_result ).

WRITE: / 'Success flag:', lv_send_result.

COMMIT WORK.

CATCH cx_bcs INTO lx_exception.

WRITE:/ 'Message sending failed:', lx_exception->error_type.

ENDTRY.


*&-----------------------------*
*& Form add_attachment
*&-----------------------------*

FORM add_attachment USING po_attachee TYPE REF TO cl_document_bcs.

DATA:
lt_attachment TYPE soli_tab,
lx_exception TYPE REF TO cx_bcs.

APPEND '<html><head/><body><font color="#0000FF">Your attachment is bluey!</font></body></html>' TO lt_attachment.

TRY.

po_attachee->add_attachment(
EXPORTING
i_attachment_type = 'HTM'
i_attachment_subject = 'My Attachment'
i_att_content_text = lt_attachment ).

CATCH cx_bcs INTO lx_exception.

WRITE:/ 'Attachment failed:', lx_exception->error_type.

ENDTRY.

ENDFORM. "add_attachment

Tuesday, March 3, 2009

Upload documents to the MIME Repository

Use program BSP_UPDATE_MIMEREPOS to upload files into the MIME Repository at a specific path location.

Select "Process Single File Only" unless you want your entire directory contents sitting in a transport!