Professional Documents
Culture Documents
1 2 3
About this document ......................................................................................... 4 About Connect for SAP................................................................................... 5 Architectural overview ....................................................................................... 6
3.1 RFC function architecture .......................................................................................................................... 7 3.1.1 Data representation ............................................................................................................................... 7 3.1.2 Data mapping ......................................................................................................................................... 8 3.1.3 Early and late function binding .......................................................................................................... 10 3.2 Client applications .....................................................................................................................................12 3.2.1 Using connection aliases ................................................................................................................... 13 3.2.2 Features of transactional calls ........................................................................................................... 13 3.3 Server applications ....................................................................................................................................14 3.3.1 Specifying registration parameters................................................................................................... 15 3.3.2 Features of transactional calls ........................................................................................................... 15
Installation ....................................................................................................... 16
4.1 4.2 System requirements ................................................................................................................................ 16 Installing librfc32.dll ................................................................................................................................... 16 4.2.1 Short path..............................................................................................................................................16 4.2.2 Full path ................................................................................................................................................. 17 4.3 Additional requirements ........................................................................................................................... 18 4.4 Installing into CodeGear Delphi or C++ Builder .................................................................................... 19 4.4.1 Building Connect for SAP binaries ................................................................................................. 19 4.4.2 Installing components......................................................................................................................... 20 4.5 Installing into FPC / Lazarus..................................................................................................................... 22 4.5.1 Limitation and known issues ............................................................................................................. 22 4.5.2 Installing components......................................................................................................................... 22
5 6 7 8
HowTo call ABAP function with Connect for SAP ........................................ 23 HowTo work with Connect for SAP components ......................................... 25 How to write a Server function with Connect for SAP.................................. 28 HowTo write a Server function with Connect for SAP as NT service .......... 29
Appendix A Data type and mapping .................................................................... 31 Appendix B Early and late function binding......................................................... 33 Appendix C Defining server parameters ............................................................. 34 Appendix D Transaction management in Connect for SAP server application 35
Getting Started Guide - Page 2 of 51 2000-2009 gs-soft AG, Switzerland
Appendix E Connect for SAP component list ................................................... 38 Appendix F Listing of Connect for SAP client application ................................. 40 Appendix G Listing of Connect for SAP server as console application............ 42 Appendix H Listing of Connect for SAP server as NT service.......................... 48
You can find in this guide general overview of Connect for SAP software and its possible applications. This document helps to understand main architectural concepts of Connect for SAP work: information on RFC function architecture, different types of data mapping and function binding. You will also learn general concepts of creating client and server applications based on Connect for SAP . The guide provides the developer with necessary installation instructions and gives a brief overview of components installed. Here are some practical suggestions How to . They give process overviews of creating simple both client and server applications and contains some recommendations how to use Connect for SAP components during design time as well as at run time.
If you need to get any additional information not mentioned in this guide do not hesitate to contact us:
https://www.gs-soft.com/confluence/display/SAPx sapx@gs-soft.com
3 Architectural overview
On Figure 1 you can see the way Delphi applications can interact with SAP system through Connect for SAP . Connect for SAP can be used both in client and server applications. In the first case, when the developer wants to call an ABAP function he has to use Connect for SAP object methods and properties. Connect for SAP packs all the necessary data and transfers the call to the RFC library. In such a way the client request is sent to the SAP system. On receiving the request the SAP application server processes it and returns the result. Connect for SAP gets resulting data from the RFC library and the developer can have access to it.
RFC library
Client
SAP gateway Call an external function
RFC library
Server
Figure 1: Interaction of a SAP system with Delphi application based on Connect for SAP
In the second case Connect for SAP server application is constantly waiting for SAP system client
request. When the request occurs Connect for SAP receives and processes it. Connect for SAP also undertakes to send the result to the SAP system in correct format.
SAPx
RFC data types
RFC function
Export parameters
Tables
Import parameters
How Connect for SAP will do that is controlled by alias parameters TSAPxRFCAliasGS.DataFormat.IntType and TSAPxRFCAliasGS.DataFormat.FloatType. By default they have values itAutoDetect and ftAutoDetect. The alias parameter TSAPxRFCAliasGS.DataFormat.BytesPerChar specifies the server side character data representation bytes per char. By default it has value bcAutoDetect. Using default values, Connect for SAP will automatically detect server side data representation. In some special cases, you can decide to force Connect for SAP to expect some specified data representation. It is not recommended, although.
3.1.2.1 Simple data types Figure 3 shows concepts of simple RFC data type mapping (you can find more details on data mapping
procedure in Appendix A). If a data type has ambiguous mapping, the developer can definitely indicate the target Delphi data type. Otherwise, Connect for SAP maps this data type to the most appropriate Delphi data type.
Parameter
Connect for SAP includes TSAPxRFCvParamsGS component derived from TDataSet that, on the one hand, offers clear and easy interface for Delphi developers and, on the other hand, works with RFC library using RFC data types and formats. TSAPxRFCvParamsGS represents each function simple parameter by single field, and structured parameter by one top level field with subfields. You can choose which parameter types (input, output or both) TSAPxRFCvParamsGS includes by specifying ParamKinds.
Connect for SAP includes TSAPxRFCvTableGS component derived from TDataSet that, on the one hand, offers clear and easy interface for Delphi developers and, on the other hand, works with RFC library using RFC data types and formats. TSAPxRFCvTableGS corresponds to one table parameter with TableName name.
Early binding has a higher productivity as it excludes application roundtrip to the SAP system for metadata retrieval;
Early binding allows to use Code Insight feature and find some mistakes during compile process; Early binding is sensitive to client and server Unicode mode, due to differences in structure layouts for different Unicode modes;
The developer can choose one binding mode or another depending on the specific task (you can find more details on quantitative indicators for early and late binding in Appendix B).
RFC
1 n
TSAPxRFCvClientConnectionGS
1 n
TSAPxRFCvFunctionGS
1 n
TSAPxRFCvServerTableGS
1 n
TSAPxRFCvParamsGS
1
Delphi application
n
TSAPxRFCvTableGS
SAPx
TDataSource
TDataSource
TDataSource
property represents output parameter collection, the InParams input ones, the Table table ones. These property are not accessible at design-time. The developer can use TSAPxRFCvParamsGS and TSAPxRFCvTableGS components to operate with a TSAPxRFCvFunctionGS function parameters and tables. Set Func property to a function component. Use TSAPxRFCvParamsGS.ParamKinds to specify parameter types (input, output or both) to represent. Use TSAPxRFCvTableGS.TableName to specify table parameter to represent. The components TSAPxRFCvParamsGS, TSAPxRFCvTableGS, and TSAPxRFCvServerTableGS inherited from TDataSet can be linked with any data aware controls. To build a client application you can use components as well as objects encapsulated into these components, eg RFCFunction property of TSAPxRFCvFunctionGS.
1 1
SAPxRFCServerApplication
1 n
TSAPxRFCvServerConnectionGS
1 n
TSAPxRFCvServerFunctionGS
And the SAPxRFCServerApplication is a singleton, controlling Connect for SAP server application life cycle. All TSAPxRFCvServerConnectionGS and TSAPxRFCvServerFunctionGS objects must be created and setup before calling SAPxRFCServerApplication.Start. The method creates thread for each server connection. Then each thread registers its server connection at gateway, installs transaction control and installs all associated with this connection custom functions. Now the Connect for SAP server application is able to handle requests from external SAP systems. The SAPxRFCServerApplication.Shutdown method stops the Connect for SAP server application. Server applications as well as client ones can be built on both Connect for SAP components and objects encapsulated into these components.
4 Installation
4.1 System requirements
Before installing Connect for SAP ensure that: SAP RFC non-Unicode library version at least 4.6 is installed on your PC - librfc32.dll. It is required for pre-2009 Delphi version tools. SAP RFC Unicode library version at least 4.6 is installed on your PC - librfc32u.dll. It is required for Delphi 2009 and higher tools.
Notice. SAP RFC library may be installed as part of SAPgui installation. Notice. SAP RFC library from SAP GUI v 6.x has a bug each unload of librfc32.dll will result memory loss around 6 Mb. Notice. UTF8 character data is supported properly by SAP RFC library from SAP GUI v 6.x or higher.
SAP R/3 system you want to work with is at least Release 2.1. CodeGear Delphi 5 / 6 / 7 / 2005 / 2006 / 2009 / 2010 or CodeGear C++Builder 5 / 6 / 2006 / 2007 / 2009 / 2010 is installed on your PC.
Notice. Only Delphi 2009 and higher offers full Unicode support.
To install librfc32.dll copy only librfc32.dll file. To install librfc32u.dll copy files: librfc32u.dll icudt30.dll icuin30.dll icuuc30.dll libsapu16vc71.dll libsapucum.dll
o o
From command prompt execute SAPCAR xvf <downloaded SAR file path> Copy required files to c:\windows\system32 bin\librfc32.dll
Read SAP Note 684106 and optionally : o o download and setup R3DLLINS.exe for SAP release 6.40 and 7.00 download and setup vcredist_<platform>.exe (32-bit) for SAP release 4.6D EX2, 6.40 EX2, 7.10 from http://www.microsoft.com/downloads/details.aspx?FamilyID=200B2FD9AE1A-4A14-984D-389C36F85647&displaylang=en
Table 1: SAP R/3 function modules, used by Connect for SAP software Function module RFC_GET_FUNCTION_INTERFACE Used for To dynamically obtain
function module interface from nonUnicode servers. RFC_GET_FUNCTION_INTERFACE_US To dynamically obtain function module interface from Unicode servers. RFC_GET_STRUCTURE_DEFINITION To dynamically obtain record data type layout from non-Unicode servers. RFC_GET_UNICODE_STRUCTURE To dynamically obtain record data type layout from Unicode servers. TSAPxRFCFunctionGS, TSAPxRFCvFunctionGS, TSAPxRFCTableGS, TSAPxRFCvTableGS TSAPxRFCFunctionGS, TSAPxRFCvFunctionGS, TSAPxRFCTableGS, TSAPxRFCvTableGS TSAPxRFCFunctionGS, TSAPxRFCvFunctionGS
Used by TSAPxRFCFunctionGS,
TSAPxRFCvFunctionGS
RFC_SYSTEM_INFO
TSAPxRFCClientConnectionGS, TSAPxRFCvClientConnectionGS
RFC_READ_TABLE
RFC_FUNCTION_SEARCH
RFC_GROUP_SEARCH
Tool Delphi 5
Delphi 6 Delphi 7 Delphi 2005, Win32 platform Delphi 2005, .Net platform Delphi 2006 / C++ Builder 2006, Win32 platform
compileD2006Net.bat
compileD2007Win32.bat
Delphi 2007, .Net platform Delphi 2009 / C++ Builder 2009 Delphi 2010 / C++ Builder 2010 C++ Builder 5* C++ Builder 6
*Note: Generally, we do not support C++ Builder 5 anymore. If you want to work with Connect for SAP and C++ Builder 5; please contact us first.
All BAT files will automatically detect is the tool installed or not and where it is installed. And if the tool is not installed you will get an error message about that. The compiled binary files will be put into <SAPx>\Lib\<Tool> folder. For example, Delphi 2010 files will be put into <SAPx>\Lib\Delphi2010.
Tool Delphi 5
Delphi 6 Delphi 7 Delphi 2005 Win32 platform Delphi / C++ Builder 2006 Win32 platform
gsSAPxRFCD2007.dpk
Delphi 2005.Net platform Delphi 2006 .Net platform Delphi 2007 .Net platform Delphi / C++ Builder 2009 Delphi / C++ Builder 2010 C++ Builder 5* C++ Builder 6
*Note: Generally, we do not support C++ Builder 5 anymore. If you want to work with Connect for SAP and C++ Builder 5; please contact us first.
3. Click on Compile button in Package window and then press Install button. The new components should appear in the Delphi Component Palette (Figure 7).
Figure 7: Delphi component palette after successful installation of Connect for SAP .
You can find list of all Connect for SAP components in Appendix E.
Figure 8: The main form of the application calling ABAP function module RFC_GET_NAMETAB
3. Set the key components properties according to Table 4.
Table 4: Key components properties and their values
GetNameTab
TSAPxRFCvFunctionGS
4. Implement the event handlers: btnConnectClick, btnDisconnectClick and btnExecuteClick as it is shown on Listing 1.
Listing 1: Implementation of event handlers
procedure TfrmMain.btnExecuteClick(Sender: TObject); begin with GetNameTab do begin Prepared := True; InParams.ParameterByName('TABNAME').AsString := edtTableName.Text; ExecFunction; edtStamp.Text := OutParams.ParameterByName('HEADER').SubFields.FieldByName('CRSTAMP').AsString; end; end; { --------------------------------------------------------------------------- } procedure TfrmMain.btnConnectClick(Sender: TObject); begin ClientConnection.Connected := True; end; { --------------------------------------------------------------------------- } procedure TfrmMain.btnDisconnectClick(Sender: TObject); begin ClientConnection.Connected := False; end;
5. Run the application. 6. Press Connect button and log in the SAP system. 7. Specify the target table name and press Execute button. The final result is shown on Figure 9
Figure 10: The main application form with Connect for SAP client components located on it.
3. Now you have access to function parameters and tables using data aware controls such as TDBGrid, TDBEdit, TDBLabel and others. To make it possible key components properties should be maintained in accordance with Table 5.
Table 5: Maintaining key Connect for SAP components properties for work using data aware controls. Component name ClientConnection Class name TSAPxRFCvClientConnectionGS Property AliasFileName = <Full name of alias file>
AliasName = <Any valid alias>
GetFuncData
TSAPxRFCvFunctionGS
PInput
TSAPxRFCvParamsGS
POutput
TSAPxRFCvParamsGS
Table
TSAPxRFCvTableGS
DataSet = PInput DataSet = Poutput DataSet = Table DataSource = dsrInput DataField = I_FUNC_LOC
DataSource = dsrOutput DataSource = dsrTables OnClick = btnConnectClick OnClick = btnDisconnectClick OnClick = btnPrepareClick OnClick = btnExecuteClick
4. Run the application and connect to the SAP system by clicking on Connect button. When clicking on Prepare button you prepare the GetFuncData function to access to its parameter list and tables (Listing 2 shows implementation of btnConnectClick and btnPrepareClick event handlers). When the function is prepared, its parameters and tables will be displayed in DB grids.
Listing 2: Implementation of btnConnectClick and btnPrepareClick event handlers
procedure TfrmMain.btnConnectClick(Sender: TObject); begin ClientConnection.Connected := True; end; procedure TfrmMain.btnPrepareClick(Sender: TObject); begin GetFuncData.Prepare; PInput.Active := True; POutput.Active := True; Table.Active := True; end;
5. Enter I_FUNC_LOC input function parameter value use edtFuncLoc control. Then press the Execute button. Figure 11 shows the results of executing RFC_GET_FUNC_LOC_DATA ABAP function module.
3. Implement InitConnection and InitFunction procedures to initialize server connection (FSConnection1) and server function (FSFunction1). The developer can specify server connection parameters either in program code, for example in InitConnection procedure, or use capability of Connect for SAP to take these parameters out of command line. In our example we are going to use the second way, therefore the server program should be launched with the following command line:
Table 6: Maintaining of key Connect for SAP components work properties using data aware controls. Component (object) name
FSConnection1
Class name
TSAPxRFCvServerConnectionGS
Property
CommandLine.IniDest = DEST1 OnCheckTID = HandleCheckTID OnCommit = HandleCommit OnConfirm = HandleConfirm OnRollback = HandleRollback
FSConnection2
TSAPxRFCvServerConnectionGS
CommandLine.IniDest = DEST2 OnCheckTID = HandleCheckTID OnCommit = HandleCommit OnConfirm = HandleConfirm OnRollback = HandleRollback
FSFunction11
TSAPxRFCvServerFunctionGS
FSFunction12
TSAPxRFCvServerFunctionGS
FSFunction21
TSAPxRFCvServerFunctionGS
FSFunction22
TSAPxRFCvServerFunctionGS
4. Define destinations DEST1 and DEST2 in saprfc.ini file. 5. Implement handlers for the following TServices events: OnStart, OnStop, OnPause and OnContinue. These handlers are quite simple (see Listing 3).
Listing 3: Implementation of event handlers controlling Connect for SAP application server.
procedure TSAPxRFCServer.ServiceStart(Sender: TService; var Started: Boolean); begin SAPxRFCServerApplication.Start; Started := not SAPxRFCServerApplication.Terminated; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceStop(Sender: TService; var Stopped: Boolean); begin SAPxRFCServerApplication.Shutdown; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServicePause(Sender: TService; var Paused: Boolean); begin SAPxRFCServerApplication.Pause; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceContinue(Sender: TService; var Continued: Boolean); begin SAPxRFCServerApplication.Resume; end;
6. Include all server function actions into HandleExecute event handler. 7. If the server has to support transactions, it is necessary to implement event handlers such as HandleCheckTID, HandleCommit, HandleRollback and HandleConfirm.
Delphi 2009 and higher: ftWideString (size <= 8192) ftWideMemo (size > 8192) ftSmallInt (size <= 4) ftInteger (size <= 9) ftLargeInt (size > 9) ftVarBytes (size <= 8192) ftBlob (size > 8192) ftFloat
dtNumGS
Int64
dtByteGS
RawByteString
dtBCDGS
Integer Int64 Currency Double String Integer ShortInt SmallInt Double TDateTime TDateTime UnicodeString
ftInteger ftSmallInt ftSmallInt ftFloat ftDate ftTime ftWideString (size <= 8192) ftWideMemo (size > 8192) ftWideMemo ftBlob Not supported
Conversion of dtStructureGS data type to Delphi field type RFC data type Delphi data type (see gsSAPxRFCStdObj) dtStructureGS
TSAPxRFCParameterGS 11 TSAPxRFCFieldsListGS 1N TSAPxRFCFieldGS
Converting RFC table parameters to Delphi data type RFC data type Delphi data type (see gsSAPxRFCStdObj) RFC table parameter TSAPxRFCTableGS Delphi field type (see gsSAPxRFCvClient) TSAPxRFCvTableGS
Statistics of function execution for different binding modes Binding mode Single function call Sequential function calls (100 times) Early binding ~ 0.161 sec ~14.191 sec Late binding ~ 0.46 sec ~14.882 sec
Function transfer phase is initiated in ABAP program and is divided into three parts: T1 OnCheckTID event handler has to check TID status, update it and return corresponding check result T2 OnExecute event handler should contain the required RFC server function implementation T3 (T3) OnCommit (OnRollback) event handler updates TID status and commits (rolls back) database (non-SAP database) transaction(s) Confirmation phase starts as soon as RFC library informs SAP system about successful T3 (not T3). TSAPxRFCvServerConnectionGS component receives confirmation of the current transaction immediately. In OnConfirm event handler the developer should update TID status (delete). After this phase is over current transaction is successfully completed on both sides. A simple example of transaction management is shown in Listing 7: Transactional management.
TSAPxRFCvServerConnectionGS
F1
T1
OnCheckTID // Check and update TID
T2
RFC library
T3 T3'
OnCommit // Update TID and commit DB if necessary OnRollback // Update TID and rollback DB if necessary
F2
T4
OnConfirm // Update (delete) TID
procedure TxServer.HandleRollback(Sender: TObject; const ATID: String); begin RollbackDB(ATID); // rolling non-SAP database transaction back end;
Client components
Connect for SAP components used in client programs with access to SAP application server RFC functions are called client components. Using Connect for SAP Explorer Connect for SAP Explorer is a specially designed tool that offers the developer SAP system dictionary information on RFC objects. For more detailed information about this tool, please, refer to Connect for SAP Explorer User Guide. TSAPxRFCvClientConnectionGS
The TSAPxRFCvClientConnectionGS is the main client component. It connects to the specified SAP system and supports data exchange between a client program and the SAP system. TSAPxRFCvFunctionGS
The TSAPxRFCvFunctionGS component allows execution of an ABAP RFC function module. It contains sets of input and output parameters and table lists that are used for access to the function module data. TSAPxRFCvTableGS
The TSAPxRFCvTableGS is a TDataSet component descendant; that is why it can be used by data aware controls. It allows access to the specified table from the TSAPxRFCvFunctionGS table list. TSAPxRFCvServerTableGS
The TSAPxRFCvServerTableGS is also a TDataSet component descendant; that is why it can be used by data aware controls as well. It allows to get dictionary information on specified SAP DB table (fields description) and data stored within this table. TSAPxRFCvParamsGS
The TSAPxRFCvParamsGS corresponds to a set of function parameters. It allows to edit and display a set of parameters using data aware controls.
Server components
The set of Connect for SAP server components allows implementation of non-SAP server programs that enhance SAP system functionality. TSAPxRFCvServerConnectionGS
The TSAPxRFCvServerConnectionGS is the main component for non-SAP server programs. It registers all supported server functions on SAP gateway; processes client requests and dispatches them. TSAPxRFCvServerFunctionGS
The TSAPxRFCvServerFunctionGS component allows implementation of a certain part of server functionality. Every TSAPxRFCvServerFunctionGS component belongs to the specified server connection and can receive client requests only from it.
GrdTable: TDBGrid;
btnPrepare: TButton; lblFieldName: TLabel; procedure btnExecuteClick(Sender: TObject); procedure btnConnectClick(Sender: TObject); procedure btnDisconnectClick(Sender: TObject); procedure btnPrepareClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); end; var frmMain: TfrmMain; implementation {$R *.dfm} { --------------------------------------------------------------------------- } procedure TfrmMain.btnExecuteClick(Sender: TObject); begin GetFuncData.ExecFunction; end; { --------------------------------------------------------------------------- } procedure TfrmMain.btnConnectClick(Sender: TObject); begin ClientConnection.Connected := True; end;
{ --------------------------------------------------------------------------- } procedure TfrmMain.btnDisconnectClick(Sender: TObject); begin ClientConnection.Connected := False; end; { --------------------------------------------------------------------------- } procedure TfrmMain.btnPrepareClick(Sender: TObject); begin GetFuncData.Prepare; PInput.Active := True; POutput.Active := True; Table.Active := True; end; { --------------------------------------------------------------------------- } procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction); begin ClientConnection.Connected := False; end; end.
function GetTABNAME: String; procedure SetFLAG(const AValue: String); function GetFLAG: String; procedure InstallStructure; public constructor Create; override; property TABNAME: String read GetTABNAME write SetTABNAME; property FLAG: String read GetFLAG write SetFLAG; end; {-----------------------------------------------------------------------------} { TSAPxRFCZMY_SERVER_FUNCTIONFuncGS } {-----------------------------------------------------------------------------} TSAPxRFCZMY_SERVER_FUNCTIONFuncGS = class(TSAPxRFCServerFunctionGS) private function GetASTAT: TSAPxRFCZMY_STRUCTUREStrGS; function GetDATA: TSAPxRFCABAPTEXTTableGS; function GetFTABNAME: string; procedure SetFTABNAME(Value: string); public constructor Create; override; property ASTAT: TSAPxRFCZMY_STRUCTUREStrGS read GetASTAT; property FTABNAME: string read GetFTABNAME write SetFTABNAME; property DATA: TSAPxRFCABAPTEXTTableGS read GetDATA; end; {-----------------------------------------------------------------------------} { TxServer } {-----------------------------------------------------------------------------} constructor TxServer.Create; begin FSConnection1 := TSAPxRFCServerConnectionGS.Create; FSFunction1 := TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.Create; InitConnection; InitFunction; end; {-----------------------------------------------------------------------------} destructor TxServer.Destroy; begin FSConnection1.Free; FSFunction1.Free; inherited Destroy; end; {-----------------------------------------------------------------------------} procedure TxServer.InitConnection; begin with FSConnection1 do begin OnError := HandleError; OnCheckTID := HandleCheckTID; OnCommit := HandleCommit; OnConfirm := HandleConfirm; OnRollback := HandleRollback; end; end; {-----------------------------------------------------------------------------} procedure TxServer.InitFunction;
begin // the initialization of server function with FSFunction1 do begin Connection := FSConnection1; OnExecute := HandleExecute; end; end; {-----------------------------------------------------------------------------} procedure TxServer.Start; begin SAPxRFCServerApplication.Start; end; {-----------------------------------------------------------------------------} procedure TxServer.Shutdown; begin SAPxRFCServerApplication.Shutdown; end; {-----------------------------------------------------------------------------} procedure TxServer.HandleExecute(AFunction: TSAPxRFCServerFunctionGS); var sStructDump, sTabName: String; begin if AFunction is TSAPxRFCZMY_SERVER_FUNCTIONFuncGS then with AFunction as TSAPxRFCZMY_SERVER_FUNCTIONFuncGS do begin sTabName := FTABNAME; sStructDump := ASTAT.TABNAME + '; ' + ASTAT.FLAG; DATA.Append; DATA.LINE := sTabName + '; ' + sStructDump; DATA.Post; end; end; {-----------------------------------------------------------------------------} procedure TxServer.HandleError(Sender: TObject; E: Exception; var AErrAction: TSAPxRFCErrorActionGS); begin { Error handling } end; {-----------------------------------------------------------------------------} procedure TxServer.HandleCheckTID(Sender: TObject; const ATID: String; var AResult: TSAPxRFCCheckTIDResultGS); begin { Check status of transaction with ATID } { if the transaction has not been started, then } { AResult := crOkGS, else AResult := crCancelGS } end; {-----------------------------------------------------------------------------} procedure TxServer.HandleCommit(Sender: TObject; const ATID: String); begin { do DB Commit } { Update status of transaction with ATID } end; {-----------------------------------------------------------------------------}
procedure TxServer.HandleConfirm(Sender: TObject; const ATID: String); begin { Update status of transaction with ATID } end; {-----------------------------------------------------------------------------} procedure TxServer.HandleRollback(Sender: TObject; const ATID: String); begin { do DB Rollback } end; {-----------------------------------------------------------------------------} { TSAPxRFCABAPTEXTTableGS } {-----------------------------------------------------------------------------} constructor TSAPxRFCABAPTEXTTableGS.Create; begin inherited Create; TableType := dtCharGS; with Fields.AddField do begin Name := 'LINE'; DataType := dtCharGS; DataSize := 72; Offset := 0; end; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCABAPTEXTTableGS.SetLINE(const AValue: String); begin Fields[0].AsString := AValue; end; {-----------------------------------------------------------------------------} function TSAPxRFCABAPTEXTTableGS.GetLINE: String; begin Result := Fields[0].AsString; end; {-----------------------------------------------------------------------------} { TSAPxRFCZMY_STRUCTUREStrGS } {-----------------------------------------------------------------------------} constructor TSAPxRFCZMY_STRUCTUREStrGS.Create; begin inherited Create; InstallStructure; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCZMY_STRUCTUREStrGS.SetTABNAME(const AValue: String); begin SubFields[0].AsString := AValue; end; {-----------------------------------------------------------------------------} function TSAPxRFCZMY_STRUCTUREStrGS.GetTABNAME: String; begin Result := SubFields[0].AsString; end;
{-----------------------------------------------------------------------------} procedure TSAPxRFCZMY_STRUCTUREStrGS.SetFLAG(const AValue: String); begin SubFields[1].AsString := AValue; end; {-----------------------------------------------------------------------------} function TSAPxRFCZMY_STRUCTUREStrGS.GetFLAG: String; begin Result := SubFields[1].AsString; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCZMY_STRUCTUREStrGS.InstallStructure; var oStr: TSAPxRFCStructureCacheItemGS; i: Integer; begin oStr := FSAPxRFCEnvironment.StructureCache.FindStructure('ZMY_STRUCTURE'); if oStr = nil then begin oStr := FSAPxRFCEnvironment.StructureCache.Add; with oStr do begin StructName := 'ZMY_STRUCTURE'; with Elements.AddElement do begin Name := 'TABNAME'; DataType := dtCharGS; DataSize := 30; Offset := 0; end; with Elements.AddElement do begin Name := 'FLAG'; DataType := dtCharGS; DataSize := 1; Offset := 30; end; end; oStr.Install; end; DataType := dtStructureGS; TypeHandle := oStr.TypeHandle; SubFields.Clear; for i := 0 to oStr.Elements.Count - 1 do oStr.Elements[i].CreateField(SubFields); end; {-----------------------------------------------------------------------------} { TSAPxRFCZMY_SERVER_FUNCTIONFuncGS } {-----------------------------------------------------------------------------} constructor TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.Create; begin inherited Create; Name := 'ZMY_SERVER_FUNCTION'; with InParameters.AddParameterEx(TSAPxRFCZMY_STRUCTUREStrGS) do begin Name := 'FSTAT'; DataSize := 31; end; with InParameters.AddParameter do begin Name := 'FTABNAME'; DataSize := 30;
DataType := dtCharGS; end; with Tables.AddTableEx(TSAPxRFCABAPTEXTTableGS) do begin Name := 'FDATA'; RecordSize := 72; Open; end; end; {-----------------------------------------------------------------------------} function TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.GetASTAT: TSAPxRFCZMY_STRUCTUREStrGS; begin Result := InParameters[0] as TSAPxRFCZMY_STRUCTUREStrGS; end; {-----------------------------------------------------------------------------} function TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.GetDATA: TSAPxRFCABAPTEXTTableGS; begin Result := Tables[0] as TSAPxRFCABAPTEXTTableGS; end; {-----------------------------------------------------------------------------} function TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.GetFTABNAME: string; begin Result := InParameters[1].AsString; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCZMY_SERVER_FUNCTIONFuncGS.SetFTABNAME(Value: string); begin InParameters[1].AsString := Value; end; {-----------------------------------------------------------------------------} var Srv: TxServer; F1: TextFile; Ch: Char; begin Srv := TxServer.Create; try Srv.Start; AssignFile(F1, ''); Reset(F1); try repeat Read(F1, Ch); until UpperCase(Ch) = 'Q'; finally CloseFile(F1); end; finally Srv.Shutdown; Srv.Free; end; end.
{ TSAPInfoService } {-----------------------------------------------------------------------------} function TSAPxRFCServer.GetServiceController: TServiceController; begin Result := ServiceController; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceStart(Sender: TService; var Started: Boolean); begin SAPxRFCServerApplication.Start; Started := not SAPxRFCServerApplication.Terminated; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServicePause(Sender: TService; var Paused: Boolean); begin SAPxRFCServerApplication.Pause; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceStop(Sender: TService; var Stopped: Boolean); begin SAPxRFCServerApplication.Shutdown; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceContinue(Sender: TService; var Continued: Boolean); begin SAPxRFCServerApplication.Resume; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceCreate(Sender: TObject); begin FTransList := TStringList.Create; CreatingOnFly; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceDestroy(Sender: TObject); begin FTransList.Free; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.FSFunctionExecute(AFunction: TSAPxRFCServerFunctionGS); begin { non-transactional actions } end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.FSTxFunctionExecute(AFunction: TSAPxRFCServerFunctionGS); begin { transactional actions } end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.ServiceExecute(Sender: TService);
begin while not Terminated do ServiceThread.ProcessRequests(True); end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.CreatingOnFly; var i: Integer; oFSFunction: TSAPxRFCvServerFunctionGS; begin for i := 0 to ComponentCount - 1 do if Components[i] is TSAPxRFCvServerFunctionGS then begin oFSFunction := TSAPxRFCvServerFunctionGS(Components[i]); oFSFunction.InParameters.Clear; oFSFunction.OutParameters.Clear; with oFSFunction.InParameters.AddParameter do begin { specifying a set of input parameters } end; with oFSFunction.OutParameters.AddParameter do begin { specifying a set of output parameters } end; end; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.HandleCheckTID(Sender: TObject; const ATID: String; var AResult: TSAPxRFCCheckTIDResultGS); begin if FTransList.IndexOf(ATID) = -1 then begin FTransList.AddObject(ATID, TObject(tsCreated)); AResult := crOkGS; end else AResult := crCancelGS; end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.HandleCommit(Sender: TObject; const ATID: String); var i: Integer; begin i := FTransList.IndexOf(ATID); if i <> -1 then FTransList.Objects[i] := TObject(tsExecuted); { DB commit } end; {-----------------------------------------------------------------------------} procedure TSAPxRFCServer.HandleConfirm(Sender: TObject; const ATID: String); var i: Integer; begin i := FTransList.IndexOf(ATID); if i <> -1 then FTransList.Delete(i); end; {-----------------------------------------------------------------------------}
procedure TSAPxRFCServer.HandleRollback(Sender: TObject; const ATID: String); begin { DB rollback } end; end.