Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
0 Kudos


In different postings I show the possibilities to use different languages with ABAP, e.g. here.

Here now an example how to use VBScript inside ABAP and how to store the VBScript source as include.

At first create a new include, e.g with the name ZVBSCRIPT001:
'-Begin-----------------------------------------------------------------

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

'-Function plus---------------------------------------------------------
Function plus(val1, val2)
plus = val1 + val2
End Function

'-Function minus--------------------------------------------------------
Function minus(val1, val2)
minus = val1 - val2
End Function

'-Function plusminus----------------------------------------------------
Function plusminus(val1, val2, val3)
Dim res
res = plus(val1, val2)
plusminus = minus(res, val3)
End Function

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

As you can see, it is a collection of VBScript functions. Don't forget to activate this include. If an error occurs, ignore it.

Now create a new function module, e.g. with the name ZREADVBCODE:
"-Begin-----------------------------------------------------------------
Function ZREADVBCODE .

*"--------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(I_INCLNAME) TYPE SOBJ_NAME
*" EXPORTING
*" VALUE(E_STRINCL) TYPE STRING
*"--------------------------------------------------------------------

Data resTADIR Type TADIR.
Data tabIncl Type Table Of String.
Data lineIncl Type String Value ''.
Data strIncl Type String Value ''.

Select Single * From TADIR Into resTADIR
Where OBJ_NAME = I_InclName.
If sy-subrc = 0.
Read Report I_InclName Into tabIncl.
If sy-subrc = 0.
Loop At tabIncl Into lineIncl.
If lineIncl <> ''.
"-Trim leading and trailing spaces----------------------------
Condense lineIncl.
"-If line is no comment---------------------------------------
If lineIncl+0(1) <> ''''.
Concatenate strIncl lineIncl
cl_abap_char_utilities=>cr_lf Into strIncl.
EndIf.
lineIncl = ''.
EndIf.
EndLoop.
EndIf.
EndIf.
E_strIncl = strIncl.

EndFunction.
"-End-------------------------------------------------------------------

This function module reads an include and delivers the content of the include as string.

As last source the program ZVBSCRIPT:
"-Begin-----------------------------------------------------------------
Report zVBScript.

Type-Pools OLE2.

Data ScriptCtrl Type OLE2_OBJECT.
Data Result Type Integer.
Data InclCode Type String Value ''.

Create Object ScriptCtrl 'MSScriptControl.ScriptControl'.
If sy-subrc = 0 And ScriptCtrl-Handle <> 0 And ScriptCtrl-Type = 'OLE2'.

"-Allow to display UI elements--------------------------------------
Set Property Of ScriptCtrl 'AllowUI' = 1.
"-Intialize the VBScript language-----------------------------------
Set Property Of ScriptCtrl 'Language' = 'VBScript'.

"-Read Visual Basic Script code from include file-------------------
Call Function 'ZREADVBCODE'
Exporting
I_InclName = 'ZVBSCRIPT001'
Importing
E_strIncl = InclCode.

"Include ZVBSCRIPT001.

Call Method Of ScriptCtrl 'AddCode' Exporting #1 = InclCode.
If sy-subrc = 0.
Call Method Of ScriptCtrl 'Eval' = Result
Exporting #1 = 'plusminus(32, 16, 8)'.
Write: / Result. "Result = 40
EndIf.

"-Free the object---------------------------------------------------
Free Object ScriptCtrl.

EndIf.

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

It creates an Visaul Basic Script Control and reads the include ZVBSCRIPT001. It adds the source from the include and with the method Eval we execute the VBScript function plusminus.

With this way it is very easy to integrate and to use VBScript sources with the SAP development workbench. So it is much more handier as the concatenation of a string with a macro - like in my other examples. This paves the way for an easy polyglot programming.

Here an example with a string as return value.
"-Begin-----------------------------------------------------------------
Report zVBScript.

Data:
ScriptCtrl Type OLE2_OBJECT,
Result Type String,
InclCode Type String.

Create Object ScriptCtrl 'MSScriptControl.ScriptControl'.
If sy-subrc = 0 And ScriptCtrl-Handle <> 0 And ScriptCtrl-Type = 'OLE2'.

"-Allow to display UI elements--------------------------------------
Set Property Of ScriptCtrl 'AllowUI' = 1.
"-Intialize the VBScript language-----------------------------------
Set Property Of ScriptCtrl 'Language' = 'VBScript'.

InclCode = 'Function strRet :'.
InclCode = InclCode && ' strRet = "Hello World" :'.
InclCode = InclCode && 'End Function'.

Call Method Of ScriptCtrl 'AddCode' Exporting #1 = InclCode.
If sy-subrc = 0.
Call Method Of ScriptCtrl 'Eval' = Result
Exporting #1 = 'strRet'.
Write: / Result. "Result = Hello World
EndIf.

"-Free the object---------------------------------------------------
Free Object ScriptCtrl.

EndIf.

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

9 Comments
JandeMooij
Explorer
0 Kudos

Hello Stefan,

I have been following your examples on different sites and am intrigued by the possibilities of SAP GUI Scripting. I have a use case for a SAP GUI Script to run a transaction on SAP with a function like this :

Function ProcessRow()

Dim W_Transaction, W_Variant

W_Transaction = "/nPC00_M16_CALC_SIMU"

W_Variant = "DEMO1"

objSess.findById("wnd[0]").Maximize

objSess.findById("wnd[0]/tbar[0]/okcd").Text = W_Transaction

objSess.findById("wnd[0]").sendVKey 0

objSess.findById("wnd[0]/tbar[1]/btn[17]").press

objSess.findById("wnd[1]/usr/txtV-LOW").Text = W_Variant

objSess.findById("wnd[1]/usr/txtENAME-LOW").Text = ""

objSess.findById("wnd[1]/usr/txtENAME-LOW").SetFocus

objSess.findById("wnd[1]/usr/txtENAME-LOW").caretPosition = 0

objSess.findById("wnd[1]").sendVKey 8

objSess.findById("wnd[0]/tbar[1]/btn[8]").press

End Function

which I have stored in an include like you do in this example above, but when I execute this in ABAP with call method of 'AddCode' I get return code 2 - how to I debug my script and/or do you have a working example for this use case (calling SAP transaction from SAP with a Script) ?


Thanks in advance!

Jan

stefan_schnell
Active Contributor
0 Kudos

Hello Jan,

it is possible to do that. You must develop your script completely outside from the SAP backend context and only then you should use. It is not possible to debug your script in the SAP backend context.

Here an example script which works:

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

  Function ProcessRow()

    If Not IsObject(application) Then
      Set SapGuiAuto = GetObject("SAPGUI")
      Set application = SapGuiAuto.GetScriptingEngine
    End If

    If Not IsObject(connection) Then
      Set connection = application.Children(0)
    End If

    If Not IsObject(session) Then
      Set session = connection.Children(0)
    End If

    W_Transaction = "/nPC00_M16_CALC_SIMU"
    W_Variant = "SAP&OC"

    session.findById("wnd[0]").Maximize
    session.findById("wnd[0]/tbar[0]/okcd").Text = W_Transaction
    session.findById("wnd[0]").sendVKey 0
    session.findById("wnd[0]").sendVKey 4
    session.findById("wnd[1]/usr/lbl[1,3]").caretPosition = 1
    session.findById("wnd[1]").sendVKey 2
    session.findById("wnd[0]/tbar[1]/btn[8]").press

    ProcessRow = 1

  End Function

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

And here the ABAP report:

"-Begin-----------------------------------------------------------------
  Report zVBScript.

    "-Type pools--------------------------------------------------------
      Type-Pools OLE2.

    "-Variables---------------------------------------------------------
      Data ScriptCtrl Type OLE2_OBJECT.
      Data Result Type Integer.
      Data InclCode Type String Value ''.

    "-Main--------------------------------------------------------------
      Create Object ScriptCtrl 'MSScriptControl.ScriptControl'.

      If sy-subrc = 0 And ScriptCtrl-Handle <> 0 And
        ScriptCtrl-Type = 'OLE2'.

        "-Allow to display UI elements----------------------------------
          Set Property Of ScriptCtrl 'AllowUI' = 1.

        "-Intialize the VBScript language-------------------------------
          Set Property Of ScriptCtrl 'Language' = 'VBScript'.

        "-Read Visual Basic Script code from include file---------------
          Call Function 'Z_READCODE'
            Exporting I_InclName = 'Z_VBSCRIPT001'
            Importing E_strIncl = InclCode.

        Call Method Of ScriptCtrl 'AddCode' Exporting #1 = InclCode.

        If sy-subrc = 0.

          Call Method Of ScriptCtrl 'Eval' = Result
            Exporting #1 = 'ProcessRow()'.

          Write: / Result. "Result = 1

        EndIf.

        "-Free the object-----------------------------------------------
          Free Object ScriptCtrl.

      EndIf.

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

I check it out and it works.

But you must be very carefully to control an SAP session from another SAP session. You must be very sure that the session you want to control with your script is not the session which executes the report.

Cheers

Stefan

JandeMooij
Explorer
0 Kudos

Thanks Stefan, much appreciated !

JandeMooij
Explorer
0 Kudos

Hi Stefan,

The problem I face is that code that runs fine in the VBA editor, sometimes gives subrc=2 when  Call Method Of ScriptCtrl 'AddCode' Exporting #1 = InclCode is executed. Any idea how I can syntax check this or is there something obvious I need to know when using code like this :

Function StartProcessing(Optional mysystem As String)

Dim SapGuiAuto, WScript, msgcol

Dim objGui  As GuiApplication

Dim objConn As GuiConnection

Dim objSess As GuiSession

Dim objSBar As GuiStatusbar

Dim W_System

Dim iCtr As Integer

Dim W_Obj1, W_Obj2, W_Obj3, W_Obj4, iRow

Dim W_Func

Dim W_Src_Ord

Dim W_Ret As Boolean

Dim il, it

Dim W_conn, W_Sess

Dim W_Transaction, W_Variant

Dim lineitems As Long

If mysystem = "" Then

     W_System = "ELS010"

Else

     W_System = mysystem

End If

If W_System = "" Then

    Exit Function

End If

If Not objSess Is Nothing Then

     If objSess.Info.SystemName & objSess.Info.Client = W_System Then

         Exit Function

     End If

End If

If objGui Is Nothing Then

    Set SapGuiAuto = GetObject("SAPGUI")

    Set objGui = SapGuiAuto.GetScriptingEngine

End If

  For il = 0 To objGui.Children.Count - 1

    Set W_conn = objGui.Children(il + 0)

     For it = 0 To W_conn.Children.Count - 1

         Set W_Sess = W_conn.Children(it + 0)

         If W_Sess.Info.SystemName & W_Sess.Info.Client = W_System And W_Sess.Info.Transaction <> "SE38" Then

             Set objConn = objGui.Children(il + 0)

             Set objSess = objConn.Children(it + 0)

             Exit For

         End If

     Next

  Next

If objSess Is Nothing Then

    MsgBox "No active session to system " + W_System + ", or scripting is not enabled.", vbCritical + vbOKOnly

    GoTo myerr

End If

If IsObject(WScript) Then

    WScript.ConnectObject objSess, "on"

    WScript.ConnectObject objGui, "on"

End If

Set objSBar = objSess.findById("wnd[0]/sbar")

objSess.findById("wnd[0]").Maximize

On Error GoTo myerr

W_Transaction = "/nPC00_M16_CALC_SIMU"

W_Variant = "DEMO1"

objSess.findById("wnd[0]").Maximize

objSess.findById("wnd[0]/tbar[0]/okcd").Text = W_Transaction

objSess.findById("wnd[0]").sendVKey 0

objSess.findById("wnd[0]/tbar[1]/btn[17]").press

objSess.findById("wnd[1]/usr/txtV-LOW").Text = W_Variant

objSess.findById("wnd[1]/usr/txtENAME-LOW").Text = ""

objSess.findById("wnd[1]/usr/txtENAME-LOW").SetFocus

objSess.findById("wnd[1]/usr/txtENAME-LOW").caretPosition = 0

objSess.findById("wnd[1]").sendVKey 8

objSess.findById("wnd[0]/tbar[1]/btn[8]").press

Exit Function

myerr:

End Function

stefan_schnell
Active Contributor
0 Kudos

Hello Jan,

it is not possible to use VBA code with this method. You can only use VBScript. In your case e.g. the Dim declaration with a specification of type generates an error.

Cheers

Stefan

SapekshGupta
Explorer
Hi Stefan,

Is there any way to return a string or character array from the VBS function as a result back into SAP ?

I have been looking for it for quite a few weeks on different sites but haven't been able to find a way. All the above examples demonstrate importing the result only as an integer and we cannot use import a character string directly this way as it results in a runtime error.

Can you please suggest any alternate way to import results as a character string?

Thanks in advance!

Sapeksh
stefan_schnell
Active Contributor
sapeksh_gupta

Hello Sapeksh,

I added an example with a string as return value above.

Best regards
Stefan
SapekshGupta
Explorer
Thanks Stefan! Much appreciated.

Honestly, that was a bit stupid of me not to look at the simpler side of just changing the type of return variable to string, though I did try OBJ_RECORD and OLE2_OBJECT in its place and failed somehow due to some mistakes in the script. 🙂

Warm regards,

Sapeksh
stefan_schnell
Active Contributor
0 Kudos
You are always welcome sapeksh_gupta
Labels in this area