Quantcast
Channel: SCN : Document List - ABAP Connectivity
Viewing all 63 articles
Browse latest View live

Email Sending Functionality for Different Business Process in Sap

$
0
0

Email Sending Functionality for Different Business Process in Sap

Nov, 2013

 

 

Introduction

Every Business Process in SAP Follow different communication types to communicate with its Business partners like Print and send via post, Fax, and Email (Internet).Several E-mail communications need to be sent to Vendors & Customers who are the business partners for the organization which contains several Business Processes like Payment Advice, Dunning forms and PO’s etc., with PDF and Excel as attachment, which is a very eco-friendly way. Presently many are using the process of taking a print out and sending it through the post. This Process has lot of paper wastage. So instead of this we can send a mail which saves lot of paper wastage .This process enables the Go green Initiative and reduces lot of manual effort. With the recent releases in SAP all the Business process are enhanced with Email sending functionality.

Introduction to Email Processes

Every Standard FI process like Dunning and Payment and collection advice has a default way of sending there notices to the customer or vendor by post. Sending a mail is not a standard SAP functionality; in order to achieve this nonstandard Functionality we have BTE.  This is an enhancement technique (Open FI) that was developed for Financial Accounting component. This functionality is primarily used in FI in the areas of dunning, Payment advice Customer and Vendor Statement etc. Each of them has their own Function modules which will not interfere with each other.

           Each of these has a BTE’s enabled to fill the FINNA-NACHA structure to determine whether the output should be sent as fax, print via post or email, i.e., if FINAA-NACHA = 1 - print via post and FINAA-NACHA = ‘I’ its email and if its ‘2’ FAX.

This Document contains how this mail functionality can be achieved by using the BTE’s for Different applications in FI.

1. Application Area: FI - Accounts payable and Accounts receivable – Dunning

     Application of the process BTE event '00001040' -

· This process BTE is useful during a dunning run when a dunning notice needs to be sent to the customer by the medium of an electronic form (EMAIL).
As a default property, the dunning notice gets printed and is sent to the customer either by scanning the copy or via 'POST'.

· This same dunning notice could be a very beneficial if it is sent by means of electronic form directly after the dunning has been carried out.

· So, to achieve this non-standard functionality we need to enhance the standard process.

      Transaction - FIBF -> Environment -> Info systems (Processes)

· Click on execute,

 

· Select the BTE 00001040 as it deals with the Output device/medium

Fig1.jpg

· Change the Already Present function module to Z function Module.

fig2.jpg

Now, technically the BTE is ready to work as we have registered the BTE.

As a functional aspect, the following things are needed to be taken care of.

· Standard communication option - to 'EMAIL' in the 'General' Tab in customer master 'XD02/01'.

fig3.jpg

· After configuring these basic steps, the BTE is complete to trigger for dunning run for this particular customer.

     Dunning Run

· SAPF150D2-This Program can be used to execute the Dunning form by giving the Run date and identification and the logic in the FM's can be checked by placing the debugger.

· Best way is to check in the debugger,

fig4.jpg

Ø  FINAA-NACHA - For Communication Medium (I- Internet, 1-Print Out, 2-Fax)

Ø  FINAA_INTAD – Email Address to send the PDF

 

Fig5.jpg

Ø Process the next step by confirming the 'Send to mail' dialog,

Ø If 'C_FINAA-INTAD' is left blank the system will pick from the customer master 'Clerks internet', else it will take from the value 'C_FINAA-INTAD'. This enables the PDF sending functionality which enables is standard process and the logic to send excel can be written in the above FM only. Also if you need to fill the Subject of Email use itcpo-tdtitle structure which of 50 characters. If we need to send the Body also Maintain the standard text as mentioned in the below screen shot.

fig6.jpg

NOTE: If we need to send many attachments other than PDF we have to write the code in the above FM call the common mail sending functionality. In this case first a mail will be sent with Excel or some other as attachment then the standard PDF functionality is called.

This is a very eco-friendly means of informing the customers for their over-due items.

 

 

2. Application Area: FI – Payment Advice and Collection Advice:

     Application of the process BTE event '00002040' –

This BTE is called in the standard include RFFORI06 as shown below.

fig7.png

· In the transaction FIBF Select the BTE 00002040 as it deals with the Output device/medium sample_process_00002040 will be assigned.

 

· Since this is not a standard functionality we need to enhance the FM so copy the

sample_process_00002040 into Zsample_process_00002040.

Logic in the FM

Check if customer or Vendor has Email Maintained in the Master Data. If it’s maintained then

· The structure c_finna included the internet address.

          We set the transmission medium to ‘I’ as below.

          c_finaa-nacha = 'I'.

          c_finaa-intad = l_smtp_addr(130). [The email Obtained from the master data]

·    Later the mail sending functionality can be called after the close_form as shown in the below screen shot or By OTF data and excel can be created using the tab_regup structure in the   form avis_schreiben.

3. Application Area: FI – Customer/Vendor Balance Confirmation:

     Application of the process BTE event '00002410' –

· This process BTE is useful during a Customer/Vendor Balance Confirmation form which needs to be sent to the Customer/Vendor by an electronic form (EMAIL). By default, the form is sent to the Customer/Vendor either by Fax or via 'POST'.

· But as an environmental aspect to avoid wastage of paper, the same Statement could be sent by means of electronic form directly after the Customer/Vendor Statement run has been carried out.

· So, to achieve this functionality we need to enhance the standard process.

     Transaction - FIBF -> Environment -> Info Systems (Processes)

· Click on Execute.

· Select BTE 00002410 as it deals with Determining the Output Device

fig8.png

· Click on Sample Function Module. The FM 'SAMPLE_PROCESS_00002410' is assigned. In order to include the mail sending functionality, Copy the Function Module into a Z Function Module and make the required changes to enable the mail sending functionality.

     Logic in the FM:

Check if the Customer or Vendor has Email Maintained in the Master Data. If it is maintained then

· The structure c_finna includes the internet address.

We set the transmission medium to ‘I’ as below.

          C_finaa-nacha = 'I'.

         C_finaa-intad = l_smtp_addr(130). [Email Obtained from the master data]

· Later the mail sending functionality can be called after the Close_form as shown in the below screen shot or By OTF data, and excel can be created using the Structure HBSIDH for Customer and HBSIKH for Vendor.

Fig9.png

4. How to achieve Mail Functionality Technically:

Create a Common Functionality for sending mail using classes

i) For sending the subject greater than 255 characters   

· At present using the FM SO_DOCUMENT_SEND_API1 has the capability of sending only 50 characters but using the below method of the class the subject more than 255 characters.

· So cl_bcs class is used for the below purpose.

· There is also any option of changing the sender ID in case the requirement is not    to use the           

· SAP master User ID using the cl_bcs  class.

· Create the below object of type cl_bcs  and call the method  set_message_subject        

          w_send_request     TYPE REF TO cl_bcs           VALUE IS INITIAL,      
     
CALL METHOD w_send_request->set_message_subject
       
EXPORTING
          ip_subject = subject.

ii) For Sending Multiple Attachments like PDF and Excel

· In case multiple attachments the below method add_attachment attachment can be used by looping on the attachments obtained to this function module.

     f_ATTACHMENTS    TYPE      RMPS_T_POST_CONTENT

      w_document       TYPE REF TO cl_document_bcs  VALUE IS INITIAL,

     
LOOP AT attachments INTO f_attachment.


        w_attachment_subject = f_attachment-subject.
        w_filesize = f_attachment-docsize.

· This Method will have the option to take input as method subject, filesize and
        w_document->add_attachment(
       
EXPORTING
        i_attachment_type    = f_attachment-doc_type
        i_attachment_subject = w_attachment_subject
        i_attachment_size    = w_filesize
        i_att_content_text   = f_attachment-cont_text[] ).

      ENDLOOP.

    iii) For Sending Email to multiple recipients like To, BCC and CC,

· The below Logic can applied to provide cc bcc and to as like multiple receivers. The method

add_recipient   has the option to give blind_copy, Copy and recipient.

w_recipient      TYPE REF TO if_recipient_bcs VALUE IS INITIAL,

· Loop at the multiple receivers

LOOP AT receivers INTO f_receivers.

          w_recipient_mail = f_receivers-receiver .

· The below method sets them mail ID of the Receiver.
          w_recipient = cl_
cam_address_bcs=>create_internet_address(
                         w_recipient_mail).

        w_send_request->add_recipient(
           
EXPORTING
            i_recipient = w_recipient
            i_express =
'X'
            i_copy = f_receivers-copy
            i_blind_copy = f_receivers-blind_copy).
ENDLOOP.


Upload Files to SharePoint folders From SAP

$
0
0

Hi Friends,

 

Now-a-days we hear a lot about integrating SAP with Share Point.

I have recently work on such a requirement, where in I need to Upload files to SharePoint folders from SAP. So wanted to share my experience.

 

There are two different scenarios:

 

1) SharePoint and SAP are hosted on same server.

 

2) SharePoint and SAP are hosted on different server.

 

 

1) SharePoint and SAP are hosted on same server.

 

In this scenario,

 

Files can be directly uploaded Via GUI_UPLOAD or any equivalent FM or Classes.

 

STEPS:

  • Create new document library in your share point site.
  • GOTO--> Library and click on "Open with explorer" icon as shown below

folder.JPG

  • Then the server location opens as below

path.JPG

  • Pass the path to GUI_UPLOAD to upload to the folder.

 

 

2) SharePoint and SAP are hosted on different server.

 

In this case, we make use of a facility provided by Share Point known as "Communication Through Incoming email setings" to upload files onto it's folders.

 

STEPS:

 

                                                     

  • Create new document library in your share point site.

 

  • Once library created. Go to "Document library settings". -> Communication -> Incoming email settings

 

email.JPG

 

  • Enable the settings

 

              "Incoming email"=Yes

 

              Email address = "Define unique email ID"

 

              E-Mail Attachments=Save all attachments in root folder

 

address.JPG

 

  • Use email ID, in your ABAP program to send document in email.

 

 

 

Once you send mail to specific email ID as maintained in share point site, you will see document getting placed automatically in share point whatever you send it through email (as attachment ).

ABAP Connectivity to Integrate Any Bex Query to SAP Dashboards using Web Service on top of Function Module Concept

$
0
0

Follow the below steps to expose any Bex Query to Xcelsius which will enable to create Dashboard for your SAP Bex Query. The Connectivity used here is Web Services on top of ABAP Function Module.

 

For example consider a End to End Scenario, where i need to create a dashboard to display the status of SAP BW Process chains.

Above scenario can be achieved by Creating a data source on top of Standard tables namely,

  1. RSREQDONE
  2. RSICCONT

which provide data about the Process chains.

 

Create View “ZCUBE_DETAILS” on top of table above mentioned tables,

1.png

Create data source in Tcode RSO2 on top of the View.

2.png

Check whether data is pulled in RSA3

3.png


Replicate the Data source in BW,

4.png

Create cube ZCB_LOAD which will contain the standard Info objects which corresponds to the fields in the created Data source

5.png

Create Transformation between Data source and Cube and map them.

6.png

Create Query on Top of Cube which will display the necessary monitoring parameters like Start time, End time, Records Fetched, Status and Data of run of a process chain etc.

7.png

Create a “RFC Enabled” Function module in SE37 which will output data of the above created query as shown below,

8.png  9.png

FM Contains the attached code which will convert a Bex query as a FM output

Input parameter: Query name

Output Parameter: Query output captured in a table.


FUNCTION ZPRGM_QRY_XML .
TYPE-POOLS: rrx1 .
DATA: r_dataset TYPEREFTO cl_rsr_data_set.
DATA: lcount TYPEi .
DATA: xcount TYPEi .

DATA: i_var TYPE rrx1_t_var.
DATA: i_var_final TYPE rrx1_t_var.
DATA: wf_variant TYPE variant .
DATA: wa_axis LIKELINEOF r_dataset->n_sx_version_20a_1-axis_data .
DATA: wa_axis_info LIKELINEOF r_dataset->n_sx_version_20a_1-axis_info .
DATA: wa_chars LIKELINEOF wa_axis_info-chars .
DATA: tmp_char TYPE rrws_thx_axis_chars.
DATA: wa_tmp_char TYPE rrws_sx_axis_chars .
DATA: wa_attrinm TYPE rrws_s_attrinm.

DATA: wa_cell LIKELINEOF r_dataset->n_sx_version_20a_1-cell_data .
DATA: wa_textsymbols LIKELINEOF r_dataset->n_sx_version_20a_1-txt_symbols .
DATA: wa_textsymbols1 LIKELINEOF r_dataset->n_sx_version_20a_1-txt_symbols .
DATA: wa_set LIKELINEOF wa_axis-set.
DATA: tmp_set TYPE rrws_tx_set.
DATA: wa_tmp_set TYPE rrws_sx_tuple .
DATA: wa_dattrinm TYPE rrws_s_attributes .
DATA: i_iset_iobjnm TYPE  rsd_iobjnm ,
e_iobjnm TYPE  rsd_iobjnm .
DATA: error_message TYPE string ,
xml_out TYPE string .
DATA: q_variables TYPE rrxw3tquery .

DATA: error_string TYPE string.
DATA: no_of_chars TYPE  i ,
no_of_keyf TYPEi .
DATA: var_nam(10) .
DATA: iobj_detail TYPE bapi6108 .
DATA: iobj_details TYPE bapi6108_t .
DATA: it_fieldcat TYPE lvc_t_fcat,
is_fieldcat LIKELINEOF it_fieldcat.

DATA: returnTYPE bapiret2_tab .
FIELD-SYMBOLS: <ltable> TYPEANYTABLE,
<l_line>  TYPEANY,
<l_field> TYPEANY,
<field>   TYPEANY.
TYPES: BEGINOF metatype ,
fieldname(30),
outputlen(6) TYPE n,
datatype(4) ,
scrtext_l(40),
ENDOF metatype .
DATA: meta_data TYPESTANDARDTABLEOF metatype ,
wa_meta_data TYPE metatype .

DATA: off  TYPEi,
moff TYPEi,
mlen TYPEi.
DATA: iobj_return TYPE bapiret2_tab .,
DATA:      wf_view TYPE rszviewid .

DATA: i_axis_info TYPE  rrws_thx_axis_info ,
i_cell_data TYPE  rrws_t_cell ,
i_axis_data TYPE  rrws_thx_axis_data ,
i_txt_symbols TYPE  rrws_t_text_symbols .

DATA: n_counter(3) TYPE n .
DATA: char_count TYPEi .
DATA: wf_fldnm(40) .

DATA: struct_type TYPEREFTO cl_abap_structdescr,
tab_type TYPEREFTO cl_abap_tabledescr ,
comp_tab TYPE cl_abap_structdescr=>component_table,
comp LIKELINEOF comp_tab,
dref TYPEREFTOdata ,
dref1 TYPEREFTOdata ,
op_len TYPEi .
DATA: fieldsTYPE tihttpnvp .
DATA: wa_fields TYPE ihttpnvp ,
wa_var TYPE w3query ,
wa_out TYPE zxml_out ,
w_col TYPEi.

CLEAR :fields, q_variables ,i_axis_info,i_cell_data,i_axis_data,i_txt_symbols.
REFRESH: fields, q_variables,i_axis_info,i_cell_data,i_axis_data,i_txt_symbols .

IF wf_query ISNOTINITIAL.
CLEAR : xml_out , return .
REFRESHreturn .

CALLFUNCTION'RRW3_GET_QUERY_VIEW_DATA'
EXPORTING
i_infoprovider          = wf_ip
i_query                 = wf_query
i_view_id               = wf_view
i_t_parameter           = q_variables
IMPORTING
e_axis_info             = i_axis_info
e_cell_data             = i_cell_data
e_axis_data             = i_axis_data
e_txt_symbols           = i_txt_symbols
EXCEPTIONS
no_applicable_data      = 1
invalid_variable_values = 2
no_authority            = 3
abort                   = 4
invalid_input           = 5
invalid_view            = 6
OTHERS                  = 7.

CASE sy-subrc .

WHEN0 .
** find no. of key figures
CLEAR: lcount ,wa_axis , wa_axis_info .
READTABLE i_axis_data  INTO wa_axis WITHKEY axis = '000'  .
IF sy-subrc EQ0 .
CLEAR no_of_keyf .
LOOPAT wa_axis-setINTO wa_set .
ATNEW tuple_ordinal .

no_of_keyf = no_of_keyf + 1 .
ENDAT .
ENDLOOP .
CLEAR wa_set .
ENDIF .

** find number of characteristics
READTABLE i_axis_info  INTO wa_axis_info WITHKEY axis = '001'  .
IF sy-subrc EQ0 .
CLEAR no_of_chars .
DESCRIBETABLE wa_axis_info-chars LINES no_of_chars .
ENDIF .

CLEAR : iobj_detail , iobj_details .
REFRESH iobj_details .
CLEAR wa_axis_info .
* get chars. details
READTABLE i_axis_info  INTO wa_axis_info WITHKEY axis = '001'  .
IF sy-subrc EQ0 .
CLEAR wa_chars .
REFRESH tmp_char .

LOOPAT wa_axis_info-chars INTO wa_chars .
CLEAR wa_tmp_char .
MOVE-CORRESPONDING wa_chars TO wa_tmp_char .
INSERT wa_tmp_char INTOTABLE tmp_char.
IFNOT wa_chars-attrinm[] ISINITIAL .
LOOPAT wa_chars-attrinm INTO wa_attrinm .
CLEAR :wa_tmp_char-chanm , wa_tmp_char-caption .
MOVE: wa_attrinm-attrinm TO wa_tmp_char-chanm ,
wa_attrinm-caption TO wa_tmp_char-caption .
INSERT wa_tmp_char INTOTABLE tmp_char.
ENDLOOP .
ENDIF .
ENDLOOP .


LOOPAT tmp_char INTO wa_chars .
CLEAR off .
CLEAR :off, moff, mlen .
FIND'___'INSECTION OFFSET off OF
wa_chars-chanm .
IF sy-subrc EQ0 .
CLEAR : i_iset_iobjnm , e_iobjnm .
MOVE: wa_chars-chanm TO i_iset_iobjnm .
CALLFUNCTION'RSD_IOBJNM_GET_FROM_INFOSET'
EXPORTING
i_iset_iobjnm = i_iset_iobjnm
IMPORTING
e_iobjnm      = e_iobjnm
EXCEPTIONS
name_error    = 1
no_field      = 2
OTHERS        = 3.

CLEAR wa_chars-chanm  .
MOVE: e_iobjnm TO wa_chars-chanm .

ELSE.

FIND'__'INSECTION OFFSET off OF
wa_chars-chanm
MATCH OFFSET moff
MATCH LENGTH mlen.
IF sy-subrc EQ0 .
off = moff + mlen .
SHIFT wa_chars-chanm LEFTBY off PLACES .
ENDIF .
ENDIF . " two __ or three _
CLEAR: iobj_return .
REFRESH : iobj_return .

CALLFUNCTION'BAPI_IOBJ_GETDETAIL'
EXPORTING
version    = rs_c_objvers-active
infoobject = wa_chars-chanm
IMPORTING
details    = iobj_detail.


IF  NOT iobj_detail ISINITIAL .
APPEND iobj_detail TO iobj_details .
CLEAR iobj_detail .
ELSE .

MOVE: wa_chars-chanm TO iobj_detail-infoobject ,
wa_chars-caption TO iobj_detail-textlong .

APPEND iobj_detail TO iobj_details .
CLEAR iobj_detail .

ENDIF .
CLEAR : iobj_detail .
ENDLOOP .
ENDIF .

* build field cat. for building the itab
CLEAR: is_fieldcat, iobj_detail, it_fieldcat .
REFRESH : it_fieldcat .
LOOPAT iobj_details INTO iobj_detail .
is_fieldcat-fieldname = iobj_detail-infoobject .
IF is_fieldcat-fieldname+0(1) EQ'0' .
SHIFT is_fieldcat-fieldname LEFTBY1PLACES .
ENDIF .
*        IF iobj_details-datatp = 'CHAR' .
*          is_fieldcat-datatype = iobj_details-datatp.
is_fieldcat-outputlen = '130' .
*        ELSE .
is_fieldcat-datatype = 'CHAR' . "iobj_details-datatp.
*          is_fieldcat-outputlen = iobj_details-outputlen .
*        ENDIF .

is_fieldcat-scrtext_l = iobj_detail-textlong.
APPEND is_fieldcat TO it_fieldcat.
CLEAR : is_fieldcat , iobj_detail .
ENDLOOP .


CLEAR :n_counter, wa_axis .
READTABLE i_axis_data  INTO wa_axis WITHKEY axis = '000'  .
IF sy-subrc EQ0 .
LOOPAT wa_axis-setINTO wa_set .
ATNEW tuple_ordinal .

n_counter = n_counter + 1 .

CONCATENATE'VALUE' n_counter INTO is_fieldcat-fieldname .
is_fieldcat-outputlen = '30'.
is_fieldcat-datatype = 'CHAR'.
ENDAT .
CONCATENATE is_fieldcat-scrtext_l wa_set-caption INTO is_fieldcat-scrtext_l SEPARATEDBY  ` ` .

*        is_fieldcat-scrtext_l = wa_set-caption.
ATENDOF tuple_ordinal .
SHIFT is_fieldcat-scrtext_l LEFT DELETING LEADING' ' .
APPEND is_fieldcat TO it_fieldcat.
CLEAR : is_fieldcat .
ENDAT .

ENDLOOP .
ENDIF .

CLEAR: meta_data, wa_meta_data .
REFRESH meta_data .
LOOPAT it_fieldcat INTO is_fieldcat .

MOVE-CORRESPONDING is_fieldcat TO wa_meta_data .
APPEND wa_meta_data TO meta_data .
CLEAR: wa_meta_data, is_fieldcat .
ENDLOOP .

* create itab
SORT it_fieldcat BY fieldname.
DELETEADJACENTDUPLICATESFROM it_fieldcat COMPARING fieldname .
CLEAR: comp , comp_tab ,is_fieldcat .
REFRESH comp_tab .

LOOPAT it_fieldcat INTO is_fieldcat .
CLEAR op_len .
op_len = is_fieldcat-outputlen .
comp-name = is_fieldcat-fieldname.
comp-type = cl_abap_elemdescr=>get_c( op_len ).
APPEND comp TO comp_tab.
CLEAR : is_fieldcat , comp .
ENDLOOP .

CLEAR struct_type .

CALLMETHOD cl_abap_structdescr=>create
EXPORTING
p_components = comp_tab
p_strict     = cl_abap_structdescr=>false
RECEIVING
p_result     = struct_type.

CLEAR tab_type .
CALLMETHOD cl_abap_tabledescr=>create
EXPORTING
p_line_type  = struct_type
p_table_kind = cl_abap_tabledescr=>tablekind_std
RECEIVING
p_result     = tab_type.

CREATEDATA dref1 TYPE HANDLE tab_type.

ASSIGN dref1->* TO<ltable>.

CREATEDATA dref TYPE HANDLE struct_type.

ASSIGN dref->* TO<l_line>.

CLEAR :wa_axis , char_count , lcount, xcount.
REFRESH tmp_set .
LOOPAT i_axis_data INTO wa_axis WHERE axis = '001' .
LOOPAT wa_axis-setINTO wa_set .
CLEAR wa_tmp_set .
MOVE-CORRESPONDING wa_set TO wa_tmp_set .
INSERT wa_tmp_set INTOTABLE tmp_set.
IFNOT wa_set-attributes[] ISINITIAL .
LOOPAT wa_set-attributes INTO wa_dattrinm .
CLEAR: wa_tmp_set-chanm , wa_tmp_set-chavl , wa_tmp_set-chavl_ext , wa_tmp_set-caption .
MOVE: wa_dattrinm-attrinm TO wa_tmp_set-chanm ,
wa_dattrinm-attrivl TO wa_tmp_set-chavl ,
wa_dattrinm-attrivl TO wa_tmp_set-chavl_ext ,
wa_dattrinm-caption TO wa_tmp_set-caption .

INSERT wa_tmp_set INTOTABLE tmp_set.
ENDLOOP .
ENDIF .
ENDLOOP .
ENDLOOP .

LOOPAT tmp_set INTO wa_set .
ATNEW tuple_ordinal .
IF lcount GT0 .
lcount = lcount - 1 .
ENDIF .
CLEAR<l_line> .
ENDAT .
CLEAR off .

CLEAR :off, moff, mlen .
FIND'___'INSECTION OFFSET off OF
wa_set-chanm .
IF sy-subrc EQ0 .
CLEAR : i_iset_iobjnm , e_iobjnm .
MOVE: wa_set-chanm TO i_iset_iobjnm .
CALLFUNCTION'RSD_IOBJNM_GET_FROM_INFOSET'
EXPORTING
i_iset_iobjnm = i_iset_iobjnm
IMPORTING
e_iobjnm      = e_iobjnm
EXCEPTIONS
name_error    = 1
no_field      = 2
OTHERS        = 3.

CLEAR wa_set-chanm  .
MOVE: e_iobjnm TO wa_set-chanm .
ELSE.

FIND'__'INSECTION OFFSET off OF
wa_set-chanm
MATCH OFFSET moff
MATCH LENGTH mlen.
IF sy-subrc EQ0 .
off = moff + mlen .
SHIFT wa_set-chanm LEFTBY off PLACES .
ENDIF .
ENDIF . " check three _ or two _

IF wa_set-chanm+0(1) EQ'0' .
SHIFT wa_set-chanm LEFTBY1PLACES .
ENDIF .
ASSIGNCOMPONENT wa_set-chanm OFSTRUCTURE<l_line> TO<l_field>.
IF wa_set-chavl = '#' .
ELSE .
CONCATENATE wa_set-chavl_ext wa_set-caption INTO<l_field> SEPARATEDBY' ' .
ENDIF .

ATENDOF tuple_ordinal .
CLEAR: xcount , char_count , n_counter .

lcount = lcount + 1 .

LOOPAT i_cell_data INTO wa_cell FROM lcount .

n_counter = n_counter + 1 .
IF n_counter GT no_of_keyf .
EXIT .
ENDIF .
CONCATENATE'VALUE' n_counter INTO wf_fldnm .
ASSIGNCOMPONENT wf_fldnm OFSTRUCTURE<l_line> TO<l_field>.

<l_field> = wa_cell-value .

ENDLOOP .

lcount = lcount + no_of_keyf .
w_col = 1.
DO9TIMES.
ASSIGNCOMPONENT w_col OFSTRUCTURE<l_line> TO<field>.
IF w_col = 1.
wa_out-date = <field>.
ELSEIF w_col = 2.
wa_out-req = <field>.
ELSEIF W_COL = 3.
wa_out-P_ID = <field>.
ELSEIF W_COL = 4.
wa_out-T_OBJ = <field>.
ELSEIF W_COL = 5.
wa_out-U_NAM = <field>.
ELSEIF W_COL = 6.
wa_out-S_TIME = <field>.
ELSEIF W_COL = 7.
wa_out-E_TIME = <field>.
ELSEIF W_COL = 8.
wa_out-N_REC = <field>.
ELSEIF W_COL = 9.
wa_out-STAT = <field>.
ENDIF.
w_col = w_col + 1.
ENDDO.
APPEND wa_out TO out.
CLEAR wa_out.
ENDAT .
ENDLOOP .
ENDCASE .
ENDIF .
ENDFUNCTION.


Create Web Service on top of the Function Module

10.png

Complete the below navigation steps which will create a Web service

11.png

15.png

Goto Tcode SOAMANAGER to configure the Web Service: give the name of web service created in BW and Click on “Create Service”

16.png


Provide the Service name and Binding Name as shown,

17.png

Select the appropriate Authentication method as shown below

18.png

Click on “Open porttype WSDL document”,

19.png

New page will open, copy the link from the Address bar, which is the WSDL link

20.png


Open SAP Dashboard tool and create a Blank model. And under “Connection” Create a “Web Service Connection”

21..png


Provide the WSDL link in the WSDL URL as shown below and map the source and target fields in the Spread sheet. Hard code the Name of the query in the Xcelsius spread sheet.

22.png


Map the objects to a  Drop down box and apply the destination on to a Spread Table component and give a selection


23.png


Click on Preview, Process chain status details will be shown as below,

24.png


Now we have created a Dashboard which reads the Sap Bex query through a Web service connection which is created upon a ABAP Function Module!



Change Pointers in R/3

$
0
0

Introduction:

This document explains how to track the Material Master Data changes using change pointers in SAP R/3 environment.

Let us understand by taking following example -

The requirement is to track the Material Master changes in SAP R/3 environment and to send the information to some Legacy system (in form of AL11 Text file), if following fields changes –

    • If any new Material is created.
    • If Material is assigned with Dangerous indicator profile
    • UN Number
    • Dangerous Good Class
    • Dangerous Good Packing Group

 

Master data changes can be distributed with the SMD (Shared Master Data) tool. Changes to the Master Data are written in change documents interface, which in turn logs entries into change pointers.

 

The following step shows the change pointers settings and how to track the change logs for modified data.


Step 1 – Create Message Type (WE81)

 

   1.jpg

 

Step 2: Assign Table Fields to Message type (BD52)


Assign table fields to message type which needs to be considered for Change pointers generation.

  2.jpg


Step 3: Activate Change Pointers generally (BD61)


3.jpg

 

Step 4: Activate change pointers corresponding to fields in message type(BD50)

 

4.jpg


Also check if the data elements of all the required fields has ‘change Document’ field checked (Below screen shot for Material Number)

5.jpg

 

Step 5: Create a new Part Number and change following fields to test the generation of change logs in table CDHDR, CDPOS, BDCP and BDCPS.

  • Dangerous indicator profile (Transaction MM02)
  • UN Number (Transaction DGP3)
  • Dangerous Good Class (Transaction DGP3)
  • Dangerous Good Packing Group (Transaction DGP3)

Transaction - MM02

Transaction - DGP3

 

6.jpg

 

7.jpg

 

Step 6: Create a report which will perform following functions -

  • Read non processed change logs using Function Module CHANGE_POINTERS_READ by passing the Message type name

 

  8.jpg

 

  • Create a text file with all the required material information
  • Transfer that file on the application server (AL11)

 

And from application server the file is transferred to legacy system using some UNIX Script (this is out of scope of this BOK)

In addition to above FM (change_pointers_Read) you can also see the logs in following Table –

  • CDHDR (Change Document Header Table)
  • CDPOS (Change Document Items)
  • BDCP   (Change Pointer table
  • BDCPS (Change Pointer Status table)

 

 

IDOC Generation to send modified records –

In addition to above report you can also create a Function module and create an IDOC’s to send the modified data to legacy system-

Step1 – Create a Function module (e.g. ZTESTFM)

In this you can populate the IDOC segments and use the FM - MASTER IDOC_DISTRIBUTE to create and IDOC

Step2 – Assign Function module to Message Type (Transaction BD60)

  9.jpg

 

Step 7: For the master data that are processed set the change pointer status to ‘Processed’ by setting its value to 'X' by calling function module CHANGE_POINTER_STATUS_WRITE.

 

10.jpg

 

Delete change pointers

Transaction is BD22 or the standard program RBDCPCLR deletes the obsolete/processed change pointers.

 

11.jpg

NW RFC SDK Part 1: RFC Client Programs

$
0
0

Improve Communication Between Your C/C++ Applications and SAP Systems with SAP NetWeaver RFC SDK – Part 1: RFC Client Programs.

View this Document

NW RFC SDK Part 2: RFC Server Programs

$
0
0

Improve communication between your C/C++ applications and SAP systems with SAP NetWeaver RFC SDK – Part 2: RFC server programs.

View this Document

NW RFC SDK Part 3: Advanced Topics

$
0
0

Improve communication between your C/C++ applications and SAP systems with SAP NetWeaver RFC SDK – Part 3: Advanced topics.

View this Document

SAP-to-SAP Integration Using Custom IDOCs

$
0
0

SAP-to-SAP Integration Using Custom IDOCs

Summary

 

Using IDOCs data can be exchanged between SAP R/3 and Non R/3 systems. The objective of this document to show / configure data transmission from one SAP R/3 system to another SAP R/3 system via custom IDOC.

What is an IDOC?

IDOC is simply a data container used to exchange information between any two processes that can understand the syntax and semantics of the data.

In other words, an IDOC is like a data file with a specified format which is exchanged between 2 systems which know how to interpret that data.

IDOC stands for” Intermediate Document”

When we execute an outbound ALE or EDI Process, an IDOC is created.

In the SAP System, IDOCs are stored in database. Every IDOC has an unique number (within a client).

 

Key Features

  • IDOCs are independent of the sending and receiving systems.(SAP-to-SAP as well as Non-SAP)
  • IDOCs are based on EDI standards, ANSI ASC X12 and EDIFACT. In case of any conflict in data size, it adopts one with greater length.
  • IDOCs are independent of the direction of data exchange e.g. ORDERS01 : Purchasing module : Inbound and Outbound
  • IDOCs can be viewed in a text editor. Data is stored in character format instead of binary format.


 

 

The Idoc structure consists of 3 parts –

  1. The administration part (Control Record)- which has the type of idoc,message type, the current status, the sender, receiver etc. This is referred to as the Control record.
  2. The application data (Data Record) – Which contains the data. These are called the data records/segments.
  3. The Status information (Status Record)– These give you information about the various stages the idoc has passed through.

 

You can view an IDOC using transaction WE02 or WE05

 

 

 

Control Record

  • All control record data is stored in EDIDC table. The key to this table is the IDOC Number
  • It contains information like IDOC number, the direction (inbound/outbound), sender, recipient information, channel it is using, which port it is using etc.
  • Direction ‘1’ indicates outbound, ‘2’ indicates inbound.

 

Data Record

  • Data record contains application data like employee header info, weekly details, client details etc
  • All data record data is stored in EDID2 to EDID4 tables and EDIDD is a structure where you can see its components.
  • It contains data like the idoc number, name and number of the segment in the idoc, the hierarchy and the data
  • The actual data is stored as a string in a field called SDATA, which is a 1000 char long field.

 

Status Record

  • Status record are attached to an IDOC at every milestone or when it encounter errors.
  • All status record data is stored in EDIDS table.
  • Statuses 0-42 are for outbound while 50-75 for inbound

IDOC Types

An IDOC Type (Basic) defines the structure and format of the business document that is to be exchanged. An IDOC is an instance of an IDOC Type , just like the concept of variables and variables types in programming languages. You can define IDOC types using WE30.

 

What is a Segment?

Segment defines the format and structure of a data record in IDOC. Segments are reusable components.

For each segment SAP creates

  • Segment Type (version independent)
  • Segment Definition (version dependent)
  • Segment Documentation

The last 3 characters is the version of the segment

Definitions keep changing as per the version but the segment type remains the same.

Transaction :WE31

What is Extension IDOC type ?

An IDOC is of 2 types:-

  1. Basic

     2. Extension

 

SAP provides many a pre-defined Basic IDOC Types which can not be modified. In case you want to add more data to these restricted basic type  you may use an extension type. Most of the times you will NOT use extension.

Documentation

Each IDOC are thoroughly documented in transaction WE60

Message Type

A message represents a specific type of document that is transmitted between two partners Ex. Orders, orders responses, invoices etc

An idoc type can be associated with many message types

Also a message type can be associated with different idoc types. Transaction WE81

Partner Profiles

A partner is defined as a business partner with whom you conduct business and exchange documents

In the partner profile of a partner that we exchange Idocs with, we maintain the parameters that are necessary for exchanging the data. The transaction used is WE20.

Port

The port defines the technical characteristics of the connection between your SAP system and the other system you want to transfer data with (subsystem). The port defines the medium in which data is exchanged between the 2 systems.

There are different types of ports. The 2 most commonly used are the TRFC ports used in ALE  and File ports which EDI uses.

For TRFC ports we have to give the name of the logical destination created using SM59.

When using file port you can specify the directory where the IDOC file should be placed. The other system or the middleware will pick up the file from here. The Function module can be used to generate a file name for the idoc. While testing you can use “Outbound file” to specify a constant file name. The tab “outbound trigger” can be used to supply information if we want to trigger some processing on the subsystem when an idoc is created at this location. We have to specify the command file name and the directory which has to be run.

The transaction used in WE21.

IDOC inbound and Outbound processing

The Outbound Process

Steps Involved -

  1. Create segments(WE31)
  2. Create an idoc type(WE30)
  3. Create a message type (WE81)
  4. Associate a message type to idoc type(WE82)
  5. Create a port(WE21)
  6. If you are going to use the message control method to trigger idocs then create the function                 module for   creating the idoc and associate the function module to an outbound process code.
  7. Otherwise create the function module or stand alone program which will create the idoc
  8. Create a partner profile(WE20) with the necessary information in the outbound parameters for the partner you want to exchange the idoc with.Trigger the idoc.

 

The Inbound Process

Steps Involved-

  1. Creation of basic Idoc type (Transaction WE30)
  2. Creating message type (Transaction WE81)
  3. Associating the Message type to basic Idoc type (Transaction WE82)
  4. Create the function module for processing the idoc
  5. Define the function module characteristics (BD51)
  6. Allocate the inbound function module to the message type(WE57)
  7. Defining process code (Transaction WE42)
  8. Creation of partner profile (Transaction WE20)

 


 

Regards,
Sanjeev


Massive GOS attchment upload to FI docuemnt

$
0
0

Hello All,

This program upload FI scan file to FI document ,

note :scan file must pdf format , and pdf file must equal  FI number,

 

 

*&---------------------------------------------------------------------*
*& Report  ZGOS_ATTACHMENT
*&
*&---------------------------------------------------------------------*
*& Mass Upload gos file to FI document.
*&
*&---------------------------------------------------------------------*
REPORT  ZGOS_ATTACHMENT.
*report  zgos_attachment.
*Macros.
include <cntn01>.
swc_container lt_message_container.
*top dec.
type-pools: slis, abap, truxs.
data:      gt_filename type standard table of dxfilep with header line,      wa_filename type dxfilep,      gt_bin      type solix occurs 0,      wa_bin      type solix,      g_filename  type string,      l_obj       type swc_object,      gs_obja     type borident,      gs_objb     type borident,      gs_binrel   type gbinrel,      gt_binatt   type standard table of brelattr,      g_attsize   type wsrm_error-wsrm_direction,      objkey TYPE BORIDENT-OBJKEY.
DATA : BEGIN OF bin_tab OCCURS 0,       tx TYPE c  LENGTH 255,      END OF bin_tab.
selection-screen begin of block b0 with frame title text-001.
parameters: p_file  type rlgrap-filename OBLIGATORY,            gjahr TYPE gjahr OBLIGATORY,            bukrs TYPE bukrs DEFAULT '1000'.
selection-screen end of block b0.
DATA: lt_file_table TYPE TABLE OF sdokpath,      wa_file_table LIKE LINE OF lt_file_table,      lt_dir_table  TYPE TABLE OF sdokpath,      lv_belnr TYPE bkpf-belnr,      lv_char TYPE n LENGTH 10,      ls_bkpf TYPE bkpf.
DATA : FILEPATH TYPE  STRING,      FILENAME  TYPE  STRING,      doc_t TYPE string.
DATA: ls_file_table TYPE sdokpath,      ls_output     TYPE sdokpath,      lt_output     TYPE TABLE OF sdokpath.
DATA: lv_dir          TYPE cffile-filename, lv_flag(3)      TYPE n,      lv_app_path(80) TYPE c,               lv_file_count   TYPE i,      lv_cnt(3)       TYPE n,               lv_text(200)    TYPE c,      lv_filename     TYPE string.
DATA : BEGIN OF bel_t OCCURS 0,    belnr TYPE belnr,  END OF bel_t.
DATA : lv_text_path(50).
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN  on <parameters>                                 *
*----------------------------------------------------------------------*
at selection-screen on p_file.  if p_file is initial.    message e999(yfimc01) with 'Please select the file path'. "#EC NOTEXT  endif.
*----------------------------------------------------------------------*
* AT SELECTION-SCREEN  on HELP-REQUEST|VALUE-REQUEST                   *
*----------------------------------------------------------------------*
at selection-screen  on value-request for p_file.
*  call function 'F4_FILENAME'
*    exporting
*      program_name  = syst-cprog
*      dynpro_number = syst-dynnr
*      field_name    = 'P_FILE'
*    importing
*      file_name     = p_file.  PERFORM value_request_pc_file_download USING p_file.
start-of-selection.  CALL FUNCTION 'TMP_GUI_DIRECTORY_LIST_FILES'    EXPORTING      directory  = p_file      filter     = '*.PDF'    IMPORTING      file_count = lv_file_count    TABLES      file_table = lt_file_table      dir_table  = lt_dir_table    EXCEPTIONS      cntl_error = 1      OTHERS     = 2.  CLEAR wa_file_table.  LOOP AT lt_file_table INTO wa_file_table.    CLEAR : ls_bkpf.    lv_text_path = wa_file_table-PATHNAME.    REPLACE ALL OCCURRENCES OF '.PDF' IN lv_text_path WITH ''.    REPLACE ALL OCCURRENCES OF '.pdf' IN lv_text_path WITH ''.    CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'      EXPORTING        INPUT         = lv_text_path     IMPORTING       OUTPUT        = lv_belnr              .
*    WRITE lv_text_path to lv_char .
*    move lv_char to lv_belnr.    SELECT SINGLE * FROM bkpf INTO ls_bkpf WHERE belnr = lv_belnr AND                                    bukrs = bukrs  AND                                    GJAHR = GJAHR.    IF sy-subrc = 0.      CLEAR : g_filename , g_attsize , gt_bin.      CONCATENATE p_file wa_file_table-PATHNAME INTO g_filename.      concatenate    bukrs  "company code                       lv_belnr "FI Document                       gjahr  "fiscal year                       into                       objkey.
****************************************************************************8     MOVE p_file TO FILEPATH.     MOVE wa_file_table-PATHNAME TO FILENAME.     MOVE lv_belnr to doc_t.     CALL FUNCTION 'ZHR_GOS_UPLOAD'      EXPORTING        OBJTYPE        = 'BKPF'        OBJKEY         = OBJKEY        FILEPATH       = FILEPATH        FILENAME       = FILENAME        DOCTITLE       = doc_t        DOCTYPE        = 'PDF'      TABLES        BIN_TAB        = bin_tab      EXCEPTIONS        UNKNOWN_ERROR  = 1        NO_FILE_OR_BIN = 2        NO_DOC_TYPE    = 3        OTHERS         = 4.
*******************************************************************************
*      call function 'GUI_UPLOAD'
*        exporting
*          filename                = g_filename
*          filetype                = 'BIN'
*        importing
*          filelength              = g_attsize
*        tables
*          data_tab                = gt_bin
*        exceptions
*          file_open_error         = 1
*          file_read_error         = 2
*          no_batch                = 3
*          gui_refuse_filetransfer = 4
*          invalid_type            = 5
*          no_authority            = 6
*          unknown_error           = 7
*          bad_data_format         = 8
*          header_not_allowed      = 9
*          separator_not_allowed   = 10
*          header_too_long         = 11
*          unknown_dp_error        = 12
*          access_denied           = 13
*          dp_out_of_memory        = 14
*          disk_full               = 15
*          dp_timeout              = 16
*          others                  = 17.
*
*      if sy-subrc <> 0.
*      else.
**    file Uploaded successfully.
**    convert uploaded file contents into BIN format.
*        data: l_seq type i.
*        swc_container      l_cont.
*        swc_create_object  l_obj  'MESSAGE'       ''.
*        swc_set_element    l_cont 'NO_DIALOG'     'X'.
*        swc_set_element    l_cont 'DOCUMENTTITLE' g_filename.
*        swc_set_table      l_cont 'Content_Hex'   gt_bin.
*        swc_set_element    l_cont 'DOCUMENTTYPE'  'TXT'.
*        swc_set_element    l_cont 'DOCUMENTSIZE'  g_attsize.
*        swc_refresh_object l_obj.
*        swc_call_method    l_obj  'CREATE'        l_cont.
*        swc_get_object_key l_obj  gs_objb-objkey.
*        gs_objb-objtype = 'MESSAGE'.   "type of attach document
*        gs_obja-objtype = 'BKPF'.      "BO of SAP Document.
*        concatenate    bukrs  "company code
*                       lv_belnr "FI Document
*                       gjahr  "fiscal year
*                       into
*                       gs_obja-objkey.
*        call function 'BINARY_RELATION_CREATE_COMMIT'
*          exporting
*            obj_rolea      = gs_obja
*            obj_roleb      = gs_objb
*            relationtype   = 'ATTA'
*          importing
*            binrel         = gs_binrel
*          tables
*            binrel_attrib  = gt_binatt
*          exceptions
*            no_model       = 1
*            internal_error = 2
*            unknown        = 3
*            others         = 4.
*        if sy-subrc eq 0.
*          message s043(sgos_msg).
*        endif.
*      endif.    ENDIF.  ENDLOOP.
*&---------------------------------------------------------------------*
*&      Form  VALUE_REQUEST_PC_FILE_DOWNLOAD
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_P_FILE  text
*----------------------------------------------------------------------*
FORM VALUE_REQUEST_PC_FILE_DOWNLOAD  USING   field.  CALL FUNCTION '/SAPDMC/LSM_F4_FRONTEND_FILE'    CHANGING      pathfile         = p_file    EXCEPTIONS      canceled_by_user = 1      system_error     = 2      OTHERS           = 3.  CLEAR lv_dir.
* Below functionality used to delete the file name form the selected path.  DO.    SEARCH p_file FOR '\'.    IF sy-subrc EQ 0.      lv_flag = strlen( p_file ).      sy-fdpos = sy-fdpos + 1.      CONCATENATE  lv_dir p_file+0(sy-fdpos)  INTO lv_dir.      p_file+0(sy-fdpos) = ''.      CONDENSE p_file.    ELSE.      EXIT.    ENDIF.  ENDDO.  CLEAR p_file.  p_file = lv_dir.  CONCATENATE 'Directory selected: --> ' p_file INTO ls_output SEPARATED BY space.  APPEND ls_output TO lt_output.  CLEAR ls_output.
ENDFORM. " value_request_pc_file_download




FUNCTION ZHR_GOS_UPLOAD.


FUNCTION ZHR_GOS_UPLOAD.
 *"----------------------------------------------------------------------
 *"*"Local Interface:
 *"  IMPORTING
 *"     REFERENCE(OBJTYPE) TYPE  BORIDENT-OBJTYPE
 *"     REFERENCE(OBJKEY) TYPE  BORIDENT-OBJKEY
 *"     REFERENCE(FILEPATH) TYPE  STRING OPTIONAL
 *"     REFERENCE(FILENAME) TYPE  STRING OPTIONAL
 *"     REFERENCE(DOCTITLE) TYPE  STRING OPTIONAL
 *"     REFERENCE(DOCTYPE) TYPE  SOFM-DOCTP OPTIONAL
 *"  TABLES
 *"      BIN_TAB
 *"  EXCEPTIONS
 *"      UNKNOWN_ERROR
 *"      NO_FILE_OR_BIN
 *"      NO_DOC_TYPE
 *"----------------------------------------------------------------------  include : <cntn01>.   constants:             c_docnm  type borident-objtype value 'MESSAGE',             c_reltyp type breltyp-reltype  value 'ATTA'.   types: begin of ty_message_key,           foltp type so_fol_tp,           folyr type so_fol_yr,           folno type so_fol_no,           doctp type so_doc_tp,           docyr type so_doc_yr,           docno type so_doc_no,           fortp type so_for_tp,           foryr type so_for_yr,           forno type so_for_no,          end of ty_message_key.   data : xobject_b type borident.   data : xobject_a type borident.   data : xdoc_size    type i.   data : xfile_lines   type i.   data : xmessage_key type ty_message_key.   data : xmessage     type swc_object.   data : idoc_content type standard table of soli-line.   data : xdoc_content type soli-line.   data : xfilenamepath type string.   data : xdoctitle type string.   data : xdoctype type sofm-doctp.   data : xfname type string.   if bin_tab[] is initial     and ( filename is initial       or  filepath is initial ).     raise no_file_or_bin.   endif.   if not bin_tab[] is initial      and doctype is initial.     raise no_doc_type.   endif.   if not bin_tab[] is initial.     xdoctype = doctype.     translate xdoctype to upper case.   else.     split filename at '.' into xfname xdoctype.     translate xdoctype to upper case.   endif.
 *  * Create an initial instance of BO 'MESSAGE' - to call the
 * instance-independent method 'Create'.   swc_create_object xmessage 'MESSAGE' xmessage_key.
 * define container to pass the parameter values to the method call
 * in next step.   swc_container imessage_container.
 * Populate container with parameters for method   if doctitle is initial.     xdoctitle = filename.   else.     xdoctitle = doctitle.   endif.   swc_set_element imessage_container 'DOCUMENTTITLE'  xdoctitle.   swc_set_element imessage_container 'DOCUMENTLANGU' 'E'.   swc_set_element imessage_container 'NO_DIALOG'     'X'.   swc_set_element imessage_container 'DOCUMENTNAME'   c_docnm.   swc_set_element imessage_container 'DOCUMENTTYPE'   xdoctype.   if not bin_tab[] is initial.
 * Translate table to 255, if not 255.     data: tab_len type i.     read table bin_tab index 1.     tab_len = strlen( bin_tab ).     if tab_len < 255.       data: xbuffer type string.       loop at bin_tab.         translate bin_tab using ' ~'.         concatenate xbuffer bin_tab into xbuffer.       endloop.       translate xbuffer using '~ '.       do.         xdoc_content = xbuffer.         append xdoc_content to idoc_content.         shift xbuffer left by 255 places.         if xbuffer is initial.           exit.         endif.       enddo.     else.       idoc_content[] =  bin_tab[].     endif.   else.     concatenate filepath filename into xfilenamepath.
 * Upload file from frontend     call function 'GUI_UPLOAD'          exporting               filename = xfilenamepath               filetype = 'BIN'
 *              HEADER_LENGTH =         IMPORTING           FILELENGTH = xdoc_size          tables               data_tab = idoc_content          exceptions               others   = 17.   endif.
 *  * 'DocumentContent' is a multi-line element ( itab ).   swc_set_table imessage_container 'DocumentContent' idoc_content.
 * Size is required in case of File attachments   describe table idoc_content lines xfile_lines.   read table idoc_content into xdoc_content index xfile_lines.
 *  xdoc_size = ( 255 * ( xfile_lines - 1 ) ) +
 *              strlen( xdoc_content  ).   swc_set_element imessage_container 'DOCUMENTSIZE'   xdoc_size .
 * Refresh to get the reference of create 'MESSAGE' object for attachment   swc_refresh_object xmessage.   swc_call_method xmessage 'CREATE' imessage_container.
 * Get Key of new object   swc_get_object_key xmessage xmessage_key.
 * Now we have attachment as a business object instance. We can now
 * attach it to our main business object instance.
 * Create main BO object_a   xobject_a-objkey = objkey.   xobject_a-objtype = objtype.
 * Create attachment BO object_b   xobject_b-objkey = xmessage_key.   xobject_b-objtype = c_docnm.   call function 'BINARY_RELATION_CREATE'        exporting             obj_rolea    = xobject_a             obj_roleb    = xobject_b             relationtype = c_reltyp        exceptions             others       = 1.   if sy-subrc = 1.     raise unknown_error.   endif.   commit work.
 ENDFUNCTION.

How to use RFC-SDK with FreeBASIC - Part 3: Server Apps (SAP uses FreeBASIC)

$
0
0

Hello community,

 

in the 3rd part now an example of an SAP server application. That means that you can use FreeBASIC functions from SAP via ABAP Call Function command.


'-Begin-----------------------------------------------------------------
'
' To know the gateway service (gwserv) and host (gwhost) use TAC SMGW
' and the menu Goto > Parameters > Display and look at the attribute
' entries gateway hostname and gateway service.
'
' Insert in the file Windows\system32\drivers\etc\services the entry
' sapgw00 with 3300/tcp for sapgw00, or e.g. for sapgw99 3399/tcp.
'
' Customize with TAC SM59 the RFC destination PBTESTPROGRAM
'
'-----------------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "sapnwrfc.inc"

 

  '-Function ABAPCall---------------------------------------------------
    Function ABAPCall(ByVal rfcHandle As Integer, _
      ByVal funcHandle As Integer, errorInfo As RFC_ERROR_INFO) _
      As Integer

      MessageBox(null, "ABAP call", "", MB_OK Or MB_ICONINFORMATION)

      Return RFC_OK
    End Function

 

  '-Variables-----------------------------------------------------------
    Dim RfcErrorInfo As RFC_ERROR_INFO
    Dim connParams(3) AS RFC_CONNECTION_PARAMETER
    Dim As Integer hDesc, hConn, rc
    Dim As WString * 16 nProgramID, nGWHost, nGWServ
    Dim As WString * 16 vProgramID, vGWHost, vGWServ

 

  '-Main----------------------------------------------------------------
    nProgramID = "PROGRAM_ID" : vProgramID = "FBTESTPROGRAM"
    nGWHost    = "GWHOST"     : vGWHost    = "ABAP"
    nGWServ    = "GWSERV"     : vGWServ    = "sapgw00"

 

    connParams(0).name = @nProgramID : connParams(0).value = @vProgramID
    connParams(1).name = @nGWHost    : connParams(1).value = @vGWHost
    connParams(2).name = @nGWServ    : connParams(2).value = @vGWServ

 

    hDesc = RfcCreateFunctionDesc("ABAPCall", RfcErrorInfo)
    RfcErrorHandler()

    If hDesc <> 0 And RfcErrorInfo.code = RFC_OK Then

      RfcInstallServerFunction "", hDesc, @ABAPCall, RfcErrorInfo
      RfcErrorHandler()

      If RfcErrorInfo.code = RFC_OK Then

        hConn = RfcRegisterServer(@connParams(0), 3, RfcErrorInfo)
        RfcErrorHandler()

        If hConn <> 0 And RfcErrorInfo.code = RFC_OK Then

          rc = RFC_OK
          While rc = RFC_OK Or rc = RFC_RETRY
            rc = RfcListenAndDispatch(hConn, 4, RfcErrorInfo)
            Select Case rc
              Case RFC_OK
                OutputDebugString("RFC_OK")
              Case RFC_RETRY
                OutputDebugString("RFC_RETRY")
            End Select
          Wend

 

        End If

 

      End If

 

    End If

 

'-End-------------------------------------------------------------------

 

At first we define the function in FreeBASIC which was called from ABAP, here ABAPCall. Now we define the connections parameters for the server registration. Parallel you must configure with the TAC SM59 your server program in the SAP system.

 

0801_SM59.jpg

 

We create a function description via RfcCreateFunctionDesc and install our function via RfcInstallServerFunction. With RfcRegisterServer we register the server on the SAP system and with an endless loop we listen via RfcListenAndDispatch about our ABAP call to the FreeBASIC server application.

 

Here the ABAP program to call the FreeBASIC function:


"-Begin-----------------------------------------------------------------
  Report zFBServerTest.

 

  Call Function 'ABAPCall' Destination 'FBTESTPROGRAM'.

 

"-End-------------------------------------------------------------------

 

As you can see, it is also very easy to code a server application which uses FreeBASIC functions from an SAP system.

 

Cheers
Stefan

 

 

P.S. You find Part 1 here, and Part 2 here.

How to use RFC-SDK with FreeBASIC - Part 2: Client Apps (FreeBASIC uses SAP)

$
0
0

Hello community,

 

in the 2nd part now a few examples of SAP NetWeaver client applications.

 

We start with a simple ping, to demonstrate how to call an ABAP function module from FreeBASIC.


'-Begin-----------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "sapnwrfc.inc"

 

  '-Variables-----------------------------------------------------------
    Dim RfcErrorInfo As RFC_ERROR_INFO
    Dim connParams(6) AS RFC_CONNECTION_PARAMETER
    Dim As Integer hRFC, hFuncDesc, hFunc
    Dim As WString * 16 nASHost, nSysNr, nClient, nUser, nPassWd, nLang
    Dim As WString * 16 vASHost, vSysNr, vClient, vUser, vPassWd, vLang

 

  '-Main----------------------------------------------------------------
    nASHost = "ASHOST" : vASHost = "ABAP"
    nSysNr  = "SYSNR"  : vSysNr  = "00"
    nClient = "CLIENT" : vClient = "001"
    nUser   = "USER"   : vUser   = "BCUSER"
    nPassWd = "PASSWD" : vPassWd = "minisap"
    nLang   = "LANG"   : vLang   = "EN"

 

    connParams(0).name = @nASHost : connParams(0).value = @vASHost
    connParams(1).name = @nSysNr  : connParams(1).value = @vSysNr
    connParams(2).name = @nClient : connParams(2).value = @vClient
    connParams(3).name = @nUser   : connParams(3).value = @vUser
    connParams(4).name = @nPassWd : connParams(4).value = @vPassWd
    connParams(5).name = @nLang   : connParams(5).value = @vLang

 

    hRFC = RfcOpenConnection(@connParams(0), 6, RfcErrorInfo)
    RfcErrorHandler()
    If hRFC <> 0 And RfcErrorInfo.code = RFC_OK Then

 

      '-Variant 1-------------------------------------------------------
      '-
      '- Do not use lowercase characters in FM name,
      '- use only uppercase characters
      '-
      '-----------------------------------------------------------------
        hFuncDesc = RfcGetFunctionDesc(hRFC, "RFC_PING", RfcErrorInfo)
        RfcErrorHandler()

        If hFuncDesc <> 0 And RfcErrorInfo.code = RFC_OK Then

          hFunc = RfcCreateFunction(hFuncDesc, RfcErrorInfo)
          RfcErrorHandler()

          If hFunc <> 0 And RfcErrorInfo.code = RFC_OK Then

            RfcInvoke hRFC, hFunc, RfcErrorInfo
            RfcErrorHandler()

 

            If RfcErrorInfo.code = RFC_OK Then
              MessageBox(null, "Ping successful", "FM RFC_PING", _
                MB_OK Or MB_ICONINFORMATION)
            End If

 

            RfcDestroyFunction hFunc, RfcErrorInfo
            RfcErrorHandler()

 

          End If

        End If

 

      '-Variant 2-------------------------------------------------------
        RfcPing hRFC, RfcErrorInfo
        RfcErrorHandler()

        If RfcErrorInfo.code = RFC_OK Then
          MessageBox(null, "Ping successful", "Function RfcPing", _
            MB_OK Or MB_ICONINFORMATION)
        End If

 

      RfcCloseConnection hRFC, RfcErrorInfo
      RfcErrorHandler()

 

    End If

 

'-End-------------------------------------------------------------------

 

We open the connection and get a function description from the function module RFC_PING via RfcGetFunctionDesc. With this function description we create the function via RfcCreateFunction in the context of our program and execute it with RfcInvoke. If RfcInvoke is successful we get a message box. Last but not least we destroy the function with RfcDestroyFunction.

The 2nd variant is only an example how to use the function RfcPing from the SAP NetWeaver RFC library.

 

Our next example is the using of the function module RFC_SYSTEM_INFO. We use the same way as above, but after the invoke we read the result

of the function module. The result is in the structure RFCSI_EXPORT, we get it with RfcGetStructure and the entries with RfcGetChars.


'-Begin-----------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "sapnwrfc.inc"

 

  '-Variables-----------------------------------------------------------
    Dim RfcErrorInfo As RFC_ERROR_INFO
    Dim connParams(8) AS RFC_CONNECTION_PARAMETER
    Dim As Integer hRFC, hFuncDesc, hFunc, hStruct
    Dim As WString * 16 nASHost, nSysNr, nClient, nUser, nPassWd, _
      nLang, nUseSAPGUI, nTrace
    Dim As WString * 16 vASHost, vSysNr, vClient, vUser, vPassWd, _
      vLang, vUseSAPGUI, vTrace
    Dim As WString * 9 SAPHost, SAPSysID
    Dim As WString * 11 SAPDBSys
    Dim As WString * 33 SAPDBHost

 

  '-Main----------------------------------------------------------------
    nASHost    = "ASHOST"     : vASHost    = "ABAP"
    nSysNr     = "SYSNR"      : vSysNr     = "00"
    nClient    = "CLIENT"     : vClient    = "001"
    nUser      = "USER"       : vUser      = "BCUSER"
    nPassWd    = "PASSWD"     : vPassWd    = "minisap"
    nLang      = "LANG"       : vLang      = "EN"
    nUseSAPGUI = "USE_SAPGUI" : vUseSAPGUI = "0"
    nTrace     = "TRACE"      : vTrace     = "0"

 

    connParams(0).name = @nASHost    : connParams(0).value = @vASHost
    connParams(1).name = @nSysNr     : connParams(1).value = @vSysNr
    connParams(2).name = @nClient    : connParams(2).value = @vClient
    connParams(3).name = @nUser      : connParams(3).value = @vUser
    connParams(4).name = @nPassWd    : connParams(4).value = @vPassWd
    connParams(5).name = @nLang      : connParams(5).value = @vLang
    connParams(6).name = @nUseSAPGUI : connParams(6).value = @vUseSAPGUI
    connParams(7).name = @nTrace     : connParams(7).value = @vTrace

 

    hRFC = RfcOpenConnection(@connParams(0), 8, RfcErrorInfo)
    RfcErrorHandler()

    If hRFC <> 0 And RfcErrorInfo.code = RFC_OK Then

      hFuncDesc = RfcGetFunctionDesc(hRFC, "RFC_SYSTEM_INFO", _
        RfcErrorInfo)
      RfcErrorHandler()

      If hFuncDesc <> 0 And RfcErrorInfo.code = RFC_OK Then

        hFunc = RfcCreateFunction(hFuncDesc, RfcErrorInfo)
        RfcErrorHandler()

        If hFunc <> 0 And RfcErrorInfo.code = RFC_OK Then

          RfcInvoke hRFC, hFunc, RfcErrorInfo
          RfcErrorHandler()

          If RfcErrorInfo.code = RFC_OK Then

            RfcGetStructure hFunc, "RFCSI_EXPORT", @hStruct, _
              RfcErrorInfo
            RfcErrorHandler()

            If RfcErrorInfo.code = RFC_OK Then

              RfcGetChars hStruct, "RFCHOST", @SAPHost, 8, _
                RfcErrorInfo
              RfcGetChars hStruct, "RFCSYSID", @SAPSysID, 8, _
                RfcErrorInfo
              RfcGetChars hStruct, "RFCDBHOST", @SAPDBHost, 32, _
                RfcErrorInfo
              RfcGetChars hStruct, "RFCDBSYS", @SAPDBSys, 10, _
                RfcErrorInfo

 

              MessageBox(null, "Host: " & SAPHost & Chr(13,10) & _
                "SysID: " & SAPSysID & Chr(13,10) & _
                "DBHost: " & SAPDBHost & Chr(13,10) & _
                "DBSys: " & SAPDBSys, "FM RFC_SYSTEM_INFO", _
                MB_OK Or MB_ICONINFORMATION)
             
            End If 
           
          End If

 

          RfcDestroyFunction hFunc, RfcErrorInfo
          RfcErrorHandler()

 

        End If

      End If

 

      RfcCloseConnection hRFC, RfcErrorInfo
      RfcErrorHandler()

 

    End If

 

'-End-------------------------------------------------------------------

 

The result is displayed in a message box.

 

0104_Result.jpg

 

As you can see, it is very easy to code a client application which uses function modules from an SAP system.

 

Cheers
Stefan

 

 

P.S. You find Part 1 here, and Part 3 here.

How to use RFC-SDK with FreeBASIC - Part 1: The Connection

$
0
0

Hello community,

 

FreeBASIC is a powerful free and open source BASIC compiler for Windows and Linux. You find the official site here and the very good German site here. The actual version 0.90.1 can only create 32-bit applications, but the new beta release 0.91 can also create 64-bit applications - look here (in German). FreeBASIC is an ideal partner to SAP NetWeaver RFC SDK, because it is very easy to use SAP NetWeaver RFC SDK with FreeBASIC. This is the reason for this tutorial.

 

We start with an include file called sapnwrfc.inc. It collects constants, structures and declarations:


'-Begin-----------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "windows.bi"

 

  '-Constants-----------------------------------------------------------
    Enum
      RFC_OK = 0
      RFC_RETRY = 14
    End Enum

 

  '-Structures----------------------------------------------------------
 
    '-RFC_ERROR_INFO----------------------------------------------------
      Type RFC_ERROR_INFO
        code As Integer
        group As Integer
        key As WString * 128
        message As WString * 512
        abapMsgClass As WString * 21
        abapMsgType As WString * 2
        abapMsgNumber As WString * 4
        abapMsgV1 As WString * 51
        abapMsgV2 As WString * 51
        abapMsgV3 As WString * 51
        abapMsgV4 As WString * 51
      End Type

 

    '-RFC_CONNECTION_PARAMETER------------------------------------------
      Type RFC_CONNECTION_PARAMETER
        name As WString Ptr
        value As WString Ptr
      End Type

 

  '-Declarations--------------------------------------------------------
    Declare Function RfcCloseConnection StdCall Lib "sapnwrfc" _
      Alias "RfcCloseConnection" (ByVal rfcHandle As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcCreateFunction StdCall Lib "sapnwrfc" _
      Alias "RfcCreateFunction" (ByVal funcDescHandle As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcCreateFunctionDesc StdCall Lib "sapnwrfc" _
      Alias "RfcCreateFunctionDesc" (name As WString, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcGetChars StdCall Lib "sapnwrfc" _
      Alias "RfcGetChars" (ByVal dataHandle As Integer, _
      name As WString, ByVal charBuffer As WString Ptr, _
      bufferLength As Integer, errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcGetStructure StdCall Lib "sapnwrfc" _
      Alias "RfcGetStructure" (ByVal dataHandle As Integer, _
      name As WString, ByVal strucHandle As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcDestroyFunction StdCall Lib "sapnwrfc" _
      Alias "RfcDestroyFunction" (ByVal funcHandle As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcGetFunctionDesc StdCall Lib "sapnwrfc" _
      Alias "RfcGetFunctionDesc" (ByVal rfcHandle As Integer, _
      funcName As WString, errorInfo As RFC_ERROR_INFO) _
      As Integer

 

    Declare Function RfcGetVersion StdCall Lib "sapnwrfc" _
      Alias "RfcGetVersion" (ByVal MajorVersion As Long Ptr, _
      ByVal MinorVersion As Long Ptr, ByVal PatchLevel As Long Ptr) _
      As WString Ptr

 

    Declare Function RfcInstallServerFunction StdCall Lib "sapnwrfc" _
      Alias "RfcInstallServerFunction" (sysID As WString, _
      ByVal funcDescHandle As Integer, ByVal serverFunction As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcInvoke StdCall Lib "sapnwrfc" _
      Alias "RfcInvoke" (ByVal rfcHandle As Integer, _
      ByVal funcHandle As Integer, errorInfo As RFC_ERROR_INFO) _
      As Integer

 

    Declare Function RfcListenAndDispatch StdCall Lib "sapnwrfc" _
      Alias "RfcListenAndDispatch" (ByVal rfcHandle As Integer, _
      ByVal timeout As Integer, errorInfo As RFC_ERROR_INFO) _
      As Integer

 

    Declare Function RfcOpenConnection StdCall Lib "sapnwrfc" _
      Alias "RfcOpenConnection" (ByVal connectionParams As Integer, _
      ByVal paramCount As Integer, errorInfo As RFC_ERROR_INFO) _
      As Integer

 

    Declare Function RfcPing StdCall Lib "sapnwrfc" _
      Alias "RfcPing" (ByVal rfcHandle As Integer, _
      errorInfo As RFC_ERROR_INFO) As Integer

 

    Declare Function RfcRegisterServer StdCall Lib "sapnwrfc" _
      Alias "RfcRegisterServer" (ByVal connectionParams As Integer, _
      ByVal paramCount As Integer, errorInfo As RFC_ERROR_INFO) _
      As Integer

 

  '-Macros--------------------------------------------------------------
    #Macro RfcErrorHandler()
      If RfcErrorInfo.code <> RFC_OK Then
        MessageBox(null, RfcErrorInfo.message, "RFC Error Message", _
          MB_OK Or MB_ICONERROR)
      End If
    #EndMacro

 

'-End-------------------------------------------------------------------

 

Not all functions of the SAP NetWeaver RFC library are declared, only the functions we needed for this tutorial. Store this file, that are all preparations.

 

Now we take a look at our first FreeBASIC program:


'-Begin-----------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "sapnwrfc.inc"

 

  '-Variables-----------------------------------------------------------
    Dim RfcErrorInfo As RFC_ERROR_INFO
    Dim connParams(6) AS RFC_CONNECTION_PARAMETER
    Dim hRFC As Integer
    Dim As WString * 16 nASHost, nSysNr, nClient, nUser, nPassWd, nLang
    Dim As WString * 16 vASHost, vSysNr, vClient, vUser, vPassWd, vLang

 

  '-Main----------------------------------------------------------------
    nASHost = "ASHOST" : vASHost = "ABAP"
    nSysNr  = "SYSNR"  : vSysNr  = "00"
    nClient = "CLIENT" : vClient = "001"
    nUser   = "USER"   : vUser   = "BCUSER"
    nPassWd = "PASSWD" : vPassWd = "minisap"
    nLang   = "LANG"   : vLang   = "EN"

 

    connParams(0).name = @nASHost : connParams(0).value = @vASHost
    connParams(1).name = @nSysNr  : connParams(1).value = @vSysNr
    connParams(2).name = @nClient : connParams(2).value = @vClient
    connParams(3).name = @nUser   : connParams(3).value = @vUser
    connParams(4).name = @nPassWd : connParams(4).value = @vPassWd
    connParams(5).name = @nLang   : connParams(5).value = @vLang

 

    hRFC = RfcOpenConnection(@connParams(0), 6, RfcErrorInfo)
    RfcErrorHandler()
    If hRFC <> 0 And RfcErrorInfo.code = RFC_OK Then

      MessageBox(null, "Check connection with TAC SMGW in the " & _
        "SAP system", "", MB_OK Or MB_ICONINFORMATION)

      RfcCloseConnection hRFC, RfcErrorInfo
      RfcErrorHandler()

    End If

 

'-End-------------------------------------------------------------------

 

It is very easy. In the first block we define the connection parameter and then we open a connection to our SAP system via the function RFCOpenConnection. The program stops with a message box and in our SAP system we find, with the TAC SMGW, our connected client application.

 

0101_SMGW.jpg

 

After closing the message box we close the connection via the function RFCCloseConnection.

 

As you can see, it is very easy to code a client application which connects an SAP system.

 

Cheers
Stefan

 

 

P.S. You find Part 2 here, and Part 3 here.

Upload Files to SharePoint folders From SAP

$
0
0

Hi Friends,

 

Now-a-days we hear a lot about integrating SAP with Share Point.

I have recently work on such a requirement, where in I need to Upload files to SharePoint folders from SAP. So wanted to share my experience.

 

There are two different scenarios:

 

1) SharePoint and SAP are hosted on same server.

 

2) SharePoint and SAP are hosted on different server.

 

 

1) SharePoint and SAP are hosted on same server.

 

In this scenario,

 

Files can be directly uploaded Via GUI_UPLOAD or any equivalent FM or Classes.

 

STEPS:

  • Create new document library in your share point site.
  • GOTO--> Library and click on "Open with explorer" icon as shown below

folder.JPG

  • Then the server location opens as below

path.JPG

  • Pass the path to GUI_UPLOAD to upload to the folder.

 

 

2) SharePoint and SAP are hosted on different server.

 

In this case, we make use of a facility provided by Share Point known as "Communication Through Incoming email setings" to upload files onto it's folders.

 

STEPS:

 

                                                     

  • Create new document library in your share point site.

 

  • Once library created. Go to "Document library settings". -> Communication -> Incoming email settings

 

email.JPG

 

  • Enable the settings

 

              "Incoming email"=Yes

 

              Email address = "Define unique email ID"

 

              E-Mail Attachments=Save all attachments in root folder

 

address.JPG

 

  • Use email ID, in your ABAP program to send document in email.

 

 

 

Once you send mail to specific email ID as maintained in share point site, you will see document getting placed automatically in share point whatever you send it through email (as attachment ).

SAP Connectivity with MS Excel

$
0
0

Data from SAP to MS Office Applications

1.jpg

         

Using the connection SAP with MS Office, users spreads data from SAP application to right within Microsoft Office desktop applications, including Excel, Outlook, Word and Power point.

With the SAP-MS Office connectivity, end-users can interact with SAP transactions directly within their Excel spreadsheet, their Outlook e-mail screen, and their Word documents and on their Power point presentations.

Here we have a simple application to connect SAP with MS-office tool’s Excel.
But before that……Why? How? And Use!

 

Why Data from SAP to MS Office Applications

2.jpg

In spite of large moneys in SAP, most business users continue to be unsatisfied with it because data from SAP is not easily accessible in their favorite desktop productivity tools -- Microsoft Excel, Microsoft Outlook and Microsoft Word. Since Microsoft Office Applications are not connected to SAP, users are forced to

  • Use error-prone cut-copy-paste to populate their Excel spreadsheets.
  • Switch screens from Outlook to gather data and take decisions as they respond to e-mails.
  • Manually update data from Excel Spreadsheets to enterprise applications.


  Benefits of Data from SAP to Microsoft Office Applications
SAP-MS Office Connectivity extends data from SAP to Microsoft Excel, Microsoft Outlook and Microsoft Word using a SOA based    Information Delivery Server and Microsoft Office Add-ins, and provides the following benefits

  • Eliminates cut-and-paste based data collecting mechanism from SAP to Microsoft Excel.
  • Enables users to get real-time data from SAP within Excel with a single-click Refresh.
  • Enables users to query and update SAP transactions from within Outlook screens.
  • Allows the users to update SAP from within Excel, Outlook and Word.
  • Avoids any data-integrity issues with copying and reduces compliance issues.


  Who Benefits

  • Production and Logistics Managers who want to create Excel reports from latest SAP data.
  • Managers who want to track projects and status automatically as they receive status e-mails.
  • Analysts who want to combine data from SAP and other enterprise data stores for budgeting purposes.

 

Example:

3.jpg

Here is the main part comes up. We shall take simple scenario for SAP with MS Excel connectivity.  So let’s begin!!

Just before start, I would like to give little overview on what we are actually going to do. So, here are the scenarios!!

Excel File Scenarios

  • Create a MS excel file for user input.
  • Create user interface in excel sheet to input data for the customer master and output cells.
  • Apply VB code to make connection with SAP.
  • Read the input data for customer master from the excel file sheet.
  • Fetch data from SAP using connection code from SAP.
  • Display output within excel sheet itself.

SAP Scenarios

  • Create a function module in ABAP that is “Remote Enabled”.
  • Create IMPORT, EXPORT and TABLES parameters as per requirement from MS excel.
  • Write logic to display customer master details based on input from Excel file.
  • Activate the function module.

Well……………“A picture says thousand words”. So, let’s begin!

 

MS Excel – User Interface

  First of all, lets create MS excel file with customer master input. We shall create simple selection screen for user input.

4.jpg

Well……filling cell values are simple here but how to add buttons (Get Address and Reset Output) here? This was also new in my case since new version of MS office.


Just follow following steps for this:


Click MS office button and select “Excel Options” button from the menu.

 

5.jpg

You will see here a new tab named “Developer”

 

6.jpg

 

Click on “Insert” and then select “Button” from the form control. Later on you can double click on the button and set its properties (Caption, Color, etc.)

Congratulations! Our input screen is finished here. Let’s design our output screen now.

 

7.jpg

I have created my output screen just after the input screen. You can create anywhere in the excel file. Here terms ‘anywhere’ descries to other worksheet also.

The output screen is simple as you see. Nothing much to do here. I just simple colored the cells for better look.

Great! Looks like we finished user interface here. (Did we miss something...’Naah’ for now!)

 

 

SAP – Select Data

Since we are taking simple example to fetch detail from customer master, let’s create a function module for it.

 

 

Create a function module.

8.jpg

Enter function group and Short text.

 

9.jpg

Make sure your function module is “Remote Enabled”.

 

10.jpg


Now let’s create “Tables” parameters:

 

11.jpg



Here we have two “Tables” parameters

  • ET_KUNNR (Input) : Customer numbers pass in to the function module
  • ET_CUST_LIST (Output): Data will be fetched in function module and display on the excel sheet.
    • Note: We have created a Z structure (ZNM_CUST_LIST) for the output list. Here are the fields for the structure:

12.jpg


We are all set with input and output structures.

Now, let’s fetch the data. Here is the only coding part came up in SAP. Look at below screen.

 

13.jpg


Here, we are selecting all the customer details from the KNA1 (customer master) table from the input table (ET_KUNNR) from excel file and return to the table (ET_CUST_LIST).

Now we have all the records in the table ET_CUST_LIST.

So, again congratulation friends! You have completed most of the things. The remaining step now is to display the list in the excel file.

 

 

Let’s now connect the SAP and MS Excel.

Go to the ‘Developer’ tab and click on “Visual Basic” icon.

 

14.jpg


The VB editor will be opened and we are going to write the code for connection of excel and SAP with sending and receiving data.

Here is the variable declaration list.  These are the global variables. Let’s understand each of them.

 

Capture.PNG

 

 

 

Variable

Description

objBAPIControl

For creating object to access SAP functions.

objgetaddress

To make BAPI function call via objBAPIControl.

 

vLastRow

Last row of output list

vRows

Total number of records returned from the SAP

 

vcount_add

Variable for increment records

Index_add

Variable for next record (Index)

 

objaddress

Object for SAP table (for customer master output)

objkunnr

Object for SAP table (for customer master input)

Variable

Description

LogonControl

Logon control is to make login in SAP.

R3Connection

Ro make connection to SAP R/3 using logon control.

retcd

Return Code

SilentLogon

If ‘True’ no popup will ask to enter SAP login details


Here are the properties for the “Get Address” button.

 

16.jpg

 

Let’s code when “Get Address” button is clicked.

Setup the local variables

 

Private Sub GetAddress_Click()

Now let’s setup the connection with SAP R/3 using following code.

Capture.PNG

 

Let’s do SAP Login here.

 

19.jpg

 

Perfect!! We have made the connection with SAP R/3. Now we are able to send and receive the data from MS Excel to SAP R/3 and vice versa.

But how to send my customer details and receive? Hmmm…..we need to use internal tables those are created in SAP function module. (Do you remember?....NO?... checkout Tables parameters in  function ZNM_GET_CUSTOMER_DETAILS). So, let’s do this.

20.jpg

 

Here, ZNM_GET_CUSTOMER_DETAILS is our function module created in SAP.

ET_KUNNR: Customer details input details

ET_CUST_LIST: Customer output details.

Capture.PNG

We are reading here each cell from excel worksheet for input.

 

Capture.PNG

 

Here we have called the FM and passed the input details to process.

Result:

Capture.PNG

 

vcount_add returns total number of records from the SAP. And we have already set the loop to display records in the cells.

Here, R3Connection.Logoff is to sign off from your SAP account.

Here is the output screen:

 

24.jpg

 

 

Wow!! We have output result. Good job!! But what is the use of another button “Reset Output” here? Yes…good question.

The “Reset Output” button will clear all the data and messages from the screen. Look at below code:

 

 

-----------------------------------------------------------------------------------------------------------------------

Now we have completed the entire example here. N’ joy.

 

Here is the entire code:

SHEET1:

Option Explicit

Private LogonControl As SAPLogonCtrl.SAPLogonControl

Private R3Connection As SAPLogonCtrl.Connection

Private TableFactory As SAPTableFactory

Public Functions As SAPFunctionsOCX.SAPFunctions

Dim objBAPIControl, objgetaddress As Object

Dim vLastRow, vRows As Integer

Dim vcount_add, index_add As Integer

Dim rng As Range

Public objaddress, objkunnr As SAPTableFactoryCtrl.Table

 

MODULE:

Sub GetAddress_click()

' Set Connection

Set LogonControl = CreateObject("SAP.LogonControl.1")

Set objBAPIControl = CreateObject("SAP.Functions")

Set R3Connection = LogonControl.NewConnection

R3Connection.Client = "700"

R3Connection.ApplicationServer = ""

R3Connection.Language = "EN"

R3Connection.User = ""

R3Connection.Password = ""

R3Connection.System = ""

R3Connection.SystemNumber = ""

R3Connection.UseSAPLogonIni = False

SilentLogon = False

retcd = R3Connection.Logon(0, SilentLogon)

If retcd <> True Then MsgBox "Logon failed": Exit Sub

objBAPIControl.Connection = R3Connection

Set objgetaddress = objBAPIControl.Add("ZNM_GET_EMPLOYEE_DETAILS")

Set objkunnr = objgetaddress.Tables("ET_KUNNR")

Set objaddress = objgetaddress.Tables("ET_CUST_LIST")

Dim sht As Worksheet

Set sht = ThisWorkbook.ActiveSheet

' Changes for the Loop

'Dim int1 As Integer

'Do While sht.Cells(int1, 2).Value <> " "

 

 

' Changes for the Loop End

If sht.Cells(6, 2).Value <> " " Then

'If ThisWorkbook.ActiveSheet.Cells(6, "B").Value <> " " Then

'objkunnr.Rows.Add objkunnr.Value(1, "SIGN") = ThisWorkbook.ActiveSheet.Cells(6, 2).Value

objkunnr.Rows.Add

objkunnr.Value(1, "SIGN") = sht.Cells(6, 2).Value

'objkunnr.Value(1, "OPTION") = ThisWorkbook.ActiveSheet.Cells(6, 3).Value

objkunnr.Value(1, "OPTION") = sht.Cells(6, 3).Value

'objkunnr.Value(1, "LOW") = ThisWorkbook.ActiveSheet.Cells(6, 4).Value

objkunnr.Value(1, "LOW") = sht.Cells(6, 4).Value

'objkunnr.Value(1, "HIGH") = ThisWorkbook.ActiveSheet.Cells(6, 5).Value

objkunnr.Value(1, "HIGH") = sht.Cells(6, 5).Value

'End If

End If

returnfunc = objgetaddress.call

If returnfunc = True Then

vcount_add = objaddress.Rows.Count

For index_add = 1 To vcount_add

    vRows = 11 + index_add

    sht.Cells(vRows, 2) = objaddress.Value(index_add, "KUNNR")

    sht.Cells(vRows, 3) = objaddress.Value(index_add, "LAND1")

    sht.Cells(vRows, 4) = objaddress.Value(index_add, "NAME1")

    sht.Cells(vRows, 5) = objaddress.Value(index_add, "ORT01")

    sht.Cells(vRows, 6) = objaddress.Value(index_add, "PSTLZ")

    sht.Cells(vRows, 7) = objaddress.Value(index_add, "REGIO")

    sht.Cells(vRows, 8) = objaddress.Value(index_add, "KTOKD")

    sht.Cells(vRows, 9) = objaddress.Value(index_add, "TELF1")

    sht.Cells(vRows, 10) = objaddress.Value(index_add, "TELFX")

    Next index_add

End If

' If address not exist then Show error

If vcount_add = "" Then

    sht.Cells(10, 11) = "Invalid Input"

Else

'    ActiveSheet.Cells(10, 12) = "BAPI Call is Successfull"

'    ActiveSheet.Cells(11, 12) = vcount_add & "rows are entered"

    sht.Cells(10, 12) = "BAPI Call is Successfull"

    sht.Cells(11, 12) = vcount_add & " rows are entered"

End If

R3Connection.Logoff

End Sub

Data Transfer from SAP to SFTP server Using OS Commands

$
0
0

Today’s enterprise concerns about every aspect of our internal LAN networks just as much as we had to worry about our WAN connections. Through the growth of the Internet and the technologies that have been developed around them, data is more vulnerable today than at any point in the past. Data transfer is so integral to the proper flow of business processes and corporate communication that it must be a high priority for any company.

 

Regardless of the industry, every company has an obligation to keep private information secure. Whether it is customer data or employee details, a company is required to take security measures to keep personal information safe. Laws and legislations have been passed, and more are proposed that require certain types of traffic (legal, financial, and health) to be securely encrypted whenever they cross unsecure networks.

 

 

This document briefly explains the steps to establish the connection between SAP and SFTP server, describes the creation of external OS commands using SM69 and execution of external OS commands using FM  SXPG_COMMAND_EXECUTE  programmatically.

 

Secure File Transfer Protocols:

 

SSH:

SSH or Secure Shell is a cryptographic network protocol that allows data to be exchanged using a secure channel between two networked devices.  It provides strong authentication and secure communications over insecure channels. It can transfer files using the secure file transfer protocol  (SFTP) or secure copy protocol (SCP).

 

It uses public-key cryptography to authenticate the remote computer and allow it to  authenticate the user. It was designed as a replacement for Telnet and other unsecure remote shells, which send information, notably passwords, in plaintext, rendering them susceptible to packet analysis (internal and external threats). 

 

SSH tunnelling allows you to create an encrypted connection between Source system (SAP) and the target system (SFTP Server) at the remote site. Over this single connection, you can run the external OS commands using the FM SXPG_COMMAND_EXECUTE to transfer the files securely.

 

SSH.jpg

 

SFTP and SCP:

 

There are multiple mechanisms for transferring files using the SSH (Secure Shell) protocol. In this document, we are focusing on Secure File Transfer Protocol (SFTP)  and Secure Copy Protocol (SCP) .

 

Secure File Transfer Protocol (SFTP) is a subsystem of the Secure Shell protocol. SFTP has several advantages over the non-secure FTP. First, SFTP encrypts both the username/password and the data being transferred. Second, it uses the same port as the Secure Shell server, eliminating the need to open another port on the firewall or router. Using SFTP also avoids the network address translation (NAT) issues that can often be a problem with regular FTP.

 

While SFTP is very similar in operation and commands to FTP, developers may find SCP much easier to use in automation scenarios. Both SFTP and FTP are session based, whereas, SCP is a single copy command.

 

 

About Key Pair:

 

SSH uses public-key cryptography to authenticate the remote computer and allow it to  authenticate the user. An SSH identity uses a pair of keys, one private and one public .The Public and Private key pair comprise of two uniquely related cryptographic keys.

 

The Public Key is what its name suggests - Public. It is made available to everyone via a publicly accessible repository or directory. On the other hand, the Private Key must remain confidential to its respective owner.

 

During authentication, the SSH client and server have a little conversation about your private and public key. If they match (according to a cryptographic test), your identity is proven, and authentication succeeds.

 

To generate the private/public keys, you need to install the SSH client tool in the source system.

 

  • PuTTY is the most popular secure SSH clients. Its very small is size and easy use.
  • Cygwin is popular for Windows Servers which provide a Linux look and feel.
  • OpenSSH client tool is popular tool for UNIX. It is the implementation of the SSH protocol. OpenSSH is recommended for remote login, making backups, remote file transfer via scp or sftp, and much more.

 

Creation of OS Commands using SM69 for Secure Data Transfer:

 

SCP Command:

 

It copies files between hosts on a network. It uses SSH for data transfer, and uses the same authentication and provides the same security as SSH. SFTP command is session based, whereas, SCP is a single copy command. We may find SCP much easier to use in automation scenarios.

 

Example :

scp-2 -4 -c blowfish –C  <Source Folder>\srcfile.dat  scpuser@<ipaddress>:<target_folder>\targetfile.dat

 

 

SCP_Cmd.JPG

 

Execution of OS Commands using FM:

 

Using the FM SXPG_COMMAND_EXECUTE, you can execute the external  commands which are created in the SM69.  You should have an authorization to execute the external commands using this FM.

 

SXPG.jpg

 

Where,

COMMAND NAME: Specify the name of external command which is created in the SM69. For example: ZSCP_COMMAND

ADDITIONAL_PARAMETERS: Specify the parameters to execute the external commands.

For example:  <Source Folder>\srcfile.dat  sftpuser@<ipaddress>:<target_folder>\targetfile.dat

 

 

Summary for using the secure protocols:

  

  • Install SSH client tool (PUTTY for windows / OpenSSH for UNIX) on the source system.

  • Generate the public and private keys using the key generation program which is available in the SSH client tool.

  • Install the public key in the target server on the .ssh/authorized_keys file.

  • Store the private key on the source system in the passphrase-protected format.  Protect your private key with a strong passphrase.

  • The standard TCP port 22 has been assigned for contacting SSH servers. Hence, it must be open for these secure protocols to work.

  • Create an external OS Command in SM69 for file transfer between the networked devices.

  • Using the FM SXPG_COMMAND_EXECUTE,  execute the external OS command to transfer the files securely.


RFC Read Table Exported Result in JSON Format too

$
0
0

Hello community,

 

I read here about the possibility to export any result from a function module (FM) in JSON format - a very good idea , many thanks to Cesar Martin.

 

I use the FM RFC_READ_TABLE very often and so I implemented a small extension to export the result also in JSON format.

 

Here a short two step instruction:

 

  1. Add in your copy of RFC_READ_TABLE a new export parameter, e.g. DATA_JSON from the type table of lines.

    001.JPG
  2. Add at the bottom of your copy of RFC_READ_TABLE, in the line 199 between the last EndSelect and EndIf, the following code.

      "-Export data in JSON format------------------------------------------
      "-
      "- Check the created JSON file with http://www.jsonlint.com validator
      "-
      "---------------------------------------------------------------------

        "-Variables---------------------------------------------------------
          Data strJSON Type SDBLIN1024.
          Data cntData Type i Value 0.
          Data cntLine Type i Value 0.

        Describe Table DATA Lines cntData.

        strJSON = `{`.
        Append strJSON To DATA_JSON.
        Concatenate `  "` QUERY_TABLE '" : [' Into strJSON.
        Append strJSON To DATA_JSON.
        Loop At DATA.
          cntLine = cntLine + 1.

          strJSON = `    {`.
          Append strJSON To DATA_JSON.
          Loop At FIELDS.

            Move DATA-WA+FIELDS-OFFSET(FIELDS-LENGTH) To strJSON.
            Condense strJSON.
            Case FIELDS-TYPE.
              When 'I' Or 'b' Or 's' Or 'P' Or 'F'.
                Concatenate `      "` FIELDS-FIELDNAME `" : ` strJSON
                  Into strJSON.
              When Others.
                Concatenate `      "` FIELDS-FIELDNAME `" : "` strJSON '"'
                  Into strJSON.
            EndCase.
            If sy-tabix < sy-tfill.
              Concatenate strJSON ',' Into strJSON.
            EndIf.
            Append strJSON To DATA_JSON.

          EndLoop.
          strJSON = `    }`.
          If cntLine < cntData.
            Concatenate strJSON ',' Into strJSON.
          EndIf.
          Append strJSON To DATA_JSON.

        EndLoop.

        strJSON = `  ]`.
        Append strJSON To DATA_JSON.
        strJSON = `}`.
        Append strJSON To DATA_JSON.

 

With this way you get the result also in JSON format.

002.JPG

003.JPG

004.JPG

And now you can easily create JSON images of any table via your copy of RFC_READ_TABLE.

 

Here an example via COM Connector (CCo) with VBScript:

 

'-Begin-----------------------------------------------------------------

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Constants-----------------------------------------------------------

    Const RFC_OK = 0

    Const ForWriting = 2

 

  '-Variables-----------------------------------------------------------

    Dim SAP, hRFC, rc, hFuncDesc, hFunc, hTable, RowCount, i, hRow

    Dim charBuffer, charFile, FSO, F, tableName

 

  '-Main----------------------------------------------------------------

    tableName = InputBox("Name of the table", "Request", "SFLIGHT")

    Set SAP = CreateObject("COMNWRFC")

    If IsObject(SAP) Then

      hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

        "CLIENT=000, USER=BCUSER")

      If hRFC Then

        hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_RFC_READ_TABLE_JSON")

        If hFuncDesc Then

          hFunc = SAP.RfcCreateFunction(hFuncDesc)

          If hFunc Then

 

            rc = SAP.RfcSetChars(hFunc, "QUERY_TABLE", tableName)

            rc = SAP.RfcSetChars(hFunc, "DELIMITER", "~")

 

            If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then

 

              If SAP.RfcGetTable(hFunc, "DATA_JSON", hTable) = RFC_OK Then

                rc = SAP.RfcGetRowCount(hTable, RowCount)

                rc = SAP.RfcMoveToFirstRow(hTable)

                For i = 1 To RowCount

                  hRow = SAP.RfcGetCurrentRow(hTable)

                  rc = SAP.RfcGetChars(hRow, "LINE", charBuffer, 1024)

                  charFile = charFile & RTrim(charBuffer) & vbCrLf

                  If i < RowCount Then

                    rc = SAP.RfcMoveToNextRow(hTable)

                  End If

                Next

 

                '-Write JSON file---------------------------------------

                  Set FSO = CreateObject("Scripting.FileSystemObject")

                  If IsObject(FSO) Then

                    Set F = FSO.OpenTextFile(tableName & ".json", _

                      ForWriting, True)

                    F.Write charFile

                    F.Close

                    Set FSO = Nothing

                  End If

 

              End If

            End If

 

          rc = SAP.RfcDestroyFunction(hFunc)

          End If

        End If

 

        rc = SAP.RfcCloseConnection(hRFC)

      End If

      Set SAP = Nothing

    End If

 

'-End-------------------------------------------------------------------

 

Enjoy it.

 

Cheers

Stefan

RFC Destination Check

$
0
0

ABAP Connection or RFC Destination needs to be checked before calling any remote enabled function module, if connection is  checked prior to a Remote function module call, we can avoid system dumps whenever RFC destination is down or incase of login problems.

 


Manual way to test a RFC connection is to goto transaction SM59, select the RFC Destination, Double click on the same and Click on Action Button - Connection Test

 

 

 

conncetion_test.png

 

 

AUTOMATED PROGRAM TO SIMULATE SM59 - Connection Test

 

I have create a program using a standard function module CAT_CHECK_RFC_DESTINATION , Syntax of the program as follows :

 

 

REPORT zcvtest.

PARAMETERS: P_lsys like RSCAT-RFCDEST.

data: l_msgv1 type sy-msgv1,
      l_msgv2 type sy-msgv2,
      l_subrc type sy-subrc.

CALL FUNCTION 'CAT_CHECK_RFC_DESTINATION'
  EXPORTING
    rfcdestination       = p_lsys
IMPORTING
   MSGV1                = l_msgv1
   MSGV2                = l_msgv2
   RFC_SUBRC            = l_subrc.

if l_subrc = '0'.
  write: 'Success'.
else.
  write: l_msgv1,l_msgv2.
endif.

 

Test Results

 

Negative Case - A Failed RFC

 

 

 

sm59_1.png

Using the program, Same RFC destination is checked:

 

Selection Screen

 

SS1.png

 

Output

 

OP1.png

 

 

Success Case

 

sm59_2.png

 

Selection screen

 

SS2.png

 

Output

 

Op2.png

 

Value : This document shows efficient way of using Function module to check RFC connection before making any RFC Calls, this will make sure that no dumps are encountered in the production system.

How to use Windows PowerShell 3 inside ABAP

$
0
0

Hello community,

 

one year ago I presented here the possibility to use Windows Power Shell 2 scripting language inside ABAP. As examples I presented here how to use VB# with this szenario, and here how to call DLL functions. Now a tiny update to the version 3 of PowerShell.

 

You can download from SAPIEN Technologies Inc. a free library to use PowerShell 3 with ABAP - ActiveXPoshV3x86.exe. Install and register it. It is now very easy possible to use PowerShell inside ABAP, here an example which stores the PowerShell script inside an ABAP include - look here for a detailed description with a VBScript example. Our PowerShell script containes a VB# class with three methods.

 

#-Begin-----------------------------------------------------------------

 

$VBCode = @"

 

Option Strict On

 

Imports System

Imports Microsoft.VisualBasic

 

Namespace VBCode

 

  Public Class VB

 

    Public Shared Function Hello1() As String

      Return "Hello World!"

    End Function

 

    Public Function Hello2(ByVal Name As String) As String

      Return "Hello " & Name & "!"

    End Function

 

    Public Sub Hello3(ByVal Name As String)

      MsgBox(Name, MsgBoxStyle.OkOnly, "Hello")

    End Sub

 

  End Class

 

End Namespace

 

"@;

 

Add-Type -TypeDefinition $VBCode -Language VisualBasic

$VB = new-Object VBCode.VB

 

[VBCode.VB]::Hello1()

$VB.Hello2("Stefan")

$VB.Hello3("Stefan")

 

#-End-------------------------------------------------------------------

 

 

It is necessary to store this code in an own include.

 

zPowerShell.JPG

 

With the function module zReadInclAsString and the following report you can use the PowerShell code and execute it inside your ABAP report.

 

 

"-Begin-----------------------------------------------------------------

  Program zUseVBSharp.

 

    "-TypePools---------------------------------------------------------

      Type-Pools OLE2 .

 

    "-Constants--------------------------------------------------------

      Constants OUTPUT_CONSOLE Type i Value 0.

      Constants OUTPUT_WINDOW Type i Value 1.

      Constants OUTPUT_BUFFER Type i Value 2.

 

    "-Variables---------------------------------------------------------

      Data PS Type OLE2_OBJECT.

      Data Result Type i Value 0.

      Data strResult Type String Value ''.

      Data tabResult Type Table Of String.

      Data PSCode Type String Value ''.

      Data InclName Type SOBJ_NAME Value 'ZPOWERSHELL'.

 

    "-Main--------------------------------------------------------------

      Create Object PS 'SAPIEN.ActiveXPoSHV3'.

 

      If sy-subrc = 0 And PS-Handle <> 0 And PS-Type = 'OLE2'.

 

        Call Method Of PS 'Init' = Result Exporting #1 = 0.

 

        If Result = 0.

 

          Call Method Of PS 'IsPowerShellInstalled' = Result.

 

          If Result <> 0.

 

            Set Property Of PS 'OutputMode' = OUTPUT_BUFFER.

 

            "-Read PowerShell code from include file--------------------

              Call Function 'ZREADINCLASSTRING'

                Exporting I_InclName = InclName

                Importing E_strIncl = PSCode.

 

            Call Method Of PS 'Execute' Exporting

              #1 = PSCode.

 

            Call Method Of PS 'OutputString' = strResult.

 

            Split strResult At cl_abap_char_utilities=>cr_lf

              Into Table tabResult.

 

            Loop At tabResult Into strResult.

              Write: / strResult.

            EndLoop.

 

          EndIf.

 

        EndIf.

 

        Free Object PS.

      EndIf.

 

"-End-------------------------------------------------------------------

 

zUseVBSharpABAP.JPG

 

Here the result.

Result.JPG

 

With the library from SAPIEN you can use also actual PowerShell 3 and dotNET 4 functionalities easily inside your ABAP program.

 

Enjoy it.

 

Cheers

Stefan

Tip: How To Download An SAP Table in Excel Easily

$
0
0

Hello community,

 

the function group TXXL (Interface to Excel list viewer), in the package SGRP (Graphic ABAP Development), is an oldie - but an an goldie.

 

Here a tiny function module to export any SAP table in Excel with the FM XXL_SIMPLE_API, all you must know is the name of the table - and a where and sort condition, if you want. The execution of this FM opens Excel instance and shows the SAP table in Excel.

 

 

Function Z_GET_TABLE_AS_EXCEL.

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

*"*"Lokale Schnittstelle:

*"  IMPORTING

*"     VALUE(I_TABLENAME) TYPE  DD02L-TABNAME

*"     VALUE(I_OPTIONS) TYPE  CHAR1024 DEFAULT SPACE

*"     VALUE(I_SORT) TYPE  CHAR1024 DEFAULT SPACE

*"  EXCEPTIONS

*"      DIM_MISMATCH_DATA

*"      FILE_OPEN_ERROR

*"      FILE_WRITE_ERROR

*"      INV_WINSYS

*"      INV_XXL

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

 

   "-Variables-----------------------------------------------------------

     Data dref Type Ref To Data.

     Data tabledescr_ref Type Ref To cl_abap_tabledescr.

     Data descr_ref Type Ref To cl_abap_structdescr.

     Data comp_descr Type abap_compdescr.

 

     Field-Symbols <fs> Type Standard Table.

 

     Data t_vkey Type Table Of gxxlt_v With Header Line.

     Data t_online Type Table Of gxxlt_o.

     Data t_print Type Table Of gxxlt_p.

 

   "-Main----------------------------------------------------------------

     Create Data dref Type Standard Table Of (I_TABLENAME).

     Assign dref->* To <fs>.

 

     tabledescr_ref ?= cl_abap_typedescr=>describe_by_data( <fs> ).

     descr_ref ?= tabledescr_ref->get_table_line_type( ).

 

     Select * From (I_TABLENAME) Into Table <fs> Where (I_OPTIONS)

       Order By (I_SORT).

 

     Loop At descr_ref->components Into comp_descr.

       t_vkey-col_no = sy-tabix.

       t_vkey-col_name = comp_descr-NAME.

       Append t_vkey.

     EndLoop.

 

     Call Function 'XXL_SIMPLE_API'

       Tables

         COL_TEXT = t_vkey

         DATA = <fs>

         ONLINE_TEXT = t_online

         PRINT_TEXT = t_print

       Exceptions

         DIM_MISMATCH_DATA = 1

         FILE_OPEN_ERROR = 2

         FILE_WRITE_ERROR = 3

         INV_WINSYS = 4

         INV_XXL = 5

         Others = 6.

 

     Case sy-subrc.

       When 1. Raise DIM_MISMATCH_DATA.

       When 2. Raise FILE_OPEN_ERROR.

       When 3. Raise FILE_WRITE_ERROR.

       When 4. Raise INV_WINSYS.

       When 5. Raise INV_XXL.

     EndCase.

 

EndFunction.

 

"-End-------------------------------------------------------------------

 

Enjoy the 41 lines of code.

 

Cheers

Stefan

Tip: How To Upload CSV Files via ABAP Easily

$
0
0

Hello community,

 

files with comma separated values (CSV) are a good and easy way for exchanging data. Also you have the possibility to manipulate the data e.g. via Microsoft Access, Microsoft Excel or Open Office Calc easily. But for the last step, to upload the file in an SAP system, I can't find an easy way. So I create a class with three methods to upload a CSV file. Here a code example how to do that:

 

"-Begin-----------------------------------------------------------------
Report  Z_CSV_LOAD.  "-Variables-----------------------------------------------------------    Data CSV Type Ref To Z_CSV_IMPORT.  "-Main----------------------------------------------------------------    Delete From SFLIGHT.    Commit Work.    Create Object CSV.    CSV->Load_CSV_File( 'C:\Dummy\sflight.csv' ).    CSV->Transform_CSV_Data( 'SFLIGHT' ).    CSV->Get_CSV_Data( 'SFLIGHT' ).

"-End-------------------------------------------------------------------

 

With three lines of code you can upload the content of a CSV file into an SAP table.

 

  1. Load_CSV_File
    Loads the CSV file from the presentation server.
  2. Transform_CSV_Data
    With this method you have the possibility to manipulate the head line and the CSV data. Often it is necessary to add the field MANDT and the correct content. Also it is often necessary to correct date fields.
  3. Get_CSV_Data
    Copies the data into the SAP table. It is not necessary that the column of the CSV file must have the same position as the field in the SAP table. It is only necessary that the column and field names are equal.

 

"-Begin-----------------------------------------------------------------

Class Z_CSV_IMPORT Definition Public Final Create Public .

Public Section.

  Methods Constructor.  Methods LOAD_CSV_FILE    Importing      Value(I_FILENAME) Type String.  Methods TRANSFORM_CSV_DATA    Importing      Value(I_TABLENAME) Type String.  Methods GET_CSV_DATA    Importing      Value(I_TABLENAME) Type String.

Protected Section.

  Data G_CSV_DATA type STRINGTAB .  Data G_ERROR_FLAG type ABAP_BOOL value ABAP_FALSE.  Data G_TAB_FIELDS Type Standard Table Of String .

Private Section.

EndClass.



Class Z_CSV_IMPORT Implementation.


Method Constructor.
"-Begin-----------------------------------------------------------------

  Clear G_CSV_DATA.

"-End-------------------------------------------------------------------
EndMethod.


Method GET_CSV_DATA.
"-Begin-----------------------------------------------------------------

  "-Structures----------------------------------------------------------    Types: Begin Of l_typ_Confrontation,             IntFieldName Type String,             IntFieldPos Type i,             IntFieldTyp Type String,             CSVFieldPos Type i,             CSVFieldName Type String,           End Of l_typ_Confrontation.  "-Variables-----------------------------------------------------------    Data l_rda_data Type Ref To Data.    Data l_rda_wa Type Ref To Data.    Data l_rcl_descr_tab Type Ref To cl_abap_tabledescr.    Data l_rcl_descr_struc Type Ref To cl_abap_structdescr.    Data l_comp_descr Type abap_compdescr.    Data l_tab_content Type Standard Table Of String.    Data l_Line Type String Value ''.    Data l_tab_confrontation Type Standard Table Of l_typ_Confrontation      With Key CSVFieldPos.    Data l_FieldName Type String Value ''.    Data l_Content Type String Value ''.    Data l_Conf Type l_typ_Confrontation.    Field-Symbols  <l_Table> Type Standard Table.    Field-Symbols  <l_comp> Type Any.    Field-Symbols  <l_wa> Type Any.  "-Main----------------------------------------------------------------    If G_CSV_DATA Is Not Initial And G_ERROR_FLAG = ABAP_FALSE.      "-Reference to Table----------------------------------------------        Create Data l_rda_data Type Standard Table Of (I_TABLENAME).        Assign l_rda_data- >* To  <l_Table>.      "-Get Structure of Table------------------------------------------        l_rcl_descr_tab ?= cl_abap_typedescr= >describe_by_data(  <l_Table> ).        l_rcl_descr_struc ?= l_rcl_descr_tab- >get_table_line_type( ).      "-Define Line of Table--------------------------------------------        Create Data l_rda_wa Like Line Of  <l_Table>.        Assign l_rda_wa- >* To  <l_wa>.      "-Compare Field Names of the Table with Headline of CSV-----------      "-      "- With this step is the position of the column indifferent. It      "- is only necessary that the field of the table and the column      "- of the CSV file must have the same name.      "-      "-----------------------------------------------------------------        Loop At l_rcl_descr_struc- >components Into l_comp_descr.          l_Conf-INTFIELDNAME = l_comp_descr-NAME.          l_Conf-INTFIELDPOS = sy-tabix.          l_Conf-INTFIELDTYP = l_comp_descr-TYPE_KIND.          Loop At g_tab_fields Into l_FieldName.            l_Conf-CSVFIELDPOS = -1.            l_Conf-CSVFIELDNAME = 'UNKNOWN'.            If l_comp_descr-NAME = l_FieldName.              l_Conf-CSVFIELDNAME = l_FieldName.              l_Conf-CSVFIELDPOS = sy-tabix.              Exit.            EndIf.          EndLoop.          Append l_Conf To l_tab_confrontation.        EndLoop.        Delete l_tab_confrontation Where CSVFIELDPOS = -1.        Sort l_tab_confrontation By CSVFIELDPOS.      "-Copy Data-------------------------------------------------------        Loop At G_CSV_DATA Into l_Line From 2.          Split l_Line At ';' Into Table l_tab_content.          Loop At l_tab_content Into l_Content.            Condense l_Content.            Read Table l_tab_confrontation With Key CSVFieldPos = sy-tabix              Into l_Conf.            If sy-subrc = 0.              Assign Component l_Conf-INTFIELDNAME Of Structure  <l_wa>                To  <l_comp>.              If l_Conf-INTFIELDTYP = 'P'.                Replace All Occurrences Of '.' In l_Content With ''.                Replace ',' In l_Content With '.'.                 <l_comp> = l_Content.              Else.                 <l_comp> = l_Content.              EndIf.            EndIf.          EndLoop.          Append  <l_wa> To  <l_Table>.          Clear  <l_wa>.        EndLoop.      "-Write Data into Table-------------------------------------------        Insert (I_TABLENAME) From Table  <l_Table>.        If sy-subrc  <> 0.          G_ERROR_FLAG = ABAP_TRUE.        EndIf.    EndIf.

"-End-------------------------------------------------------------------
EndMethod.


Method LOAD_CSV_FILE.
"-Begin-----------------------------------------------------------------

  Call Function 'GUI_UPLOAD'    Exporting      FILENAME = i_FileName      FILETYPE = 'ASC'    Tables      DATA_TAB = g_csv_data    Exceptions     OTHERS = 1.   If sy-subrc  <> 0.     G_ERROR_FLAG = ABAP_TRUE.   EndIf.

"-End-------------------------------------------------------------------
EndMethod.


Method TRANSFORM_CSV_DATA.
"-Begin-----------------------------------------------------------------

  "-Variables-----------------------------------------------------------    Data l_Fld1 Type String Value ''.    Data l_Fld2 Type String Value ''.    Data l_Fld3 Type String Value ''.    Data l_FldRest Type String Value ''.    Field-Symbols  <Line> Type String.  "-Main----------------------------------------------------------------    If G_CSV_DATA Is Not Initial And G_ERROR_FLAG = ABAP_FALSE.      "-Manipulate Headline---------------------------------------------        Read Table G_CSV_DATA Index 1 Assigning  <Line>.         <Line> = 'MANDT;' &&  <Line>.      Condense  <Line> No-Gaps.      Split  <Line> At ';' Into Table g_tab_fields.    EndIf.    "-Transformation----------------------------------------------------      Loop At G_CSV_DATA From 2 Assigning  <Line>.         <Line> = sy-mandt && ';' &&  <Line>.      EndLoop.

"-End-------------------------------------------------------------------
EndMethod.

EndClass.

"-End-------------------------------------------------------------------

 

Enjoy it.

 

Cheers

Stefan

Viewing all 63 articles
Browse latest View live