[ABAP] JavaScript-Code über MSScriptControl ausführen

* http://www.thescarms.com/VBasic/Scripting.aspx

* JS-Code mit Beispielfunktionen einfügen
DATA(it_js_code) = VALUE stringtab( ( |var oJSON = \{| )
                                    ( |  "name" : "Heinz",| )
                                    ( |  "age"  : 56,| )
                                    ( |  "city" : "Hamburg"| )
                                    ( |\};| )
                                    ( |function add(a, b) \{| )
                                    ( |  return a + b;| )
                                    ( |\};| )
                                    ( |function getJSONString() \{| )
                                    ( |  return oJSON["name"];| )
                                    ( |\};| )
                                   ).

DATA: lv_jscode TYPE string.

* VBA-Code in String wandeln
LOOP AT it_js_code ASSIGNING FIELD-SYMBOL(<c>).
  DATA(lv_codeline) = condense( <c> ).
  IF lv_jscode IS INITIAL.
    lv_jscode = lv_codeline.
  ELSE.
    lv_jscode = |{ lv_jscode }{ cl_abap_char_utilities=>cr_lf }{ lv_codeline }|.
  ENDIF.
ENDLOOP.

* Scriptcontrol-Objekt erzeugen
DATA: o_scr TYPE ole2_object.
* Variablen für Fehleranalyse
DATA: o_error TYPE ole2_object.
DATA: lv_line TYPE string.
DATA: lv_number TYPE string.
DATA: lv_desc TYPE string.
DATA: lv_source TYPE string.

CREATE OBJECT o_scr 'MSScriptControl.ScriptControl'.

* wenn Erzeugung ok
IF sy-subrc = 0 AND o_scr-handle <> 0 AND o_scr-type = 'OLE2'.
  WRITE: / 'Header', o_scr-header.
  WRITE: / 'Type', o_scr-type.
  WRITE: / 'Handle', o_scr-handle.
  WRITE: / 'CB-Index', o_scr-cb_index.
  WRITE: / 'CLSID', o_scr-clsid.

* GUI anzeigen
  SET PROPERTY OF o_scr 'AllowUI' = 1.
* Sprache ist 'JScript'
  SET PROPERTY OF o_scr 'Language' = 'JScript'.

* Code hinzufügen und Syntaxcheck
  CALL METHOD OF o_scr 'AddCode'
    EXPORTING
      #1 = lv_jscode.

* wenn Syntax ok
  IF sy-subrc = 0.
* Funktionsaufruf mit Übergabeparametern
    DATA: lv_res_i TYPE i.
    CALL METHOD OF o_scr 'Eval' = lv_res_i
      EXPORTING
        #1 = 'add(1, 2)'.

    WRITE: / 'add(1, 2) =', lv_res_i.

* Aufruf Stringfunktion
    DATA: lv_res_str TYPE string.
    CALL METHOD OF o_scr 'Eval' = lv_res_str
      EXPORTING
        #1 = 'getJSONString()'.

    WRITE: / 'getJSONString() =', lv_res_str.

* Aufruf einer nicht vorhandenen Funktion --> Fehlerauswertung
    DATA: lv_res_input TYPE string.
    CALL METHOD OF o_scr 'Eval' = lv_res_input
      EXPORTING
        #1 = 'getInput()'.

    IF sy-subrc = 0.
      WRITE: / 'getInput() =', lv_res_input.
    ELSE.
* Fehlerauswertung
      GET PROPERTY OF o_scr 'Error' = o_error.
      GET PROPERTY OF o_error 'Line' = lv_line.
      GET PROPERTY OF o_error 'Number' = lv_number.
      GET PROPERTY OF o_error 'Description' = lv_desc.
      GET PROPERTY OF o_error 'Source' = lv_source.

      WRITE: / 'Line:', lv_line.
      WRITE: / 'Number:', lv_number.
      WRITE: / 'Desc:', lv_desc.
      WRITE: / 'Source:', lv_source.
    ENDIF.
  ELSE.
    WRITE: / 'Fehler im Code: ', sy-subrc.
  ENDIF.

* Objekt zerstören
  FREE OBJECT o_scr.
ENDIF.