Vergleich der Nutzung von COM-Bibliotheken in VBScript und ABAP

Component Object Model (COM) Bibliotheken fanden ihren Ursprung in der fehlenden Transparenz von Dynamic Link Libraries (DLL). Während die DLLs nach außen nur ihre Funktionsaufrufe exponieren stellen COM-Bibliotheken auch deren Parameter mit den Datentypen zur Verfügung. Zusätzlich können auch Enumerationen exponiert werden. COM-Bibliotheken sind der nächste Schritt in der DLL-Evolution. Auch der Ansatz zum Aufruf von Funktionen wurde verändert, während DLLs in den Adressraum eingeblendet und die Funktionen direkt adressiert werden nutzen COM-Bibliotheken eine abstraktere Schnittstelle. Hierfür wird u.a. die Windows-Registry genutzt in der entsprechende Einträge vorgenommen werden müssen. Leider hat sich die Erstellung und Nutzung von COM-Bibliotheken nur sehr bedeckt verhalten. SAP hat ABAP mit entsprechenden Befehlen versehen, die im Kontext des SAP GUI für Windows mit einem Dialog-Benutzer zum Einsatz gebracht werden können. Leider hat sich auch hier der Einsatz nur sehr verhalten dargestellt, oftmals setzten Entscheider lieber auf den Einsatz von teuren Server-Lösungen statt die verfügbare Leistung des Frontendservers zu nutzen. Nichts desto trotz stehen die Möglichkeiten zur Verfügung und hier möchte ich einen kleinen Vergleich der Nutzung von COM-Bibliotheken zwischen VBScript und ABAP durchführen.

VBScript ist die Skriptsprache die seit langem Windows begleitet und bis zur aktuellen Version 10 verfügbar ist. VBScript ist fest mit COM verbunden und bietet beste Möglichkeiten zur einfachen Nutzung. Aus dieser Perspektive der beste Partner um die notwendigen Ausprägungen zur Nutzung mit ABAP zu vergleichen.

Beginnen wir mit der Objekterzeugung (Instanzierung einer Klasse):
VBS: Set oCon = CreateObject(„ADODB.Connection“)
ABAP: Create Object oCon ‚ADODB.Connection‘.
Das ist sehr äquivalent, deutlich ist der gleiche Ansatz zu erkennen, trotz der unterschiedlichen Sprachen.

Schauen wir uns nun das Schreiben von Attributen an:
VBS: oCon.CursorLocation = adUseClient
ABAP: Set Property Of oCon ‚CursorLocation‘ = adUseClient.
Immer noch äquivalent, obwohl die Ausprägung in ABAP länger formuliert ist, aber dafür technisch präziser.
Beim Lesen von Attributen ist es genauso:
VBS: oRecSet.RecordCount
ABAP: Get Property Of oRecSet ‚RecordCount‘ = cntRec.
Hier zeigt sich allerdings ein signifikanter Unterschied, VBScript bietet die Möglichkeit der direkten Wertrückgabe mit Aufruf des Attributes. Das ist mit ABAP nicht möglich, hier müssen stets Variablen verwendet werden, das macht den Quelltext natürlich umfangreicher.

Beim Methodenaufruf gestaltet es sich ähnlich:
VBS: oCon.Open „DRIVER=SQLite3 ODBC Driver;Database=C:\Dummy\MyDb.db3;“
ABAP: Call Method Of oCon ‚Open‘ Exporting
#1 = ‚DRIVER=SQLite3 ODBC Driver;Database=C:\Dummy\MyDb.db3;‘.

Last but not least die Objektzerstörung:
Set oCon = Nothing
Free Object oCon.

Wie wir sehen ist der Unterschied alles in allem nicht allzu groß. Die COBOL-Ursprünge die noch in ABAP erkennbar sind machen den Quelltext umfangreicher und an manchen Stellen, je nach Einsatz, auch etwas komplexer. Generell lässt sich aber festhalten, dass die Nutzung von COM-Bibliotheken mit ABAP sich ähnlich gestaltet wie in VBScript. Wenn man die VBScript-Möglichkeiten nicht ausschöpft, kann man sehr äquivalenten Code zu ABAP erstellen und damit auf diesem Wege beispielsweise ein Prototyping der Komponenten auf dem Frontend-Server durchführen.

Hinweis: Zur Analyse von COM-Bibliotheken empfiehlt sich der OLE/COM Object Viewer von Microsoft. Er ist Bestandteil des Microsoft SDK für Windows und kann kostenlos geladen werden. Dies ist besonders von Vorteil um zu ermitteln ob es sich bei einem Aufruf um eine Methode oder ein Attribut handelt. Der Unterschied ist im VBScript nicht so signifikant wie in ABAP.

Nun mag es der Eine oder Andere für fragwürdig halten einen solchen Vergleich vorzunehmen, ich sehe hier jedoch keine Probleme, denn ein Blick über den Tellerrand ist stets ein Gewinn.

 

Hier noch der direkte Vergleich zweier äquivalenter Quelltexte. Zuerst in VBScript:

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

  '-Directives----------------------------------------------------------
    Option Explicit

  '-Constants-----------------------------------------------------------
    Const adUseClient = 3

  '-Sub Main------------------------------------------------------------
    Sub Main()

      '-Variables-------------------------------------------------------
        Dim oCon, sSQL, i, oRecSet, oField

      Set oCon = CreateObject("ADODB.Connection")
      If Not IsObject(oCon) Then
        Exit Sub
      End If
      oCon.CursorLocation = adUseClient
      oCon.Open "DRIVER=SQLite3 ODBC Driver;Database=C:\Dummy\MyDb.db3;"

      sSQL = "DROP TABLE tblTest"
      On Error Resume Next
      oCon.Execute sSQL
      On Error GoTo 0

      sSQL = "CREATE TABLE tblTest(ID INTEGER PRIMARY KEY, " & _
        "NAME VARCHAR(40))"
      oCon.Execute sSQL

      For i = 1 To 16
        sSQL = "INSERT INTO tblTest VALUES( " & CStr(i) & _
          ", 'Name" & CStr(i) & "')"
        oCon.Execute sSQL
      Next

      sSQL = "SELECT * FROM tblTest"
      Set oRecSet = oCon.Execute(sSQL)
      For i = 1 To oRecSet.RecordCount
        For Each oField In oRecSet.Fields
          WScript.Echo oField.Name, oField.Value
        Next
        oRecSet.MoveNext
      Next

      oCon.Close
      Set oCon = Nothing

    End Sub

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

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

 

Nun in ABAP:

"-Begin-----------------------------------------------------------------
Report ZODBC_SQLITE.

  "-Constants-----------------------------------------------------------
    Constants adUseClient Type i Value 3.

  "-Variables-----------------------------------------------------------
    Data oCon Type OLE2_OBJECT.
    Data oRecSet Type OLE2_OBJECT.
    Data oFields Type OLE2_OBJECT.
    Data oField Type OLE2_OBJECT.
    Data cntRec Type i.
    Data cntFields Type i.
    Data sSQL Type String.
    Data i Type i.
    Data j Type i.
    Data nameField Type String.
    Data valueField Type String.

  "-Main----------------------------------------------------------------
    Create Object oCon 'ADODB.Connection'.
    If sy-subrc <> 0 Or oCon-Handle <= 0 Or oCon-Type <> 'OLE2'..
      Exit.
    EndIf.
    Set Property Of oCon 'CursorLocation' = adUseClient.
    Call Method Of oCon 'Open' Exporting
      #1 = 'DRIVER=SQLite3 ODBC Driver;Database=C:\Dummy\MyDb.db3;'.

    sSQL = 'DROP TABLE tblTest'.
    Call Method Of oCon 'Execute' Exporting #1 = sSQL.

    sSQL = 'CREATE TABLE tblTest(ID INTEGER PRIMARY KEY, NAME VARCHAR(40))'.
    Call Method Of oCon 'Execute' Exporting #1 = sSQL.

    i = 1.
    While i <= 16.
      sSQL = 'INSERT INTO tblTest VALUES(' && i && ', ''Name' && i && ''')'.
      Call Method Of oCon 'Execute' Exporting #1 = sSQL.
      i = i + 1.
    EndWhile.

    sSQL = 'SELECT * FROM tblTest'.
    Call Method Of oCon 'Execute' = oRecSet Exporting #1 = sSQL.
    Get Property Of oRecSet 'RecordCount' = cntRec.
    i = 1.
    While i <= cntRec.
      Get Property Of oRecSet 'Fields' = oFields.
      Get Property Of oFields 'Count' = cntFields.
      j = 0.
      While j <= cntFields - 1.
        Get Property Of oFields 'Item' = oField Exporting #1 = j.
        Get Property Of oField 'Name' = nameField.
        Get Property Of oField 'Value' = valueField.
        Write: / nameField, ` `, valueField.
        j = j + 1.
      EndWhile.
      Call Method Of oRecSet 'MoveNext'.
      i = i + 1.
    EndWhile.

    Call Method Of oCon 'Close'.
    Free Object oCon.

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

image_pdfimage_print