SAP integration

 

 

 

 

 


Contents

 

 

1          SAP BAPI Control          3

1.1.1      Hvad er SAP BAPI kontrollen............................................................................... 3

1.1.2      Bug I SAP Automation 4.6B................................................................................. 3

1.2      Eksempel 1 Liste over Company codes....................................................................... 3

1.2.1      BAPI Exploreren................................................................................................. 4

1.2.2      Initialisering af business object I VB...................................................................... 4

1.2.3      GetList – Liste over company codes..................................................................... 4

1.2.4      GetDetail............................................................................................................ 5

1.2.5      Hvad er ikke med ?............................................................................................. 5

1.2.6      Kode til Company Code list eksemplet.................................................................. 5

1.3      Kilder........................................................................................................................ 9

2          SAP DCOM Connector   11

1.1      Brug af DCOM Connectoren...................................................................................... 11

1.1.1      Opsætning af destinationer................................................................................ 12

1.1.2      Identificering af de BAPIs og/eller RFC enablede function modules der skal bruges. 12

1.1.3      Generering af proxy........................................................................................... 12

1.2      Visual Basic project................................................................................................. 12

1.2.1      Kode................................................................................................................ 13

1.3      Kilder...................................................................................................................... 16

2          Help values        17

 

 


1       Introduktion

 

Dette dokument indeholder en introduktion til integration imellem SAP og Visual Basic, samt relaterede emner. Der gennemgås 2 metoder til integration:  

 

 

·         BAPI ActiveX kontrollen

·         SAP DCOM connectoren

 

Der er til hver metode en kort introduktion og beskrivelse, efterfulgt at et kode eksempel. Desuden gennemgås anvendelsen af Helpvalues i forbindelse med begge metoder.

 

Kode eksemplerne er det klassiske CompanyCod eksempel. De eksempler jeg har set har imdlertid lidt af den svaghed at dels har indeholdt en masse overflødig kode for at gøre eksemplet smart, dels har der manglet kommentarer. Jeg har derfor valg at kode mine egne eksempler hvor alt overflødigt (nsæsten) er skåret væk, og med rigeligt med kommentarer. Eksemplerne skal derfor ikke tages som udtryk for optimal VB kode.

 

1.1      COM/DCOM

 

Når man taler om integration imellem SAP og bla. Visual Basic kommer man ikke uden om begrebet COM (Microsofts Component Object Model). Det har ikke været muligt at finde en umiddelbar simpel og forståelig definition på COM. Her f.eks. en hentet fra Microsofts hjemmeside:

 

The Component Object Model (COM) is a software architecture that allows applications to be built from binary software components. COM is the underlying architecture that forms the foundation for higher-level software services, like those provided by OLE. OLE services span various aspects of commonly needed system functionality, including compound documents, custom controls, interapplication scripting, data transfer, and other software interactions.

 

I praksis er et COM objekt en ActiveX komponent eller DLL der har nogle egenskaber og metoder der kan kaldes udefra.

 

-

DCOM ( Distributed Component Object Model ):

 

DCOM allows you to use regular COM objects over a network.

DCOM allows the client and the object to communicate across  computer boundaries.

 

 

Microsoft:

DCOM is simply "COM with a longer wire"—a low-level extension of the Component Object Model, the core object technology within Microsoft® ActiveX™. The ActiveX Web site can be found at http://www.microsoft.com/activex/default.htm. Major development tools vendors—including Microsoft, Borland, Powersoft/Sybase, Symantec, ORACLE, IBM, and Micro Focus—already sell software development tools that produce ActiveX components. These tools and the applications they produce automatically support DCOM, providing the broadest possible industry support. Additionally, over 1,000 existing commercial software components that will work with DCOM are already available for use by developers.

           

 

The DCOM Component Connector is a a means for technical interoperability of SAP components (written in ABAP or ABAP Objects) and COM components (written in VB, Java, C++, Cobol, Delphi or any other COM-compliant language) on the basis of Microsoft's Distributed Component Object Model (DCOM). Check out the latest version of the

 

 


2       SAP BAPI Control

 

2.1.1       Hvad er SAP BAPI kontrollen

 

SAP BAPI ActveX kontrollen wdobapi.ocx  er en kontrol der anvendes at kalde BAPIs.

 

·         BAPI kontrollen kan anvendes i Visual Basic og andre udviklings miljøer der understøtter COM.

 

·         BAPI kontrollen egner sig bedst for enkeltbruger desktop applikationer.

 

·         BAPI kontrollen indholder ikke metadata og Type Library. Kontrollen understøtter således ikke IntelliSense i VB.

 

·         Table parametre returneres som objekter, hvilket gør koden der skal skrives mindre gennemskuelig.

 

·         Såfremt kravende til hvilke BAPI’s der skal kaldes ændres, behøver man kun at ændre i VB koden.

 

 

 

 

2.1.2       Bug I SAP Automation 4.6B

 

BAPI kontrollen i SAP Automation 4.6B giver på nogle PC’ere en Out of memory fejl når den placeres på en form. Dette er tilsyneladende en bug I denne version. Den eneste løsning jeg p.t. har set foreslået er denne (Fra SapAssist):

 

 The BAPI control in newer versions of SAP Automation creates all types of problems. The good BAPI control is in SAP Automation 4.0B that can still be found on www.saplabs.com - Downloads.

The way I set my machines to develop all this magic:
- install SAP Automation 4.0B - good BAPI control, fast single RFC test environment, has transaction functionality
- install SAP Automation 4.5A or 4.6B
- install DCOM CC 4.6B

Just for the sheer hell of it manually register dcom cc core DLL’s - they are in ccpack directory of dcomcc.


2.2      Eksempel - Liste over Company codes

 

Dette er et meget simpelt eksempel hvor kun den mest nødvendige VB kode er medtaget (I modsætning til SAP’s tilsvarende eksempel som det tager nogen tid + VB forståelse at arbejde sig igennem).

 

I eksemplet dannes en liste over Company codes + navn. Til at danne listen anvendes business objected CompanyCode. Når man dobbeltklikker på en Company code i listen, vises nogle detaljer om Company coden.

 

 

2.2.1       BAPI Exploreren

 

I SAP kan man hente nærmere oplysninger om de enkelte BAPI’s I BAPI Exploreren. Denne kaldes med transaction BAPI.

 

I BAPI exploreren vælges Financial Accounting -> CompanyCode

 

Når man trykker CompanyCode, vises en liste over de attributter og metoder dette objet har.

 

 

2.2.2       Initialisering af business object I VB

 

Business objectet declares I VB som et generisk object:

 

Dim oCompanyCode As Object    

 

Selve initialiseringen ser således ud når man vil have hele listen med Company Codes:

 

Set oCompanyCode = SAPBAPIControl1.GetSAPObject("CompanyCode")

 

Bemærk at metoden GetSAPObject også har parametrene ObjKey1 – ObjKey10. Disse bruges til at hente en bestemt instance af objectet. I dette tilfælde ønsker vi alle Company Codes, og bruger derfor ikke ObjKey.

 

Når vi derimod skal hente detaljer om den enkelte CompanyCode ved kald til GetDetail metoden,

Skal business objectet initialiseres med en nøgle (Company code):

 

Set oCompanyCode = oBapiControl.GetSAPObject("CompanyCode", CompanyCode)

 

 

 

 

2.2.3       GetList – Liste over company codes

 

Til at danne listen over Company  codes, skal anvendes metoden GetList.

 

Tryk på metoden GetList. I feltet Function module ses at listen dannes ved kald til funktions modulet BAPI_COMPANYCODE_GETLIST.

 

For at finde ud af hvilke import/export paremtre dette funktionsmodul har, dobbeltklikker man  på det.

 

Det ses at funktonsmodulet ingen import parametre har, men 1 export parameter RETURN (Returkode) og 1 table COMPANYCODE_LIST. Når felterne i dette table refereres i VB, er det nødvendigt at kende navnene på dem. COMPANYCODE_LIST er defineret I strukturen BAPI0002_1. Når man klikker på denne, kan man se at den har 2 felter COMP_CODE og COMP_NAME.  På samme måde kan man se hvilke felter der indgår I paremeteren Return. Vedr. Return parameteren findes der en glimrende artikel på IntellgentERP: Error handling in BAPI enabled programs.

 

Bemærk: Navnene på felterne I tabellen, kan også hentes i VB koden, ved at loope igennem kolonnerne I retur tabellen og teste på kolonnernes Name attribut. Se nærmere I eksemplet.

 

I modsætning til hvad der er tilfældet når man bruger componenter genereret ved hjælp af DCOM connectoren, returneres tabellen desværre ikke som et recordset til VB. I stedet skal man declare et generisk object som tabellen lægges i. Man kan herefter loope igennem kolonner og rækker i objektet for at få adgang til dets data. 

 

Hvis man ser nærmere på det tilsvarende eksempel fra SAP (X:\XX\SAPpc\SAPGUI\rfcsdk\OCX\SAMPLES\COMPANYC.ZIP) ,  kan man hvis man anvender SAP’s SAPTableView kontrol til at vise data, imidlertid bruge table objektet direkte I denne kontrol:

 

otabCompanyCodes.Views.Add SAPTableView1.object

otabCompanyCodes.Refresh

 

I den efterfølgende kode er imidlertid anvendt en Listbox kontrol, for at anskueliggøre  hvordan man klarer det ”manuelt”.

 

2.2.4       GetDetail

 

Når man dobbeltklikker på en CompanyCode I Listboxen, vises nærmere detaljer om denne CompanyCode. Dette sker ved kald til metoden GetDetail.

 

GetDetail er en såkaldt  instance method, idet man skal identificere et bestemt object I databasen ved hjælp af en nøgle. I BAPI exploreren kan man se at denne nøgle hedder CompanyCodeId.

 

2.2.5       Hvad er ikke med ?

 

Når detaljerne for en Company code vises, er det kun selve koden for language og Country der vises. Det er muligt at hente teksterne til disse fra business objectet HelpValues.

 

Nærmere om dette kan findes I artiklen Getting  help for values: The HelpValues Object der kan findes på IntelligentERP.

 

 

 

 

2.2.6       Kode til Company Code list eksemplet

 

2.2.6.1.1        Forberedelse

 

Når Visual Basic er starte op skal Logon og BAPI kontrollerne tilføjes

 

Gå ind menuen: Project -> Components

 

Vælg fanebladet Controls

 

Sæt hak ud for SAP Logon Control og SAP BAPI Control og tryk på OK.

 

Disse 2 kontroller vises nu I toolboxen. Træk dem hen på formen. De får automatisk navnene SAPLogonControl1 og SAPBAPIControl1.

 

Her ud over skal listboxen og labels placeres på formen.

 

 


 

 


Kode

 

 

Private Sub SAPLogonControl1_Click()

  '--------------------------------------------------------

  ' Log on to the SAP system

  '--------------------------------------------------------

     

       

  'Set the connection property of the BAPI control

  Set SAPBAPIControl1.Connection = SAPLogonControl1.NewConnection

 

 

 

  With SAPBAPIControl1.Connection

    'The properties of the connection, does not have to be set here.

    'If you does not set the ApplicationServer property,

    'a SAP logon pad will be shown automatically, and you can select the system to logon to

    'If you set the ApplicationServer property, you should also set the

    'System property.

    '

    'After you have selected which system to logon to, a logon screen will be

    'shown automatically. If you have set the User, Language and password properties, the

    'values for these properties is shown on the logon screen.

           

    '.ApplicationServer = "10.42.1.23"

    '.System = "00"

    '.Client = "800"

    .User = "HenrikF"

    .Language = "EN"

    '.Password =

   

   'Check if the connection was succesfully established

    If Not .Logon(Me.hWnd, False) Then

      MsgBox "Connection failed"

      Exit Sub

    Else

      MsgBox "Connect successfull"

    End If

 

    'Display system info - Just for fun

    '.SystemInformation

   

   

  End With

 

  'Display list of comapny codes

  Call ListCompanyCodes

End Sub

 

Private Sub ListCompanyCodes()

’------------------------------------------------------------------------

'Display list of Company Codes

’------------------------------------------------------------------------

  Dim oCompanyCode As Object     'Declare business object

  Dim otabCompanyCodes As Object 'Return table from BAPI

  Dim oReturn As Object          'Return code from BAPI

  Dim oCol As Object             'Column in otabCompanyCodes

  Dim oRow As Object             'Row in otabCompanyCodes

  

  

  'Clear the listbox

  lstCompanyCodes.Clear

 

 

  'Create business object. The name of the business object is case

  'sensitive and must match a business object in BOR.

  'Note that the GetSAPObject method also has optionally object key parameters,

  'but as we want to read all company codes, we don't use them here

  Set oCompanyCode = SAPBAPIControl1.GetSAPObject("CompanyCode")

 

 

  'Call method GetList of the business object. This method returns

  '- CompanyCodeList

  '- Return

  '

  'These 2 parameters are returned to VB in

  'otabCompanyCodes and oReturnCode

 

  oCompanyCode.GetList CompanyCodeList:=otabCompanyCodes, Return:=oReturn

 

 

  'Check the return code from GetList. Informational messages will be treated as

  'succesfull execution.

  '

  'These fields from oReturnCode will be used:

  ' - TYPE    Message type: S Success, E Error, W Warning, I Info, A Abort

  ' - CODE    Message code

  ' - Message Message text

 

  If oReturn.Value("TYPE") = "" Or _

     oReturn.Value("TYPE") = "S" Or _

     oReturn.Value("TYPE") = "I" Then

     'Success !!!

  Else

    'Error

    MsgBox "Return type: " & oReturn.Value("TYPE") & vbCrLf & _

           "Return Code " & oReturn.Value("CODE") & ": " & _

           oReturn.Value("MESSAGE"), vbOKOnly, "Error"

  End If

 

 

  'Display the names of the columns in otabCompanyCodes and display them

  'in a label. This method could also be used instead of explicitly

  'writing the column names when the Listbox is filled.

 

  lblComapnyCodeStructure.WordWrap = True

  lblComapnyCodeStructure = "Structure for GetList method: " & vbCrLf

 

  For Each oCol In otabCompanyCodes.Columns

    lblComapnyCodeStructure.Caption = lblComapnyCodeStructure.Caption & oCol.Name & ", "

  Next oCol

 

  'Fill the listbox. The columns in otabCompanyCodes are referenced explicitly

  For Each oRow In otabCompanyCodes.Rows

    lstCompanyCodes.AddItem oRow("COMP_CODE") & " - " & oRow("COMP_NAME")

  Next oRow

  

   

  'Clean up

   Set oCompanyCode = Nothing

  

 

End Sub

 

Private Sub lstCompanyCodes_DblClick()

  ’-----------------------------------------------------------------------------------------------

  'When dobbelclicking on the listbox, get the Company code part

  'of the selected item in the listbox, and call the procedure

  'that displays information for a specific company

  ’-----------------------------------------------------------------------------------------------

  Dim strCompanyCode As String

   

  'VB stuff to get the Company code part of the list item in the listbox

  strCompanyCode = Left(lstCompanyCodes, InStr(lstCompanyCodes, "-") - 1)

   

  Call ShowDetail(strCompanyCode)

 

End Sub

 

 

Private Sub ShowDetail(strCompanyCode As String)

  Dim oCompanyCode As Object  'Business object

  Dim oDetail As Object       'Details returned

  Dim oReturn As Object       'Return code

 

  'Initialize labels used to show company details

  lblCompanyCode.Caption = ""

  lblCompanyName.Caption = ""

  lblLanguage.Caption = ""

  lblCountry.Caption = ""

 

  'Create business object. Note that we are know using the strCompanyCode as

  'object key to get information about a specific company

  Set oCompanyCode = SAPBAPIControl1.GetSAPObject("CompanyCode", strCompanyCode)

 

  'Call method GetDetail of the business object.

  oCompanyCode.GetDetail Return:=oReturn, CompanyCodeDetail:=oDetail

   

  'Check the return code from GetDetail

  If oReturn.Value("TYPE") = "" Or _

     oReturn.Value("TYPE") = "S" Or _

     oReturn.Value("TYPE") = "I" Then

     'Success !!!

  Else

    'Error

    MsgBox "Return type: " & oReturn.Value("TYPE") & vbCrLf & _

           "Return Code " & oReturn.Value("CODE") & ": " & _

           oReturn.Value("MESSAGE"), vbOKOnly, "Error"

  End If

 

 

  'Show details

  lblCompanyCode.Caption = oDetail.Value("COMP_CODE")

  lblCompanyName.Caption = oDetail.Value("COMP_NAME")

  lblLanguage.Caption = oDetail.Value("LANGU")

  lblCountry.Caption = oDetail.Value("COUNTRY")

  

  Set oCompanyCode = Nothing

End Sub

 

Private Sub Form_Unload(Cancel As Integer)

   'Log off

   SAPBAPIControl1.Connection.Logoff

End Sub

 

 

 

2.3      Kilder

 

Thomas G.Schuessler: A beginners guide to accessing BAPI’s with the SAP DCOM Connector

SAP Professional Journal January/February 2000,

 

 

SAP Library – BAPI ActiveX control

 

Eksempler fra SAP:   X:\XX\SAPpc\SAPGUI\rfcsdk\OCX\

 


3       SAP DCOM Connector

 

SAP DCOM connectoren (SDC) er et værktøj der genererer ”proxies” (DLL’er ) der giver adgang til BAPIs og andre RFC-enablede funktioner I SAP.

 

·         Kan bruges I alle udvklingsmiljøer der understøtter COM

 

·         Optimeret til brug for server baserede applikationer

 

·         Indeholder metadata og type Library informationer. Man kan derfor anvende VB’s IntelliSense når man skriver kode, hvilket letter arbejdet betydeligt.

 

·         SDC generere C++ source kode for proxys. Det er derfor nødvendigt at have en C++ kompiler installeret (F.eks. Microsofts Visual C++). Det er ikke nødvendigt at kende noget til C++.

 

·         Alle table parametre afleveres som ADO (ActiveX Data Object recordset). Disse kan umiddelbart anvendes i Visual Basic. Dette gør disse parametre betydeligt lettere at anvende end de table objekter der returneres fra BAPI kontrollen.

 

·         Såfremt kravende til hvilke BAPIs der skal kaldes ændres, skal man enten generere DLL igten eller danne en ekstra DLL.

 

 

3.1      Brug af DCOM Connectoren

 

DCOM connectoren er et HTML baseret værktøj der bruges til at generere DLL’er (Proxys), der bruges som et mellemled når man kalder BAPIs.

 

Før DCOM connectoren kan bruges, er det en forudsætning at Visual C++ 6.00 (Eller større) er installeret, idet SDC bruger C++ til at generere proxies.

 

Før man går igang med at generer proxys, skal man definere SAP destinationer (Menupunktet Destinations), det vil sige hvilke SAP systemer man vil logge på.  Herefter går man over i Object builderen og logger på en af de  destinationer man tidligere har defineret.  

Efter at man har logget på, får man en  oversigt over de BAPIs der er tilgængelige i det pågældende system (Svarer nogenlunde til BAPI expolreren i SAP). Alternativt kan man vælge at få en oversigt over andre RFC functions. Man tilføjer herefter de BAPIs/RFC functions man ønsker at anvende til sit COM object. Når man er færdig med dette, generere man sin Proxy som derefter er klar til anvendelse.

 

Der er her ingen grund til at gå dybere ned i hvordan man anvender DCOM connectoren. I stedet anbefales det at læse Thomas G.Schuessler’s artikel A beginners guide to accessing BAPI’s with the SAP DCOM Connector (SAP Professional Journal January/February 2000).

 

Når man anvender proxys genereret med DCOM Connectoren, skal man være opmærksom på at alle metoder prefixes med BAPI. Metoden GetList hedder således BapiGetList.

 

 

3.2      Eksempel - Liste over Company codes

 

Dette eksempel svarer i pricippet til det der blev gennemgået under BAPI ActiveX kontrollen. Logon metoden er dog en lidt anden, idet SessionComponent anvendes til logon i stedet for Logon ActiveX kontrollen.

 

 

3.2.1        Generering af proxy

 

Når proxien generes skal følgende BAPIs inkluderes:

 

CompanyCode  (Financial accounting)

HelpValues (Basis components)

BapiService (Basis components)

SessionComponent (Inkluderes ved at sætte X I checkboksen Session i COM/MTS)

 

Bemærk at det vil være en god ide at ændre default navnet på session komponenten

 

 

3.2.2       Visual Basic project

 

I projectet skal der oprettes en reference til den  genererede proxy:

 

Dette gøre via menuen Project -> References 

 

Find proxien i listen og kryds den af. Hvis den ikke findes I listen, kan man browse efter den.

 

Da proxien returnere tables som ADO recordset, skal der også oprettes en reference til  Microsoft ActiveX Data Objects Recordset Library.

 

Her ud over anvendes i dette eksempel Microsoft DataGrid Control til at vise CompanyCode liste.

                                               

Da SessionComponent er medtaget I proxien, kan denne bruges til at logge på SAP. Den har ikke noget grafisk interface, så hvis man vil give brugeren mulighed for at ændre I logon parametrene, skal man selv udvikle dette I VB.

 

 

3.2.3       Kode

 

Option Explicit

'***************************************************************************

' This project uses a proxy generated by the SAP DCOM Connector to display a

' list of CompanyCodes and details about a selected company.

'

' The following references must are made in Project -> References

'

' - SAP46B.Business Object Proxies. CompanyCodeProxy

' - Microsoft ActiveX Data Objects Recordset Library

'

' The proxy includes the following business objects:

'

' - CompanyCode

' - HelpValues

' - BapiService

'

' and the SessionComponent

'

' Programmer: Henrik Frank 26-09-2000

'***************************************************************************

 

Private oSession As SessionComponent 'Declare session object

Private oCompanyCode As CompanyCode           'Declare company code object

Private rsCompanyCodes As Recordset  'Recordset returned from the BapiGetList ethod

Private rsReturn As Recordset                            'Returncode from Bapi methods

 

Private Sub cmdConnect_Click()

  '***************************************************************************

  ' Connect to SAP

  '***************************************************************************

  Dim strLogonMessage As String

  Dim strConnectProperties As String

  

  '------------------------------------------------------------------------------

  'Initialize oSession

  '------------------------------------------------------------------------------

  Set oSession = New SessionComponent

 

  '------------------------------------------------------------------------------

  ' Log on. Use the PutSessionInfo method of oSession to specify the logon

  ' parameters. This can be done in two different ways. You can either specify all

  ' logon information in the destination parameter, or only specify the basic

  ' system information, and then use the PutSessionInfo properties

  ' UserId,..... to specify other logon properties.

  '------------------------------------------------------------------------------

 

 

  '--- Using the destination parameter. The destination parameter has these

  '--- options:

  '

  'ashost   = Application server name

  'sysnr    = System number

  'mshost   = Message server

  'group    = Load balancing group

  'r3name   = R/3 system name

  'type     = System type (2 = R/2, 3 = R/3

  'client   = Client number

  'lang     = Language code

  'user     = UserId

  'passwd   = Password

  'trace    = Trace option (0=trace off, 1=trace on)

 

 

 

 strConnectProperties = _

    "{" & _

    "ashost    = 10.42.1.23 " & _

    "sysnr     = 00 " & _

    "type      = 3 " & _

    "client    = 800 " & _

    "lang      = EN " & _

    "user      = henrikf " & _

    "passwd = xxxxx " & _

    "}"

 

  oSession.PutSessionInfo Destination:=strConnectProperties

 

'--- Using a combination of Destination  PutSessionInfo properties

'  strConnectProperties = "{ashost = 10.42.1.23 sysnr = 00 client = 800}"

'  oSession.PutSessionInfo Destination:=strConnectProperties, _

'                          UserID:="henrikf", _

'                          Password:="vimmer3", _

'                          Language:="EN", _

'                          Client:="800"

 

  '---------------------------------------------------------------------------

  ' Logon to SAP. Note that error messages are returned from the

  ' logon method in the strLogonMessage string

  '---------------------------------------------------------------------------

  If oSession.Logon(strLogonMessage) = False Then

    MsgBox "Error in logon: " & " " & strLogonMessage

     Exit Sub

  End If

 

  'Show company codes in a DataGrid

  Call ShowCompanyCodes

 

End Sub

 

 

Private Sub ShowCompanyCodes()

  '***************************************************************************

  ' This procedure shows a list of Company Codes in a DataGrid

  '***************************************************************************

 

  '------------------------------------------------------------------------------

  'Create instance

  '------------------------------------------------------------------------------

  Set oCompanyCode = oSession.CreateInstance("SAP46B.CompanyCode")

 

 

  '---------------------------------------------------------------------------

  ' Call GetList method - Note that the methods are allways prefixed with Bapi

  ' in proxys generated by the DCOM Connector

  '

  ' When the business object returns a table, the proxys generated by

  ' the DCOM connector returns a recordset (ADO).

  '---------------------------------------------------------------------------

  oCompanyCode.BapiGetList CompanyCodeList:=rsCompanyCodes, _

                           Return:=rsReturn

                           

  'Check return code

  If Not (rsReturn!Type = "" Or _

          rsReturn!Type = "S" Or _

          rsReturn!Type = "I") Then

    MsgBox rsReturn!Type & " " & rsReturn!Code & ": " & rsReturn!Message

    Exit Sub

  End If

                           

  '------------------------------------------------------------------------------

  'Fill DataGrid1 with company codes

  '------------------------------------------------------------------------------

  DataGrid1.AllowUpdate = False

  If rsCompanyCodes Is Nothing Then

    MsgBox "No company codes defined"

    Exit Sub

  Else

    Set DataGrid1.DataSource = rsCompanyCodes

  End If

 

End Sub

 

Private Sub DataGrid1_Click()

 '***************************************************************************

 ' Show details for a company code

 '***************************************************************************

  Dim rsDetail As Recordset

 

  lblDetails.Caption = "Details for company: "

  lblCountry.Caption = ""

  lblLanguage.Caption = ""

 

  '----------------------------------------------------------------------------------------------------------------------

  'Set the keyfield for the CompanyCode object. This object has only 1 keyfield

  'called CompanyCodeId. The proxy class's InitKeys method is used to set the keyfield

  'The keyfield = the CompanyCode in the line of the DataGrid that was double clicked

  '----------------------------------------------------------------------------------------------------------------------

  oCompanyCode.InitKeys rsCompanyCodes!Comp_Code

  

 

  '------------------------------------------------------------------------------

  'Call GetDetail method and test Return code

  '------------------------------------------------------------------------------

  oCompanyCode.BapiGetDetail CompanycodeDetail:=rsDetail, _

                             Return:=rsReturn

 

  'Check return code. Note the check for Type=W and Code="FN021".

  'This warning indicates that the address data is not complete.

  'In this example this is considered ok

  If Not (rsReturn!Type = "" Or _

          rsReturn!Type = "S" Or _

          rsReturn!Type = "I" Or _

          (rsReturn!Type = "W" And rsReturn!Code = "FN021")) Then

    MsgBox rsReturn!Type & " " & rsReturn!Code & ": " & rsReturn!Message

    Exit Sub

  End If

 

 

 

  lblDetails.Caption = "Details for company: " & vbCrLf & rsDetail!Comp_Code & _

" " &  _rsDetail!Comp_Name

  lblCountry.Caption = "Country: " & rsDetail!Country

  lblLanguage.Caption = "Language: " & rsDetail!Langu

 

End Sub

 

Private Sub Form_Unload(Cancel As Integer)

 ’Clean up

  Set oCompanyCode = Nothing

  Set oSession = Nothing

End Sub

 

 

3.3      Destinations og sessions styring

 

Oprettelse/Rettelse/Sletning af destinationer vil normal foregå ved hjælp af DCOM Connectoren. Man har imidlertid mulighed for selv at kode et program til dette formål. SDC gemmer destinationer (SAP system og optionelt Client, Userid, Password og Sprog) på klienten. Disse oplysninger ligger i Windows registry, og kan hentes med SAP DCOM Administration Component (ccadmin.dll).

 

En måske mere nærliggende anvendelse, er at oplysningerne kan anvendes til at kode en logon pad. Det er dog kun de Destinationer der er oprettet ved hjælp af DCOM Connectoren, man kan hente oplysninger om.

 

 

3.3.1       Eksempel på anvendelse af SAP DCOM Administration Component

 

Dette eksempel er afgrænset til at vise hvordan man henter en oversigt over destinationer, og bruger dem til at logge på SAP. 

 

Man skal først skabe en refererence til SAP DCOM Administration Component fra VB projektet.

 

Brug menuen Project -> References og søg efter SAP DCOM Administration Component

 

Man vil højst sandsynligt ikke se den i listen over ”Available references”, og er derfor nødt til at Browse knappen til at finde den. Før man gør dette, kan man evt. finde den ved hjælp af Windows Find funktion. Der skal ledes efter ccadmin.dll.

 

Til at foretage logon til SAP kan anvendes SessionComponent klassen i den proxy der blev genereret i forbindelse med CompnyCode eksemplet. Der skal derfor også refereres til denne.

 

Endvidere skal der refereres til Microsoft ActiveX Objects Recordset x.x. Library  (P.t. MSADOR15.DLL ), idet table parametre returneres som ADO reordsets.

 

Endelig bruges en MsDatagrid til at vise destinationerne i.

 

3.3.1.1         CCADMINLib

 

Type libraryet for ccadmin.dll hedder CCADMINLib. I forbindelse med logon til SAP er det klassen CCRegistry der her er interessant. Denne indeholder bla. metoden GetDistinations som returenere alle destinationer defineret via SDC, som et recordset. Dette recordset inholder 2 felter:  Destination som er navnet på destinationen og Options som indeholder en streng med de optioner man bruger når man logger på. Denne streng svarer til den der er anvendt til logon i eksemplet på anvendelse af DCOM connectoren ( Linien: oSession.PutSessionInfo Destination:=strConnectProperties ), det vil bla. være:

 

ashost              Application server  

sysnr                System number

type                  System type (R2/R3)

client                Client

lang                  Language

user                  User

passwd             Password

 

 

3.3.1.2         Kode

 

'-------------------------------------------------------------------------------

' This project shows how to read destination information for destinations

' created by the SAP DCOM Connector. The project uses the SAP DCOM

' Connector Administration Component ( ccadmin.dll ), to read destination information

' from the Windows registry.

'

' Note that the project uses a proxy generated by the DCOM Connector to

' logon to SAP. The proxy contains the SessionComponent class.

'

' A list of available destinations and there options is  shown. Choose a destination

' and clicl on the Logon button, to logon to the SAP system.

'

' Programmer: Henrik Frank 05-10-2000

'-------------------------------------------------------------------------------

 

Public strPassWord As String

Private rsDestinations As Recordset       'Recordset to store destinations

Private oCCREgistry As CCRegistry         'CCRegistry object

Private oSession As SessionComponent  'Declare session object

 

Private Sub Form_Load()

 

 'Create instance of CCRegistry

 Set oCCREgistry = New CCRegistry

 

 'Read destinations into recordset

 Set rsDestinations = oCCREgistry.GetDestinations

  

 'Setup of datagrid and show destinations

 DataGrid1.AllowUpdate = False

 Set DataGrid1.DataSource = rsDestinations

 DataGrid1.Columns(0).Width = 1200

 DataGrid1.Columns(1).Width = 8000

 

End Sub

 

 

Private Sub cmdLogon_Click()

  Dim strLogonMessage As String

  Dim strPw As String

 

  '------------------------------------------------------------------------------

  'Initialize oSession

  '------------------------------------------------------------------------------

  If rsDestinations!Options = "" Then

    MsgBox "Choose a system"

    Exit Sub

  End If

 

  'Instantiate the SessionComponent

  Set oSession = New SessionComponent

 

  '---------------------------------------------------------------------------

  ' The logon information from the detination recordset rsDestinations is used

  ' to logon. The password parameter does not seems to work (Maybe because

  ' the password is represented by *******), so we have to ask for it.

  '---------------------------------------------------------------------------

  strPassWord = ""

  frmPassWord.Show vbModal          'Enter password

  If strPassWord = "" Then Exit Sub 'Logon canceled

 

   oSession.PutSessionInfo Destination:="{" & rsDestinations!Options & "}", _

                          Password:=strPassWord

 

  '---------------------------------------------------------------------------

  ' Logon to SAP. Note that error messages are returned from the

  ' logon method in the strLogonMessage string

  '---------------------------------------------------------------------------

  If oSession.Logon(strLogonMessage) = False Then

    MsgBox "Error in logon: " & " " & strLogonMessage

     Exit Sub

  Else

    MsgBox "Congratulations - Logon was successful"

  End If

 

 

End Sub

 

Private Sub cmdLogOff_Click()

  Set oSession = Nothing

  MsgBox "Logged off"

  Unload Me

End Sub

 

 

3.4      Kilder


Thomas G.Schuessler: A beginners guide to accessing BAPI’s with the SAP DCOM Connector

SAP Professional Journal January/February 2000,

 

Thomas G.Schuessler: Destination and Session Management for the SAP DCOM Conector

SAP Professional Journal March/April 2000,

 

4       Help values

 

Help values kan hentes ved hjælp af business objektet Helpvalues. Dette kan findes I BAPI exploreren (Transaktionskode: BAPI) under Basis Components -> Middleware.

 

Anvender man DCOM Connectoren skal dette object inkluderes når man generere proxy’en. 

 

Hvis der findes en GetList metode I det Business object man arbejder med, anbefales det at anvende denne metode I stedet for at anvende Helpvalues, idet dette er mindre perfomance krævende og ldesuden ettere at arbejde med. Dette er f.eks.tilfældet med CompanyCode som har en GetList metode.

 

Af hesyn til evt. ændringer af Helpvalues objektet, anbefaler Schuessler at man lægger koden i en DLL. Man skal i givet fald kun rette i DLL’en i stedet for at rette i alle programmerne der bruger Helpvalues objektet.

 

Bemærk: En DLL kan bla. programmeres i Visual Basic

 

 

Til at hente en liste over værdier anvendes GetList metoden. Denne har følgende parametre:

 

Parameter

Data type

Kræ-vet

Beskrivelse

Eksempel

ObjType

Char 10

 

Internt navn på Business objectet

 

BUS0002

ObjName

Char 32

 

Officielt navn på Business objectet

 

CompanyCode

Method

Char 32

X

Navn på BAPI metode f.eks. GetDetail

 

GetDetail

Parameter

Char 32

X

Navn på parameter

 

CompanyCodeDetail

Field

Char 32

 

Felt navn I struktur eller table parameter

 

Currency

MaxOfRows

Integer

 

Maks antal rækker der returneres (Default alle)

 

 

DescriptionOnly

Char 1

 

X = Kun table Description4HV

Blank: Også table Helpvalues og Values4Field

 

 

Return

Structure

 

 

X

Retur kode information (BAPIRETURN)

 

Selection4Helpvalues

 

Table BAPIF4B

 

Selektions kriterier

 

Helpvalues

Table BAPIF4C

 

Hjælpe værdier der matcher udsøgningskriterierne

 

Values4Field

Table BAPIF4D

 

Felt værdi

 

Description4HV

Table BAPIF4E

 

Structur for data I table Helpvalues

 

 

Bemærk:

 

Enten ObjType eller ObjName skal udfyldes.

 

Field parameteren er krævet hvis parameteren er en struktur eller table.

 

 

Da Helpvalues table parameteren kun har et felt Helpvalues som er en string på 255 karaktere, der indeholder alle Helpvalues felterne, kan man ikke uden videre anvende den returnerede værdi.

 

Når man f.eks. søger helpvalues for CompanyCode sprog, vil både sprogkoden og betegnelsen bliver returneret i en streng f.eks: N Dutch

 

Man er her formodentlig kun ude efter betegnelse på sproget, og det er derfor nødvendig at kende positionen og længden på betegnelsen inden i strengen. Dette gøres ved hjælp af parameteren Description4HV, som er en tabel der inholder strukturen på HelpValues tabellen.

 

Description4HV tabellen indholder følgende felter:

 

Field Name                  Data Type        Description

TABNAME                    Character 30      Table name

FIELDNAME                  Character 30      Field name

LANGU                         Character 2       Logon language code

POSITION                     NumChar 4        Index of the field (not set by the BAPI)

OFFSET                       NumChar 6        Offset of this field in the Helpvalues table (zero-based)

LENG                           NumChar 6        Length of this field in the Helpvalues table

FIELDTEXT                    Character 60      Descriptive text for this field

REPTEXT                      Character 55      Report header text for this field

SCRTEXT_S                  Character 10      Short field label

SCRTEXT_M                 Character 20      Medium field label

SCRTEXT_L                  Character 40      Long field label

 

Såfremt man søger efter SPTXT vil felterne indeholder følgende værdier:

 

TABNAME                    T002T

FIELDNAME                  SPTXT

LANGU                         E                      (Bemærk at dette er logon sproget)

POSITION                     2

OFFSET                       2         

LENG                           16

FIELDTEXT                    Language

REPTEXT                      Language

SCRTEXT_S                  Language

SCRTEXT_M                 Language

SCRTEXT_L                  Language

 

Man skal i denne tabel søge efter det feltnavn man ønsker hjælpeværdi for SPTXT, og herefter anvende POSITION og OFFSET til at finde feltet i HelpValues.

 

Såfremt man anvender en proxy genereret med DCOM connectoren som returnere alle table parametre som recordset, vil dette se således ud:

 

oHelpvalues.BapiGetList ObjName:="CompanyCode", _

                          Method:="GetDetail", _

                          Parameter:="CompanycodeDetail", _

                          Field:="LANGU", _

                          Return:=rsReturn, _

                          Selection4HelpValues:=rsSelectionTable, _

                          Helpvalues:=rsHelpValues, _

                          Description4HV:=rsStructure

 

Do While Not rsStructure.EOF

      If rsStructure!Fieldname = "SPTXT" Then

        intStart = rsStructure!Offset

        intLength = rsStructure!Leng

        Exit Do

      End If

      rsStructure.MoveNext

 Loop

   

 strHelpvalue_Language = Trim$(Mid$(rsHelpValues!Helpvalues, intStart + 1, intLength))

 

Syntaxen er lidt mere kringlet såfremt man anvender BAPI ActiveX kontrollen. Se nærmere i kode eksemplet.

 

4.1      Kode

 

Implementeringen af help values i VB afviger en del afhængig af om man bruger en proxy genereret med DCOM connectoren, eller man anvender BAPI ActiveX kontrollen. Nedenfor er vist  2 simple kode eksempler der viser hvordan man ud fra en sprogkode kan hente teksten til denne.

 

 

4.1.1       Help values - BAPI ActiceX kontrollen

 

Sub xxxx

lblLanguage.Caption = oDetail.Value("LANGU") & " " & _

                        Get_Helpvalue_Language(oDetail.Value("LANGU"))

End Sub

 

 

Private Function Get_Helpvalue_Language(strLanguageCode As String) As String

  'This function returns the language text for strLanguageCode

  Dim oHelpValues As Object                  'Help value object

  Dim oSelectionTable As Object             'Table object used for selection criterias

  Dim oHelpValuesTable As Object         'Table for hold help values

  Dim oTableStructure As Object             'Table for structure of data in oValuesTable

  Dim oReturn As Object                                     'Return code from BAPI call

  Dim intStart As Integer, intLength As Integer

  Dim oRow As Object

   

  '------------------------------------------------------------------

  'Create instance of the SAP Helpvalues object.

  'The method GetSAPObject creates a instance of an object which is stored in

  'the R/3 database.

  '------------------------------------------------------------------

  Set oHelpValues = SAPBAPIControl1.GetSAPObject("Helpvalues")

   

   

  '-------------------------------------------------------------------

  ' Build table for selection criterias

  '-------------------------------------------------------------------

 

  'Dimensioning the selection table object

  Set oSelectionTable = SAPBAPIControl1.DimAs(oHelpValues, _

                                      "GetList", "Selection4Helpvalues")

   

  'Add empty row to selection table

  Set oRow = oSelectionTable.Rows.Add

 

  'Fill the row with selection criteria

  oRow.Value("SELECT_FLD") = "SPRAS"

  oRow.Value("SIGN") = "I"

  oRow.Value("OPTION") = "EQ"

  oRow.Value("LOW") = strLanguageCode

 

  '-------------------------------------------------------------------

  ' Read help values, using the GetList method of the Helpvalues

  ' object. The paramters can be found in SAP using the BAPI eplorer

  '-------------------------------------------------------------------

  oHelpValues.GetList ObjName:="CompanyCode", _

                      Method:="GetDetail", _

                      Parameter:="CompanyCodeDetail", _

                      Field:="LANGU", _

                      Selection4Helpvalues:=oSelectionTable, _

                      HelpValues:=oHelpValuesTable, _

                      Description4HV:=oTableStructure, _

                      Return:=oReturn

 

  'Check return code

  If oReturn.Value("CODE") <> "" Then

     Err.Raise 2002, "Countries", "Could not access country information."

  End If

 

  '----------------------------------------------------------------------------

  ' The Helpvalues table oHelpValuesTable contains only one field.

  ' The contents of this field (one string containing multiple "columns")

  ' must be dissected based on the information in the Description4HV table.

  ' Helpvalues.GetList inserts blanks between the "columns" contained in the

  ' HELPVALUES field.

  '

  ' The Description4HV ( In this example: oTableStructure ) contains the following

  ' fields:

  '

  ' TABNAME     Character30   Table name

  ' FIELDNAME   Character 30  Field name

  ' LANGU       Character 2   Language code

  ' POSITION    NumChar 4     Index of the field (not set by the BAPI)

  ' OFFSET      NumChar 6     Offset of this field in the Helpvalues table (zero-based)

  ' LENG        NumChar 6     Length of this field in the Helpvalues table

  ' FIELDTEXT   Character 60  Descriptive text for this field

  ' REPTEXT     Character 55  Report header text for this field

  ' SCRTEXT_S   Character 10  Short field label

  ' SCRTEXT_M   Character 20  Medium field label

  ' SCRTEXT_L   Character 40  Long field label

  '----------------------------------------------------------------------------

 

  

  'Using the KeyColumn property of the table's Columns collection,

  'we specify that we want to search for entries in the FIELDNAME column of the table.

  oTableStructure.Columns.Keycolumn = oTableStructure.Columns("FIELDNAME").Index

    

  'Find SPTXT in Description4HV ( In this example: oTableStructure )

  'How do we know that we are looking for SPTXT. Well, you have to

  'look it up in the BAPI explorer. Choose BAPI CompanyCode method

  'CompanycodeDetail. Doubleclick on the dictionay reference, and choose the

  'Entry help/Check tab. Double click on Srch help for LANGU

  Set oRow = oTableStructure.Rows.Item("SPTXT")

  If Err.Number <> 0 Then

    Exit Function

  End If

 

  'Find offset and length og field SPTXT in and store them

  intStart = oRow.Value("OFFSET")

  intLength = oRow.Value("LENG")

  Set oRow = oHelpValuesTable.Rows(1)

 

  ’Return helpvalue         

  Get_Helpvalue_Language = Trim$(Mid$(oRow.Value("HELPVALUES"), intStart + 1, intLength))

 

End Function

 

 

 

 

4.1.2       Help values – DCOM proxy

 

Sub xxxx

  ’Call the function Get_Helpvalue_Language

   lblLanguage.Caption =  _

  "Language: " & rsDetail!Langu & Get_Helpvalue_Language(rsDetail!Langu)

End Sub

 

Private Function Get_Helpvalue_Language(strLanguageCode As String) As String

 '***************************************************************************

 ' This function returns the language text for strLanguageCode

 '***************************************************************************

 

  Dim oHelpvalues As Helpvalues      'Help value object

  Dim rsSelectionTable As Recordset  'Recordset used for selection criterias

  Dim rsHelpValues As Recordset      'Help values returned

  Dim rsStructure As Recordset       'Structure of help values recordset

  Dim intStart As Integer, intLength As Integer

   

    

  '--------------------------------------------------------------------------

  ' Initialize the help value object. Note that the Destination property

  ' has to be set

  '--------------------------------------------------------------------------

  Set oHelpvalues = New Helpvalues

  oHelpvalues.Destination = oSession.Destination

    

    

  '--------------------------------------------------------------------------

  ' Build table for selection criterias.

  ' The DimAs method creates a recordset which has the structure of the

  ' specified parameter. In this case it is the Selection4Helpvalues table

  ' parameter of the Helpvalues object, which is used to specify

  ' selection criterias for the help values.

  '

  ' DimAs should allways be used when a structure has to be filled

  ' before calling a BAPI.

  '--------------------------------------------------------------------------

 

  Call oHelpvalues.DimAs("BapiGetList", "Selection4Helpvalues", rsSelectionTable)

 

  ’Build selection criteria     

  rsSelectionTable.AddNew

  rsSelectionTable!Select_Fld = "SPRAS"

  rsSelectionTable!Sign = "I"

  rsSelectionTable!Option = "EQ"

  rsSelectionTable!Low = strLanguageCode

  rsSelectionTable.Update

 

  '--------------------------------------------------------------------------

  ' Call the Helpvalues Bapi GetList method

  '--------------------------------------------------------------------------

  oHelpvalues.BapiGetList ObjName:="CompanyCode", _

                          Method:="GetDetail", _

                          Parameter:="CompanycodeDetail", _

                          Field:="LANGU", _

                          Return:=rsReturn, _

                          Selection4HelpValues:=rsSelectionTable, _

                          Helpvalues:=rsHelpValues, _

                          Description4HV:=rsStructure

                          'Values4Field := _

                          'DescriptionOnly := _

                          'ExplicitShlp :=

                          'MaxOfRows :=

                      

   If rsReturn!Code <> "" Then

    MsgBox "Could not access language information"

   Else

    '--------------------------------------------------------------------------

    ' Return the help value. The HelpValue tabel parameter has only

    ' one field, which in this case contains both language code and

    ' language text. As we are only interested in the language text, it is

    ' necessary to use the structure returned by the Description4HV parameter

    ' to extract the part of the field that contains the language text. Before

    ' we do that the record that contains the language text SPTXT must be found.

    ' Then the Offset and Leng fields in Description4HV is used to find

    ' the language text in the HelpValues table.

    '--------------------------------------------------------------------------

          

    Do While Not rsStructure.EOF

      If rsStructure!Fieldname = "SPTXT" Then

        intStart = rsStructure!Offset

        intLength = rsStructure!Leng

        Exit Do

      End If

      rsStructure.MoveNext

    Loop

   

    Get_Helpvalue_Language = Trim$(Mid$(rsHelpValues!Helpvalues, intStart + 1, intLength))

   End If

                      

   Set oHelpvalues = Nothing

End Function

 

4.2      Kilder:

 

 

 

Thomas G. Schuessler: Getting Help for Values: The Helpvalues Object

Artiklen kan findes på: IntelligentERP http://www.intelligenterp.com/columns/archive/index.shtml

 

 

Eksempler fra SAP:   X:\XX\SAPpc\SAPGUI\rfcsdk\OCX\SAMPLES\COMPANYC.ZIP

 

5       Andre relaterede emner

 

5.1      Hvordan man kan hente metadata fra SAP

 

I mange tilfælde vil kendskab til SAP metadata på designtidspunktet være tilstrækkeligt, men i nogle tilfælde kan det være nødvendigt at kunne hente disse data dynamisk (Runtime).

 

SAP har en funktion der kan bruges til dette formål DDIF_FIELDINFO_GET. Bemærk at dette ikke er en BAPI, men den kan kaldes enten ved hjælp af RFC, BAPI ActiveX kontrollen, eller DCOM Connectoren.

 

Import parametre:

 

TABNAME                    Char30              Navn på struktur /tabel

FIELDNAME                  Char30              Navn på felt

LANGU                         Char1                Sprog kode                    (Default er logon sproget)

 

Den eneste krævede paramater er TABNAME

 

Export parametre:

 

X030L_WA                    Structure X030L Header information for strukture/tabel

 

Table parametre:

 

DFIES_TAB                  Structure DFIES Metadata for felter i strukture/tabel

 

 

Bemærk at der i 4.6 er tilføjet flere parametre.

 

 

 

5.1.1       Eksempel

 

Jeg har med DCOM Connectoren genereret en proxy for SAP funktionen DDIF_FIELDINFO_GET.

 

Proxyen DDIF_FIELDINFO_GET.dll indeholder klassen CLASS_DDIF_FIELDINFO_GET

 

 

 

 

 

5.1.2       Kilder

 

 

Thomas G.Schuessler: Using parameter metadata in ABAP programming

Artiklen kan findes på: IntelligentERP http://www.intelligenterp.com/columns/archive/index.shtml

 

 

 

 

 

 

6       Andre nyttige kilder

 

Thomas G. Schuessler:  Error handling in BAPI enabled programs.

Artiklen kan findes på: IntelligentERP http://www.intelligenterp.com/columns/archive/index.shtml

 

Open Bapi Network: http://www.sap.com/solutions/technology/bapi/index.ht