Quantcast
Channel: SCN : Document List - ABAP Development
Viewing all 935 articles
Browse latest View live

Excel worksheet reading from SAP application server

$
0
0

Issue Faced:

Excel worksheet reading from SAP application server  will  not work, file should be either  .xml  based excel file or .csv based excel or .dat type excel file  to be read from application server

Normal Excel-File  reading from the application server is not possible because, the Excel format before Office 2007 where a binary format (Suffix: .xls). The newer Office file format (Suffix: xlsx) is a zipped XML Format. To read the binary Excel-Format you need an OLE Connection between SAP GUI and MS: Office. But at the application server in background you doesn't have this OLE Connection.

Usually the payment details through third parties  are returned as  Excel files  and getting stored in Server location. So reading of these excel file is required for storing the  details in SAP tables.

 

Solution:

 

There are many possible solutions. We have evaluated 3 solutions for our purpose as it’s difficult to track presentation layer files each time. So reading from Server location is easier.

 

1) Upload the files from the presentation server in foreground. There are some function modules in the standard which can read the xls format.

2) Write an Excel-macro based solution which converts all Excel Files in the CSV-Format so that the same could be read from applications server directly.

3) Creating a temporary excel  file in presentation server based on the application server file using Sap function module :ARCHIVFILE_SERVER_TO_CLIENT,

    and reading it as normal presentation server- excel file and storing in the data in SAP table and deleting  the temp file in the end.


How to handle DUMP : DYNPRO_SEND_IN_BACKGROUND

$
0
0

BACKGROUND

 

DUMP : DYNPRO_SEND_IN_BACKGROUND

 

We may get the above mentioned DUMP in case of Inbound IDOC / RFC Call / Background Job.

 

These inbound IDOC / RFC Call / Background Job may be used for creation of some documents like Invoice, Sales Order or Purchase Order.

 

Now we might have made some extra Z enhancement in user exits or BADIs where you have used a POP-UP screen for some sort of user confirmation. For Example, we frequently use FM "POPUP_TO_CONFIRM" for this. Or may be we have called a screen which requires some user actions(inputs).

 

When a screen which requires an input is called in background, the system gives the above mentioned DUMP. This happens because  there is no user connection in case of inbound IDOC / RFC Call / Background Job. The inbound IDOC was may be triggered from a 3rd Party Non-SAP System or the RFC Call was made from a different System.

 

You will get a DUMP like this:

dump screen.png

 

 

HOW TO HANDLE THIS SITUATION

 

While providing any POP-UP screen, we need to check the User Type.


We may follow the steps below:


1) We will get the user ID in this variable sy-uname.

2) There is a table USR02 where we will find logon details of any user.

3) There is a field USTYP, which will tell us what kind of user it is.


Below are the possible type of users.

type of users.png

 

We can put a simple code to check what kind of user it is. If it is a Dialog User(A), then only provide the POP-UP screen or else don't. We can handle the action automatically with some logic according to the requirement.

 

table.png

 

 

We can also create a function module which you can just call when needed. Refer below Picture.

FM.png

Binary search on SAP DB sorted tables

$
0
0

Use index table key in your Select statement!- this is very clear and correct advise ...unfortunately not always easy to achieve it !

 

 

Most often WM / SD / FI are the departaments which are in the top of transactions recorders . Their Docu Header Tables ( those which are ending in K – from german Kopf) is having the binom Docu Number – Date of creation available , and , in all cases Docu Number is index key ! Most of our sql queries will rely on a lot of different secondary key and for sure there will be a ‘Where date in [] ‘ .

 

My aim is to build a FM which must have as import parameters a table name , key field and date name field and export a min and max key field which can be used in a further selection . First I will test the logic on a single table using 2 routines . With help of your comments & advises I should be able to build the final version.

 

In example below I am trying to determine a minimum and a maximum document number range , based on a date range , which can be used in a Sql select directive in order to increase the performances .

 

In my scarce resources sandbox system , LTAK counts almost 2 mil records while LTAP around 10 mil .

Selecting from LTAK only based on LGNUM and BDATU is like watching a 3 legs dog walking ! Of course , LTAP is doing even worse (assuming that you won't use a inner join with LTAK or FAE )!


Trivial condition for binary search is to have an ascending sorted table , it means that document number must be generated by NUMBER_GET_NEXT which implies an entry in NRIV table for this specific number range.

LTAK is matching the case .

 

 

Binary search approach :

According to picture bellow we have to find all TANUM which are laying in a given date range ( s_datum ) in Selection-Screen and for a known LGORT .

My approach is to find a TANUM at left of s_datum-low and one at right of s_datum-high . Of course , first TANUM and last TANUM in LTAK table would fulfill it , but won't increase select performances , therefore , we have defined a delta (type i) and build 2 ranges based on it. Intersection between any of delta_date range and s_datum range should be the null set . The length (delta) of delta_date range must be defined in such a way to avoid a large number of iterations in order to find an entry inside of it . It is easy observable that the length and number of iterations are inversely proportional . A small delta would find a TANUM closer to one of the s_datum 's edges but the number of hits would increase , viceversa , a big delta would return in less iterations a TANUM which may not be too close to s_datum's edges .


 

SCNBS.jpg

 

Coding :

1 . Defining variabiles and selection-screen :

in structures gs_min_ltak and gs_max_ltak we are recording first and last entry in LTAK table ;

min_tanum and max_tanum structures will hold the found values for which we are looking for ;

delta_date is the range in which we will search for min_tanum and max_tanum ;

delta (type INT1/{0} ) is the legth of delta_date interval .


2 . Routine find_min_max_tanum_in_ltak is responsabile for binary search recursivity .

1st  step would be to read extremities of table ( min and max tanum )

  SELECT SINGLE * FROM ltak INTO gs_min_ltak WHERE lgnum = p_lgnum.
SELECT  * FROM ltak UP TO 1 ROWS INTO gs_max_ltak WHERE lgnum = p_lgnum ORDER BY tanum DESCENDING.
ENDSELECT.

2nd  , based on length of interval , we would determine a maximum number of failed iterations . ( generously i choose a max of 2 x (log base 2 of N )    where N is number of rec in LTAK ) .

max_iterations 2 * log( gs_max_ltak-tanum - gs_min_ltak-tanum ) / log( 2 ) .

If number of failed iterations would be greater than an expected number of iterations , then we might consider the existence of noise in data distribution ( mass documents deletion , long period of time without records ..) or our delta value was setted up in such a way to find posted records during the weekend ( which may have a low value of probability density function for this interval).

3rd set_delta_date_range routine is responsabile for setting the boundaries of left and right intervals,where we have to find our records .

4th find_tanum routine is the recursive binary search routine .


Exemple of SAT measurement

I have measured runtime of finding 1 record in LTAK table in a given period . It took almost 12 secondes .

Same interogation was done in binary search in my Z report . It took 0,1 seconds to find 2 TANUMs (left and right of interval ) . Please see bellow results .

 

SAT - SE16N / LTAK Table

SAT SE16N LTAK.jpg

SAT - SE16N Measurement

SAT SE16N LTAK result.jpg

 

SAT - Z_MIN_MAX_LTAK

SAT BS LTAK.jpg

SAT - Z_MIN_MAX_LTAK measurement

SAT BS LTAK Result.jpg

Z_MIN_MAX_LTAK output

BS Report Output.jpg

 

*&---------------------------------------------------------------------*
*& Report  Z_MIN_MAX_LTAK
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

report z_min_max_ltak.

data : gs_min_ltak type ltak ,
gs_max_ltak
type ltak.
data : min_tanum type ltak ,
max_tanum
type ltak .
data : number_iterations type i,
target
type string ,
lv_error
type xflag.
data : delta_date type range of sy-datum with header line .

data max_iterations type i.
select-options : s_datum for sy-datum obligatory.
parameters : p_lgnum type lgnum default 'SVT' obligatory,
p_delta
type int1 default 8 obligatory. " In my case 8 days are the maximum which can exists without records .

at selection-screen .
if s_datum-high is  initial.
message e031(/iwbep/epm_product) with 'Date to '.
*   &1 is mandatory
endif.
if p_delta = 0.
message e094(axt_model) with 'Delta'.
*   Field &1: Enter a length greater than 0
endif.
start-of-selection .
perform find_min_max_tanum_in_ltak .
perform write.

*&---------------------------------------------------------------------*
*&      Form  FIND_MIN_MAX_TANUM_IN_LTAK
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form find_min_max_tanum_in_ltak .

select single * from ltak into gs_min_ltak where lgnum = p_lgnum.
select  * from ltak up to 1 rows into gs_max_ltak where lgnum = p_lgnum order by tanum descending.
endselect.
max_iterations
2 * log( gs_max_ltak-tanum - gs_min_ltak-tanum ) / log( 2 ) .
if s_datum-low < gs_min_ltak-bdatu and s_datum-high < gs_min_ltak-bdatu.
message e048(ei).
*   No data selected for this time period
elseif s_datum-low > gs_max_ltak-bdatu  and s_datum-high > gs_max_ltak-bdatu  .
message e048(ei).
*   No data selected for this time period
endif.

if s_datum-low <= gs_min_ltak-bdatu .
min_tanum
= gs_min_ltak.
else.
target
= 'MIN' .
perform set_delta_date_range using target.
perform find_tanum using gs_min_ltak-tanum gs_max_ltak-tanum target.
endif.

if s_datum-high >= gs_max_ltak-bdatu.
max_tanum
= gs_max_ltak.
else.
target
= 'MAX'.
perform set_delta_date_range using target.
perform find_tanum using min_tanum-tanum gs_max_ltak-tanum target.
endif.
if lv_error is not initial.
message ' Too many iterations .Increase delta !' type 'E' display like 'E' .
endif.
endform.                    " FIND_MIN_MAX_TANUM_IN_LTAK
*&---------------------------------------------------------------------*
*&      Form  FIND_TANUM
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_MIN  text
*      -->P_MAX  text
*      -->P_TARGET  text
*----------------------------------------------------------------------*
form find_tanum  using  p_min type tanum
p_max
type tanum
p_target
type string.

data :temp_tanum type tanum ,
temp_ltak
type ltak.
number_iterations
= number_iterations + 1 .
temp_tanum
= ( p_max - p_min ) / 2 + p_min .
select single * from ltak into temp_ltak where lgnum = p_lgnum and tanum = temp_tanum .
if sy-subrc <> 0.
select single * from ltak into temp_ltak where lgnum = p_lgnum and tanum > temp_tanum .
case p_target.
when 'MIN'.
perform find_tanum using temp_ltak-tanum p_max p_target.
when 'MAX'.
perform find_tanum using p_min temp_ltak-tanum p_target.
when others.
endcase.
else.
***********delta too small or too many gaps ( records are not uniform distributed)
if number_iterations > max_iterations . " Empty interval
case target.
when 'MIN'.
min_tanum
-tanum = p_min.
lv_error
= 'X'.
exit.
when 'MAX'.
max_tanum
-tanum = p_max .
lv_error
= 'X'.
exit.
when others.
endcase.
endif.
**********************************
if temp_ltak-bdatu in delta_date.
case target.
when 'MIN'.
min_tanum
= temp_ltak.
exit.
when 'MAX'.
max_tanum
= temp_ltak.
exit.
when others.
endcase.
elseif temp_ltak-bdatu < delta_date-low.
perform find_tanum using temp_ltak-tanum p_max target.
elseif temp_ltak-bdatu > delta_date-high .
perform find_tanum using p_min temp_ltak-tanum target.
endif.
endif.
endform.                    " FIND_TANUM
*&---------------------------------------------------------------------*
*&      Form  SET_DELTA_DATE_RANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_TARGET  text
*----------------------------------------------------------------------*
form set_delta_date_range  using p_target type string.
free delta_date.
case p_target.
when 'MIN'.
delta_date
-low = s_datum-low - p_delta .
delta_date
-high = s_datum-low - 1.
delta_date
-sign = 'I'.
delta_date
-option = 'BT'.
append delta_date.
when 'MAX'.
delta_date
-low = s_datum-high + 1.
delta_date
-high = s_datum-high + p_delta .
delta_date
-sign = 'I'.
delta_date
-option = 'BT'.
append delta_date.
when others.
endcase.
endform.                    " SET_DELTA_DATE_RANGE
*&---------------------------------------------------------------------*
*&      Form  WRITE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
form write .
write :/ 'Our goal was to find a min TANUM and a max TANUM in LTAK table ,'.
write :/ 'positioned to the left of s_datum-low = ' ,s_datum-low , ' and to the right side of s_datum-high = ' ,s_datum-high , ' within a range (delta) of max ', p_delta centered, 'days.' .
skip.
write :/ 'Goal was achieved in a # of iterations = ' ,number_iterations no-zero left-justified , 'Number of max allowed iterations = ' , max_iterations.
write :/ 'Min TANUM= ' , min_tanum-tanum no-zero left-justified .
write :/ 'Min TANUM date = ' , min_tanum-bdatu left-justified.
write :/ 'Max TANUM= ' , max_tanum-tanum no-zero left-justified.
write :/ 'Max TANUM date ' , max_tanum-bdatu left-justified.

endform.                    " WRITE

Main Memory Synchronization - BANK_REGISTER

$
0
0

Hi ABAPers,

 

This particular document is very useful for those who work on SAP Financial Services Industry, especially for SAP Banking Services.

 

Problem Behind:

 

When you do any updates to Account Master by using a BAPI/BTE/BADI or infact All the LUW Programs that is being called in the Custom update Function Group. Then there is a chance of getting the Warning messages saying "GUID not found / Searching for GUID" and also a huge performance impact in several ways. This is because the Memory that is being consume by that specific processor is not being refreshed for each COMMIT / ROLLBACK.

 

Solution:

 

Registration for Main Memory Synchronization

 

Refer to the following notes on implementation:

Implement a refresh function module to initialize the global data on the program or function group.

 

  • This function module does not have any parameters.
  • Create event Load-of-Program in the function group or program to be initialized and call up function module BANK_REGISTER (registration for main memory synchronization).
  • LOAD-OF-PROGRAM. CALL FUNCTION `BANK_REGISTER`   EXPORTING     I_REFRESH_MODULE = `` Transfer the name of your refresh module when you access the module. As an example, use the function group BCA_OBJ_CONTRACT (Object Layer of Contract Module Contract Anchor) and the include LBCA_OBJ_CONTRACTLOP for its LOAD-OF-PROGRAM event.

For example : Create a Function Module ZBS_CLEAR_MEMORY where you just CLEAR and REFRESH your global variables declared in the TOP Include of your Custom Function Group.

 

Call the FM BANK_REGISTER in the LOAD-OF-PROGRAM (In TOP Include) as mentioned below.

 

CALL FUNCTION BANK_REGISTER

   EXPORTING

     I_REFRESH_MODULE = 'ZBS_CLEAR_MEMORY'.

 

Post Implementation Benefits:

 

Better Performance in the Program Executions

Better Performance in the Parallel Processing Framework

No Unnecessary messages in SLG1/BALLOG

Quicker updates in the Bulk Account Master Updates

 

Please do refer to the Function Module Documentation of BANK_REGISTER to Know more about MAIN MEMORY SYNCHRONIZATION.

 

The Function Module Documentaiton also explains answers for these questions.

1. When must synchronization be carried out ?

2. Which Types of Transactions are affected ?

3. Which Program are affected ?

4. How does the Process Function?

 

There is also a better way to do this in case of ABAP Object with the Interface provided by SAP which is "IF_BANK_REGISTER".

Hope this helps all the ABAPers who are working on SAP Financial Services or SAP Banking Services.

There is also a similar kind of Function Module available in SAP CRM for Product Profile updates, Soon I will be writing another document for that.

 

Best Regards,

Bhargav.

Tax Interface Exit Implementation Guidelines

$
0
0

Due to the complexities of U.S tax rules and regulations which seem to vary based on industry or business practice, SAP has provided a Function Module exit within the tax interface programming logic to allow customers and partners to handle customer and partner specific functionality.

 

SAP enhancement FYTX0002 consist of the following components which can be viewed in transaction SMOD.

  1. Function Module exit EXIT_SAPLFYTX_USER_001
  2. Customizing Include CI_TAX_INPUT_USER

 

Function Module exit EXIT_SAPLFYTX_USER_001 has the following important interface parameters.

 

screenshot1.png

 

screenshot2.png

 

The fields of the changing parameter CH_USER_CHANGED_FIELDS can be modified within the Function Module exit EXIT_SAPLFYTX_USER_001.

 

Customizing include CI_TAX_INPUT_USER can be used to add additional fields from structures KOMP, KOMK and XKOMV.

 

If you want to pass additional fields from pricing that are not in KOMP and KOMK to the tax Function Module exit EXIT_SAPLFYTX_USER_001 then you can add those fields to the pricing includes INCLUDE KOMKAZ in KOMK (header data) and INCLUDE KOMPAZ in KOMP (item data).

 

You can populate these fields as well as existing fields in KOMP and KOMK in USEREXIT_PRICING_PREPARE_TKOMK and

USEREXIT_PRICING_PREPARE_TKOMP in programs MV45AFZZ (order processing) and RV60AFZZ (billing).

 

In addition to the Function Module exit mentioned above the badi EXTENSION_US_TAXES also needs to be implemented to handle specific business scenarios such as Purchase orders, Incoming invoice (MIRO).

 

Purchase order

In order to process account assignment data for Purchase order line items in the Function Module exit EXIT_SAPLFYTX_USER_001 implement the method ME_TAXCOM_MEPO of the badi EXTENSION_US_TAXES as follows.


Sample code

*Read account assignment data for item
READ TABLE im_accounting INDEX 1 INTO wa_im_accounting.
*G/L account number
EXPORT wa_im_accounting-sakto FROM wa_im_accounting-sakto TO MEMORY ID 'GL_ACCOUNT'.
*Cost center
EXPORT wa_im_accounting-kostl FROM wa_im_accounting-kostl TO MEMORY ID 'COST_CNTR'.
*WBS Element
EXPORT wa_im_accounting-ps_psp_pnr FROM wa_im_accounting-ps_psp_pnr TO MEMORY ID 'WBS'.
*Internal Order
EXPORT wa_im_accounting-aufnr FROM wa_im_accounting-aufnr TO MEMORY ID 'IO'.

 

Process this data in the Function Module exit EXIT_SAPLFYTX_USER_001 as follows.

 

Sample code

*G/L account number
IMPORT wa_im_accounting-sakto TO wa_im_accounting-sakto FROM MEMORY ID 'GL_ACCOUNT'.
*Cost center
IMPORT wa_im_accounting-kostl TO wa_im_accounting-kostl FROM MEMORY ID 'COST_CNTR'.
*WBS Element
IMPORT wa_im_accounting-ps_psp_pnr TO wa_im_accounting-ps_psp_pnr FROM MEMORY ID 'WBS'.
*Internal Order
IMPORT wa_im_accounting-aufnr TO wa_im_accounting-aufnr FROM MEMORY ID 'IO'.


Incoming invoice (MIRO)

In order to send additional data for tax system implement the method MM_DATA_FOR_TAX_SYSTEM of the badi EXTENSION_US_TAXES as follows.


Sample code

*Item Data from FI Document
EXPORT it_bseg FROM ti_bseg TO MEMORY ID 'TI_BSEG'.
EXPORT it_bseg_mat FROM ti_bseg_mat TO MEMORY ID 'TI_BSEG_MAT'.
*Item Data from MM Document
EXPORT it_drseg FROM ti_drseg TO MEMORY ID 'TI_DRSEG'.
*Link Table BSEG-DRSEG
EXPORT it_matkl FROM ti_bseg_mat TO MEMORY ID 'TI_MATKL'.

 

Process this data in the Function Module exit EXIT_SAPLFYTX_USER_001 as follows.

 

Sample code

*Item Data from FI Document
IMPORT it_bseg TO it_bseg FROM MEMORY ID 'TI_BSEG'.
IMPORT it_bseg_mat TO it_bseg_mat FROM MEMORY ID 'TI_BSEG_MAT'.
*Item Data from MM Document
IMPORT it_drseg TO it_drseg FROM MEMORY ID 'TI_DRSEG'.
*Link Table BSEG-DRSEG
IMPORT it_matkl TO it_matkl FROM MEMORY ID 'TI_MATKL'.


Vendor invoice (FB60)

The data required for vendor invoice processing can be imported in the Function Module exit EXIT_SAPLFYTX_USER_001 from the memory id as follows.


Sample code

IMPORT xbkpf xbseg FROM MEMORY ID '%BKPF%'.

 

Sales order

If you want to process Customer details within the Function Module exit EXIT_SAPLFYTX_USER_001 for instance customer number, customer name and pricing subtotal then add these fields to customizing include CI_TAX_INPUT_USER and process as follows.

 

Sample code

if i_input_user-kunnr is not initial.  select single name1 from kna1 into lv_name where kunnr eq i_input_user-kunnr.
endif.
*Pricing subtotal
ch_user_changed_fields-freight_am = i_input_user-zzwi20. 

 

For all the business scenarios, once we import the data in Function Module exit EXIT_SAPLFYTX_USER_001 the data can be processed based on the specific business requirement and then assigned to changing parameter CH_USER_CHANGED_FIELDS as needed.

 

Important SAP Notes for tax interface exit implementation

302998, 1692637, 1730413, 1790294

How To add Custom Fields as Selection Inputs to IW38/39

$
0
0

This document details out the steps to be followed to add custom fields as selection screen inputs to IW38 / IW39 t-codes.


In this example, the custom fields added to CI_AUFK include structure is being added as selection screen input as well as outputted in the IW38 ALV output.

For adding custom fields as output, the structure RIHAUFK_LIST has to be enhanced. An append structure has to be created with the custom fields.

In this example, the custom fields added to CI_AUFK structure are added as fields to the append structure so that they could be added to the IW38 output.


Note: The field names in the append structure and CI_AUFK structure are retained the same so that the standard code automatically populates the values for the custom fields.
Append Structure.jpg

Custom Fields as Selection Screen Input


For adding custom field as a selection screen input to IW38

Create an enhancement implementation to enhancement spot ES_RIAUFK20, as highlighted in GREEN in the below screenshot.

ES_RIAUFK20 - Enh Impl.jpg

In the created implementation, add the below code to create the selection screen inputs.

EnhImp01.jpg


For adding labels to the custom selection screen inputs

Create an enhancement implementation at the start of the include MIOLXF19. In this implementation, set the labels for the custom selection screen inputs.


EnhImp02.jpg

Add custom fields to the fields for selection

Add the custom fields (added to the selection) to the list of fields for selection so that they are always fetched as they are not filtered by standard program. This would be required as the OBJECT_TAB internal table gets populated only for the fields selected in the ALV display layout. For this purpose, the enhancement implementation would need to be created at the end of the routine CHECK_FIELDCAT_VARIANT_L in the program RIAUFK20.


EnhImp03.jpg

 

Filter records based on custom field input

In this step, we filter the OBJECT_TAB based on the input on the custom fields. For this purpose, an enhancement implementation would need to be created at the end of the routine SELECTION_L in the program RIAUFK20.

EnhImp04.jpg


Result


Input Selection Screen

Input_Result.jpg


ALV Output

Output_Result.jpg

Restrict SAP user ID login for only one Terminal

$
0
0

Scenario: Client wants to restrict the user to login from any other terminal except allocated one.

 

Solution :

 

Step 1 : Use Funtion Exit : EXIT_SAPLSUSF_001 which is called immediate after login.

 

Function.png

 

Step 2 : Create Z table which contain UserId, IP Address, and Terminal Name.

 

structure.JPG

 

Step 3 : call function module  TH_USER_INFO in function exit EXIT_SAPLSUSF_001 inclue : ZXUSRU01


Here TERMINAL is terminal name and ADDRSTR is IP address

userinfo.png

 

step 4 : If it runs first time add user id, IP address and Terminal Id in table from next time validate from Z table.

 

 

 


step 5 : use function module  WS_MSG to raise error.

 


message.JPG

 

step 6 : call 'SYST_LOGOFF' if user is not authorize.


log off.JPG

 

 

Remarks : Do not use any other method to raise error, because.......

 

mas.png

 

if user is not authorize still he/she can login using Create Session

 

WS_MSG gives only below options.

 

mas.png

SAP NetWeaver AS ABAP 7.40 SP8 - Developer Edition to Download: Consise Installation Instruction

$
0
0

For general information, download link, operating system and hardware requirements see the introduction page.

Installation Instructions and First Steps

Prerequistes

 

Network configuration of the SAP host operating system: The officially supported setup requires a static IP address for the hostname used for the SAP installation. Using DHCP is possible for this testdrive version, but be aware of potential consequences. If our installation cannot ping the hostname specified when installing, the installation and startup of the SAP system will fail. Make sure that the hostname specified during installation fulfills SAP requirements, most importantly it cannot exceed 13 characters length and also needs to survive subsequent reboots.

 

Firewall: it may be necessary to deactivate the firewall.


Additional software requirements


Following software packages are required:

  • csh - Ubuntu and Debian require to install csh before you start the ABAP installation
  • libaio - SAP Sybase ASE requires the libaio library to start the installation
  • 32bit libraries - SAP Management Console (SAPMC) requires 32bit libraries (ia32, glibc.i686) for ASE related functionalities
  • libuuid - SAP AS ABAP requires the OS to run libuuid service to ensure the uniqueness of GUIDs. The service not running, you will be greeted by a short dump after login - but you can continue working on your own risk
  • English - SAP AS ABAP requires that you configure English (LANG=en_US.UTF-8) as the operating system language

 

 

Server installation

 

Login with your preferred user. You need to have the password of the root user at hand, as the installation needs root privileges. Ensure that the additional software requirements are met.

 

Make the extracted download archive available on the server. Go into the root directory of the extracted archive. We provide you with several installation options:

  • ./install.sh - installs the Developer Edition in dark mode, the installer will configure the SAP system for usage of the physical hostname
  • ./install.sh -g - will present you a SAPINST GUI allowing to modify certain system parameters
  • ./install.sh -h <own hostname> - allows you to specify your own hostname to be used by the SAP system
  • ./install.sh -s  - allows you to skip the hostname check

 

All options prompt you for a master password. Please ensure that the password length exceeds 7 characters, contains capital letters and digits but does not contain special characters. The installation starts the database and server.

 

The installation will take a while (about 20 minutes - take a break).

 

 

Client installation (optional)


SAPGUI

 

If you have already a SAP GUI installation you can connect to your sytem. If not go ahead now with the client installation. SAP GUI space in SDN SAP GUI | SCN leads you to more documentation around SAP GUI for Java Environment, requirements for the SAP GUI for Java include Sun Java SE 6 32-bit or 64-bit, a properly installed Java Plugin and C++ runtime libstdc++.so.6.

 

ABAP Plugins for Eclipse

 

Go to the SCN space ABAP in Eclipse where you will find download links and tutorials.


Post installation steps


Profile parameters

 

Some profile parameters have to be adapted:

  • icm/host_name_full= $(SAPLOCALHOST).dummy.nodomain
  • PHYS_MEMSIZE = 30%

 

License key

 

Log on to the system as user SAP* with default password DidNPLpw2014 and use transaction SLICENSE (transaction code slicense) to determine your hardware key.

 

Request the license key for your test drive at SAP Sneak Preview License Key Request . Enter your credentials and select NPL - SAP NetWeaver 7.x (Sybase ASE) as System ID. Enter your hardware key and submit the request. You will receive an e-mail with the license file attached.

 

Go to transaction slicense and install the license file. They system type changes Demo. You can now explore the demo scenarios and develop using the ABAP tools in Eclipse and new features like the core data services or SAPUI5 UIs.

 


Administration of the application server ABAP


Starting and stopping the server


Terminal commands

 

With the user npladm you can start and stop the server using the terminal commands startsap and stopsap respectively or the newer sap control commands.


SAP Management Console (SAPMC)


Assuming that your server is configured to run Java applets and that the NPL server host is reachable from your OS, enter http://<NPL server host name>:50013 to start the tool. SAPMC allows you to start, stop and analyse the SAP system and it's components with great ease of use, remote and/or locally. For your convenience, in the client/Misc subdirectory, we also provide the SAPMMC installation package and a template script for calling SAPMC standalone. See  SAP MMC Snap-In for more information on how to use SAPMMC on a Windows system. SAPMC standalone requires that you have installed a recent Java SDK.


Directories and Users


The installation creates following directories and users.

 

Created Directories


DirectorySize
/sapmnt~  2 GB
/sybase~ 50 GB
/usr/sap~  3 GB

 

Created Users on OS level

 

The installation creates following users on OS level. During the installation you are prompted to enter the master password.

 

User namePasswordDescription
sapadmmaster passwordCreated by SAP hostagent
npladmmaster passwordSAP System Administrator
sybnplmaster passwordSAP Database Administrator

 

The installed system disposes of the following database users:

 

User namePasswordDescription
SAPSR3DidNPLpw2014SAP Schema User

 

The installed system disposes of the following SAP users in client 001:

 

User namePasswordDescription
DDICDidNPLpw2014Data Dictionary User
SAP*DidNPLpw2014SAP Administrator
DEVELOPERabCd1234Developer User
BWDEVELOPERabCd1234Developer User

 

Uninstalling instructions

 

If you ever want to uninstall your server, you can do it as follows:

 

  • Delete the created directories
  • Delete the OS users
  • Delete the added lines in /etc/services (should be the last lines beginning with sap* and sql6* respectively)
  • Delete the line containing nplhost in /etc/hosts
  • Delete the symbolic link S99_nplhost.sh in the directory /etc/init.d/rc3.d in case of SUSE or /etc/rc3.d in case of Red Hat
  • Restart your network

 

Contact

 

We encourage you to visit our SCN ABAP community.

In case of Linux problems read the Linux FAQ.

Post your comments to the introduction page.


Negative values in invoice

$
0
0

I have come across a case where an invoice generated from a PO delivery ended up having negative volume. It was not possible to open the invoice via VF03 , nor via VF02 to correct the incorrect volume value. I also tried to cancel the invoice via VF11 but all the methods gave a short dump with error DYNPRO_FIELD_CONVERSION. This implies that the screen processing action was terminated due to wrong values in some fields. To cross check the field which was in error, I checked VBRP table. The short dump also mentioned the same field VBRP-VOLUM. This was somehow negative.

 

Upon contacting SAP , they suggested a note which I would want to share in this forum.

Note : 367296 A billing document is corrupt: How it is repaired.

 

This note mentions usage of a report which is there in the correction instruction. This report would correct the error invoice and after which the consultant can cancel the same.

 

However, if due to rigid authorization processes in your project, if you cannot make arrangements for this report to be implemented in production at the earliest you could edit the VBRP entry in debug mode which is definitely not a good practice and you should refrain from doing so.

Generated ALE-IDOC Interfaces

$
0
0

Introduction


One cannot create an extension for generated IDOC types, since the extension concept for ALE interfaces created by T-Code BDBG or BDFG does not run with extension types.


BAPIs are the standardized interfaces for ALE-supported communication.The IDOCtypes required for the ALE services can be generated from BAPIs. So, one can create their own BAPIs in the customer namespace and generate the associated BAPI-ALE interface.


In the process, the following objects are generated for a BAPI:

  • A message type (in customer namespace)
  • A Basic IDoc type, including all of its segments
  • An Outbound function module which uses the BAPI data to generate the IDoc and also dispatches it
  • An Inbound Function Module that fills the BAPI with the IDoc data on the inbound side.


The generated ALE IDoc interface performs the following tasks:

  • Creates an IDoc from the BAPI data
  • Sends the IDoc to the target system
  • Receives the IDoc in the target system, creates the BAPI data from the IDoc and calls the BAPI


Step By Step Procedure for Creating Generated IDOC


STEP 1: Create a new structure with the customer fields that are required under the IDOC type as shown below.

step1.jpg


STEP 2: Create a new remote enabled function module which is responsible for generating IDOC through SE37 as shown below.

step2.jpg


STEP 3: Once the function module is created we need to create a BAPI for the outbound processing. This is implemented as a Business Object’s (BO) method, and will utilize the outbound function module previously created.


Go to SWO1 transaction and create new Object as a copy of EQUI object as shown below. (We can also create a new object and a method. However in case we need methods of EQUI, we can just copy the Object)

step3.jpg

 

STEP 4: Add new method to the Business Object created with the function module previously created as shown below and press tick.png.

step4.jpg

 

STEP 5: Provide Method, Method name and Description and click onnext.png.

step5.jpg

 

STEP 6: Do not make any changes here and just click on next.png.

step6.jpg

 

STEP 7: A confirmation popup comes up and select ‘Yes’ to continue.

step7.jpg

 

STEP 8: Once the method is created, do not forget to make the  method function API enabled. This is done as shown below. Double click on the method to get this popup.

step8.jpg


Once this is done, notice a small green icon beside the method(greenicon.png). This indicates that the method is API enabled.

 

STEP 9: Now click on object and go to ‘Edit menu’ and select the release status as ‘To Implemented’ as shown below.

step9.jpg


STEP 10: Save the object type with the confirmation that pops up on changing the Release type to Implemented.

step10.jpg


STEP 11: Now click on object and go to ‘Edit menu’ and select the release status as ‘To Released’.

step11.jpg

 

You will see a small tick beside object name as seen below on 'Release' which indicates the object is released.

step11_1.jpg


STEP 12: Now click on method and go to ‘Edit menu’ and select the release status as ‘To Released’ as shown below. (Before doing this make sure that the Function module created is set to release.)

step12.png

 

You will see a small tick beside method name as shown below on 'Release' which indicates the method is released.

step12_1.jpg


STEP 13: Click on  generate.png(Generate) once the above steps are completed successfully and Save.

step13.jpg


STEP 14: Now, go to BDBG T-Code and provide the Object and Method names created as shown below and Click on  create.png(Create).

step14.jpg


STEP 15: Provide message type and click on tick.png.

step15.jpg


STEP 16: Provide name for IDoc type, Outbound function module and Inbound function module as required and click on tick.png.

step16.jpg

 

Following is the result.

result.jpg


Click on the IDoc type to check the structure generated.

idoc_type.jpg


Generated Segment:

gen_segment.jpg


One important thing to note here is, we have to make sure that IDOC types and Generated Segments have to be set to release to ensure their visibility across systems.



Configuration Required


Create a Distribution Model – BD64 as shown below (Add BAPI with the Sender and Receiver along with the Object and Method Created above).


Create a new model view.

config1.jpg


Select the Model View created and Click on ‘Add BAPI’ and provide the Sender/Receiver and Object/Method details as shown below.

config2.jpg


On adding the BAPI, the model view looks like as shown below.

config3.jpg


After, this go to Environment-> Generate Partner Profiles. This will create an entry in Outbound parameters of Partner Profile.



Sample ABAP code to try


Following is the sample code to be filled in the Function Module Created.


FUNCTION zbapi_gen_idoc.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  IMPORTING

*"     VALUE(EXTERNAL_NUMBER) LIKE  BAPI_ITOB_PARMS-EQUIPMENT OPTIONAL

*"     VALUE(DATA_GENERAL) LIKE  BAPI_ITOB STRUCTURE  BAPI_ITOB

*"       OPTIONAL

*"     VALUE(DATA_SPECIFIC) LIKE  BAPI_ITOB_EQ_ONLY STRUCTURE

*"        BAPI_ITOB_EQ_ONLY OPTIONAL

*"     VALUE(DATA_FLEET) LIKE  BAPI_FLEET STRUCTURE  BAPI_FLEET

*"       OPTIONAL

*"     VALUE(VALID_DATE) LIKE  BAPI_ITOB_PARMS-INST_DATE OPTIONAL

*"     VALUE(DATA_INSTALL) LIKE  BAPI_ITOB_EQ_INSTALL STRUCTURE

*"        BAPI_ITOB_EQ_INSTALL OPTIONAL

*"     VALUE(DATA_GENERATED) LIKE  ZDATA_GENERATED STRUCTURE

*"        ZDATA_GENERATED OPTIONAL

*"  TABLES

*"      RETURN STRUCTURE  BAPIRET2

*"----------------------------------------------------------------------

 

   DATA: it_receivers TYPE STANDARD TABLE OF bdi_logsys,

         it_filters   TYPE STANDARD TABLE OF bdi_fobj.

 

* Call the function module to get the receivers list.

   CALL FUNCTION 'ALE_ASYNC_BAPI_GET_RECEIVER'

     EXPORTING

       object                   = 'ZEQUI'

       method                   = 'ZCUSTSEGMENT'

     TABLES

       receivers                = it_receivers

       filterobject_values      = it_filters

     EXCEPTIONS

       error_in_filterobjects   = 1

       error_in_ale_customizing = 2

       OTHERS                   = 3.

 

   CALL FUNCTION 'ZOUTOUT_GEN_IDOC_EQUI'

     EXPORTING

       externalnumber       = external_number

       datageneral          = data_general

       dataspecific         = data_specific

       datafleet            = data_fleet

       validdate            = valid_date

       datainstall          = data_install

       datagenerated        = data_generated

     TABLES

       receivers            = it_receivers

     EXCEPTIONS

       error_creating_idocs = 1

       OTHERS               = 2.

   IF sy-subrc <> 0.

* Implement suitable error handling here

   ENDIF.

 

ENDFUNCTION.


Following explains how we can make use of this FM.


Create a new BTE on equipment save and add the below logic. This will trigger the IDOC.


FUNCTION zbte_interface_pm000020 .

*"--------------------------------------------------------------------

*"*"Local Interface:

*"  IMPORTING

*"     REFERENCE(HEQKT_OLD) LIKE  EQKT STRUCTURE  EQKT

*"     REFERENCE(HEQUI_OLD) LIKE  EQUI STRUCTURE  EQUI

*"     REFERENCE(HEQUZ_OLD) LIKE  EQUZ STRUCTURE  EQUZ

*"     REFERENCE(HILOA_OLD) LIKE  ILOA STRUCTURE  ILOA

*"     REFERENCE(HEQBS_OLD) LIKE  EQBS STRUCTURE  EQBS

*"     REFERENCE(HEQKT_NEW) LIKE  EQKT STRUCTURE  EQKT

*"     REFERENCE(HEQUI_NEW) LIKE  EQUI STRUCTURE  EQUI

*"     REFERENCE(HEQUZ_NEW) LIKE  EQUZ STRUCTURE  EQUZ

*"     REFERENCE(HILOA_NEW) LIKE  ILOA STRUCTURE  ILOA

*"     REFERENCE(HEQBS_NEW) LIKE  EQBS STRUCTURE  EQBS

*"  TABLES

*"      IHPA_OLD STRUCTURE  IHPAVB OPTIONAL

*"      IHPA_NEW STRUCTURE  IHPAVB OPTIONAL

*"--------------------------------------------------------------------

 

   INCLUDE: <cntain>.

 

   DATA: l_return           TYPE swotreturn,

         lt_cont            TYPE swconttab,

         l_objhnd           TYPE swo_objhnd,

         ls_externalnumber  TYPE bapi_itob_parms-equipment,

         lt_datageneral     TYPE STANDARD TABLE OF bapi_itob,

         lt_dataspecific    TYPE STANDARD TABLE OF bapi_itob_eq_only,

         lt_datafleet       TYPE STANDARD TABLE OF bapi_fleet,

         ls_validdate       TYPE bapi_itob_parms-inst_date,

         lt_datainstall     TYPE TABLE OF  bapi_itob_eq_install,

         lt_datagenerated   TYPE TABLE OF  zdata_generated.

 

   DATA :ls_datageneral     TYPE   bapi_itob,

         ls_dataspecific    TYPE   bapi_itob_eq_only,

         ls_datafleet       TYPE   bapi_fleet,

         ls_datainstall     TYPE   bapi_itob_eq_install,

         ls_datagenerated   TYPE   zdata_generated.

 

   CALL FUNCTION 'SWO_CREATE'

     EXPORTING

       objtype           = 'ZEQUI_GEN'

       objname           = 'ZBAPIGENIDOC'

     IMPORTING

       object            = l_objhnd

     EXCEPTIONS

       no_remote_objects = 1

       OTHERS            = 2.

   IF sy-subrc <> 0.

     "Error Handling

   ENDIF.

 

   CLEAR: ls_datageneral,ls_dataspecific,ls_datagenerated.

 

   swc_set_element lt_cont 'EXTERNALNUMBER'     hequi_new-equnr.

 

   ls_datageneral-objecttype      = hequi_new-eqart .      " equi

   ls_datageneral-manfacture      = hequi_new-herst .      " equi

   ls_datageneral-descript        = heqkt_new-eqktx .      " eqkt

   ls_datageneral-manmodel        = hequi_new-typbz .      " equi

   ls_datageneral-comp_code       = hiloa_new-bukrs .      " iloa

   swc_set_element lt_cont 'DATAGENERAL'    ls_datageneral.

 

 

   ls_dataspecific-material       = hequi_new-matnr.

   ls_dataspecific-serialno       = hequi_new-sernr.

   swc_set_element lt_cont 'DATASPECIFIC'     ls_dataspecific.

 

   ls_datagenerated-zext1         = 'Equipment'.

   ls_datagenerated-zext12        = 'TestEquipment'.

   swc_set_element lt_cont 'DATAGENERATED' ls_datagenerated.

 

 

   CALL FUNCTION 'SWO_INVOKE'

     EXPORTING

       object             = l_objhnd

       verb               = 'ZBAPITESTFINAL'

     IMPORTING

       return             = l_return

     TABLES

       container          = lt_cont.

 

   COMMIT WORK.

 

ENDFUNCTION.



Some other ways that you can try


For Inbound usage:

  • The Inbound FM already has the logic to split the SDATA of a segment into required structures. It also calls the FM/BAPI that was used to create the IDoc Structure. So, just by maintaining Partner Profiles in the Inbound parameter is the only config that you might have to do.
  • So, the logic that you want to perform can be written within the FM/BAPI created.


For Outbound usage:

  • Capture the required data into the structures/tables. Call the Outbound FM by passing these structures/tables. That's it !! The triggering of IDoc will be handled by this FM only.


Issues that you may face during this process


  • When a new segment has to be introduced, the whole interface has to be deleted and should be regenerated again. In this process of regenerating, just by generating the program in SWO1 will not create the new segment. So don't panic !! Have a solution for that too.
    • In SWO1, the method that was created has to be deleted. Freshly new method has to be introduced, with the updated Function Module attached to it. Doing this, the parameters will be imported again and the program generated henceforth will have its own logic to generate new segment.


  • The multiple occurrence of segment within the IDOC is restricted to one if we have defined only the import parameters.
    • To have multiple occurrence of a segment, declare the required structure in the ‘Tables’ tab of the function module builder.

ABAP 7.40 Quick Reference

$
0
0

So you're an experienced ABAP programmer wanting to leverage off the fantastic new functionality available to you in ABAP 7.40!

 

However, searching for information on this topic leads you to fragmented pages or blogs that refer to only a couple of the new features available to you.

What you need is a quick reference guide which gives you the essentials you need and shows you how the code you are familiar with can be improved with ABAP 7.40.

 

The below document contains exactly this!

 

It gives examples of "classic" ABAP and its 740 equivalent. It goes into more details on the more difficult topics normally via examples. This allows the reader to dive in to the level they desire. While this document does not contain everything pertaining to ABAP 740 it certainly covers the most useful parts in the experience of the author.

 

The document has been compiled by drawing on existing material available online as well as trial and error by the author. In particular the blogs by Horst Keller have been useful and are the best reference I have found (prior to this document ). He has a landing page of sorts for his various blogs on the topic here:

ABAP Language News for Release 7.40

 

Credit also goes to Naimesh Patel for his useful explanations and examples on ABAP 7.40. Here is his example of the "FOR iteration expression" which I leaned on (links to his other 740 articles can be found at the bottom of the link):

http://zevolving.com/2015/05/abap-740-for-iteration-expression/

 

I compiled the below document to make the transition to using ABAP 740 easier for myself and my project team. It has worked well for us and I hope it will do the same for you.

 

Regards,

Jeff Towell

 

 

ABAP 7.40 Quick Reference  

 

 

Author:

Jeffrey Towell

Created:

2015

 

Contents

 

1. Inline Declarations

2. Table Expressions

3. Conversion Operator CONV

     I.  Definition.

     II. Example.

4. Value Operator VALUE

     I.   Definition.

     II.  Example for structures.

     III. Examples for internal tables.

5. FOR operator

     I.   Definition.

     II.  Explanation.

     III. Example 1.

     IV. Example 2.

     V. FOR with THEN and UNTIL|WHILE.

6. Reduce

     I.   Definition.

     II.  Note.

     III. Example 1.

     IV. Example 2.

     V.  Example 3.

7. Conditional operators COND and SWITCH

     I.   Definition.

     II.  Example for COND.

     III. Example for SWITCH.

8.Strings

     I.   String Templates.

     II.  Concatenation.

     III. Width/Alignment/Padding.

     IV. Case.

     V.  ALPHA conversion.

     VI.  Date conversion.

9. Classes/Methods

     I.   Referencing fields within returned structures.

     II.  Methods that return a type BOOLEAN.

     III. NEW operator

10. Meshes

     I.   Problem.

     II.  Solution.

     III. Output

11. Filter

     I.   Definition.

     II.  Problem.

     III. Solution.

 

1. Inline Declarations

 

Description

Before 7.40

With 7.40

Data statement

DATA text TYPE string.
text = `ABC`.

DATA(text)=`ABC`.

Loop at into work area

DATA wa like LINE OF itab.
LOOP AT itab
INTO wa.  
  ...
ENDLOOP.

LOOP AT itab INTO DATA(wa).  
  ...
ENDLOOP
.

Call method

DATA a1 TYPE ...

DATA a2 TYPE ...

oref->meth( IMPORTING p1 = a1

            IMPORTING p2 = a2

          ).

oref->meth(

        IMPORTING p1 = DATA(a1)

        IMPORTING p2 = DATA(a2)).

Loop at assigning

FIELD-SYMBOLS: <line> type …

LOOP AT itab ASSIGNING <line>.

  ...

ENDLOOP.

LOOP AT itab

   ASSIGNING FIELD-SYMBOL(<line>).
   ...
ENDLOOP.

Read assigning

FIELD-SYMBOLS: <line> type …

READ TABLE itab

           ASSIGNING <line>.

READ TABLE itab

   ASSIGNING FIELD-SYMBOL(<line>).

Select into

table

DATA itab TYPE TABLE OF dbtab.

SELECT * FROM dbtab

   INTO TABLE itab

        WHERE fld1 = lv_fld1.

SELECT * FROM dbtab

   INTO TABLE DATA(itab) 

        WHERE fld1 = @lv_fld1.

Select single

into

SELECT SINGLE f1 f2 

  FROM dbtab

  INTO (lv_f1, lv_f2)

WHERE ...

WRITE: / lv_f1, lv_f2.

SELECT SINGLE f1 AS my_f1,

              F2 AS abc  

         FROM dbtab

         INTO @DATA(ls_str) "struc

        WHERE ...

WRITE: / ls_str-my_f1, ls_str-abc.

 

 

 

2. Table Expressions

If a table line is not found, the exception CX_SY_ITAB_LINE_NOT_FOUND is raised. No sy-subrc.


Description

Before 7.40

With 7.40

Read Table  index

READ TABLE itab INDEX idx

      INTO wa.

wa = itab[ idx ].

Read Table  using key

READ TABLE itab INDEX idx

     USING KEY key

      INTO wa.

wa = itab[ KEY key INDEX idx ].

Read Table  with key

READ TABLE itab

  WITH KEY col1 =

           col2 =

       INTO wa.

wa = itab[ col1 = col2 = ].

Read Table  with key components

READ TABLE itab

      WITH TABLE KEY key

COMPONENTS col1 =

           col2 =

      INTO wa.

wa = itab[ KEY key col1 =

                    col2 = ].

Does record exist?

READ TABLE itab ...

    TRANSPORTING NO FIELDS.

IF sy-subrc = 0.

  ...

ENDIF.

IF line_exists( itab[ ... ] ).

...

ENDIF.

Get table index

DATA idx type sy-tabix.

READ TABLE ...

  TRANSPORTING NO FIELDS.

  idx = sy-tabix.

DATA(idx) =

       line_index( itab[ ... ] ).

 

NB: There will be a short dump if you use an inline expression that references a non-existent record.

        SAP says you should therefore assign a field symbol and check sy-subrc.

 

ASSIGN lt_tab[ 1 ] to FIELD-SYMBOL(<ls_tab>).
IF sy-subrc = 0.
...

ENDIF.


NB: Use itab [ table_line = … ] for untyped tables.


 

3. Conversion Operator CONV

I.  Definition

CONV dtype|#( ... )

dtype = Type you want to convert to (explicit)

#     = compiler must use the context to decide the type to convert to (implicit)


II. Example

Methodcl_abap_codepage=>convert_toexpects a string

Before 7.40

DATA text TYPE c LENGTH 255.

DATA helper TYPE string.

DATA xstr   TYPE xstring.

 

helper = text.

xstr = cl_abap_codepage=>convert_to( source = helper ).

With 7.40

DATA text TYPE c LENGTH 255.

 

DATA(xstr) = cl_abap_codepage=>convert_to( source =CONV string( text )).

OR

DATA(xstr) = cl_abap_codepage=>convert_to( source =CONV #( text )).

 

 

 

4. Value Operator VALUE

I. Definition

     Variables:    VALUE dtype|#( )

     Structures:  VALUE dtype|#( comp1 = a1 comp2 = a2 ... )

     Tables:         VALUE dtype|#( ( ... ) ( ... ) ... ) ...

 

II. Example for structures

     TYPES:  BEGIN OF ty_columns1,“Simple structure
                     cols1 TYPE i,
                     cols2 TYPE i,
                   END OF ty_columns1.

      TYPES: BEGIN OF ty_columnns2,  “Nested structure
                     coln1 TYPE i,
                     coln2 TYPE ty_columns1,
                  END OF ty_columns2.

      DATA: struc_simple TYPE ty_columns1,
                struc_nest    TYPE ty_columns2.

 

     struct_nest   = VALUE t_struct(coln1 = 1
                                                  coln2-cols1 = 1
                                                  coln2-cols2 = 2 ).


     OR


     struct_nest   = VALUE t_struct(coln1 = 1
                                                   coln2 = VALUE #( cols1 = 1

                                                   cols2 = 2 ) ).


III. Examples for internal tables

Elementary line type:

 

TYPES t_itab TYPE TABLE OF i WITH EMPTY KEY.

DATA itab TYPE t_itab.

itab = VALUE #( ( ) ( 1 ) ( 2 ) ).

 

Structured line type (RANGEStable):

 

DATA itab TYPE RANGE OF i.

itab = VALUE #( sign = 'I'  option = 'BT' ( low = 1  high = 10 )
( low = 21 high = 30 )
( low = 41 high = 50 )
option = 'GE' ( low = 61 )  ).


 

5. FOR operator

I. Definition

     FOR wa|<fs> IN itab [INDEX INTO idx] [cond]

 

II. Explanation

This effectively causes a loop at itab. For each loop the row read is assigned to a work area (wa) or field-symbol(<fs>).

This wa or <fs> is local to the expression i.e. if declared in a subrourine the variable wa or <fs> is a local variable of

that subroutine. Index like SY-TABIX in loop.

Given: 

TYPES: BEGIN OF ty_ship,
           tknum
TYPE tknum,     "Shipment Number
           name 
TYPE ernam,     "Name of Person who Created the Object
           city 
TYPE ort01,     "Starting city
           route
TYPE route,     "Shipment route
      
END OF ty_ship.
TYPES: ty_ships TYPE SORTED TABLE OF ty_ship WITH UNIQUE KEY tknum.
TYPES: ty_citys TYPE STANDARD TABLE OF ort01 WITH EMPTY KEY.

 

GT_SHIPStypety_ships. -> has been populated as follows:

RowTKNUM[C(10)]Name[C(12)]City[C(25)]Route[C(6)]
1001JohnMelbourneR0001
2002GavinSydneyR0003
3003LucyAdelaideR0001
4004ElainePerthR0003

 

 

 

III. Example 1

Populate internal table GT_CITYS with the cities from GT_SHIPS.

Before 7.40

  DATA: gt_citys TYPE ty_citys,
       gs_ship 
TYPE ty_ship,
       gs_city 
TYPE ort01.

LOOP AT gt_ships INTO gs_ship.
  gs_city
gs_ship-city.
  APPEND gs_city TO gt_citys.
ENDLOOP.

With 7.40

DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships ( ls_ship-city ) ).

 

IV. Example 2

Populate internal table GT_CITYS with the cities from GT_SHIPS where the route is R0001.


Before 7.40

  DATA: gt_citys TYPE ty_citys,
       gs_ship 
TYPE ty_ship,
       gs_city 
TYPE ort01.

LOOP AT gt_ships INTO gs_ship WHERE route = 'R0001'.
  gs_city
gs_ship-city.
  APPEND gs_city TO gt_citys.
ENDLOOP.

With 7.40

DATA(gt_citys) = VALUE ty_citys( FOR ls_ship IN gt_ships

                               WHERE ( route = 'R0001' ) ( ls_ship-city ) ).

Note: ls_ship does not appear to have been declared but it is declared implicitly.


V. FOR with THEN and UNTIL|WHILE

FOR i = ... [THEN expr] UNTIL|WHILE log_exp

Populate an internal table as follows:

TYPES:
  BEGIN OF ty_line,
    col1 TYPE i,
    col2 TYPE i,
    col3 TYPE i,
  END OF ty_line,
  ty_tab TYPE STANDARD TABLE OF ty_line WITH EMPTY KEY.

Before 7.40

DATA: gt_itab TYPE ty_tab,
      j      
TYPE i.
FIELD-SYMBOLS <ls_tab> TYPE ty_line.

j
= 1.
DO.
j
= j + 10.
IF j > 40. EXIT. ENDIF.
APPEND INITIAL LINE TO gt_itab ASSIGNING <ls_tab>.
<ls_tab>
-col1 = j.
<ls_tab>
-col2 = j + 1.
<ls_tab>
-col3 = j + 2.
ENDDO.

With 7.40

DATA(gt_itab) = VALUE ty_tab( FOR j = 11 THEN j + 10 UNTIL j > 40
                            ( col1 = j col2 = j + 1 col3 = j + ) ).

 

6. Reduce

I. Definition

... REDUCE type(

INIT result = start_value

           ...

FOR for_exp1

FOR for_exp2

...

NEXT ...

           result = iterated_value

... )

 

II. Note

     While VALUE and NEW expressions can include FOR expressions, REDUCE must include at least one FOR expression. You can use all kinds      of FOR expressions in REDUCE:

  • with IN for iterating internal tables
  • with UNTIL or WHILE for conditional iterations

III. Example 1

Count lines of table that meet a condition (field F1 contains “XYZ”).

Before 7.40

DATA: lv_lines TYPE i.

LOOP AT gt_itab INTO ls_itab where F1 = ‘XYZ’.
  lv_
lines= lv_lines + 1.
ENDLOOP.

With 7.40

DATA(lv_lines) = REDUCE i( INIT x = 0 FOR wa IN gt_itab

                    Where( F1 = ‘XYZ’ ) NEXT x = x + 1 ).

 

IV. Example 2

Sum the values 1 to 10 stored in the column of a table defined as follows

DATA gt_itab TYPE STANDARD TABLE OF i WITH EMPTY KEY.
gt_itab
= VALUE #( FOR j = 1 WHILE j <= 10 ( j ) ).

Before 7.40

DATA: lv_line TYPE i,
      lv_sum 
TYPE i.

 

LOOP AT gt_itab INTO lv_line.
  lv_sum
= lv_sum + lv_line.
ENDLOOP.

With 7.40

DATA(lv_sum) = REDUCE i( INIT x = 0 FOR wa IN itab NEXT x = x + wa ).

V. Example 3

Using a class reference - works because “write” method returns reference to instance object

With 7.40

TYPES outref TYPE REF TO if_demo_output.

DATA(output) = REDUCE outref( INIT out  = cl_demo_output=>new( )
                              text
= `Count up:`
                              FOR n = 1 UNTIL n > 11
                              NEXT out = out->write( text )
                              text
= |{ n }| ).

output->display( ).

 

 

7. Conditional operators COND and SWITCH

I. Definition

... COND dtype|#( WHEN log_exp1 THEN result1
[ WHEN log_exp2 THEN result2 ]
...
[ ELSE resultn ] ) ...

 

... SWITCH dtype|#( operand
WHEN const1 THEN result1
[ WHEN const2 THEN result2 ]
...
[ ELSE resultn ] ) ...

 

II. Example for COND

DATA(time) =

  COND string(

    WHEN sy-timlo < '120000' THEN

      |{ sy-timlo TIME = ISO } AM|

    WHEN sy-timlo > '120000' THEN

      |{ CONV t( sy-timlo - 12 * 3600 )

TIME = ISO } PM|

    WHEN sy-timlo = '120000' THEN

      |High Noon|

    ELSE

      THROW cx_cant_be( ) ).

 

III. Example for SWITCH

DATA(text) =
NEW class( )->meth(
                     SWITCH #( sy-langu
                              WHEN 'D' THEN `DE`
                              WHEN 'E' THEN `EN`
                               ELSE THROW cx_langu_not_supported( ) ) ).

 

 

8. Strings

I. String Templates

A string template is enclosed by two characters "|" and creates a character string.

Literal text consists of all characters that are not in braces {}. The braces can contain:

  • data objects,
  • calculation expressions,
  • constructor expressions,
  • table expressions,
  • predefined functions, or
  • functional methodsand method chainings

 

Before 7.40

DATA itab TYPE TABLE OF scarr.
SELECT * FROM scarr INTO TABLE itab.

DATA wa LIKE LINE OF itab.
READ TABLE itab WITH KEY carrid = 'LH' INTO wa.

DATA output TYPE string.
CONCATENATE 'Carrier:' wa-carrname INTO output SEPARATED BY space.

cl_demo_output=>display( output ).

With 7.40

SELECT * FROM scarr INTO TABLE @DATA(lt_scarr).
cl_demo_output
=>display( |Carrier: { lt_scarr[ carrid = 'LH' ]-carrname }|                                                                         ).

 

II. Concatenation

Before 7.40

DATA lv_output TYPE string.
CONCATENATE
'Hello' 'world' INTO lv_output SEPARATED BY space.

With 7.40

DATA(lv_out) = |Hello| & | | & |world|.

 

III. Width/Alignment/Padding

WRITE / |{ 'Left'     WIDTH = 20 ALIGN = LEFT   PAD = '0' }|.
WRITE / |{ 'Centre'   WIDTH = 20 ALIGN = CENTER PAD = '0' }|.
WRITE / |{ 'Right'    WIDTH = 20 ALIGN = RIGHT  PAD = '0' }|.

 

IV. Case

WRITE / |{ 'Text' CASE = (cl_abap_format=>c_raw) }|.
WRITE / |{ 'Text' CASE = (cl_abap_format=>c_upper) }|.
WRITE / |{ 'Text' CASE = (cl_abap_format=>c_lower) }|.

 

V. ALPHA conversion

DATA(lv_vbeln) = '0000012345'.
WRITE / |{ lv_vbeln  ALPHA = OUT }|.     “or use ALPHA = IN to go in other direction

 

VI. Date conversion

WRITE / |{ pa_date DATE = ISO }|.           “Date Format YYYY-MM-DD
WRITE / |{ pa_date DATE = User }|.          “As per user settings
WRITE / |{ pa_date DATE = Environment }|.   “Formatting setting of language environment

9. Classes/Methods

I. Referencing fields within returned structures

Before 7.40

DATA: ls_lfa1  TYPE lfa1,
      lv_name1
TYPE lfa1-name1.

ls_lfa1 
= My_Class=>get_lfa1( ).
lv_name1
= ls_lfa1-name1.

With 7.40

DATA(lv_name1) = My_Class=>get_lfa1( )-name1.

 

II. Methods that return a type BOOLEAN

Before 7.40

IF My_Class=>return_boolean( ) = abap_true.

ENDIF.

With 7.40

IF My_Class=>return_boolean( ).

ENDIF.

NB: The type “BOOLEAN” is not a true Boolean but a char1 with allowed values X,- and <blank>.

       Using type “FLAG” or “WDY_BOOLEAN” works just as well.

 

 

III. NEW operator

This operator can be used to instantiate an object.

Before 7.40

DATA: lo_delivs TYPE REF TO zcl_sd_delivs,

            lo_deliv  TYPE REF TO zcl_sd_deliv.

CREATE OBJECT lo_delivs.
CREATE OBJECT lo_deliv.

lo_deliv = lo_delivs->get_deliv( lv_vbeln ).

With 7.40

DATA(lo_deliv) = new zcl_sd_delivs( )->get_deliv( lv_vbeln ).

 

 

10. Meshes

Allows an association to be set up between related data groups.


I. Problem

Given the following 2 internal tables:

TYPES: BEGIN OF t_manager,
name  
TYPE char10,
salary
TYPE int4,
END OF t_manager,
tt_manager
TYPE SORTED TABLE OF t_manager WITH UNIQUE KEY name.

TYPES: BEGIN OF t_developer,
name   
TYPE char10,
salary 
TYPE int4,
manager
TYPE char10,   "Name of manager
END OF t_developer,
tt_developer
TYPE SORTED TABLE OF t_developer WITH UNIQUE KEY name.


Populated as follows:

RowName[C(10)]Salary[I(4)]
1Jason3000
2Thomas3200
Row
Name[C(10)]

Salary[I(4)Manager[C(10)]
1Bob2100Jason
2David2000Thomas
3Jack1000Thomas
4Jerry1000Jason
5John2100Thomas
6Tom2000Jason

Get the details of Jerry’s manager and all developers managed by Thomas.

 

 

II. Solution

With 7.40

TYPES: BEGIN OF MESH m_team,
         managers  
TYPE tt_manager  ASSOCIATION my_employee TO developers

                                                            ON manager = name,
         developers
TYPE tt_developer ASSOCIATION my_manager TO managers  

                                                            ON name = manager,
       END OF MESH m_team.

DATA: ls_team TYPE m_team.
ls_team
-managers   = lt_manager.
ls_team
-developers = lt_developer.

*Get details of Jerry's manager *

"get line of dev table

ASSIGN lt_developer[ name = 'Jerry' ] TO FIELD-SYMBOL(<ls_jerry>).
DATA(ls_jmanager) =  ls_team-developers\my_manager[ jerry ].

WRITE: / |Jerry's manager: { ls_jmanager-name }|,30

                  |Salary: { ls_jmanager-salary }|.


"Get Thomas' developers
SKIP.
WRITE: / |Thomas' developers:|.

 

"line of manager table

ASSIGN lt_manager[ name = 'Thomas' ] TO FIELD-SYMBOL(<ls_thomas>).
LOOP AT ls_team-managers\my_employee[ thomas ]     

        ASSIGNING FIELD-SYMBOL(<ls_emp>).

  WRITE: / |Employee name: { <ls_emp>-name }|.
ENDLOOP.

III. Output

     Jerry's manager: Jason          Salary: 3000

 

     Thomas' developers:

     Employee name: David

     Employee name: Jack

     Employee name: John

 

 

11. Filter

Filter the records in a table based on records in another table.


I. Definition

... FILTER type( itab [EXCEPT] [IN ftab] [USING KEY keyname]
           WHERE c1 op f1 [AND c2 op f2 [...]] )

 

II. Problem

Filter an internal table of Flight Schedules (SPFLI) to only those flights based on a filter table that contains the fields Cityfrom and CityTo.

 

III. Solution

With 7.40

TYPES: BEGIN OF ty_filter,
         cityfrom
TYPE spfli-cityfrom,
         cityto  
TYPE spfli-cityto,
         f3      
TYPE i,
       END OF ty_filter,
       ty_filter_tab
TYPE HASHED TABLE OF ty_filter

                     WITH UNIQUE KEY cityfrom cityto.
DATA: lt_splfi TYPE STANDARD TABLE OF spfli.

SELECT * FROM spfli APPENDING TABLE lt_splfi.

DATA(lt_filter) = VALUE ty_filter_tab( f3 = 2

                          ( cityfrom = 'NEW YORK'  cityto  = 'SAN FRANCISCO' )
             ( cityfrom = 'FRANKFURT' cityto  = 'NEW YORK' )  ).

DATA(lt_myrecs) = FILTER #( lt_splfi IN lt_filter

                                  WHERE cityfrom = cityfrom 

                                    AND cityto = cityto ).

“Output filtered records
LOOP AT lt_myrecs ASSIGNING FIELD-SYMBOL(<ls_rec>).
  WRITE: / <ls_rec>-carrid,8 <ls_rec>-cityfrom,30

           <ls_rec>-cityto,45 <ls_rec>-deptime.

ENDLOOP.

 

Note: using the keyword “EXCEPT” (see definition above) would have returned the exact opposite records i.e all records EXCEPT for those those returned above.

Validate data in Table Maintenace Generator event

$
0
0

The TMG event 01: Before Save., can be used instead of going for event 05: New Entry if you have validation process to do.


The problem with event 05 is that, control goes into the include/form only on the newly created entries. So, if you have you had to change any existing data, the control wouldn't pass through the validation code and you will be stuck in awe.


Here is a piece of code that you can use for your development purpose.


Here,

  • <action> is a flag that will have values as 'N' if a new entry is made or as 'U' if existing entry is modified.
  • <vim_total_struc>is a structure that holds the current looped value on TOTAL table.
  • it_total_zdata, internal table should be of type table z-table.


LOOP AT total.

  IF <action> EQ 'N' OR <action> EQ 'U'.

    APPEND <vim_total_struc> TO it_total_zdata.

  ENDIF.

ENDLOOP.


IF it_total_zdata[] IS NOT INITIAL.

* Perform validation

    LOOP AT it_total_zdata.

      IF it_total_zdata-name NE 'TESTNAME'.

        MESSAGE 'Name is not TESTNAME' TYPE 'S' DISPLAY LIKE 'E'.

        vim_abort_saving = c_abrt_save.

        sy-subrc = 4.

        EXIT.

      ENDIF.

    ENDLOOP.

ENDIF.


IMPORTANT POINTS  !!

  • Message should be of type 'S'. If not, the screen returns to SM30, which looks bad !! Make sure its displayed either as 'Error' or 'Warning'.
  • vim_abort_saving has to be set to 'X' to avoid data being saved. (Since the message popped is of type 'S', control proceeds further!!)
  • Set sy-subrc as '4' which stops further processing.


The above points are mandatory, if you want a message to be popped and wrong data still to be seen giving an opportunity to the user to rectify.

Production Order Goods Movement Custom Batch Number Generation

$
0
0

I searched on SCN and found there are so many threads we have asked for User Ext/Badi which updates the Batch Number when doing Goods Movement of Production Order, Non of the thread I found marked as Resolved/Answered..

 

I thought to share my past experience when I had come across similar requirement of customer and Implemented one Badi to update the Batch Number.

Requirement was when we create Production Order (Transaction Code CO01 ), SAP  Proposes Batch Number or you can Enter any batch number Manually.

1.png

After releasing production order, we normally Enter Time Ticket for Production Order( Transaction Code CO11N) and do the Goods Movement.

2.png

After Creating time ticket for production order When you try to do Goods Movement (As shown in Screen below), same batch number reflects against created production order.

3.png

But, here we want to update custom batch number with below posting date entered in below screen in CO11N :

 

4.png

Example:Batch Number should be always posting date of production order in YYMMDD format, so that user can easily identify the batches against which materials production is confirmed.

 

We will use BADI definition “WORKORDER_GOODSMVT” to update the Batch Number.

 

Step 1: Go to Transaction code SE19 and create Implementation for  BADI WORKORDER_GOODSMVT.

Step 2: Enter BADI Defination Name.

Step 3: Go to Interface Tab and select Method “GOODS_RECEIPT” to Write the Logic.

Step 4: Write the below Sample Code:

 

DATA: ls_confirmations LIKE LINE OF it_confirmations,
ix_tabix
TYPE sy-tabix.

IF sy-tcode = 'CO11N'.

READ TABLE it_confirmations INTO ls_confirmations INDEX 1.
IF sy-subrc = 0.
WRITE ls_confirmations-budat TO ls_confirmations-budat YYMMDD.
ENDIF.
CLEAR ix_tabix.
LOOP AT ct_goods_receipt INTO ls_goods_receipt.
ix_tabix
= ix_tabix + 1.
ls_goods_receipt
-charg = ls_confirmations-budat.

MODIFY ct_goods_receipt FROM ls_goods_receipt INDEX ix_tabix.
ENDLOOP.
ENDIF.

 

Step 5: Activate the Badi and Test the Scenario.

 

Note: Above Logic will not update custom batch in Production order transaction code (CO01/CO02/CO03).


In Transaction Code CO11N in Goods Movement Tab we can see the updated batch number.

 

5.png

 

Now Go to Production Order and see the “Documented Goods Movement”, you will get the updated batch number there too.

 

 

Thanks for reading this short document.

SAP NetWeaver AS ABAP 7.40 SP 8 - Developer Edition to Download: Installation on Debian Linux 8.0 (jessie)

$
0
0

This article relates to the SAP NetWeaver AS ABAP 7.40 SP8 - Developer Edition to Download. It might be placed at an intermediate level between the Concise Installation Instructions and the detailed Step-by-Step Guide by Thea Hillenbrand.

 

Personally, I prefer Debian to Ubuntu on headless server systems. It might be just a personal choice, but Ubuntu is a bit too "bunt" for me (sorry, bad pun). There are a few things to observe when installing the AS ABAP Developer Edition on a Debian Jessie system, so I decided to share my notes. I'm assuming you have a basic knowledge about Debian and have read the articles above as well as the readme file that comes with the download - you will definitely need the latter since the passwords are in there :-)

 

I'm using a headless Virtualbox setup, but I won't go into the details of its installation - there are plenty of instructions out there.

 

Install a pretty standard Debian 8.0 (jessie) amd64 system. Choose English (US) as language and then your country, making sure that you select the correct locale en_US.UTF-8. Partition the disk using the All files in one partition preset. After installing the base system, the software selection dialog appears - be sure to only select SSH server and standard system utilities here. Don't forget to install the guest additions for your virtualization software (instructions for Virtualbox are here).

 

Edit /etc/apt/sources.list and add contrib and non-free to the main sources, followed by

apt-get update

 

You need unrar from non-free because unrar-free is broken; you won't be able to extract the multi-volume archives. Now on to the dependencies:

 

apt-get install csh uuid uuid-runtime

update-rc.d uuidd enable

/etc/init.d/uuidd start

 

apt-get install unrar libaio1 lib32z1 libxtst6

That last library is required for the graphical installer, even on a headless system (ssh -XY <yourhostname>). Then edit /etc/hosts to permanently assign the IP address to the host name, thus making the installer happy. Alternatively, you might run the installer with the command line parameter -s.

 

Finally unpack the installation files and start the installation:

 

unrar x TD74SPS8_part1.rar

chmod u+x install.sh

./install.sh

Proceed as directed by the installer - this will take some time.

 

After the installation, edit /usr/sap/NPL/SYS/profile/NPL_DVEBMGS00_<yourhostname> to add the parameter icm/host_name_full if necessary and change PHYS_MEMSIZE to 30% as described in the Step-by-Step Guide. Request and install the license key as described in the readme and start hacking away...

SAP NetWeaver AS ABAP 7.40 SP 8 - Developer Edition to Download: Configuring the TMS

$
0
0

After completing the installation of the SAP NetWeaver AS ABAP 7.40 SP 8 - Developer Edition, I found out that - unlike the CAL edition - this system does not come with a fully configured TMS, or rather that you need to perform some additional steps to get the TMS working.

  1. Either edit your /etc/hosts file or modify your DNS information: Assuming that your actual hostname is mysapnpl, ensure that the system is also reachable under the hostname mysapnplci (CI for Central Instance) since that is the host name that is generated into the RFC destinations TMSADM@NPL.DOMAIN_NPL and TMSSUP@NPL.DOMAIN_NPL. Without that, you will get communication errors when executing various TMS functions. To verify that this has worked correctly, start transaction STMS, select Overview> Systems, select the line containing NPL and execute SAP System> Check> Connection Test (F5)
  2. Now check the tp profile using STMS, select Overview> Systems, select the line containing NPL and execute SAP System> Check> Transport Tool and Transport Tool. This should check out OK with a green status. In my case, the tp profile was damaged and unusable, so I had to re-create it using STMS, select Overview> Systems, then Extras> Distribute and Activate TMS Configuration, ...to All Systems...

How to convert a front end BDC recording code(generated via SHDB) into a modular Code to be run in the background using 'Call Transaction' with error Log

$
0
0

In this article,we are going to convert a bdc recording macro code into a portable code that can be utilized and embedded in any posting based program in the background with a log as well using 'CALL TRANSACTION' mechanism.

 

We can import this recording for T-code ABAVN through the file attached in this article named 'bdc_recording_ABAVN.txt.zip' via Tcode shdb. Just extract it and then import it using the instructions provided in the link below for the importing part in your system:

 

http://wiki.scn.sap.com/wiki/display/ABAP/ABAP+-+Tips+and+Tricks+Channel?original_fqdn=wiki.sdn.sap.com#ABAP-TipsandTricksChannel-[01]-HowtoexportaBDCrecordingfromoneclienttoanother:

 

For creating a batch upload program we will be using a  BDC recording in SAP carried out via transaction code 'SHDB'. We can ask a Functional Consultant of the specific module to create a BDC recording for a given transaction along with the fields that are required for batch upload. Once a recording is created we can generate a macro by clicking the [] Program button to generate the macro code for the given recording in SHDB. We can also run the macro recording in different modes as it was created originally by clicking the Process[] button in SHDB. We will follow steps from when the BDC recording macro has been created and saved as a program,with an option of 'Transfer from Recording' radio button selected in the Field Contents

                             

from the pop-up menu.

 

In our case,it will be a BDC recording for Tcode = ABAVN, which is used for directly retiring an Asset by Scrapping it,which is used in SAP FI module.

 

To have a look at the BDC recording macro code generated,refer to the code below:

__________________________________________________________________________________________________________________________

    [BDC Macro Code for Transaction ABAVN ]

 

report ZASSET_SCRAP_BDC
no standard page heading line-size 255.

include bdcrecx1.

start-of-selection.

perform open_group.

perform bdc_dynpro      using 'SAPLAMDP' '0100'.
perform bdc_field      using 'BDC_OKCODE'
                         
'=TAB02'.
perform bdc_field      using 'RAIFP2-ANLN1'
                           
'1010000017'.
perform bdc_field      using 'RAIFP2-ANLN2'
                         
'0'.
perform bdc_field      using 'RAIFP1-BLDAT'   
                           
'13.10.2015'.
perform bdc_field      using 'RAIFP1-BUDAT'
                         
'13.10.2015'.
perform bdc_field      using 'RAIFP1-BZDAT'
                         
'13.10.2015'.
perform bdc_field      using 'BDC_CURSOR'   
                         
'RAIFP2-SGTXT'.
perform bdc_field      using 'RAIFP2-SGTXT'
                         
'Asset Scrap'.
perform bdc_dynpro      using 'SAPLAMDP' '0100'.
perform bdc_field      using 'BDC_OKCODE'
                         
'=SHWD'.
perform bdc_field      using 'RAIFP2-ANLN1'   
                         
'1010000017'.
perform bdc_field      using 'RAIFP2-ANLN2'
                         
'0'.
perform bdc_field      using 'RAIFP2-MONAT'
                           
'09'.
perform bdc_field      using 'RAIFP1-BLART'
                           
'AA'.
perform bdc_field      using 'BDC_CURSOR'
                         
'RAIFP1-XBLNR'.
perform bdc_field      using 'RAIFP1-XBLNR'   
                         
'ASSET SCRAP'.
perform bdc_dynpro      using 'SAPMSSY0' '0120'.
perform bdc_field      using 'BDC_OKCODE'
                         
'=BUCH'.
perform bdc_transaction using 'ABAVN'.

perform close_group.

__________________________________________________________________________________________________________________________


Here is a brief description of the elements in the BDC recording Macro Code used in the code above:


> All the fields called in the BDC recording start with the the following fields e.g:  'perform bdc_fieldusing 'RAIFP1-BLART'' followed by a value which could either be a constant or a data object etc. as could be seen from the code above.


> The ones with the text 'BDC_CURSOR' follow up with the name of the field where the cursor is to be placed on the screen.

e.g:


perform bdc_field using 'BDC_CURSOR'
'RAIFP2-SGTXT'.


> When a specific screen or tab is called on a screen,it is usually followed with a  Module Pool Name and Screen No. e.g:


perform bdc_dynpro      using 'SAPLAMDP' '0100'.
perform bdc_field      using 'BDC_OKCODE'
'=TAB02'.


Here BDC_OKCODE is the ok code or an identifier for identifying which UI element  in Dynpro screen was clicked followed by the identifier id. For those of you who have done dynpro programming know the system constant sy-ucomm holds this value at runtime.


> Finally the transaction code for which this macro was generated is called using 'BDC_TRANSACTION'. e.g:


perform bdc_transaction using 'ABAVN'.


________


With the BDC recording out of the way,we can now concentrate on how  to convert it for Call Transaction Mechanism. The  best way to map fields is to create a single structure in ABAP for holding all values that are to be passed for all fields in the Macro recording discussed before.

e.g:

 

DATA: BEGIN OF s_assetscrap,
        bukrs type ANLA-BUKRS,"Company Code
        ANLN1 type anla-anln1,"Asset No
        ANLN2 type ANLA-ANLN2,"Sub Asset No
        BLDAT type RAIFP1-BLDAT,"Document Date
        budat type RAIFP1-BUDAT,"Posting Date
        BZDAT type RAIFP1-BZDAT,"Asset Value Date
        SGTXT type RAIFP2-SGTXT,"Text

        monat type RAIFP2-MONAT,"Posting Period
        BLART type RAIFP1-BLART,"Document Type
        XBLNR type RAIFP1-XBLNR,"Reference
      END OF s_assetscrap.


We now need to add in each of the BDC recording code lines to an internal table that will eventually be passed as a parameter when using the 'Call Transaction' construct. It will be based on 5 parameters as is required when calling a bdc code in Call Transaction construct based on the standard structure named 'BDCDATA'. Here are the fields in the structure:


  1. PROGRAM(Module Pool Name)
  2. DYNPRO(Screen No for the Dynpro)
  3. DYNBEGIN(BDC screen start)
  4. FNAM(Field name on the Screen)
  5. FVAL(Field value to be used)

 

Based on these fields,this is how we are going to convert it.


e.g:


"Original Code as provided in BDC recording macro


perform bdc_dynpro      using 'SAPLAMDP' '0100'.


"Code Converted for BDC recording called in Call Transaction construct


wa_bdcdata-program = 'SAPLAMDP'.

wa_bdcdata-dynpro = '0100'.

wa_bdcdata-dynbegin = 'X'.

wa_bdcdata-fnam = ''.

wa_bdcdata-fval = ''.


Compare the fields with the code above to get a better idea about value passed here.


Here is the complete code converted to the format as required for Call Transaction construct line by line.


_________[Each of the 19 Lines converted to Call Transaction Format based on BDCDATA structure]


> Add multiple records for this bdc recording in one go as well.


DATA:

     it_bdcdata type standard table of BDCDATA,

     wa_bdcdata like line of it_bdcdata.


"1

wa_bdcdata-program = 'SAPLAMDP'.

wa_bdcdata-dynpro = '0100'.

wa_bdcdata-dynbegin = 'X'.

wa_bdcdata-fnam = ''.

wa_bdcdata-fval = ''.


append wa_bdcdata it_bdcdata.

clear wa_bdcdata.


"...and so on. Only shortened code is shown here for illustrative purposes.


[Refer to the complete code in the attached text file named 'BDC_Recording_Code_Conversion_Code_Fragment.txt.zip'].


_________

 

 

The final element of transaction code  will be passed when using the final Call Transaction construct for uploading or posting .


dyn_begin = 'X' indicates that a screen is called at this point,therefore the module pool name and screen no is called here and for the rest field name and value pairs are passed in.


Here is how the final Call Transaction code will be called for posting this Asset Retirement via scrap:


DATA:

     it_msg type standard table of bdcmsgcoll."This will hold all Messages


  CALL TRANSACTION 'ABAVN' USING it_bdcdata

    MODE 'N'

    UPDATE 'S'

    MESSAGES INTO it_msg.

 

Here it_bdcdata is the BDC recording format converted for compatibility with BDC Recording.

     Mode   = N[For Running in the Background]

               [All Modes in BDC recording are supported like

                'E'(Errors),'A'(All Screens)]

     Update = S[Synchronous]

     it_msg = Holds all error messages and successful messages


For Logging,Internal table it_msg can be looped through for finding successful postings(msgtyp = 'S') and failed postings(msgtyp = 'F') of uploads via call transaction construct. e.g for successful messages:


LOOP AT it_msg INTO wa_msg WHERE msgtyp EQ 'S'.
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid= wa_msg-msgid
msgnr= wa_msg-msgnr
msgv1= wa_msg-msgv1
msgv2= wa_msg-msgv2
msgv3= wa_msg-msgv3
msgv4= wa_msg-msgv4
IMPORTING
message_text_output = wa_msg_all.

 

ENDLOOP.


Here the data object 'wa_msg_all' complete error message in one line, where as individual components are also store in one of the structures like wa_msg-msgid(Message Id number),wa_msg-msgnr(Message No),wa_msg-msgv1 to wa_msg-msgv4(contains error or successful messages with description).


Using this code mechanism through Call Transaction we can convert BDC recordings into portable executable code which can be embedded especially if you are working on a selective posting program using an interactive ALV report for selecting records and posting them.



How to include ABAP Quick Search into NWBC

$
0
0

Follow these 7 easy steps to include the search in your Business Client:

For functionality, see: ABAP Quick Search for NWBC

 

0. Please check the system requirements: SAP Netweaver Release 7.4 or higher.

 

1. Copy the content of the "Program.txt" to a new Program and replace the placeholder with the actual program name. (E.g. object_opener)

 

2. a) Create a transaction like this:

Create Transaction.PNG

2. b) Change the transaction so that it starts the program you created in step 1.

Create Transaction2.PNG

3. Upload the file "resultpage.html" to a new folder in the MIME Repository:

Upload Resultpage.png

Don't forget to activate it

 

4. a) Copy the content of the file "Search_Class.txt" to a new class and replace the placeholders with the actual class name. (E.g. nwbc_abap_search)

 

Meth_Descr.PNG

 

4. b) Change the constant "cv_opener_transaction" to the name of the transaction you created in step 2.

 

4. c) Change the constant "cv_result_page" to the path of the .html-file you uploaded in step 3:

 

Clonstants2.PNG

4. d) If you want to edit the whitelist of result types, you can change it in the class-constructor.

 

5. a) Start the transaction 'SICF' and create a new service (via New Sub-Element).

Create Service.PNG

5. b) Enter a description and add the search class you created in step 4 to the handler list. Don't forget to activate it.

Create Service2.PNG

6. Add a new search provider in your NWBC. Therefore go to Options --> Settings --> Connections --> Search Providers...

Type in the address and port of your server (you can find it here: Options --> Help --> About NetWeaver  Business Client --> System Information -> Server) and after that the path to the service you created in step 6 and "?type=OpenSearchDescription".

If you want to, you can add the namespace and max_results parameter, too, as shown here:

SearchProvider.png

7. Type something into the search bar and enjoy.

ABAP Quick Search for NWBC

$
0
0

In the SAP (Netweaver) Business Client you have a search bar in the upper range of the window. As soon as you type something in there, it tries to get search suggestions from all the defined so-calledsearch providers:

Context.png

It is possible to add own search providers. For more information, see: WKS: How to use NWBC in TM - Search Providers

 

The ABAP Quick Search for NWBC is such a search provider.

With that search you can easily search for all ABAP related content available on your system and open it with one click:

Example.png

 

Additional Features:

  • Results are sorted by type
  • Define a namespace and search it by typing //
  • Extra fancy result page

resultpage.PNG

  • Search for special result types by typing \<object_type> (see file ABAP_Whitelist.xlsx or the list at the end of the document)
  • Decide how to open tables: Do you want to see the structure (SE11) or the content (SE16)?

Tables.png

  • Decide how to open BOBF Business Objects: In the BOBF Test UI or in BOBF Conf UI?

OpenBOBF.png

Unfortunately, not all functions work in NWBC 4.

 

 

If you want to have the search included into your Business Client, please read this scn posting: How to include ABAP Quick Search into NWBC

 

Here is the standard list of result types for which is searched for. In case you want to search for a certain type, add \<object_type> to your search request.

E.g. "\CLAS" for classes.

 

ACIDCheckpoint Group
IWPRGW Service Builder Project
SAMCABAP Messaging Channel
SAPCABAP Push Channel
SPRXGeneric Proxy
BOBFBOPF Business Object
BOBXBOPF Enhancement Object
CLASClass
COBOBudiness Object
DEVCPackage
DOMAMain
DTELData Element
ENQULock Objects
FUGRFunction Group
FUGSFunction Groups
IAMLLanguage Dependent MIME Object
IAMUMIME Objects
IASPInternet Service
INTFinterface
MSAGMessage Classes
PARAUser Parameter
PINFPackage Interface
PROGInclude
RPDFReport Definition
SCATTest Case
SCGRService Group
SFBFBusiness Function
SFPFForm
SFPIInterface
SHLPSearch Help
SHMAShared Object Area Class
SMIMMime Objects
TABLDictionary
TRANTransactions
TTYPDictionary
TYPEDictionary
VIEWView
WDCAWeb Dynpro Application Configuration
WDCCWeb Dynpro Component Configuration
WDCPWeb Dynpro Chip
WDYAWeb Dynpro Application
WDYNWeb Dynpro Comp/INTF

Building an SAP Query with ABAP Code

$
0
0

ABAP code is used with SAP query tool to enhance the query output.

 

You can write down the code under the Extras tab for the Infoset in the SQ02 Tcode.

 

SAP doc 1.PNG

 

You will find various coding events which are similar to classical ABAP report.

 

SAP doc2.PNG

 

The code written in this code area is transmitted to the auto generated query report. You can write down your code in various coding section as per the use of them.

  • DATA Section :

       Global Data Declaration will go under this Event.

  • INITIALIZATION Section :

       As the name suggests it is used to initialize the variable with initial values.

  • AT SELECTION-SCREEN OUTPUT :

       This event is triggered before the display of selection screen.

  • START-OF-SELECTION :

       This event is triggered before starting any database accesses. Usually Data fetching logic goes under it.

  • RECORD Processing :

        Corresponds to the GET coding with Info-sets without a logical database. As there is no hierarchical view of the data, all the join tables are addressed.

  • END-OF-SELECTION :

         The END-OF-SELECTION code consists of two parts (Before list output and After list output). The first part is processed before the list is output and the  second  part afterwards. It is the right section to do aggregated calculations and actions that can only be done when data from all the selected records has been extracted.

 

However, there is a problem when queries use code in the END-OF-SELECTION section in combination with the Sap List Viewer format. In short, the code is never reached.

  • Free Coding :

          The code under this event is executed after all the events are triggered.

 

 

Logic to put extra field in the query output:

 

Let you want a date field to be fetch from a 'B' table and has to be added to your query output.

Define a Structure in DATA Event:

data: begin of ty_date occurs 0,

                   date  like B-date,

                   end of ty_date.

 

The logic to fetch the values for this field will go under the record processing event.

In Record Processing Event write down the following code:

CLEAR ty_date.

CLEAR v_date.

Select date from B into table ty_date.                    "You can mention your condition also with where clause

Sort Table ty_date BY date DESCENDING.

Read Table ty_date INDEX 1.

v_date = ty_date-date.

 

Generate the Infoset.

 

Changes to the query:

1.Run SQ01 in another session.

2. Open your Query in change mode and select the field group in which has the added extra field.

3.Select extra field.

4 Click on basic list to select that field in your O/p list.

5.Click on Test button, and see if you are getting desired result.

 

Performing Operations on the final output table data:

 

You'll find table %G00 with final data to be displayed.

Enter the following ABAP code under Data Section:

    data: str type string.

   field-symbols: <G00> type table.

   field-symbols: <G00_WA> type any.

 

Enter the below ABAP code under END-OF-SELECTION(after list) Event:

   str = '%g00[]'.

   ASSIGN (str) TO <G00>.

   loop at <G00> assigning <G00_WA>.

   ...do whatever you like here....

   endloop.

You can put your own logic inside the loop to perform. .

      

How to store a binary file as function module

$
0
0


Hello community,


many information is stored in different files with different formats. This information is often important for the customer and there is the question, how to transport this to a customer.

 

BinFile2ABAP is a program which offers this possibility. With BinFile2ABAP you can store each file in an ABAP function module.

It converts the file to an ABAP source code as a function module, form or report. With the call the file is saved on the presentation server and executed.

 

BinFile2ABAP can also create base64 encoded JSON files from any file too. You can use this JSON file in the context of your SAPUI5 development, e.g. to simulate backend databinding, via OData and the SAP Gateway, as local databinding.

 

With this kind of information you can extend your possibilities. You can integrate each type of file you want in your ABAP program, e.g. Adobe Flash and Portable Document Format (PDF), Compiled HTML Help (CHM), all image, sound and video formats etc.

 

BinFile2ABAP is free and you can download it from here.

 

BinFile2ABAP001.jpg

 

The process to generate ABAP code is very easy. Choose the binary file you want, press the button Create Code and save the file to disc. Transfer the code in your ABAP editor via clipboard or upload - that's all.

 

You can choose the line width, 16, 32, 64 or 125 bytes, this means, 32, 64, 128 or 250 characters in a line. It is dependence from the file size, because the ABAP interpreter allows max. 65535 lines to concatenate. With 125 bytes and 65535 lines you get a file size limit from 8'191'875 bytes. It is possible to create an ABAP source with more lines, but you can not compile it.


BinFile2ABAP002.JPG


The process to generate JSON code is also very easy. Choose the binary file you want, press the button Create Code and save the file to clipboard or disc - that's all. You can find an example how to use it here.


2015/11/22: Update is available

  • Now two versions are available, x86 and x64.
  • Checked with Windows 10 x64.
  • Add the possibility to create Background Light code. You can find more information about Background Light here.

 

2015/02/15: Update is available

  • Add the possibility to create JSON file with base64 encoded content.
  • Add the possibility to create function modules with an export interface.
  • Add the possibility to create function modules in ABAP in Eclipse (AiE) style.
  • New GUI design with tabs.
  • Delete the possibility to create ABAP code with more than 65535 lines, because it has no practical significance.


Enjoy it.

 

Cheers

Stefan

Viewing all 935 articles
Browse latest View live


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