Technical Articles
How to use VBScript Inside ABAP and Store VBScript Source as Include
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-------------------------------------------------------------------
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
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:
And here the ABAP report:
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
Thanks Stefan, much appreciated !
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
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
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
Sapeksh Gupta
Hello Sapeksh,
I added an example with a string as return value above.
Best regards
Stefan
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
You are always welcome Sapeksh Gupta