[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.

[ABAP] OLE2: VBScript-Code über MSScriptControl ausführen

* http://www.thescarms.com/VBasic/Scripting.aspx
* https://de.wikibooks.org/wiki/Visual_Basic_Script_(VBS):_Einf%C3%BChrung
* https://wiki.scn.sap.com/wiki/display/Snippets/How+to+use+VBScript+in+ABAP
* https://www.experts-exchange.com/questions/26443935/Login-to-SAP-with-VBScript.html

* VBS-Code mit Beispielfunktionen einfügen
* Option Explicit --> Alle Variablen im VBS müssen mit Dim deklariert werden
DATA(it_vbs_code) = VALUE stringtab( ( |Option Explicit| )
                                     ( || )
* Funktion mit Übergabeparametern
                                     ( |Function Add(val1, val2)| )
                                     ( |  Add = val1 + val2| )
                                     ( |End Function| )
                                     ( || )
* Funktion zur Anzeige einer Messagebox
                                     ( |Function ShowMsgBox(InfoText)| )
                                     ( |  Dim msg| )
                                     ( |  msg = MsgBox(InfoText, vbOkOnly, "Info")| )
                                     ( |End Function| )
                                     ( || )
* Sub (keine Parameter) mit Beispiel für Dateiausführung
                                     ( |Sub Run()| )
                                     ( |  Dim wshell| )
                                     ( |  Set wshell = CreateObject("Wscript.Shell")| )
                                     ( |  wshell.Run "cmd.exe", 1, False| )
                                     ( |End Sub| )
                                     ( || )
* einfacher Eingabedialog
                                     ( |Function Input()| )
                                     ( |  Input = InputBox("Namen:", "Namen eingeben", "Horst")| )
                                     ( |End Function| )
                                     ( || )
* Excel-OLE
                                     ( |Function GenerateXLSX(FileName)| )
                                     ( |  Dim oXL| )
                                     ( |  Set oXL = CreateObject("Excel.Application")| )
                                     ( |  oXL.Visible = True| )
                                     ( |  oXL.Workbooks.Add| )
                                     ( |  oXL.Cells(1, 1).Value = "Test"| )
                                     ( |  oXL.ActiveWorkbook.SaveAs(FileName)| )
                                     ( |  oXL.Quit| )
                                     ( |  oXL = Nothing| )
                                     ( |End Function| )
                                   ).

DATA: lv_vbscode TYPE string.

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

* Scriptcontrol-Objekt erzeugen
DATA: o_scr TYPE ole2_object.
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 'VBScript'
  SET PROPERTY OF o_scr 'Language' = 'VBScript'.

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

* wenn Syntax ok
  IF sy-subrc = 0.
* einfacher 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.

* Eingabefeld mit Rückgabestring
    DATA: lv_res_s TYPE string.

    CALL METHOD OF o_scr 'Eval' = lv_res_s
      EXPORTING
        #1 = 'Input()'.

    WRITE: / 'Input() =', lv_res_s.

    DATA(lv_txt) = |ShowMsgBox("Hallo { lv_res_s }!")|.
* MessageBox anzeigen
    CALL METHOD OF o_scr 'Eval'
      EXPORTING
        #1 = lv_txt.

    WRITE: / lv_txt.

* Subroutine für Ausführung Exe-Datei aufrufen
    CALL METHOD OF o_scr 'Run'
      EXPORTING
        #1 = 'Run'.

    WRITE: / 'Run()'.

* Excel-Datei generieren
    CALL METHOD OF o_scr 'Eval'
      EXPORTING
        #1 = 'GenerateXLSX("c:\temp\test.xlsx")'.

    WRITE: / 'GenerateXLSX()'.
  ELSE.
    WRITE: / 'Fehler im Code: ', sy-subrc.
  ENDIF.

* Objekt zerstören
  FREE OBJECT o_scr.
ENDIF.