Quantcast
Channel: SCN : Blog List - ABAP Development
Viewing all 943 articles
Browse latest View live

ABAP Report => Mobile Application automated by zMob!

$
0
0

ss2.png

 

zMob is a powerful platform allowing the generation of mobile applications from simple ABAP reports. Behind the scenes, the report is converted into a mobile UI and passed to the end user's mobile device. Once data is collected, the user submits the data back to the SAP system, where your report processes the result in real-time. Your report writes lines that are relayed back to the mobile device, processed for special tags and rendered for the user.

 

The zMob library for SAP is open source (dual licensed under the LGPL and a commercial license,) and can be downloaded from the project page at https://bitbucket.org/zmob/sap.

 

A project using zMob to generate a mobile application from ABAP reports is Microbe, an open source (MIT) microblogging platform. A recent article outlines the functionality and configuration of Microbe, but here we shall look at the implementation in more detail, plus other features of zMob - this is the ABAP Development section after all!

ss_post_plus_code.png

As can be seen in the screen shot, the parameters of a report are mapped to the fields of a mobile application. The types of the parameters must be taken from the constants of the ZMOB class, and indicate the component or device data that the report would like to process. Following are the available types:

 

UI Components

 

ZMOB=>UI_MAP

Presents a map widget showing the current location of the device.

 

ZMOB=>UI_CAPTURE_BARCODE

Presents a button that can be clicked to capture the value of a barcode using the camera.

 

ZMOB=>UI_CAPTURE_AUDIO

Presents a button that can be clicked to capture audio from the device.

 

ZMOB=>UI_CAPTURE_PHOTO

Presents a button that can be clicked to capture a photo using the camera.

 

ZMOB=>UI_CAPTURE_VIDEO

Presents a button that can be clicked to capture a video using the camera.

 

ZMOB=>UI_CHECKBOX

Presents a simple checkbox component.

 

ZMOB=>UI_COMPASS

Presents a compass, which can be frozen on a heading by clicking.

 

ZMOB=>UI_DATE

Presents a date picker widget.

 

ZMOB=>UI_KEYWEEK

Presents a key-week picker widget.

 

ZMOB=>UI_DESCRIPTION

Presents a box for text entry that grows as more text is added.

 

ZMOB=>UI_DROPDOWN

Presents a drop down list of items.

 

ZMOB=>UI_EMAIL

Presents an input field specialized for email input.

 

ZMOB=>UI_NUMBER

Presents an input field specialized for number input.

 

ZMOB=>UI_PASSWORD

Presents an input field specialized for password input.

 

ZMOB=>UI_RADIO

Presents one item from a group of radio buttons.

 

ZMOB=>UI_SLIDER

Presents a widget used to select an integer value between a maximum and minimum value.

 

ZMOB=>UI_TELEPHONE

Presents an input field specialized for telephone number input.

 

ZMOB=>UI_TEXT

Presents an input field for plain text.

 

ZMOB=>UI_TEXT_HELP

Presents an input field for plain text with help attached.

 

ZMOB=>UI_TOGGLE

Presents a toggle button for On Off values.

 

ZMOB=>UI_URL

Presents an input field specialized for http address input.

 

Device Properties

 

ZMOB=>BG_ACCELEROMETER

Returns the value of the device accelerometer at time of submit.

 

ZMOB=>BG_GEOLOC_LATITUDE

Returns the value of the device latitude at time of submit.

 

ZMOB=>BG_GEOLOC_LONGITUDE

Returns the value of the device longitude at time of submit.

 

ZMOB=>BG_GEOLOC_ACCURACY

Returns the accuracy of the device longitude/latitude coordinates at time of submit.

 

ZMOB=>BG_GEOLOC_ALTITUDE

Returns the value of the device altitude at time of submit.

 

ZMOB=>BG_GEOLOC_ALTITUDEACCURACY

Returns the accuracy of the device altitude sensor at time of submit.

 

ZMOB=>BG_GEOLOC_HEADING

Returns the value of the device heading at time of submit.

 

ZMOB=>BG_GEOLOC_SPEED

Returns the value of the device speed at time of submit.

 

ZMOB=>BG_GEOLOC_TIMESTAMP

Returns the timestamp at which the geolocation data was last updated.

 

ZMOB=>BG_DEVICE_MODEL

Returns the device's model or the name of the product.

 

ZMOB=>BG_DEVICE_UUID

Returns an ID unique to the device.

 

ZMOB=>BG_DEVICE_VERSION

Returns version information for the operating system installed on the device.

 

ZMOB=>BG_PLATFORM

Returns information on the operating system installed on the device.

 

ZMOB=>BG_USER

Returns the configured user name for the SAP user using the device.

 

Start Of Selection

Once the user has entered data into the application, they click the "Submit to SAP" button and their form data is serialized. The data is then passed back to SAP and submitted to the corresponding report. The output from the report is sent back to the mobile application and rendered.

 

Tags within the returned data are interpreted and have special meanings.

 

  • <link:...> will cause a line in the results to become a link to another ABAP report or HTTP address.
  • <img:...> [planned] to allow specifying an inline image URL
  • <html> [planned] to allow HTML output embedded within the application
  • Other tags are planned for future implementation!

 

Example Source Code

 

Following is the code contained in zmicrobe_post and zmicrobe_index for the sample microblogging application Microbe. The code is simple and straightforward, and yet achieves impressive results thanks to zMob.

 

Note that because zmicrobe_index has no parameters defined, zMob skips an input screen and renders the results of calling start-of-selection directly for the user. The lines written to output are then shown to the user in a list view, including a link to the zmicrobe_post report.

 

* entry point into microbe mobile app

REPORT  zmicrobe_index.

DATA:
  msg TYPE zmicrobe_msgs,
  txt TYPE string.

START-OF-SELECTION.

WRITE 'Welcome to the Microbe demo microblogging platform.'.
NEW-LINE.

WRITE 'See original implementation in reports ZMICROBE_INDEX and ZMICROBE_POST.'.
NEW-LINE.

WRITE 'Post a message <link:ZMICROBE_POST>'.
NEW-LINE.

SELECT * FROM zmicrobe_msgs INTO msg
  UP TO 20 ROWS
  ORDER BY timestamp DESCENDING.

CONCATENATE msg-username 'posted' msg-message
  INTO txt SEPARATED BY space.

* todo: include thumbnails <img:> - extend db..
  WRITE txt.
  NEW-LINE.
ENDSELECT.

IF sy-subrc NE 0.
*    WRITE: 'Be the first to post a message!'.
ENDIF

mob_ss_index.png

REPORT  zmicrobe_post.

PARAMETERS:
  p_msg LIKE zmob=>ui_description,
  p_usr LIKE zmob=>bg_user.

START-OF-SELECTION.

DATA:
  msg TYPE zmicrobe_msgs.

msg-timestamp = 0.
msg-username = p_usr.
msg-message = p_msg.

INSERT zmicrobe_msgs FROM msg.
COMMIT WORK AND WAIT.

write:
  'Your message has been posted.', /,
  'Back to Microbe <link:ZMICROBE_INDEX>'.

mob_post.png

Debugging

 

The zMob emulation system can be used to test your installation and your own reports from within the browser. (It is also available in the Google Chrome store for free.)

 

After activating a report and configuring user access for SAP users, the URL to your SAP system can be entered into the browser based emulator, and you will be able to see and interact with your mobile application, including logging the communication between SAP and the mobile application.

ss_debug.png

 

Your ABAP report will render within the emulator in the same way it would on a mobile device. This is a quick way to experiment and tweak your reports to make sure the correct data is being passed back and forth. It's as simple as making a minor modification to your report, activating and refreshing the browser window to see the new changes take effect!

 

Once your application looks perfect, it can be distributed to test devices for hardware integration testing. Finally, using the user authorization system, the application can be pushed to the end user devices for use in production.

 

Mobile Clients

 

Currently we are in the process of beta testing the mobile clients for Android and iOS devices. If you are interested in participating in the beta testing phase, head on over to our Google+ Community for Beta Testing. Shortly we will also be looking for beta testers with Windows Phone and Blackberry devices.

 

Links

 


Do Quality Processes really matters ?

$
0
0

"Do the Quality processes in SAP projects really matters ? ",this is  a basic question which strike to my mind,while I was sitting in the Quarterly Audit for my project."You have to update the object tracker regularly and also the defect tracker with all the efforts and if missed that will amount to Non-conformance of the quality process;The WBS of the project should be evident ;where are you putting all the efforts for TS review ? " , screamed the Auditor.

   These questions appeared to me as volleys, from which I have to safeguard my head;otherwise it would definitely strike the Head ! 

 

But do we really follow Quality processes in our projects and fill the documents in timely manner ? Or, is it simply a Historical and manipulated Data ?

And what benefit, it will provide to the project in continuous improvement ?

 

Now-a-days,in the SAP Projects - whether Implementation or Support - the environment is very challenging and more and more stressful.Every now and then there are rapid changes in the requirements and sometimes, it is seen that after the long development period of 3 months, finally the object is scrapped and it is no more required.Or otherwise, it is found that although the development is correct but the old version of the object was better;so switch to the older version  and comment the latest one ! So how you define the SDLC for this ? Within the Quality perspective,first you have to develop a technical specification or a technical design for the object and then jump to coding.But, if the requirements keeps on changing and no test data is given ? then , what should be the approach ?

 

The most favorite Question that is asked in the Audit is - "what is your delivery process ?" ."How do you deliver the object to the end customer ?" . The real problem arises when the customer do not follow any specific process and your Quality Department is adamant on following s set of processes. "We are a CMMI Level 5 company and we cannot compromise with any non-conformance of the Quality Process ", adds the QA of the project. So, how to strike a balance between the two flippers - Client and the Quality Deptt. ? Finally, what is the solution ? Is it right that you feel always overburdened with the lot of Work and always face the dilemma of managing the start data and end date of a object and its representation in the object tracker ! 

 

The purpose of the quality system of a company - I feel - is to facilitate the smooth delivery to the client and definitely of High Quality.To ensure this, there must be - what we call it as adaptation- just like in Agile Development.The Quality processes should not be blindly followed,but,rather be adapted to the client requirements and delivery processes.It must not be the case of too many processes or no process.In this way,only, the QMS may  achieve its basic organisational  goal of 'High Quality Delivery" . Till this thought is put into consideration,our Team Leads and Manager will surely have a hard time with QA !

 

 

I still feel that the debate is still not over for this moot point and would certainly like to hear the voices of fellow members and their thoughts.Please feel free to share your expression on  this.

A Developers Lament

$
0
0

I think most developers will agree with the below remarks...

 

 

 

Why, oh, why do users keep raising issues to developer’s like: “It doesn’t work, can you please check it?”, and just leave it at that? No explanation, no example, nothing…

 

 

 

To all these users I would like to say:

We REALLY want to help, we truly do. But please, please, please just give us the information we need, to help you! Do not drop the question and expect us to be able to read your minds. We can debug a program, but we cannot debug you. When raising an issue, please add a clear description of what steps were taken and what the problem is.

  • What happened and what was the expected result?
  • Which transaction did you use?
  • What message was returned?
  • When did this happen?
  • Can the issue be repeated? How?

 

 

Be as clear as you can be! It may take a bit of extra effort at the start, but in the end it will save us all a lot of time.

 

 

Please guide us through the steps with patience, because we are NOT functional people and we do not (usually) know the proper business way to do what you normally do. What is obvious to you, is not obvious to us. We may not even know the right transaction… And we do not go through the screens you use.

 

We are not trying to frustrate you by asking all the questions we ask, how silly they may seem.

 

 

We just want to help! REALLY!



Okay, now I probably have developers agreeing with me on this. Having not enough information is frustrating and makes it difficult to help efficiently. The reason for me pointing at the users, is only done because developers will recognize them as a known problem. If only we could work without users... But this blog is not aimed at users, nor written for users. It is written for developers.

Let us turn it around and let it backfire...

Now, if you are a developer and you recognize this problem (you do, don’t you?), then have a look at how developers post on SCN… I see many questions, by developers, to developers, in the above mentioned user-way.


 

 

Developers keep raising issues to developer’s like: “It doesn’t work, can you please check it?”, and just leave it at that. No explanation, no example, nothing…

 

 

To all these developers I would like to say:

We REALLY want to help, we truly do. But please, please, please just give us the information we need to help you! Do not drop the question and expect us to be able to read your minds. We can debug a program, but we cannot debug you. When raising an issue, please add a clear description of what stpes were taken and what the problem is.

  • What happened and what was the expected result?
  • Which transaction did you use?
  • What message was returned?
  • When did this happen?
  • Can the issue be repeated? How?

 

 

Be as clear as you can be! It may take a bit of extra effort at the start, but in the end it will save us all a lot of time.

 

 

Please guide us through the steps with patience, because we are NOT sitting next to you and we do not (usually) know the what you did. What is obvious to you, is not obvious to us. We may not even know the right transaction… And we do not go through the screens you use.

 

We are not trying to frustrate you by asking all the questions we ask, how silly they may seem.

 

 

We just want to help! REALLY!

Netweaver 7.4 - Value Suggest in SE80

$
0
0

Hi All,

 

I came across a nice feature - Value Suggest for Object Names in SE80 transaction in Netweaver 7.4 system and would like to share you.

 

In the earlier versions of Netweaver systems (Prior to Netweaver 7.4), to search a particular object and load it in SE80, we use wild card (*) and press Enter.

1.jpg

 

Once we press enter, the result entries will be shown in the popup.

2.jpg

 

In Netweaver 7.4, Value Suggest feature is added which shows the result entries as we type it.

3.jpg

Once we select the Object(double click), the object will be loaded without the need to pressing Enter.

 

5.jpg

6.jpg

 

It even shows the result entries as we type it using wild card (*).

4.jpg

 

Looks coooool rite.!

 

I wounder whether this feature can be switched off via user parameters for some people who don't want this feature!

 

Hope this will be more improved( the value suggest result space) and the switch on/off value suggest will be added in the near future

Display an ALV in the MODULE POOL Screen

$
0
0

This Program will Show an error log containing Material No, Source Plant, Destination Plant Status etc. in ALV report which was called from a  Module POOL.

1.JPG

 

STEP 1: Declare an internal table to be displayed in ALV Report

 

This is the Detailed Structure for ERROR LOG

 

*--Types for Error Log

types: begin of ty_err_log,

        matnr type matnr ,"Material No

        from_plant  type werks_d             ,"Plant

        dest_plant  type werks_d             ,"Plant

        from_sloc   type lgort_d             ,"Str. Location

        to_sloc     type lgort_d             ,"Str. Location

        Qty         type ktmng               ,"Qty

        charg       type charg_d             ,"Batch

        msg(132) type c ,"Message

        end of ty_err_log.

 

 

*--Internal table for error Log

data: itab_err_log type standard table of ty_err_log initial size 0.

 

 

  STEP 2: create a custom control from Screen Layout (GRID_NAME)

2.JPG

 

STEP 3: create a container for custom control and assign the grid to container

 

**&---------------------------------------------------------------------

**

**&      Form sub_alv_display

**&---------------------------------------------------------------------

**

**       Calls an ALV Report

**----------------------------------------------------------------------

 

FORM sub_alv_display .

 

* Local Variable Declaration-------------------------------------------

  DATA :

*     Local Variable for Screen Container Name

       l_screen_container     TYPE scrfname VALUE c_grid_name,

       ls_stable        TYPE lvc_s_stbl.

 

* Create a Custom Container for the Subcreen

  CREATE OBJECT v_container_9300

      EXPORTING container_name = l_screen_container.

 

 

* Assign the Grid to the Custom Container

  CREATE OBJECT v_grid_9300

      EXPORTING i_parent = v_container_9300.

 

 

 

STEP 4: Populate the field catalog  and display the ALV Report (CALL METHOD v_grid_9300->set_table_for_first_display)

 

* Set the Field Catalog

  PERFORM sub_set_fieldcat.

 

* Display the values of dynamic table in screen 9003

  CALL METHOD v_grid_9300->set_table_for_first_display

    EXPORTING

      i_structure_name = 'WA_ERR_LOG'

    CHANGING

      it_fieldcatalog  = itab_fieldcat

      it_outtab        = itab_err_log.

 

  ls_stable-row = 'X'.

  ls_stable-col = 'X'.

 

  CALL METHOD v_grid_9300->refresh_table_display

    EXPORTING

      is_stable = ls_stable

    EXCEPTIONS

      finished = 1

      OTHERS = 2.

*&---------------------------------------------------------------------*

*&      Form sub_set_fieldcat

*&---------------------------------------------------------------------*

*       Populate the Filed Catalog

*----------------------------------------------------------------------*

 

FORM sub_set_fieldcat.

  REFRESH: itab_fieldcat.

 

  PERFORM sub_create_ctlg_table USING:

      '1' 'MATNR'     'ITAB_ERR_LOG' text-001 '' '18'   '' '' '' ''

'',

      '4' 'DEST_PLANT'     'ITAB_ERR_LOG' text-004 '' '14'   '' ''

'' ''

'',

 

      '2' 'FROM_PLANT'     'ITAB_ERR_LOG' text-002 '' '14'   '' ''

'' ''

'',

      '3' 'FROM_SLOC'     'ITAB_ERR_LOG' text-004 '' '14'   '' ''

'' ''

'X',

      '5' 'TO_SLOC'    'ITAB_ERR_LOG' text-005 '' '14'   '' '' ''

''

'X',

'6'  'QTY' 'ITAB_ERR_LOG' text-006 '' '17' '' '' '' ''

'X',

'7'  'CHARG' 'ITAB_ERR_LOG' text-007 '' '10' '' '' '' ''

'X',

'8'  'MSG' 'ITAB_ERR_LOG' text-008 '' '132' '' '' ''

''

'X'.

 

  1. ENDFORM.                    " create_fieldcatalog

 

**&-------------------------------------------------------------------*

**&      Form sub_create_ctlg_table

**&--------------------------------------------------------------------*

**       inserting into field catalog table

**--------------------------------------------------------------------*

FORM sub_create_ctlg_table USING  p_colpos

                               p_fldname

                               p_tabname

                               p_dispname

                               p_reftabname

                               p_len

                               p_chk

                               p_edit

                               p_key

                               p_emphasize

                               p_do_sum.

 

  DATA: wa_fieldcat TYPE lvc_s_fcat.   "work area for fieldcat

*Assign required fields into workarea

  wa_fieldcat-col_pos         = p_colpos.

  wa_fieldcat-fieldname       = p_fldname.

  wa_fieldcat-tabname         = p_tabname.

  wa_fieldcat-coltext         = p_dispname.

  wa_fieldcat-ref_table       = p_reftabname.

  wa_fieldcat-outputlen       = p_len.

  wa_fieldcat-checkbox        = p_chk.

  wa_fieldcat-edit            = p_edit.

  wa_fieldcat-key             = p_key.

  wa_fieldcat-emphasize       = p_emphasize.

  wa_fieldcat-do_sum             = p_do_sum.

  APPEND wa_fieldcat TO itab_fieldcat.

  CLEAR wa_fieldcat.

 

  ENDFORM . "sub_create_ctlg_table


Problem in sales order creation using BAPI_SALESORDER_CREATEFROMDAT2 for BOM (Bill of Material) and Solution

$
0
0

Generally when we create sales order using BAPI_SALESORDER_CREATEFROMDAT2, there we pass item number externally into the tables parameter - ORDER_ITEMS_IN like 10, 20, 30 format.

 

Problem:

When there is BOM (bill of material) for any material that will explode when creating the sales order with those materials. Sometime it can be happen that the material has more than 9 sub items (bill of material). In this case if we pass the item number as 10, 20, 30, 40 format externally into the BAPI, then the item (which have more than 9 sub item) will over write on the next item and there will be problem in sales order creation.

 

Solution:

Pass the parameter INT_NUMBER_ASSIGNMENT with value ‘X’ into the BAPI. It will internally generates and assign the next suitable item number and avoid the overwriting of items.

 

Example:

Lets say there is two materials used to create a sales order,

MAT1

MAT2

 

And sub items (bill of material) of the materials are like,

MAT1 – BOM1, BOM2, BOM3, BOM4, BOM5, BOM5, BOM7, BOM8, BOM9, BOM10, BOM11.

MAT2 – BOM1A, BOM2A, BOM3A.

 

When we will try to create sales order using BAPI (BAPI_SALESORDER_CREATEFROMDAT2) providing the line item numbering externally (from our custom code) as 10, 20 … then we would face the same problem.

 

If we pass the parameter INT_NUMBER_ASSIGNMENT as ‘X’, then the standard code within BAPI will generate the next item assignment number and create the sales order successfully.

 

In the created sales order the line items will look like –

10 – MAT1

11 – sub item (BOM1)

12 – sub item (BOM2)

13 – sub item (BOM3)

.

.

21 – sub item (BOM11)

 

30 – MAT2

32 – sub item (BOM1A)

33 – sub item (BOM2A)

34 – sub item (BOM3A).

 

Here, instead of 20 the next item (MAT2) will start from 30.

 

This is a very simple technique and might help someone when troubling with such king of BOM issue.

Transport Tracking Made Easier in SAP

$
0
0

This blog will help in understanding the concept of transport request attributes and how it will help in transport management. This will help in achieving good governance of transport requests in big SAP implementation projects.

 

Pre-requisite:Basic knowledge of SAP transport request.

 

  • Introduction                                                         

Transport requests are used to transfer the changes done to existing objects or new objects created in the development system to quality and then finally to production system.

screen1.jpg

Production system has real and confidential data, hence while importing transports to production system transport requests needs to be verified correctly. Any mistakes in transport list can hamper existing functionality which intern will cause in change backout and development failure.

 

The order in which transports should be imported to production needs to be same as per the sequence they were moved in Quality/Acceptance system.

 

In big SAP implementation projects which are having more than 100 transport requests created by developer / functional, there will be more chance of missing transport request in final list of production. If any transport is missed in the production list, there are several possible risks involved.

Other factors involved are number of developers working on the same project, developers working on the same objects , transports which are being moved in case of production bug fixes and multiple projects being run in single environment.

 

  • Possible risks if transport is missed in the production list:

1.  Wrong object versions can go to production: If there are multiple transport requests for one object and one of the transport requests is missed during production move, then this will lead to incorrect version of the object.

 

For e.g. for report program ‘ZTEST’ one transport request ‘AB123’ was created and moved from DEV system to Acceptance system. Later on there was a defect detected in Acceptance testing.

Then to fix this defect again new transport request ‘AB456’ was created and moved to Acceptance box. Now while preparing the production transport list for program ‘ZTEST’, latest transport request for defect fix ‘AB456’ was missed. Then incorrect version of program ‘ZTEST’ will go to production system and same defect which was already fixed in acceptance testing will remain unfixed as it is.

 

2.  Possibility of RC8 Error during transport movement to production:  If any transport of dependent object is missed in the final list of production movement then transport movement will result in RC8 Error.

 

E.g. there are 2 transport requests one is for table and another is for data element which is used in table. Both table and data element are new objects and does not exist in production before transport movement.

Object Type

Object Name

Transport Request

Data Element

ZDTELE

AB1234

Table

ZTABLE

AB5678

 

Now while preparing final transport list for production movement if transport ‘AB1234’ for Data Element ‘ZDTELE’ is missed then while moving transport request ‘AB5678’ (i.e. for table) RC8 error will occur.

 

Hence transport movement will end up with error and intern will need analysis on transport  failure. Again for missing transport request separate change management process will be required to move transport to production.

 

Above mentioned are major risks during production transport movement and may cause HUGE BUSINESS IMPACT.

 

To avoid such issues because of simple mistakes, good transport management and tracking is needed in projects.

 

  • Steps for better transport management and tracking:

o Create custom transport attribute.

Maintain custom transport attribute for each new transport request for specific development before releasing it. Hence the entire transport list  related to development will have attribute maintained.

Fetch the list of transports from E070A table where attribute name = custom attribute name.

This result will give complete list of transport requests for which custom attribute was maintained.

This will avoid human error of missing any transport request in production transport list.

Transport attribute maintenance check can be enforced for specific projects. E.g. In development environment multiple projects are being run and if we want to make transport attribute maintenance mandatory only for our project then this check can be performed specific to project ID by implementing method ‘CHECK_BEFORE_RELEASE’ of BADI “CTS_REQUEST_CHECK”.

Once this check is implemented developer/functional will not be able to release transport request without maintaining transport attribute.

Hence at the time of production move list of transports for specific development can be fetched from E070A table where transport attribute value =’XXXXXX’.

 

  • Scenario for how attribute maintenance will help in better management of transports:

In single project there are multiple developments going in parallel. Each development will have separate requirement specification document with unique number of requirement document.

 

Below is example:

Project Name:    Project1

Now under project1 there are multiple developments executed,

Development Name

Requirement Spec. Document number

DEV1

R1111

DEV2

R2222

DEV3

R3333

 

Now if we create a custom transport attribute ‘ZREQ_DOCNO’ for maintaining requirement specification document number.

Then while creating transport requests for development (i.e. DEV1), maintain transport attribute ZREQ_DOCNO = R1111’ (which is req. spec. doc. Number for DEV1).

Now if there are total 40 transport requests were created for DEV1 then list of transports can be fetched from “E070A” table where TRANSPORT ATTRIBUTE =’ ZREQ_DOCNO’ and ATTRIBUTE VALUE = ‘R1111’.

This data fetch from E070A table will give complete list of transports created for DEV1 and there will not be any miss in transport list.

Also this transport request maintenance can be made mandatory based on project ID by implementing BADI.

Transport attributes creation and BADI implementation is explained in detail further.

 

  • How to create Transport Attribute?  We can create custom transport Attributes (Z-attribute) for easier project level transport tracking.  This custom transport attribute can be maintained, so that we can find specific development transports according to custom Transport Attribute values. You can use attributes to define change requests. Also using these Attribute values, we can perform transport analysis.

 

  • Steps for creation of TP Attribute:

      1. Go to transaction SE03 (Transport Organizer Tools).Select Display/Change Request Attributes option.

 

   screen2.jpg

 

2.          2. Click on ‘Create’. New pop-up window will appear.                    screen3.jpg

      3.  Now enter the respective values for new custom Attribute:

 

      Attribute:              Enter the Attribute name for i.e. “ZREQ_DOCNO”

      Short Description: Enter Short description “Project1 Transport Attribute”.

 

There are 3 options which need to be selected according to purpose of this attribute:

1.      Attribute Value Obligatory: This specifies whether the attribute can only be assigned with a value. If it is essential that value should be specified for the attribute, then select attribute value obligatory.

2.      Attribute Assigned Externally: If this field is selected, the attribute is assigned using external interfaces only. You can then no longer add this attribute to a request, or delete it from a request. Mostly this option will not be used as we need to track transport requests in SAP.

3.      Attribute can only be assigned once for Each Request: If this field is selected then you can only assign this attribute once for each transport request.

 

We can also make these attributes mandatory to specific development client by mentioning client specific settings.

 

So here we will select option 1 & 3 to create custom attribute: then SAVE.

  screen4.jpg

Now new attribute “ZREQ_DOCNO” will be available for maintenance through SE01.

 

  • How to maintain transport attribute?

1.      Go to SE01. Display transport request.

2.      Go to properties tab of transport and enable change mode.

3.      Attribute “ZREQ_DOCNO” will be available for maintenance in attribute list.

4.      Select the attribute and enter the value for the attribute e.g. If we are creating transport request for DEV1 and requirement document number

          for DEV1 is “R1111” then we can maintain attribute having same value.

            screen5.jpg

We can define Attribute value such as some unique number for each Development for e.g. Design Document number will be different for each development. If we maintain transport attribute value “R1111” (i.e. Requirement Doc. Number) for all transport requests specific to one of the development i.e. DEV1, then it will be easier to track all the transport requests related to DEV1 for production movement.

 

So there will not be any chance of missing any transport request during production movement of the development.

 

                We can find out the list of transport requests having specific attribute value From E070A table:

                 

   screen6.jpg

 

This selection will give list of transports for which Attribute “ZREQ_DOCNO” is maintained with value “R1111” e.g. if there were three transport requests created for DEV1 so this selection will give all the three transports in output.

 

  screen7.jpg

This way we can identify all the transports for specific project or development. Risk for missing transports in the list during production movement will be minimized to great extent.

But there can be a miss, if somebody forgets to maintain attribute for transport request before releasing the request, then what will happen?

Still we will not be able to track that specific transport request for which attribute was not maintained.We can make this Transport Attribute Check mandatory based on few conditions.

 

  • How to make transport attribute maintenance mandatory according to transport description or naming?

Many projects use intelligent naming conventions for Transports. For example Project ID is mentioned in Transport request description or Design Document number is mentioned in Transport description.

 

Now if we make Transport Attribute maintenance mandatory, it will be mandatory check for all projects in specific development box. We can make this check obligatory project-ID specific.

 

  • How to automate the process of Transport Attribute maintenance?

The transport attribute maintenance can be made mandatory project specific by implementing BADI “CTS_REQUEST_CHECK”.

 

CTS_REQUEST_CHECK:  This BADI has multiple methods through which various checks can be implemented for transport requests. Method ‘CHECK_BEFORE_RELEASE’ is called before a transport request is released transport request through SE01 transaction.

By using this method we can implement our own check related to transport request:

1.      1. Check attributes and short text of transport request.

2.      2. Objects included in transport request.

 

      screen8.jpg

         

BADI implementation steps:

Transport request attribute check can be implemented specific to project or according to the short text of transport request. E.g. In development environment , if currently multiple projects are run i.e. Project1,Project2,Project3……Project(n) and we want to make transport attribute maintenance mandatory only for our project (i.e. Project1) which will help in better transport tracking.

In such scenario, we can make TP attribute mandatory for specific project by implementing BADI check.

Many projects use intelligent transport naming conventions (transport request short text). E.g. Transport request description contains PROJECT IDand based on which we can make this attribute check mandatory.

          E.g.        TR1234 (Transport Request) -> DEV: Project1:SE38_ZTESTPROGRAM (Short text)

Now while releasing the transport request TR1234, we can check if transport request short text/description contains our project ID i.e. Project1 in this case. If yes, then check if transports attribute “ZREQ_DOCNO” is maintained for TR1234. If NO, then throw error ‘Please maintain required attribute’, while releasing the request through SE01.

 

We can maintain configuration for which project ID which transport attribute should be maintained, so check can be made dynamic.

1.      1. Create custom table ‘ZATTRICHECK ‘having 2 fields Project ID and Transport Request Attribute.

 

      screen9.jpg

 

2.      2. Maintain ‘ZATTRICHECK ‘table with Project ID (i.e. project which will be present in Transport Request short text) and Transport attribute which 

            needs to  be checked for particular project ID.

   

So for below example, if Transport short text contains “Project1”, then by implementing BADI check can be performed to see whether “ZREQ_DOCNO” attribute is maintained or not while releasing the transport request.

             

      screen10.jpg

3. BADI Implementation Steps:

 

  • Go to transaction SE19 and create BADI implementation for classic BADI “CTS_REQUEST_CHECK”.

     screen11.jpg

  • Implement method CHECK_BEFORE_RELEASE.
  • Source code implementation:

                        1.First check if transport request is “Higher-Level Request”, if transport is Higher-Level then only Attribute check should be performed.This check can be performed by querying E070 table.

                        2.If transport is higher level, then fetch Project ID and Transport Attribute from custom table ‘ZATTRICHECK ‘into internal table.

                        3.Fetch transport attributes maintained for the current transport request from E070A table.

                        4.Check if transport request short text for Project ID in custom table ‘ZATTRICHECK ‘. If short text contains Project ID which is in custom table,then perform further check for transport attribute.

                        5. Check if custom table TP attribute present in Attributes fetched from E070A table for this transport request.

                        6. If transport attribute is not present then populate the error “Please maintain required attribute”.

 

 

  • Implementation Source Code:

*$*$**********************************************************************************************************

*$*$    PROGRAM ID    : ZCTS_REQUEST_CHECK                                                              *   

*$*$    TITLE                : BADI Impl.to check Transport Attribute                                             *     

*$*$    AUTHOR           : SANJANA LINGRAS                                                                       *

*$*$    DESCRIPTION   : BADI implementation to check if required                                          *     

*$*$                               transport attribute is maintained before                                             *   

*$*$                               release of TP.                                                                                 *

*$*$------------------------------------------------------------------------------------------------------------------------------------* 

METHOD if_ex_cts_request_check~check_before_release.

  TYPES:  BEGIN OF y_tpchk,
            zprojid  TYPE zattricheck-zprojid,
            ztpattri TYPE zattricheck-ztpattri,
          END OF y_tpchk,

          BEGIN OF y_attri,
            ztkorr TYPE e070a-trkorr,
            zattri TYPE e070a-attribute,
          END OF y_attri.

  DATA  : t_tpchk TYPE STANDARD TABLE OF y_tpchk,
          t_attri TYPE STANDARD TABLE OF y_attri.

  DATA : w_request    TYPE e070-strkorr,
         w_result_tab TYPE match_result_tab,
         w_flag       TYPE string.

  CLEAR w_request.

  FIELD-SYMBOLS : <fs_tpchk> TYPE y_tpchk,
                  <fs_attri> TYPE y_attri.

  FREE : t_tpchk,
         t_attri.

    SELECT SINGLE          “Check whether TP is higher level request
           strkorr
      INTO w_request
      FROM e070
     WHERE trkorr EQ request.

    IF  sy-subrc  EQ 0
    AND w_request IS INITIAL.

      SELECT zprojid        “Fetch proj.ID and attribute from custom table
             ztpattri
        FROM zattricheck
        INTO TABLE t_tpchk.

      IF sy-subrc EQ 0.

        SORT t_tpchk
          BY zprojid.

      ENDIF.

      IF t_tpchk IS NOT INITIAL.

        SELECT trkorr      “Fetch Attribute for current transport request
               attribute
          INTO TABLE t_attri
          FROM e070a
           FOR ALL ENTRIES IN t_tpchk
         WHERE attribute EQ t_tpchk-ztpattri
           AND trkorr    EQ request.

        IF sy-subrc  EQ 0.

          SORT t_attri
            BY ztkorr
               zattri.

        ENDIF.

      ENDIF.

      UNASSIGN <fs_tpchk>.

      LOOP AT t_tpchk
        ASSIGNING <fs_tpchk>.

        FREE w_result_tab.

 

“Check if transport short text contains project ID which is maintained in custom table.

 

        FIND ALL OCCURRENCES OF SUBSTRING <fs_tpchk>-zprojid IN text
          RESULTS w_result_tab.

        IF  sy-subrc     EQ 0
        AND w_result_tab IS NOT INITIAL.

          READ TABLE t_attri
            ASSIGNING <fs_attri>
            WITH KEY zattri = <fs_tpchk>-ztpattri
            BINARY SEARCH.

      IF  sy-subrc   NE 0  “If attribute is not maintained then throw error
      AND <fs_attri> IS NOT ASSIGNED.

            “Populate error message with Attribute Name
              (WITH <fs_tpchk>-ztpattri)

      ENDIF.

      ENDIF.

    ENDLOOP.

   ENDIF.
  ENDIF.

ENDMETHOD.

 

4.      4. BADI Implementation Result: If developer or functional tries to release transport request without maintaining required transport attribute error will be thrown. User will not be able to release request without maintaining attribute for our specific project.

 

                        screen12.jpg

 

This way we can eliminate the risk of missing the transport in final transport list for production.

 

 

  • Benefits of Transport Tracking:

1. Eliminate the risks:  Proper transport tracking will reduce potential human errors in preparing final transport lists.

2. Save efforts of change management:  If transports are managed properly within the project then it will reduce the burden of change  management which is required for missing transports movement.

3. Cost benefits:  It will reduce the cost which is required for extra change management efforts and rework on transports.

4. Less Rework: Production transport movement will be smoother and no rework will be needed for analysis of issues or errors.

 

Before moving transport list to production it is always a good idea to recheck the list.

 

Preventing transport movement issues and risks before production move is always better than solving them after production move.

 

Keeping the transport list clean and simple will prevent lot of issues arise later on

Understanding Widening Cast in ABAP Objects

$
0
0

There are many discussions about Widening cast in SCN. some say, it is Up casting while other say it is Down casting. I remember in a way as depicted below and still following the same.

 

Let's take a simple inheritance tree.

          inh_tree.jpg

 

Narrowing Cast:

2.jpg

 

Assigning/copying the instance of sub class to super class instance is called Narrowing Cast.

As shown in the figure, assigning sub class to super class is going up wards. From sub class(es) to super class while moving Up the path becomes narrow as shown in the left image. So I simply remember this. Narrowing cast = Up cast .

 

 

 

 

 

 

 

 

Widening Cast:

3.jpg

 

Assigning/coping the instance of super class to the sub class instance is called Widening Cast.

This is the reverse of Narrowing cast. As shown in the figure, assigning super class to sub class is going down wards. From super class to sub class while moving Down the path becomes wider as shown in the left image. So I simply remember this - Widening cast = Down cast.

 

 

 

 

 

 

 

 

I will still remember the above inheritance tree while referring casting and refer Widening cast as Down casting ( though is is referred as up casting from release 7.0).

 

Coming to the topic, I use Widening cast in this blog (instead of up/down casting ) .

 

To understand the Widening cast, I will just explain with the simple program.

 

Simple Inheritance Report
REPORT zkk_widening_cast_demo.

CLASS lcl_parent DEFINITION.
   PUBLIC SECTION.
     METHODS parent_method.

ENDCLASS.                    "lcl_parent DEFINITION

  CLASS lcl_child DEFINITION INHERITING FROM lcl_parent.
   PUBLIC SECTION.
     METHODS parent_method REDEFINITION.
     METHODS child_method.

ENDCLASS.                    "lcl_child DEFINITION

  CLASS lcl_parent IMPLEMENTATION.

   METHOD parent_method.
     WRITE / 'Called -> parent method in Parent Class!'.
   ENDMETHOD.                    "parent_method
ENDCLASS.                    "lcl_parent IMPLEMENTATION


CLASS lcl_child IMPLEMENTATION.

   METHOD parent_method.
     WRITE / 'Called -> parent redifinition method in Child Class!'.
   ENDMETHOD.                    "parent_method
   METHOD child_method.
     WRITE / 'Called -> child method in Child Class!'.
   ENDMETHOD.                    "child_method

ENDCLASS.                    "lcl_child IMPLEMENTATION

  START-OF-SELECTION.

   DATA: lr_parent TYPE REF TO lcl_parent,
         lr_child  TYPE REF TO lcl_child.

   CREATE OBJECT: lr_parent,lr_child.

   lr_parent->parent_method( ).
   lr_child->parent_method( ).
   lr_child->child_method( ).

 

Now after executing this I got the below output:

4.jpg

 

Now I am interested in child(sub) class method in my parent(super) class. Which mean when I call the 'parent_method' of parent class in the above report then it should call the 'parent_method' of child class( Redefined method call instead of original method call). So I do a Narrowing cast.

 

continuing the above report.

 

CREATE OBJECT: lr_parent,lr_child.   WRITE / 'Before Narrowing Cast:'.   lr_parent->parent_method( ).   lr_child->parent_method( ).   lr_child->child_method( ).
 *  Narrowing cast   lr_parent = lr_child.   WRITE / 'After Narrowing Cast:'.   lr_parent->parent_method( ).   lr_child->parent_method( ).   lr_child->child_method( ).

 

Now when I execute the above report, I get the below output, which is as expected.

5.jpg

 

Now I am interested in parent(super) class method in my child(sub) class. Which mean when I call the 'parent_method' of child class in the above report then it should call the 'parent_method' of super class( Super class method call instead of redefined sub class method call). So I do a Widening cast.

 

CREATE OBJECT: lr_parent,lr_child.   WRITE / 'Before Widening Cast:'.   lr_parent->parent_method( ).   lr_child->parent_method( ).   lr_child->child_method( ).   TRY .
 *   Widening Cast     lr_child ?= lr_parent.          WRITE / 'After Widening Cast:'.     lr_parent->parent_method( ).     lr_child->parent_method( ).     lr_child->child_method( ).   CATCH cx_sy_move_cast_error.     WRITE / 'Widening Cast Failed!'.   ENDTRY.

 

The output is as below:

6.jpg

After seeing the above output, we remember that " It is always not possible to do Widening cast as the sub class will have more functionality compared to super class" .

 

So, I removed the method definition 'child_method' in the child class and tried Widening cast. I got the same output!

 

I created an empty class definitions and tried widening cast to see the widening cast success message .

 CLASS lcl_parent DEFINITION.
 ENDCLASS.                    "lcl_parent DEFINITION
 CLASS lcl_child DEFINITION INHERITING FROM lcl_parent.
 ENDCLASS.                    "lcl_child DEFINITION
 CLASS lcl_parent IMPLEMENTATION.
 ENDCLASS.                    "lcl_parent IMPLEMENTATION
 CLASS lcl_child IMPLEMENTATION.
 ENDCLASS.                    "lcl_child IMPLEMENTATION
 START-OF-SELECTION.   DATA: lr_parent TYPE REF TO lcl_parent,         lr_child  TYPE REF TO lcl_child.   CREATE OBJECT: lr_parent,lr_child.   TRY .
 *   Widening Cast     lr_child ?= lr_parent.     WRITE / 'Widening Cast Success!'.   CATCH cx_sy_move_cast_error.     WRITE / 'Widening Cast Failed!'.   ENDTRY.

 

Now we will see the output which we are all waiting for!

10.jpg

 

disappointed? 

 

The above example was taken from one of the tweets of  Uwe Fetzer and is the motivation for writing this blog.

 

7.jpg

 

The Widening cast will always fail unless the assigning instance has the same type of instance to which we are assigning.

 

So people used to tell do Narrowing cast before Widening Cast!, to have the assigning instance same reference.

 

I will take the main report and do a narrowing cast before widening cast.

 

REPORT zkk_widening_cast_demo.
 CLASS lcl_parent DEFINITION.   PUBLIC SECTION.     METHODS parent_method.
 ENDCLASS.                    "lcl_parent DEFINITION
 CLASS lcl_child DEFINITION INHERITING FROM lcl_parent.   PUBLIC SECTION.     METHODS parent_method REDEFINITION.     METHODS child_method.
 ENDCLASS.                    "lcl_child DEFINITION
 CLASS lcl_parent IMPLEMENTATION.   METHOD parent_method.     WRITE / 'Called -> parent method in Parent Class!'.   ENDMETHOD.                    "parent_method
 ENDCLASS.                    "lcl_parent IMPLEMENTATION
 CLASS lcl_child IMPLEMENTATION.   METHOD parent_method.     WRITE / 'Called -> parent redifinition method in Child Class!'.   ENDMETHOD.                    "parent_method   METHOD child_method.     WRITE / 'Called -> child method in Child Class!'.   ENDMETHOD.                    "child_method
 ENDCLASS.                    "lcl_child IMPLEMENTATION
 START-OF-SELECTION.   DATA: lr_parent TYPE REF TO lcl_parent,         lr_child  TYPE REF TO lcl_child.   CREATE OBJECT: lr_parent,lr_child.   WRITE / 'Before Widening Cast:'.   lr_parent->parent_method( ).   lr_child->parent_method( ).   lr_child->child_method( ).   lr_parent = lr_child. " Narrowing cast   TRY .
 *   Widening Cast     lr_child ?= lr_parent.     WRITE / 'After Widening Cast:'.     lr_parent->parent_method( ).     lr_child->parent_method( ).     lr_child->child_method( ).   CATCH cx_sy_move_cast_error.     WRITE / 'Widening Cast Failed!'.   ENDTRY.

 

Now lr_parent has same type of lr_child as we did Narrowing cast. We will see the output:

8.jpg

Wow! widening cast is successful this time. But we can see that this output is same as the output of Narrowing cast shown above (which is not what we required).

 

Because, we have copied the lr_child instance to lr_parent ( lr_parent = lr_child " Narrow cast) before widening cast. Now lr_parent has same type of lr_child and we assign lr_child ?= lr_parent which is noting but copying child class instance to child class instance!

 

So, when this Widening cast is actually useful?

 

To explain this, I will take a simple example using interfaces:

 

REPORT zkk_widening_cast_demo.
 INTERFACE lif_test.   METHODS interface_method.
 ENDINTERFACE.                    "lif_test
 CLASS lcl_myclass DEFINITION.   PUBLIC SECTION.     INTERFACES lif_test.
 ENDCLASS.                    "lcl_class1 DEFINITION
 CLASS lcl_myclass IMPLEMENTATION.   METHOD lif_test~interface_method.     WRITE / 'Interface method call in My Class'.   ENDMETHOD.                    "lif_test~interface_method
 ENDCLASS.                    "lcl_class1 IMPLEMENTATION
 START-OF-SELECTION.   DATA: lr_intf TYPE REF TO lif_test,         lr_mine TYPE REF TO lcl_myclass.   CREATE OBJECT lr_intf TYPE lcl_myclass.   TRY .
 *   Widening Cast       lr_mine ?= lr_intf.       WRITE /'Widening Cast Successful!'.     CATCH cx_sy_move_cast_error.       WRITE / 'Widening Cast Failed!'.   ENDTRY.

 

Output:

9.jpg

Since we cannot directly assign the interface reference to class reference,

 

As using, lr_mine = lr_intf   " will give syntax error because lr_intf is not the same type of lr_mine.

 

So we do a Widening cast, lr_mine ?= lr_intf , which won't give syntax check and at run time if lr_intf contains the same reference of lr_mine, the reference will be copied else the exception will be thrown.

 

Now lets take one more class to understand better.

REPORT zkk_widening_cast_demo.
 INTERFACE lif_test.   METHODS interface_method.
 ENDINTERFACE.                    "lif_test
 CLASS lcl_myclass DEFINITION.   PUBLIC SECTION.     INTERFACES lif_test.
 ENDCLASS.                    "lcl_class1 DEFINITION
 CLASS lcl_yourclass DEFINITION.   PUBLIC SECTION.     INTERFACES lif_test.
 ENDCLASS.                    "lcl_class2 DEFINITION
 CLASS lcl_myclass IMPLEMENTATION.   METHOD lif_test~interface_method.     WRITE / 'Interface method call in My Class'.   ENDMETHOD.                    "lif_test~interface_method
 ENDCLASS.                    "lcl_class1 IMPLEMENTATION
 CLASS lcl_yourclass IMPLEMENTATION.   METHOD lif_test~interface_method.     WRITE / 'Interface method call in Your class'.   ENDMETHOD.                    "lif_test~interface_method
 ENDCLASS.                    "lcl_class2 IMPLEMENTATION
 START-OF-SELECTION.   DATA: lr_intf TYPE REF TO lif_test,         lr_mine TYPE REF TO lcl_myclass,         lr_your TYPE REF TO lcl_yourclass.
 *  CREATE OBJECT lr_intf TYPE lcl_myclass.   CREATE OBJECT lr_intf TYPE lcl_yourclass.    TRY .
 *      Widening Cast        lr_mine ?= lr_intf.        WRITE /'Widening Cast Successful!'.      CATCH cx_sy_move_cast_error.        WRITE / 'Widening Cast Failed!'.    ENDTRY.

 

In this case the widening cast will be failed since lr_intf is not of same type as lr_mine.

 

We use widening cast mainly while dealing with interfaces and in case of dynamic programming.

 

Now, If we look at the below statement

 

CREATE OBJECT lr_intf TYPE lcl_yourclass.    TRY .
 *      Widening Cast        lr_mine ?= lr_intf.        WRITE /'Widening Cast Successful!'.      CATCH cx_sy_move_cast_error.        WRITE / 'Widening Cast Failed!'.    ENDTRY.

 

is nothing but Narrowing cast before widening cast,

DATA lr_mine1 TYPE REF TO lcl_myclass.   CREATE OBJECT lr_mine1.   lr_intf = lr_mine1.  " Narrowing Cast   TRY .
 *      Widening Cast       lr_mine ?= lr_intf.       WRITE /'Widening Cast Successful!'.     CATCH cx_sy_move_cast_error.       WRITE / 'Widening Cast Failed!'.   ENDTRY.

 

So in this context, "Do Narrowing cast before Widening cast"  makes sense without confusion!

 

Hope I tried to explain Widening cast to some extent!.  Comments are welcome


Background jobs with users for authorization - report

$
0
0

Recently I had an issue to make an report for background jobs that are planned to run from dialog user. All informations I needed was in transaction sm37, but for every job I had to double click on it and go to 'step' options to check background user name. I made an ABAP program which make this report for me. Some of those jobs have more than one step, my report takes them into account. Here you have my program code, to make it working you have to create screen with container for alv list, gui status, and structures in se11: zbackground_jobs and zbackground_jobs_3f. Screenshots with structures and gui are attached.

 

Background jobs report

REPORT Z_BGJ_REPORT.

data: container_r type ref to cl_gui_custom_container,

       grid_r type ref to cl_gui_alv_grid.

 

data: it_bgj type table of zbackground_jobs,

       it_bgjt type table of zbackground_jobs_3f,

       wa_bgj type zbackground_jobs,

       wa_usr02 type usr02,

       wa_tbtcpv type tbtcpv.

 

select JOBNAME JOBCOUNT STATUS from TBTCO into corresponding fields of table it_bgjt where status = 'S'.

 

Loop at it_bgjt into wa_bgj.

   select * from tbtcpv into wa_tbtcpv where JOBCOUNT = wa_bgj-JOBCOUNT and JOBNAME = wa_bgj-JOBNAME.

     wa_bgj-AUTHCKNAM = wa_tbtcpv-AUTHCKNAM.

   select single * from usr02 into wa_usr02 where bname = wa_bgj-authcknam.

     wa_bgj-ustyp = wa_usr02-ustyp.

   append wa_bgj to it_bgj.

   endselect.

endloop.

 

call screen 321.

 

*&---------------------------------------------------------------------*

*&      Module  alv_pbo_876  OUTPUT

*&---------------------------------------------------------------------*

*       text

*----------------------------------------------------------------------*

MODULE STATUS_0321 OUTPUT.

   SET PF-STATUS 'LIST_STATUS'.

   if container_r is initial.

CREATE OBJECT CONTAINER_R

   EXPORTING

*    PARENT                      =

     CONTAINER_NAME              = 'ALV_CONTAINER'

*    STYLE                       =

*    LIFETIME                    = lifetime_default

*    REPID                       =

*    DYNNR                       =

*    NO_AUTODEF_PROGID_DYNNR     =

*  EXCEPTIONS

*    CNTL_ERROR                  = 1

*    CNTL_SYSTEM_ERROR           = 2

*    CREATE_ERROR                = 3

*    LIFETIME_ERROR              = 4

*    LIFETIME_DYNPRO_DYNPRO_LINK = 5

*    others                      = 6

     .

IF SY-SUBRC <> 0.

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

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

ENDIF.

 

CREATE OBJECT GRID_R

   EXPORTING

*    I_SHELLSTYLE      = 0

*    I_LIFETIME        =

     I_PARENT          = container_r

*    I_APPL_EVENTS     = space

*    I_PARENTDBG       =

*    I_APPLOGPARENT    =

*    I_GRAPHICSPARENT  =

*    I_NAME            =

*    I_FCAT_COMPLETE   = SPACE

*  EXCEPTIONS

*    ERROR_CNTL_CREATE = 1

*    ERROR_CNTL_INIT   = 2

*    ERROR_CNTL_LINK   = 3

*    ERROR_DP_CREATE   = 4

*    others            = 5

     .

IF SY-SUBRC <> 0.

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

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

ENDIF.

 

   CALL METHOD GRID_R->SET_TABLE_FOR_FIRST_DISPLAY

     EXPORTING

*      I_BUFFER_ACTIVE               =

*      I_BYPASSING_BUFFER            =

*      I_CONSISTENCY_CHECK           =

       I_STRUCTURE_NAME              = 'zbackground_jobs'

*      IS_VARIANT                    =

*      I_SAVE                        =

*      I_DEFAULT                     = 'X'

*      IS_LAYOUT                     =

*      IS_PRINT                      =

*      IT_SPECIAL_GROUPS             =

*      IT_TOOLBAR_EXCLUDING          =

*      IT_HYPERLINK                  =

*      IT_ALV_GRAPHICS               =

*      IT_EXCEPT_QINFO               =

*      IR_SALV_ADAPTER               =

     CHANGING

       IT_OUTTAB                     = IT_BGJ

*      IT_FIELDCATALOG               =

*      IT_SORT                       =

*      IT_FILTER                     =

*    EXCEPTIONS

*      INVALID_PARAMETER_COMBINATION = 1

*      PROGRAM_ERROR                 = 2

*      TOO_MANY_LINES                = 3

*      others                        = 4

           .

   IF SY-SUBRC <> 0.

*   Implement suitable error handling here

   ENDIF.

   endif.

 

ENDMODULE.                 " alv_pbo_321  OUTPUT

*&---------------------------------------------------------------------*

*&      Module  USER_COMMAND_0321  INPUT

*&---------------------------------------------------------------------*

*       text

*----------------------------------------------------------------------*

MODULE USER_COMMAND_0321 INPUT.

case sy-ucomm.

     when 'E'.

       leave to screen 0.

     when 'B'.

       leave program.

     when 'C'.

       leave program.

   endcase.

ENDMODULE.                 " USER_COMMAND_0321  INPUT


 

If you have problem to run this code - just look what tables I am using and make a report on your own or just review the tables.

Good luck!

 

Regards

Gabriel

Survey Bachelor Thesis - Security Risks in the SAP Environment

$
0
0

Dear SAP Community,


My name is Rick Trojahn and I study Business Informatics. I am currently working on my bachelor thesis. Therefore I created a survey on security risks in the SAP environment. I am having problems to find SAP programmers who would like to participate in my survey therefore any help will be highly appreciated!!!


 

A tutorial on how to use the survey can be found here: www.ricktrojahn.com/survey-tutorial.pdf

 

The survey itself can be found here: www.ricktrojahn.com/survey.xls

 


 

It would be nice of you to return the completed survey via email (see my account)

 

 

Thank you so much for your participation! If you have any questions feel free to contact me.

 

 

Kind Regards

Rick Trojahn

MS-Office change Layout using Open XML for SAP

$
0
0

Hello.

Often when we create documents Templates we are

wasting a lot of time and effort on visualize these documents.

In the screen cast below there is an example of how easy it

could be with using Open XML for SAP, to change some

Visual attributes of the Template.

 

 

This just one demonstration of a lot of Visual Attributes

we can have in using MS-Office with SAP.

In the blogs to come

I will try to give some more examples.

 

   Ronen Almog

Use of Standard SAP function modules in custom development

$
0
0

Hello,

 

I work on SAP Product Support. There are several incidents opened by customers related to the use of Standard SAP function modules (FM) in custom development. Basically they use a standard FM in their custom code and it does not work as they expected, then they open an OSS message asking why it does not work as they wish. My goal with this post is to share some information about FM not released for customer's use, since there are several customers that are not aware of this restriction.

 

When considering to use standard SAP FM in custom development, firstly it is advisable to check if it is released (or not) for customer' use. It is possible to check check it in tab "Attributes" when displaying the function module in transaction SE37, as shown below:

notreleased1.PNG

 

In the sample above, function module RS_VARIANT_DISPLAY is not released for customer use, hence not supported. When a function module is flagged as "Not released", SAP recommends that customers avoid using this object in their custom code. However, it is not forbidden. You can use this function as it is a global function. However, it will not be supported by SAP if it does not work as you expected. Besides, SAP might change, remove or rename this object at anytime by an upgrade or support package.

 

So it is kind of useless to open an OSS message in such cases. However, there are some alternatives:

  1. Look for a standard functionality that can be used instead;
  2. Develop the desired functionality on your own by a custom development;
  3. Create a copy of standard function and use it. Then you can adjust it as you need.

 

Further information can be found on the following notes:

SAP Note 109533 - Use of SAP function modules

SAP KBA 1909989 - Standard SAP function modules do not work as expected in custom development

 

Best regards,

Maurício Grisa.

Shortcuts that can make an ABAP'er life easier

$
0
0

Introduction

 

ABAP is quite different from many contemporary programming languages in several ways. Some aspects of ABAP would make us wonder why is it made this complex while some aspects are so awesome and more comfortable for a programmer than any other language can provide.

 

Two of those things that I find so cool are:

  • Its ingenuous IDE (ABAP Editor) and
  • Its cool Debugger

 

Eventhough the SAP IDE does not support some of the features which more prominent IDE's like Eclipse etc have, I find it so comfortable to code in ABAP Editor compared to others. The reason is because of the below shortcuts and customizations available with it. I am listing the few which I use constantly and without which I cannot think of coding ABAP.

 

Most of the programmers even with a little bit of ABAP experience would have come accross the details listed here. If you have, please ignore and if you haven't then the stage is yours..

 

Shortcut

What it does

Ctrl + D

Duplicate any line.

eg. i_vbap TYPE STANDARD TABLE OF vbap + Ctrl-D = i_vbap TYPE STANDARD TABLE OF vbap
i_vbap TYPE STANDARD TABLE OF vbap

Ctrl + /

Jump to the "command field" where we enter t-codes. This comes really handy and saves a jump from keyboard to mouse and back to keyboard just to click on the box.

Ctrl + J

Convert to Proper case where the first letter of every word becomes a capital letter. This is pretty useful when writing comments.

eg.  * this is a comment which will give absolutely no useful information will be changed to
* This Is A Comment Which Will Give Absolutely No Useful Information

Ctrl + I  &
Ctrl + Shift + I

Incremental search. This is a little improved 'Find' (Ctrl + F) function which searches as soon as you type. Useful for impatient people. Add shift to search backwards.

Ctrl + K

Toggle between Upper case and Lower Case.

Alt + Selection

This is useful in situation where you need to select only the field names of a particular table.

eg.

caufv-aufnr,

caufv-werks,

caufv-objnr,

caufv-plnbez,

caufv-gamng,

caufv-gasmg,

caufv-gmein,

caufv-plnnr,

caufv-plnal,

caufv-dispo,

caufv-fevor,

caufv-cy_seqnr ,

caufv-aufpl,

caufv-gstrp,

caufv-gltrp,

caufv-gstrs,

caufv-gltrs,

caufv-gstri,

caufv-gltri,

 

In these values, u can select only the field names by pressing Alt key and get the clipboard filled like this.

 

aufnr,

werks,

objnr,

plnbez,

gamng,

gasmg,

gmein,

plnnr,

plnal,

dispo,

fevor,

cy_seqnr ,

aufpl,

gstrp,

gltrp,

gstrs,

gltrs,

gstri,

gltri,

Tab & Shift tab

Increase and Decrease Intend

Ctrl + O

Goto a particular line in the program

Ctrl + Shift + S

Save your program in Desktop in .abap format. I came know about .abap only after learning this short cut.

Ctrl + Selection

When you do a selection with **** + -> or <- hold on to Ctrl to jump every word in that direction.

Ctrl + . & Ctrl + ,

Comment and Un-Comment selected lines.

Ctrl+Alt+T

Swaps current line with the Upper Line.
eg. INCLUDE ZTEST_ABAP_HTTP_CLIENT_TOP.
     INCLUDE ZTEST_ABAP_HTTP_CLIENT_C01. becomes


INCLUDE ZTEST_ABAP_HTTP_CLIENT_C01.
INCLUDE ZTEST_ABAP_HTTP_CLIENT_TOP.

Ctrl+Shift+L/XDeletes the whole line

 

More Editor Tools:

 

Apart from this, there are a few other things that can be set in Editor options

 

 

like,

 

Code Templates

 


 

 

Here I use a template for the text. This could be a text that is used for marking modifications or Defenition and implementation of local classes etc.


  * Begin of Insertion <SID>K12345 <username>
* End of Insertion   <SID>K12345  <username>

 

i.e when I press i* in the editor, it will prompt for code completion..

 


 

When I press Tab for completion, it pops up for TR Number…

 

 

The TR number that we give will be added in the comment.


Variable Name Suggestions

This is just a small setting but it will save you from Copy pasting or re-typing small words.

 

When you check this box, it will suggest even for variable names like…

 

Particularly useful for longer variable names.

 

 

Conclusion

 

Apart from the editor and debugger functions, the navigation and where used-list  are other funtionalities which we use more often. Especially the code maintenance and support activities are comparitively less hectic just because these features.

 

Another cool way to extend its core editor functionality for customizations could be by providing API's even for the application programmers to code and customize the editor features. It will also add to the creativity aspect on SAP side since any third programmer could come with an awesome idea as an editor extension.

 

As far as I have explored, I havent found any BADI or classes which can be used to perform editor functions. May be I have to look more or wait...


Survey Bachelor Thesis - Security Risks in the SAP Environment

$
0
0

Dear SAP Community,


My name is Rick and I study Business Informatics. I am currently working on my bachelor thesis. Therefore I created a survey on security risks in the ABAP Code. I am having problems to find SAP programmers who would like to participate in my survey therefore any help will be highly appreciated!!!

 


 

A tutorial on how to use the survey can be found here: www.ricktrojahn.com/survey-tutorial.pdf

 

The full survey itself can be found here (20 minutes): www.ricktrojahn.com/survey.xls

 

The short version survey can be found here (5 - 10 minutes):https://docs.google.com/forms/d/1y_hqb0QIcmuFs_IVE2BdRSrHDBYp_HPzs2dSMgnh0wk/viewform


 

It would be nice of you to return the completed full survey via email (see my account)

 

 

Thank you so much for your participation! If you have any questions feel free to contact me.

 

 

Kind Regards

Rick

Create flexible database tables for your applications.

$
0
0

Most of us today, working on SAP solutions have to create custom applications. These applications may be simple program to as complex as designed across multiple SAP / Non-SAP systems. One of the most important design requirements to tackle for these custom applications is the application configuration. If it is custom, 90% of the cases require custom configurations on which the application runs. These configurations also validate the underlying assumptions on which the application is designed.

 

Sometimes these configurations might be so small that they end up as constants or hard coded values. Sometimes they might end up as tables. The main problem is to understand how to define these configurations so that the code consuming it can remain generic to support reuse, scalability and flexibility objectives.

 

In my early days as a developer I was responsible for developing configuration and logic, which would for the first time be consumed by one application but over the years the same would be used by multiple similar applications. I was lucky to have a seasoned SAP developer who was collaborating with me on this development. He told me that from his experience for the first and may be even second time when we are designing these models it is very difficult to make them generic and I second that thought since it is very difficult for the application teams to have that long a vision about the applications as well as the availability of time to accomplish the same.

 

Also most of the teams across the world are switching onto Agile Development methodologies (which most of them abuse) in which the requirements and design evolve over a period of time, it is more than necessary to make the foundation (configuration) flexible enough to reduce the impact of continuous
change.

 

So here I used several learning’s from the past and came out with a concept which is flexible enough to work in any application that you create and is complimented by similar code support in other development languages like JAVA.

 

 

The case with which I want to explain this concept is that of a website. I have to create a website which will be used to sell my products in multiple subsidiaries. Each subsidiary will have its specific pricing, promotions, quota logic, order types and a lot more. For simplicity sake I will take examples of Switzerland and Germany. Apart from business logic, I want to reuse the code that I am developing for my site like the UI rendering language and other things. I also have web services to integrate my SAP backend with the site (another blog would come up soon to talk about creating just one web service to cater to all logic).

 

So how do I define my application configuration:-

 

 

  • Create a database table with some key fields ( I would use just one string or char field to store values like SWISS_UI, SWISS_PRICING, SWISS_QUOTA, SWISS_ORG, GERMAN_ORG etc) which can help you create unique config types.

 

  • Have a string define which will store all the attributes as an XML string.

 

  • Create a XSLT transformation to encode and decode the XML string.

 

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>

<xsl:template match="/">

<xsl:copy-of select="."/>

</xsl:template>

</xsl:transform>

 

  • Have a mapping structure which is a universal set of all relevant attributes related to a config type.

 

  • Create a setter ( an FM, Report, Class Method – Most preffered ) which will generate the record for the table

   
data
: tab1 type ref to data,
vbak_tab
type table of vbak,
vbak_wa
type vbak.

create data tab1 type table of vbak.

field-symbols : <tab1> type any table.

assign tab1->* to <tab1> .

select * from vbak into table <tab1> up to 1 rows.

call TRANSFORMATION transformation
SOURCE record_data
= <tab1>
result xml xml_string
.

 

 

  • Create a getter that will read the config record and reverse transform into my mapping structure which can be consumed in relevant areas of my application.

 

Call TRANSFORMATION transformation
source xml xml_string
result record_data
= <tab1>.

 

  • To map you can also use CL_ABAP_TYPEDESCR class to create another layer of generic code.

 

So this is a just a concept which you can use in your applications. You can also use it to create custom log tables, staging tables just anything where you are working with an evolving data model. Do comment if you have used any other similar approach for creating applications.


How to log any changes in MM01/MM02 customer subscreen and table

$
0
0

Sometimes clients need to log any changes made by user on customer created screen and Z table in MM01/MM02.

 

You can do it by activate user-exit at save (for example):

at user-exit insert your code:

            CALL FUNCTION 'ZMM_ZMMLABEL_CREATE_LOG'
            EXPORTING
              i_matnr     = rmmg1-matnr
              i_werks     = rmmg1-werks
              i_change_id = ('I' for insert new record, 'D' when you delete record, 'U' for update)

              i_zmmlabel  = l_zmmlabel.

 

and you must create FM:

   FUNCTION zmm_zmmlabel_create_log .
*"----------------------------------------------------------------------
*"*"Update Function Module:
*"
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(I_MATNR) LIKE  RMMG1-MATNR
*"     VALUE(I_WERKS) TYPE  RMMG1-WERKS
*"     VALUE(I_CHANGE_ID) TYPE  CDHDR-CHANGE_IND
*"     VALUE(I_ZMMLABEL) TYPE  ZMMLABEL
*"----------------------------------------------------------------------
  DATA: lt_zmmlabel   LIKE TABLE OF zmmlabel,
        zmmlabel_old  LIKE zmmlabel,
        objectid      LIKE cdhdr-objectid,
        objectclass   LIKE cdhdr-objectclas,
        tablename     LIKE cdpos-tabname,
        change_id     LIKE cdhdr-change_ind.


*  MOVE-CORRESPONDING i_zmmlabel TO zmmlabel.

  tablename   = 'ZMMLABEL'.
  objectid    = i_matnr.
  objectclass = 'MATERIAL'.

* Manage change document
  IF i_change_id = 'D'.
    CLEAR i_zmmlabel.

    SELECT * FROM zmmlabel INTO TABLE lt_zmmlabel
     WHERE matnr   = i_matnr
       AND werks   = i_werks.

    IF sy-subrc = 0.
      LOOP AT lt_zmmlabel INTO zmmlabel_old.

        CALL FUNCTION 'YMM_CREATE_CHANGE_DOCUMENT'
          EXPORTING
            objectclass      = objectclass
            objectid         = objectid
            tablename        = tablename
            workarea_new     = i_zmmlabel
            workarea_old     = zmmlabel_old
*            change_indicator = i_change_id
            change_indicator = 'U'. " if you need log all changes, please use U mode
        COMMIT WORK.

        CLEAR zmmlabel_old.
      ENDLOOP.

      DELETE zmmlabel FROM TABLE lt_zmmlabel.

      COMMIT WORK.
*      COMMIT WORK AND WAIT.
    ENDIF.

  ELSEIF i_change_id = 'U'.

    SELECT SINGLE * FROM zmmlabel INTO zmmlabel_old
     WHERE matnr   = i_matnr
       AND werks   = i_werks
       AND counter = zmmlabel-counter.

    CALL FUNCTION 'YMM_CREATE_CHANGE_DOCUMENT'
      EXPORTING
        objectclass      = objectclass
        objectid         = objectid
        tablename        = tablename
        workarea_new     = i_zmmlabel
        workarea_old     = zmmlabel_old
        change_indicator = i_change_id.

    COMMIT WORK.

    MODIFY zmmlabel FROM i_zmmlabel.

    COMMIT WORK.

*    COMMIT WORK AND WAIT.

  ELSEIF i_change_id = 'I'.
    CLEAR zmmlabel_old.

    CALL FUNCTION 'YMM_CREATE_CHANGE_DOCUMENT'
      EXPORTING
        objectclass      = objectclass
        objectid         = objectid
        tablename        = tablename
        workarea_new     = i_zmmlabel
        workarea_old     = zmmlabel_old
*            change_indicator = i_change_id
        change_indicator = 'U'. " if you need log all changes, please use U mode

    COMMIT WORK.

    MODIFY zmmlabel FROM i_zmmlabel.

    COMMIT WORK.

*    COMMIT WORK AND WAIT.

  ENDIF.
ENDFUNCTION.

 

   FUNCTION YMM_CREATE_CHANGE_DOCUMENT.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(OBJECTCLASS) LIKE  CDHDR-OBJECTCLAS
*"     VALUE(OBJECTID) LIKE  CDHDR-OBJECTID
*"     VALUE(TABLENAME) LIKE  CDPOS-TABNAME
*"     VALUE(WORKAREA_NEW) DEFAULT SPACE
*"     VALUE(WORKAREA_OLD) DEFAULT SPACE
*"     VALUE(CHANGE_INDICATOR) DEFAULT 'U'
*"----------------------------------------------------------------------

  call function 'CHANGEDOCUMENT_OPEN'
       exporting
            objectclass      = objectclass
            objectid         = objectid
       exceptions
            sequence_invalid = 1
            others           = 2.
  call function 'CHANGEDOCUMENT_SINGLE_CASE'
       exporting
            tablename              = tablename
            workarea_old           = workarea_old
            workarea_new           = workarea_new
            change_indicator       = change_indicator
       exceptions
            nametab_error          = 1
            open_missing           = 2
            position_insert_failed = 3
            others                 = 4.
  case sy-subrc.
    when 1. message a850(m3) with 'NAMETAB-ERROR'.
    when 2. message a850(m3) with 'OPEN MISSING'.
    when 3. message a850(m3) with 'INSERT ERROR'.
    when 4. message a850(m3) with 'SINGLE ERROR'.
    when others.
  endcase.
*
  udate = sy-datum.
  utime = sy-uzeit.
  tcode = sy-tcode.
  username = sy-uname.
*
  call function 'CHANGEDOCUMENT_CLOSE'
       exporting
            objectclass             = objectclass
            objectid                = objectid
            date_of_change          = udate
            time_of_change          = utime
            tcode                   = tcode
            username                = username
            object_change_indicator = change_indicator
       exceptions
            header_insert_failed    = 1
            object_invalid          = 2
            open_missing            = 3
            no_position_inserted    = 4
            others                  = 5.

  case sy-subrc.
    when 1. message a850(m3) with 'INSERT HEADER FAILED'.
    when 2. message a850(m3) with 'OBJECT INVALID'.
    when 3. message a850(m3) with 'OPEN MISSING'.
    when 5. message a850(m3) with 'CLOSE ERROR'.
    when others.
  endcase.

ENDFUNCTION.

How to Implement Function Module Exits using BADI

$
0
0

Hi Developers ,

 

Consider a scenario in which you are going to create BADI definition as well for a customer exit.

Here are the steps:

 

a ) Find out the correct customer exit for your requirement from the functional team.


      1.png

 

b ) Create enhancement in CMOD and activate the components. (See below screens)

 

     2.png

       3.png

 

         4.png

 

c)   Go to SE18 and create a BADI definition.

       5.png

d)  Create an instance method (public) for the BADI with parameters (if needed).

        

       6.png

          7.png

 

e)  Create implementation for the BSDI.

 

                8.png

 

                    

                     9.png

 

f)     Here, see the method (public) created in definition is already assigned to your implementation (EXIT_SAPLFMR4_002).

 

               10.png

               

g )  Apply the validation in the public method and business logic in private method. Call the private method in the public method after validation.

         

               11.png

 

                 12.png


Now, next step is how to call the BADI from the customer exit.

                         

                       

a)  Go to your customer exit program.

                      

                     13.png

 

b)  Create an instance of your BADI interface and call the public method (e.g. EXIT_SAPLFMR4_002).

      

                     14.png

                       15.png

 

c) The BADI (ZBADI_ZXFMCU08) is multiple uses BADI. In future if there requirements for the same customer exit, create a new implementation and a private method to apply logic in the BADI.

 


Hope this blog will prove helpful ,Pls feel free to reach out for anything !

 

 

 

Thanks and Regards,

Praveen Srivastava

Get RFC Destination Dynamically in SAP ABAP

$
0
0

Function module to get RFC destinations.

 

In CRM system FM CRM_AV_CHECK_R3_GET_DESTIN  can be used to get destination as follows,

 

  Data: lv_dest     type rfcdest.

  call function 'CRM_AV_CHECK_R3_GET_DESTIN'
      importing
        ev_destination  = lv_dest
      exceptions
        invalid_release = 1
        others          = 2.


  Another way in CRM side,

 

  DATA: lt_erpsites  TYPE STANDARD TABLE OF  smof_erpsh,
        ls_erpsites  TYPE    smof_erpsh, 
        lv_dest  TYPE   rfcdest. 
   
* * Read ERP destination
  CALL FUNCTION 'SMOF_READ_SMOFERPSH'
    EXPORTING
      i_sitetypeid = 'SMOF_ERPSITE'
      i_mandt      = sy-mandt
    TABLES
      t_erpsites   = lt_erpsites.
 
  READ TABLE lt_erpsites INTO ls_erpsites INDEX 1.
  lv_dest = ls_erpsites-rfcdest.

 

 

In ECC system FM CRM0_READ_RFC_DEST  can be used to get destination as follows,

 

  Data: lt_dest   type table of CRMRFCPAR.

  CALL FUNCTION 'CRM0_READ_RFC_DEST'
    EXPORTING
      I_CONSUMER             = 'CRM'
      i_download_type          = ' '
      i_objname                   = ' '
    tables
      t_crmrfcpar           = lt_dest.

 

From the lt_dest internal table we have to pick the rfcdest value.

 

A Dream for SE80 - Github Integration

$
0
0

When I heard Code Exchange was closing, I was bummed.  I read that a new code exchange 2.0 is being developed, but as I write this it is still under construction.  As many people have pointed out, however, that doesn't need to stop SAP developers from sharing code with one another.

 

For us ABAPers, we have few choices on how to share code, and it's not easy to share non-code development objects.  For simple programs, I can copy and paste from any forum, but what about a program has a dozen custom data elements and a few custom global classes?  Well, thanks to the fantastic SAPLink project (with which I am not affiliated), that has become a lot easier.  It's as easy as downloading a .nugg file and importing it, or so I hear.

 

I want to take the idea behind SAPLink one step further.  Instead of searching the web via browser (and by the web, I mean Google Code and Github) for a .nugg file, downloading it to a file directory, and importing it via SAPGUI, can't we do this all from SAPGUI?  We're trying to share code, so why not share while using the place where we work on the code, i.e. SE80?  If you're thinking, "That's not where I work on the code!  I use Eclipse!" well, good for you.  I hope to join your smug ranks soon, but most of what I'm proposing is probably applicable to Eclipse development too.  Certainly an ABAP-based github client is reusable.

 

So rather than spending 5 minutes explaining it, I spent half an hour stumbling through MS Paint, drawing what I had in mind.

 

Github Mockup SCN.png

 

Seriously, how cool would this be?

 

From what I can tell, although it's not possible to add tools to SE80 like this, it would still be very helpful to copy the general UI into another transaction.  It could have two or three pushbuttons on the left like SE80, but they would be along the lines of Github Repositories, Search Github, and Package Browser.  From github repositories, you could view your own repos.  Search Github would return a results list of repos, from which you could view the contents, readme, and import as an SAP development package.  Package Browser would allow a user to select and push his or her development packages to github.

 

Right now I'm thinking a 1-to-1 ratio of packages to repositories would work best for code management and sharing.  If I download/clone a repository, it becomes a package, and if I push a package to github, it becomes a repository, and any subpackages do not - they are just part of the .nugg file.

 

There are a few problems that need answers if this will get developed, such as how to handle the github readme files, but boy howdy, this would be a dream come true.

 

If this were developed, would you use it?  What other features would you like to see?

ABAP – Statement Patterns

$
0
0

SAP ABAP Editors like SE37 / SE38 have provided cool feature of Patterns. One can add ready made statements into his program directly and modify as required. This is very useful when programmer has to deal with complex statements frequently because adding template type patterns avoids risk of errors and reduces efforts of typing. Making patterns of frequent queries ensures correct syntax.

 

 

How to use statement patterns in the ABAP Editor:

...

1.          1.       In change mode of ABAP editor, click on Pattern button on tool bar and you will see a pop up with different options to choose from

2.       Choose the required pattern and, if necessary, the statement. Click on continue.

3.       Fill out the pattern with the required information.

4.       Choose continue to confirm your entries.

5.       The system inserts the statement at the cursor position in the program code.

 

 

This is the list of pattern options:

 

Statement

Explanation

CALL FUNCTION

Inserts a function call.

ABAP Objects pattern

Inserts the following basic ABAP Objects statements:

CALL METHOD

CREATE OBJECT

RAISE EVENT

RAISE EXCEPTION

MESSAGE

Inserts a MESSAGE statement for a specified message. You need to enter a message ID, a message type and number.

SELECT * FROM

Inserts a SELECT FROM <table> statement. You need to enter a name of an existing table and then select the fields you want to be included in your SELECT statement.

PERFORM

Inserts a PERFORM statement for a specified form.

AUTHORITY-CHECK

Inserts an AUTHORITY-CHECK statement for a specified authorization object.

WRITE

Inserts a WRITE statement for a specified structure or table.

CASE

Inserts a CASE statement for a specified status.

Structured Data Object

  • With fields from structure
  • With TYPE for structure

Inserts a structured data object. You can copy the fields or the structure of an existing table.

CALL DIALOG

A CALL DIALOG statement for a specified dialog module.

Other pattern

Inserts a predefined or user-defined ABAP statement.

(Source http://help.sap.com)

 

Other pattern:

 

This is a custom template type; we can create any code snippet up to 100 lines.

 

 

To create new patterns, click on Utilities > More Utilities > Edit Pattern > Create Pattern

To change new patterns, click on Utilities > More Utilities > Edit Pattern > Change Pattern

To delete new patterns, click on Utilities > More Utilities > Edit Pattern > Delete Pattern

To display new patterns, click on Utilities > More Utilities > Edit Pattern > Display Pattern

 

 

Pattern names are not user specific so common patterns can be created which can be used across all users.

 

 

Happy Coding!

Viewing all 943 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>