Eigenschaften der RFC Select Schnittstelle

Die in CIS mobile häufig verwendete "RFC Select Schnittstelle" ist eine Kombination zweier Komponenten des SAP Basis Systems:
  • ABAP Select-Anweisung zum Zugriff auf die Datenbank incl. des SAP-eigenen Cache ("Tabellenpuffer" auf Applikationsserver)
  • Remote Function Call (RFC) zum externen Aufruf von ABAP-Funktionen

In VB.NET bauen Sie eine Select-Anweisung auf (SAP-Syntax). Diese wird über RFC an einen generischen ABAP-Funktionsbaustein im SAP-System übermittelt und dort ausgeführt. Die Resultattabelle des Select stellt die Rückgabe des RFC-Aufrufs dar. In VB.NET verarbeiten Sie dann die zurückgegebenen Daten.

Zusätzlich leistet die RFC Select Schnittstelle folgendes:

  • Mehrere Zugriffe können optional auch "gebündelt" verarbeitet werden. Das heißt, mehrere Select-Anweisungen werden gesammelt und dann mit einem einzigen RFC im SAP-System ausgeführt. Die RFC gibt dann alle Resultattabellen der Select-Anweisungen zurück. Die Schnittstelle teilt sie bei der Rückgabe wieder auf die einzelnen Select-Anweisungen auf.
  • Optional können Sie Einzelzugriffe auf SAP-Tabellen in einem Cache puffern, sodass kein RFC nötig ist. Die Zugriffszeiten, falls der Satz im Cache gefunden wird, liegen in der Größenordnung weniger Mikrosekunden, während der RFC Aufruf in der Größenordnung einiger Millisekunden liegt, d.h. ein Faktor 1000.

Vor- und Nachteile:

  • Keine ABAP-Kenntnisse nötig
  • Sehr gute Performance erzielbar
  • Komplexe Select-Zugriffe nur über Definition von Views im SAP-System
  • Zusätzliche Berechtigungsprüfungen können in VB.NET erforderlich sein
  • Sehr schnelle Implementierung
  • Optimal falls alle benötigten Daten aus einer einzigen SAP-Tabelle (oder einem View) stammen
  • Mit lokalem Cache kombinierbar
Beispiel 1:
Artikelnummer und Bezeichnung des Kunden lesen

Zu einer Materialnummer wollen wir die Artikelnummer und Artikelbezeichnung des Kunden als CIS Add-on zusätzlich anzeigen. Alle Details zur Einbindung des Add-ons finden Sie im Kapitel "Add-ons implementieren" im Abschnitt Beispiel Artikelbezeichnung. Hier konzentrieren wir uns auf die Datenbeschaffung.

Im SAP-System werden diese Informationen in Transaktion VD53 angezeigt:

 

Die dazugehörige Datenbanktabelle ist die KNMT, hier mit Transaktion SE11 angezeigt, rot umrandet die beiden Felder die wir benötigen:

 

Mit den Schlüsselfeldern VKORG, VTWEG, KUNNR und MATNR möchten wir die Tabelle KNMT lesen und daraus die Felder KDMAT (Artikelnummer beim Kunden) und POSTX (Artikelbezeichnung beim Kunden) entnehmen. Das VB.NET Coding dazu kann wie folgt aussehen:

VB.net
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Private Function read_knmt(ByVal VKORG As String, ByVal VTWEG As String, _
                ByVal KUNNR As String, ByVal MATNR As String, _
                ByRef KDMAT As String, ByRef POSTX As String) As Boolean


        Dim sapknmt As New addonknmt

        ' fill all key fields
        sapknmt.vkorg = VKORG
        sapknmt.vtweg = VTWEG
        sapknmt.kunnr = KUNNR
        sapknmt.matnr = MATNR

        ' read KNMT via RFC / SAP Select
        If sapknmt.ic.RfcDatabaseRead() Then

            ' set values from KNMT 
            KDMAT = sapknmt.kdmat 'Material number (customer)
            POSTX = sapknmt.postx 'Material text   (customer)

            Return True
        Else

            KDMAT = ""
            POSTX = ""

            Return False

        End If

 

Damit das so funktioniert, insbesondere die Klasse "addonknmt" in VB.NET bekannt ist, legen Sie die Klasse im "S10 Repository" des CIS mobile Projekts an und nehmen in Ihrem VB.NET Projekt "s10cisaddon" die daraus generierten VB.NET-Klassen addonknmt und s10_addonmt auf. Das geht wie folgt:

Starten Sie das S10 Repository,




öffnen das CIS mobile Projekt und klicken Sie im Menü auf Klasse-> Aus SAP-Tabelle erzeugen

 
Im nächsten Screen geben Sie die SAP-Tabelle "KNMT" und Klasse "addonknmt" ein. Bitte selbst hinzugefügte Klassen immer mit "addon" beginnen lassen, damit es bei späteren CIS mobile Upgrades keine Überschneidungen gibt:


:

Im S10 Repository die Klasse "addonknmt" aus der SAP -Tabelle KNMT generieren

 

Als "assembly" bitte Ihr VB.NET Projekt "s10csiaddon" eintragen. Nach der Generierung steht hier zunächst "s10cis", also das CIS mobile Standardprojekt:

Generierte Klasse addonknmt im S10 Repository

 

 

Falls Sie außer den Schlüsselfeldern nur die beiden Felder KDMAT und POSTX benötigen, können Sie alle anderen Felder löschen oder mit // am Zeilenanfang auf Kommentar setzen. Das hat den Vorteil, dass die Datenbankschnittstelle nur diese beiden Felder lesen muss, was insbesondere im Fall eines passenden Sekundärindex dann schneller geht.

Falls Sie später noch andere Felder benötigen, können Sie diese entweder wieder aufnehmen (falls Sie die zusätzlichen Felder im gleichen Datenbankzugriff brauchen) oder eine zweite Klasse addonknmt2 passend für einen unterschiedlichen Datenbankzugriff anlegen.

Das Feld MANDT (Mandant im SAP-System) können Sie löschen, da es von der SAP-Select-Schnittstelle automatisch gesetzt wird. Es schadet aber auch nichts, wenn Sie es in der Klasse lassen. Auf jeden Fall ist es nicht erforderlich, MANDT zum Lesen der Tabelle mit einem Wert zu versehen.

Zum Schluss noch im S10 Repository "Generieren" drücken, um die VB.NET-Klassen zu generieren.

Klasse addonknmt im S10 Repository nach Löschen nicht benötigter Felder

 

Aus der Klasse addonknmt werden bei "Generieren" die VB.NET Dateien addonknmt.vb und s10_addonknmt.vb erzeugt. Nehmen Sie beide Dateien in Ihr VB.NET Projekt "s10ciaddon" auf. Dazu am besten die Dateien zunächst aus dem Unterverzeichnis "classes\s10cisaddon" des CIS mobile Ordners kopieren nach config\s10cisaddon:

Die beiden generierten VB.NET Dateien liegen zunächst in classes/s10cisaddon
 

Kopieren Sie die beiden Dateien in Ihr Projekt, also nach config/s10cisaddon

 

Und nehmen Sie schließlich noch beide Dateien mit "Vorhandenes Element hinzufügen" in Visual Studio in Ihr VB.NET Projekt "s10cisaddon" auf :



 

Generelles Vorgehen zum Lesen einer SAP Tabelle

1. Zu der SAP Tabelle XXXX generieren Sie im S10 Repository eine Klasse addonxxxx

2. Bei assembly= setzen Sie statt des generierten "s10cis" "s10cisaddon" ein

3. Optional: Dort die nicht benötigen Felder (aber nicht die Schlüsselfelder) entfernen

4. Auf "Generieren" klicken

5. Die beiden Dateien addonxxxx.vb und s10_addonxxxx.vb kopieren Sie von classes/s10cisaddon nach config/s10cisaddon

6. In Ihrem VB.NET Project "s10cisaddon" nehmen Sie die beiden Dateien hinzu über Projekt->Vorhandenes Element hinzufügen auf

7. Jetzt können Sie in VB.NET ein Objekt der Klasse addonxxxx anlegen und mit ic.RfcDatabaseRead() oder ic.RfcDatabaSeselect() die SAP-Tabelle lesen

Mengenzugriffe

Statt einer einzelnen Tabellenzeile können Sie auch eine Menge von Zeilen aus einer Tabelle einlesen, die durch eine WHERE-Bedingung spezifziert wird.
Ein ausführliches Beispiel dazu finden Sie bei dem Add-on Reklamationen.

Vorgehen:

1. Zu der SAP Tabelle XXXX generieren Sie im S10 Repository eine Klasse addonxxxx

2. Bei assembly= setzen Sie statt des generierten "s10cis" den Namen "s10cisaddon" ein

3. Optional: In der Klasse die nicht benötigen Felder (aber nicht die Schlüsselfelder) entfernen

4. Auf "Generieren" klicken

5. Die beiden Dateien addonxxxx.vb und s10_addonxxxx.vb kopieren Sie von classes/s10cisaddon nach config/s10cisaddon

6. In Ihrem VB.NET Project "s10cisaddon" nehmen Sie die beiden Dateien hinzu über Projekt->Vorhandenes Element hinzufügen

7. Im S10 Repository nehmen Sie in der Klasse "addon" einen "folder" auf, der Objekte der Klasse addonxxx enthält:

   folder all_xxxx class="addonxxxx"

8. Jetzt können Sie in VB.NET  mit all_xxxx.RfcDatabaseSelect() die gewünschten Tabellenzeilen einlesen

9. Mit der Schleife

    For all  x as addonxxxx in all_xxxx


    Next

 erhalten Sie nacheinander alle gelesenen Tabellenzeilen.

Beschreibung von ic.RfcDatabaseRead  (aus S10 Forum)
Funktion

Mit ic.RfcDatabaseRead() lesen Sie ein Objekt aus der SAP-Datenbank über die S10 RFC-Datenbankschnittstelle.

Alle mit dbkey="yes" spezifizierten Felder der S10-Klasse werden zur automatischen Bildung der where-Bedingung für den Datenbankzugriff über SAP-Select verwendet.

Format

ic.RfcDatabaseRead([withcache as Boolean = true]) as Boolean

Returnwert

True wenn das Objekt gefunden wurde, andernfalls False.

Argumente
withcache

Der S10-Cache wird verwendet, falls in der Klassendefinition dbcache="yes" angegeben und das Objekt nicht vorher gesperrt wurde.

   

 

Beschreibung von ic.RfcDatabaseSelect (aus S10 Forum)
Funktion

Mit ic.RfcDatabaseSelect() können Sie Datenbanktabellen aus der SAP-Datenbank über die S10 RFC-Datenbankschnittstelle lesen.

Der Ausdruck condition wird verwendet, um den SAP-Select-Befehl auszuführen (WHERE-Bedingung). Nur die erste Zeile der Ergebnistabelle wird ausgewertet; bitte verwenden Sie einen S10 Folder um mehrere Tabellenzeilen einzulesen. 

Sie können Attributnamen mit einem '@' -Präfix in dem Ausdruck verwenden, z.B. @CompanyID. Sie werden durch den Attributwert in datenbankadäquatem Format ersetzt. Strings werden z.B. mit  '...'  eingefasst und Zahlen- oder Datumsformate werden passend eingefügt.

Format

ic.RfcDatabaseSelect(condition As String) As Boolean

Argumente

condition

where-Bedingung für den SAP-Select-Aufruf. Die Syntax ist weitgehend identisch mit der Standard-SQL-Syntax, siehe die SAP-Dokumentation zur ABAP-Select-Anweisung.

Bitte beachten: Die SAP Feldnamen müssen dabei in Grossbuchstaben angegeben sein, z.B. KUNNR und nicht kunnr.

Returnwert

True wenn wenigstens eine Zeile gelesen wurde, andernfalls False

Beschreibung von folder.RfcDatabaseSelect (aus S10 Forum)
Funktion

Mit folder.DatabaseSelect() können Sie mehrere Tabellenzeilen aus einer Datenbank in einen Folder einlesen. Nur bei typisierten Foldern (classname="..." im S10 Folder-Attribut) ist das möglich.

Bestehende Elemente werden gelöscht, bevor die neuen Elemente hinzugefügt werden. Wenn Sie die vorhandenen Elemente behalten und die neuen anhängen möchten, dann verwenden Sie bitte stattdessen  folder.DatabaseAddSelect() .

Der Ausdruck stmt wird verwendet, um einen SQL Befehl auszuführen. Für alle S10 Attribute, die sich auf eine Datenbankspalte beziehen, wird versucht, sie in Übereinstimmung mit einer Spalte der Ergebnisliste zu bringen. Wenn ein Attribut nicht in der Ergebnisliste gefunden wird, wird es leer gelassen.

Für den Ausdruck stmt gibt es zwei Möglichkeiten:

  • Ein vollständiger "Select" Befehl (Vgl. Beispiel 1)
    In diesem Fall wird der Ausdruck ohne irgendwelche Änderungen ausgeführt.
     

  • Ein Ausdruck, der nicht mit "Select" beginnt (Groß- oder Kleinbuchstabe) (Vgl. Beispiel 2)
    In diesem Fall generiert das System zuerst einen Select-Befehl "Select [field list] from [table name] " , fügt dann den Ausdruck hinzu und führt den daraus resultierenden Befehl aus.
    Die [field list] besteht aus allen Datenbankfeldern der S10 Klassendefinition, und der Tabellenname ist der Tabellenname, der der  S10 Klasse zugewiesen wurde. Der Ausdruck stmt kann eine WHERE-Bedingung sein und/oder weitere SQL Sätze wie ORDER BY oder GROUP BY.

Sie können Attributnamen mit einem '@' -Präfix in dem Ausdruck verwenden, z.B. @CompanyID. Sie werden durch den Attributwert in datenbankadäquatem Format ersetzt. Strings werden z.B. mit  '...'  eingefasst und Zahlen- oder Datumsformate werden passend eingefügt.

 

Format

folder.DatabaseSelect(stmt As String) As Integer

Returnwert

Anzahl der neuen Folderelemente,  oder -1, wenn ein Datenbankfehler auftrat.

 

Bündelung von Zugriffen

Wenn Sie z.B. zwei Objekte

dim sapxxxx like addonxxxx
dim sapyyyy like addonyyyy


angelegt haben, zu denen Sie mit ic.RfcDatabaseRead() die Werte aus den SAP-Tabellen xxxx und yyyy lesen:

sapxxxx.ic.rfcdatabaseread()
sapyyyy.ic.rfcdatabaseread()


werden nacheinander zwei RFC-Aufrufe an das SAP-System durchgeführt.

Stattdessen können Sie mit

sapxxxx.ic.rfcdatabaseread(deferred:=True)
sapyyyy.ic.rfcdatabaseread
(deferred:=True)

ic.RfcExecuteDeferredCalls(rfcmessages)

arbeiten. In diesem Fall werden beide Datenbankzugriffe in einem einzigen RFC-Aufruf verarbeitet.
Auch Mengenzugriffe über folder.RfcDatabaseSelect können Sie über
deferred:=True in die gebündelte Verarbeitung aufnehmen.

Verwenden des Cache

Unabhängig von einer eventuellen Pufferung der Tabellen auf dem SAP Applikationsserver können Sie einen Zugriffscache auf der Maschine nutzen, auf dem CIS mobile läuft, und damit in vielen Fällen den RFC-Zugriff vermeiden. Das geschieht einfach durch die Zusatzangabe dbcache="yes" in der Klassendefinition im S10 Repository:

Alle gefundenen Einträge werden dann lokal gespeichert und zunächst dort gesucht. Der Cacheinhalt wird am Anfang des Tages weggeworfen und neu gebildet, d.h. die Einträge im Cache sind maximal 24 Stunden lang veraltet. Damit ist der Cache gut nutzbar für Tabellen, bei denen ein Update am nächsten Tag ausreichend ist. Zum Beispiel: Bezeichnungen von Werken, Lagerorten, Auftragsarten, Steuerkennzeichen, Zahlungsbedingungen etc. 

Die Gesamtgröße des Cache ist im S10 Repository für CIS mobile unter "Eigenschaften" definiert:

Der Cache wird für alle CIS mobile Benutzer gemeinsam genutzt, d.h. was für einen Benutzer eingelesen wurde, wird für alle anderen Benutzer verwendet.

Falls der Cache voll ist, werden die ältesten Einträge durch neu hinzugekommene verdrängt. Bei 4MB und einer durchschnittlichen Länge von 400 Byte pro gespeichertem Satz können ca. 10.000 verschiedene Einträge gepuffert werden. Das ist für eine Anwendung wie CIS mobile ausreichend, da die Menge an Schlüsseln wie Lagerorte, Auftragsarten etc. nicht so gross ist. Sie können aber auch problemlos z.B. 100MB reservieren, da der Speicher ja nur einmal anfällt, auch bei z.B. 50 aktiven Benutzern.

Mit der Trace-Funktion des S10 Repository könen Sie feststellen, welche Zugriffe über den Cache abgewickelt wurden. In dem folgenden Ausschnitt sehen Sie zwei RFC-Funktionsaufrufe und danach mehrere Tabellenzugriffe, die im Cache gefunden wurden: