Shared Top Border

Enterprise Resource
Planning Portal

 

Advertise | Founder BLOG

ERPGenie.COM ABAP Tips and Tricks Database

THE ultimate
ERP website

 

Forums | Vote for us |

Google    Other Search Options

Login

Login to view more content!!!





Lost Password?
No account yet? Register

Registered Access

Poll

What area of ABAP are you interested in?
 
Home arrow Tips and Tricks arrow Connectors / BAPIs arrow Calling An External Program From SAP
Calling An External Program From SAP PDF Print E-mail
User Rating: / 0
PoorBest 
Written by Rich   
Tuesday, 15 May 2007

Calling An External Program From SAP.

Operating system programs and other application programs can be called from SAP in one of four ways.

The first two methods depend on the location of the application program – whether it resides on the local PC, or the application server. Both are easy to implement. The third way, using ABAP objects relies on the application being called being an OLE server. The fourth I regard as a kind of back door....

An OLE server uses object technology for sharing information and services across process and machine boundaries.

 

Running An Application On The Presentation Server Or Local PC.

A program can be run on the local PC by using function modules ‘WS_EXECUTE’ (for versions < 4.6c) or ‘GUI_EXEC’ for versions of 4.6c or greater:

Code:
Form Check_Directory using pu_outdir.
*
* Check that the directory exists and if it doesn't build it up.
*
Data: Begin of t_path occurs 0,
directory(30) type c,
End of t_path,
*
begin of t_command occurs 0,
cline(72) type c,
End Of t_command,

w_path like rlgrap-filename,
w_dir_exists type i.
*
Call Function 'WS_QUERY'
Exporting FileName = pu_outdir
Query = 'DE'
Importing Return = w_dir_exists
Exceptions inv_query = 1
no_batch = 2
Frontend_Error = 3
Others = 4.
If w_dir_exists = 0.
*
* Oh Well. Start at the bottom and work down the tree.
*
Split pu_outdir at '\' into table t_path.
Zap t_command.
Move '@echo off' to t_command-cline.
Append t_command.
Loop at t_path.
If sy-tabix = 1.
Move t_path-directory to w_path.
Else.
Concatenate w_path '\' t_path-directory into w_path.
Translate w_path using '< > '.
Condense w_path no-gaps.
Translate w_path to upper case.
Call Function 'WS_QUERY'
Exporting FileName = w_path
Query = 'DE'
Importing Return = w_dir_exists
Exceptions inv_query = 1
no_batch = 2
Frontend_Error = 3
Others = 4.
If w_dir_exists = 0.
Concatenate 'mkdir' w_path
into t_command-cline
separated by ' '.
Append t_command.
EndIf.
EndIf.
EndLoop.
Move 'Exit' to t_command-cline.
Append t_command.
CALL FUNCTION 'WS_DOWNLOAD'
EXPORTING
FILENAME = 'c:\mdir.bat'
FILETYPE = 'ASC'
TABLES
DATA_TAB = t_command
EXCEPTIONS
FILE_OPEN_ERROR = 1
FILE_WRITE_ERROR = 2
INVALID_FILESIZE = 3
INVALID_TABLE_WIDTH = 4
INVALID_TYPE = 5
NO_BATCH = 6
UNKNOWN_ERROR = 7
GUI_REFUSE_FILETRANSFER = 8
OTHERS = 9.
Call Function 'WS_EXECUTE'
Exporting
Program = 'c:\mdir.bat'
Exceptions
FRONTEND_ERROR = 1
NO_BATCH = 2
PROG_NOT_FOUND = 3
ILLEGAL_OPTION = 4
GUI_REFUSE_EXECUTE = 5
OTHERS = 6.
Wait until True = False up to 2 seconds.
EndIf.
EndForm.
Or, using GUI_EXEC:

Code:
Call Function 'GUI_EXEC'
Exporting
Command = W_Batfile.
If sy-subrc <> 0.
Move c_could_not_execute to pc_status.
Else.
*
* Get the results back....
*
Zap t_batch.
Move w_txtfile to string_filename.
*
* If the file is being loaded from a floppy, there is a
* timing problem where this code is executed too quickly.
*
* Loop until we get some data or we've tried long enough
*
Do.
In either case no results are passed back to the calling ABAP. The program is executed. Full stop.

So How Do I Know When The Programs Finished.

In certain cases, the ABAP program can be dependant on the results from the program that has just been executed external to SAP. Therefore you need to be able to tell when a programs finished or not.

In object oriented languages such as VB, you can test for the application ending by trying to activate it’s window. If the window can be activated it’s still there, so go to sleep for a little while and try and activate it again. When you can’t activate it the program has finished.

It’s just as easy in ABAP, but without using any object technology.

What you do is to write a small batch file which essentially consists of:

Code:
@echo off
echo *** > c:\run.flg
Myprog
Del c:\run.flg
This batch program creates a file called run.flg which exists for the duration of the execution of the program Myprog. The file is then deleted when the program has completed.

Within your ABAP you would kick of the execution of the batch file and wait for the file Run.Flg to disappear. Due to the speed of processing you may have to code to wait for the file to appear and then wait for it to disappear.

Ok. It’s done. What About The Results ?

You can pick up the results of the local execution of the program by (as long as the program and O/S have the capability) redirecting STD Out to a file. The code snippet below was modified from a program pre 3.1. It has however had WS_ functions changed to GUI_ functions. All the functionality is now inherent in SAP. This code uses DIR to get a files statistics back by redirecting STD out to a file:

Code:
*
* Build up the file names...
*
Concatenate c_filenme '.' c_batext into w_batfile.
Concatenate c_filenme '.' c_txtext into w_txtfile.
*
* And the batch file...
*
Concatenate 'dir' pu_filename '>' w_txtfile
into w_command
separated by ' '.
Zap t_batch.
Move '@echo off' to t_batch-line.
Append t_batch.
Move w_command to t_batch-line.
Append t_batch.
Move 'Exit' to t_batch-line.
Append t_batch.
*
Move w_batfile to string_filename.
Call Function 'GUI_EXEC'
Exporting
Command = W_Batfile.
If sy-subrc <> 0.
Move c_could_not_execute to pc_status.
Else.
*
* Get the results back....
*
Zap t_batch.
Move w_txtfile to string_filename.
*
* If the file is being loaded from a floppy, there is a
* timing problem where this code is executed too quickly.
*
* Loop until we get some data or we've tried long enough
*
Do.
Call Function 'GUI_UPLOAD'
Exporting
Filename = string_filename
Filetype = 'ASC'
Tables
Data_Tab = t_batch
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.
*
* Anything in the batch listing ?
*
Describe table t_batch lines w_lines.
If w_lines <> 0.
Exit.
EndIf.
*
* Exit if we've tried 10 times.
*
If sy-index > 10.
Move 1 to sy-subrc.
Exit.
EndIf.
EndDo.
Move w_batfile to rlgrap_filename.
Call Function 'GUI_DELETE_FILE'
Exporting
File_Name = rlgrap_filename
Exceptions
Failed = 1
Others = 2.
Running Programs On The Application Server.

This is a little more complicated than running a program on the local PC as SAP is stricter in what it allows you to run on an Application server.

There are two transactions and a function module that we are interested in. These are:

SM69 – Maintain External Operating System Commands
SM49 – Execute External Operating System Commands
SXPG_COMMAND_EXECUTE – Run a command programmatically on the application server.

Maintaining External Commands.

External commands within SAP are given an arbitrary name by which they are referenced when you wish to use them. Alongside the command is the operating system that the command is for.

These two values allow the same command to be defined for more than one operating system. The only difference being the actual command line parameters themselves.

The screen shot below demonstrates this very well:



Note that there are 4 entries for the command ‘RRR_ROUTER_START’ – one for OS/400 one for SunOs, one for Unix and one for NT. The difference is in the the OS command.

So what does this mean ?? It means that the command effectively becomes operating system independent, and an ABAP program written using commands defined in SM69 can be run across numerous operating systems.

Function Module SXPG_COMMAND_EXECUTE

This function allows a programmer to run a command from within an ABAP program. The command usage is like this:

Code:
*Eject
***********************************************************************
*
* Procedure: Get_Server_File
*
* Purpose: Gets File Time and size details for server file
*
* Entry: File name to get details for
*
* Exit: File Create Date
* File modification time,
* File Size
* Status: Ok
* File Not Found
* Could not execute
*
* Called By: Perform Get_Server_file using w_filename
* changing w_date
* w_file_time
* w_file_length
* w_status
*
* Calls:
*
* Modification History:
*
* Date Reason Version Who
*
Form Get_Server_File using pu_filename like zfilepath-initpath
changing pc_date
pc_time
pc_size
pc_status type status_code.
*
Constants: c_Unix_Months(36) type c value
'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.
Data: Begin of t_splits occurs 0,
line(132) type c,
End of t_splits,
t_exec_protocol like btcxpm occurs 0 with header line,
w_lines type i,
w_month type i,
w_nummnth(2) type n,
w_filename like sxpgcolist-Parameters.

*
Move pu_filename to w_filename.
Call Function 'SXPG_COMMAND_EXECUTE'
Exporting
Commandname = 'LIST_DB2DUMP'
Additional_Parameters = w_filename
Operatingsystem = 'UNIX'
Stdout = 'X'
Stderr = 'X'
Terminationwait = 'X'
Tables
Exec_Protocol = t_exec_protocol
Exceptions
No_Permission = 1
Command_Not_Found = 2
Parameters_Too_Long = 3
Security_Risk = 4
Wrong_Check_Call_Interface = 5
Program_Start_Error = 6
Program_Termination_Error = 7
X_Error = 8
Parameter_Expected = 9
Too_Many_Parameters = 10
Illegal_Command = 11
Wrong_Asynchronous_Parameters = 12
Cant_Enq_Tbtco_Entry = 13
Jobcount_Generation_Error = 14
Others = 15.
If sy-subrc <> 0.
Move c_could_not_execute to pc_status.
Else.
*
* There should be only one line of text returned.
*
Describe table t_exec_protocol lines w_lines.
Read Table t_exec_protocol index 1.
Condense t_exec_protocol-Message.
Split t_exec_protocol at ' ' into table t_splits.
*
What The Inbound Parameters Mean.

COMMANDNAME.

This parameter is the name of the command that you wish to run, displayed in the first column of SM69 or SM49.

ADDITIONAL_PARAMETERS.

Additional command line parameters that are provided to the command after the command name. For example, the command:

Code:
Pkzip -Par *.* test.zip
would have additional command line parameters of
Code:
-Par *.* test.zip
OPERATINGSYSTEM.

This is the operating system that you wish to execute the command for. (Remember the four different versions of the command pointed out above ?). This is an optional parameter and defaults to the actual operating system your version of SAP is running under.

TargetSystem.

An RFC targeted host system. This enables you to run the command on a remote system. Again, an optional parameter.

STDOUT and STDERR.

These flags allow you to redirect the STDOUT and STDERR pipes. Optional parameters that default to using STDOUT and STDERR.

TERMINATIONWAIT.

What it says – waits for the program to complete before returning to ABAP. An optional parameter that defaults to True. (ie SAP waits)

TRACE.

An optional Boolean. Turn this on and an RFC trace file is generated. This defaults to false.

What The Outbound Parameters Mean.

STATUS.


This is the start or end status of the external command. God knows what the Start status of a program is all about. Used during an RFC Trace.

EXITCODE.
The RC code of the external program at termination or end.

EXEC_PROTOCOL.
The contents of STDOUT if you’re a Unix devotee, or CON: if you’re from the other side of the pond.

This table contains 2 fields. A length field specifying the length of the line displayed by the external program, and the line itself that was displayed…….

You can then make use of the EXEC_PROTOCOL table like so:

Code:
*
* There should be only one line of text returned.
*
Describe table t_exec_protocol lines w_lines.
Read Table t_exec_protocol index 1.
Condense t_exec_protocol-Message.
Split t_exec_protocol at ' ' into table t_splits.
*
* ls -l format:
*
* Size = 6
* Day = 7
* Month = 8
* Time = 9
* File name = 10.
*
Read Table t_splits index 10.
If t_splits-line = w_filename.
*
* Size
*
Read Table t_splits index 6.
Move t_splits-line to pc_size.
*
* Date
*
Read Table t_splits index 7.
Move t_splits-line to pc_date.
Read Table t_splits index 8.
Translate t_splits-line to upper case.
Search c_Unix_Months for t_splits-line.
If sy-subrc = 0.
Compute w_month = 1 + ( sy-fdpos / 3 ).
Move w_month to w_nummnth.
*
* Year - assume current year
*
Concatenate pc_date w_nummnth sy-datum+2(2)
into pc_date
separated by '/'.
*
* Time
*
Read Table t_splits index 9.
Move t_splits-line to pc_time.
EndIf.
Else.
Move c_file_not_found to pc_status.
EndIf.
EndIf.
OLE.

OLE is Microsofts proprietary technology for communication across process and machine boundaries. In english this means that OLE enabled programs can talk to each other regardless of where they are on a system.

This is achieved by exposing the various methods used by the application via an interface that can be accessed by external programs. This interface is based around object technology and is available in the majority of Microsoft applications from Excel to Word, Project, Outlook and so on.

How do you access these interfaces ?

By using ABAP objects and creating an object of the target application, you can then call the various methods or access the various properties within the application:

Code:
*Eject
**********************************************************************
*
* Procedure: Get_Single_Border
*
* Purpose: Get single border for a range of cells
*
* Entry: Work Sheet
* Entry: Cell Range to Get border for
* Entry: Border to Get (Excel Values)
*
* Exit: Border type (Excel Values)
*
* Called By:
* '
*
* Calls:
*
* Modification History:
*
Form Get_Single_Border Using pu_sheet Type Ole2_Object
pu_range Type XlRangeAddress
pu_border Type XlBorder
Changing pc_linestyle Type XlLineStyle.
*
Data: Range type Ole2_Object,
Borders type Ole2_Object.
*
Call Method of pu_Sheet 'Range' = Range Exporting #1 = pu_range.
Call Method of Range 'Borders' = Borders
Exporting #1 = pu_border.
Get Property of Borders: 'Linestyle' = pc_Linestyle.
*
Free object Borders.
Free object Range.
EndForm.

Open Dataset.

The OPEN DATASET command can also be used to run external programs

Have a look at the code below:

Code:
*
* Are we using a filter ?
*
If pu_filter = ''.
Open Dataset pu_dataset
for input
in text mode.
Else.
Open Dataset pu_dataset
for input
in text mode
filter pu_filter.
EndIf.
This code is part of a set of generic subroutines that I use for handling interfaces. There are two seemingly similar Open Dataset statements. The second one uses the Filter clause.

What does this do ?

The filter clause can be used to pass the file contents through an external program to perform some manipulation on the data. The program forms part of a pipe with the SAP being the recipient at the end.

To take a simple example, the following Open Dataset statement will open the named file, pass the file through a program called Fileport, translate the file from EBCDIC to ASCII (including packed fields) using the specified script and then passes the translated data onto SAP.


Code:
Open Dataset p_inf for input
in binary mode
filter '/gldata/scripts/fdr.sh'.
By changing the parameter of the filter clause, external OS programs can be run.

Related Items:

Last Updated ( Tuesday, 15 May 2007 )
 
< Prev   Next >

Google Search

Statistics

Contribution Activity
Utilities: 38
Tips and Tricks: 332
Sample Code: 164
Total Contributions: 548

Member Activity
Members: 6081 since 2/1/2007!
New: 7 since yesterday!
Visitors: 964833
We have 2 guests online

Newest Members

Welcome our newest members:

Google Ads

Shared Bottom Border

Contact Us | Polls | Add URL | Contribute | Privacy | Terms | Feedback

Discussion Forum | BLOG | Consultants: Post your resume | Companies: Advertise on ERPGenie.COM | Post Job
Financials Consultant | Consultant Review | Gallia Consulting | Supply Chain Project | SAP Financials Forum
GenieHoldings.COM, Inc. | Genie Press | WorkflowGenie | ESAGenie | ERPTopSites | ABAP Tips and Tricks | SAP Solutions Database

EDIGenie | Searching Survivor