Quantcast
Channel: SCN : Document List - Scripting Languages
Viewing all 100 articles
Browse latest View live

A Look Behind the Curtain - Lift the veil from saplogon.exe (Part 1)

$
0
0

Hello community,

 

the SAP logon program saplogon.exe is the centre of rotation of all communication between the SAP GUI for Windows and the SAP application server. The SAP logon is the one and only. If you want to know more details about the activities of the saplogon.exe process, you have the possiblity to use Microsofts Process Monitor from www.sysinternals.com. Set the filter to the process name saplogon.exe.

 

001.JPG

If you activate the capture, you can see a lot of details of activities of the following operation areas:

  1. Access to the file system.
  2. Access to the registry.
  3. Monitoring of the process and its threads, also DLL and device driver access.
  4. Network activities.

 

With this way it is e.g. very easy to detect the procedure of the execution of a SAP GUI Script via the playback function of the SAP GUI Scripting recorder - see also here.

002.JPG

If you want to know and to learn more about the activities of the saplogon.exe process, use the Process Monitor. It is very good to understand how a lot of things work.

 

Cheers

Stefan


A Look Behind the Curtain - Lift the veil from saplogon.exe (Part 2)

$
0
0

Hello community,

 

you can find the first part, with the basic explanations, here.

 

Now another way to know more details of the saplogon.exe activities. Download at first the Dependency Walker from here. It is a free utility that scans any Windows module and builds a hierarchical tree diagram of all dependent modules. Also you can profile the module to detect dynamic dependencies, child processes, thread activity, and exceptions and child processes can be profiled for their dependencies too.

 

dependency1.jpg

 

You can start the profiling with the F7 key. In the monitor you see e.g. the creation of the thread, each call to sapfewse.ocx, msscript.ocx, vbscript.dll etc. etc. etc. The information are very detailed, but you learn a lot of the dependencies between the libraries of the SAP GUI for Windows.

 

dependency2.JPG

 

If you want to know and to learn more about the activities and dependencies of the saplogon.exe process, use, beside the Process Monitor, the Dependency Walker. It is very good to understand how a lot of things work.

 

Hint: If you want to analyze the SAP GUI for Windows via saplogon.exe, you must use the 32-bit version of Dependency Walker on a 32-bit Windows platform. The 32-bit version of Dependency Walker on a 64-bit platform of Windows 7 crashes in my case.

 

Cheers

Stefan

Tip: Call the Correct Scripting Engine in a 64-bit World

$
0
0

Hello community,

 

there are two version of the Windows console cmd.exe on your 64-bit Windows. You can find the 64-bit version of the console in the directory C:\Windows\System32 and you can find the 32-bit version of the console in the directory C:\Windows\SysWOW64. If you start both versions you can't see any difference - only the path. But sometimes it is impossible to know which version of console do you use, e.g. to start a SAP GUI script aka. VBScript.

 

It is possible to differentiate the console versions with the variable PROCESSOR_ARCHITECTURE. With the 32-bit console it delivers x86 and with the 64-bit console it delivers AMD64.

 

console.JPG

With this knowledge we can define a small batch file, called e.g. autoexec.cmd, which can be started with the execution of cmd.exe.

 

@Echo Off

 

Rem -Begin--------------------------------------------------------------

 

  If %PROCESSOR_ARCHITECTURE% == x86 Goto x86

  If %PROCESSOR_ARCHITECTURE% == AMD64 Goto x64

  Goto:eof

 

  Rem -32bit------------------------------------------------------------

    :x86

      Set Path=C:\Windows\SysWOW64;C:\Windows\SysWOW64\Wbem;C:\Windows\SysWOW64\WindowsPowerShell\v1.0

    Goto:eof

 

  Rem -64bit------------------------------------------------------------

    :x64

      Set Path=C:\Windows\System32;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0

 

Rem -End----------------------------------------------------------------

 

In this case I set only different path variables. If 32-bit SysWOW64 and if 64-bit System32. Now the correct version of the Windows Scripting Host will be always startet. On a 32-bit console the 32-bit version and on a 64-bit console the 64-bit version.

 

Put two icons on your desktop, one for 32-bit and the other one for 64-bit console. And if you use the option /K with the [Path]autoexec.cmd file, the paths are set correctly.

 

Cheers

Stefan

ActiveX Component SAP.Functions with Export Parameter String

$
0
0

Hello community,

 

I use a VBS program with the SAP ActiveX components to connect to an SAP system and to execute a FM. Here the function module:


FUNCTION ZRFCINTERFACETEST.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  EXPORTING

*"     VALUE(E_RETURN) TYPE  STRING

*"----------------------------------------------------------------------

 

  E_RETURN = 'This is a test'.

 

ENDFUNCTION.


The function module has one export parameter from the type string. Here the VBS program:


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

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Variables-----------------------------------------------------------

    Dim rfcFunc, rfcCon, Func

 

  '-Sub Main------------------------------------------------------------

    Sub Main()

 

      Set rfcFunc = CreateObject("SAP.Functions")

      'Set rfcFunc = CreateObject("SAP.Functions.Unicode")

      If Not IsObject(rfcFunc) Then

        Exit Sub

      End If

 

      Set rfcCon = rfcFunc.Connection

 

      rfcCon.ApplicationServer = "BCP"

      rfcCon.System = "BCP"

      rfcCon.SystemNumber = "65"

      rfcCon.User = "HUGO"

      rfcCon.Client = "099"

      rfcCon.Language = "EN"

 

      If Not rfcCon.Logon(0, False) Then

        Exit Sub

      End If

 

      Set Func = rfcFunc.Add("ZRFCINTERFACETEST")

      '-Error here: SAP data type not supported

 

      If Func.Call Then

        MsgBox Func.Imports("E_RETURN")

      Else

        MsgBox Func.Exception

      End If

 

      rfcCon.Logoff

 

      Set rfcCon = Nothing

 

    End Sub

 

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

    Main

 

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


If the interpreter reaches the line Set Func = rfcFunc.Add("ZRFCINTERFACETEST") I get the following error:


DataTypeNotSupported.jpg

The SAP ActiveX components doesn't support string parameters. Also it doesn't support table parameters - look here. I think the ActiveX components are phased out. You can find an unanswered question about the future of ActiveX components here.


With the COM Connector (CCo) it works perfect without any errors:


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

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Constants-----------------------------------------------------------

    Const RFC_OK = 0

 

  '-Variables-----------------------------------------------------------

    Dim SAP, hRFC, rc, hFuncDesc, hFunc, charBuffer, strLen

 

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

    Set SAP = CreateObject("COMNWRFC")

    If IsObject(SAP) Then

      hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

        "CLIENT=001, USER=BCUSER")

      If hRFC Then

        hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "ZRFCINTERFACETEST")

        If hFuncDesc Then

          hFunc = SAP.RfcCreateFunction(hFuncDesc)

          If hFunc Then

            If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then

              rc = SAP.RfcGetString(hFunc, "E_RETURN", charBuffer, _

                255, strLen)

              MsgBox charBuffer

            End If

          rc = SAP.RfcDestroyFunction(hFunc)

          End If

        End If

        rc = SAP.RfcCloseConnection(hRFC)

      End If

      Set SAP = Nothing

    End If

 

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


Good scripting.


Cheers

Stefan

How to use dotNET Languages Inside SAP GUI Scripting or GuiXT

$
0
0

Hello community,

 

the basically way to use dotNET languages I describe here.

 

Here is now an alternative to use dotNET library source files direct inside SAP GUI Scripting.

 

At first a source code of a Visual Basic dotNET library file:

 

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

 

  '-Directives----------------------------------------------------------

    Option Strict On

 

  '-Imports-------------------------------------------------------------

    Imports System

    Imports Microsoft.VisualBasic

 

  '-VBCode--------------------------------------------------------------

    Namespace VBCode

 

      Public Class VB

 

        Public Shared Function Hello1() As String

          Return "Hello World!"

        End Function

 

        Public Function Hello2(ByVal Name As String) As String

          Return "Hello " & Name & "!"

        End Function

 

        Public Sub Hello3(ByVal Name As String)

          MsgBox(Name, MsgBoxStyle.OkOnly, "Hello")

        End Sub

 

      End Class

 

    End Namespace

 

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

 

You can compile this code via

vbc /target:library /out:MyLib.dll MyLib.vb

to a library an use it inside your VB projects.

 

Also you can use this code direct inside VBScript resp. SAP GUI Scripting:

 

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

 

  '-Directives----------------------------------------------------------

    Option Explicit

    On Error Resume Next

 

  '-Constants-----------------------------------------------------------

    Const OUTPUT_BUFFER = 2

    Const ForReading = 1

    Const FileName = "MyLib.vb"

 

  '-Variables-----------------------------------------------------------

    Dim FSO, File, VBCode

    Dim PS, PSCode, PSOutput

 

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

 

    '-Read the VBSharp code---------------------------------------------

      Set FSO = CreateObject("Scripting.FileSystemObject")

      If IsObject(FSO) Then

        Set File = FSO.OpenTextFile(FileName, ForReading)

        VBCode = File.ReadAll

        File.Close

        Set FSO = Nothing

      Else

        MsgBox "Can't create FileSystemObject", vbOkOnly, _

          "Important hint"

      End If

 

    If VBCode <> "" Then

 

      Set PS = CreateObject("SAPIEN.ActiveXPoSH")

      If IsObject(PS) Then

 

        PS.OutputMode = OUTPUT_BUFFER

 

        If PS.Init(vbFalse) = 0 And PS.IsPowerShellInstalled() <> 0 Then

 

          PSCode = "$VBCode = @""" & VBCode & """@;"

          PSCode = PSCode & vbCrLf

          PSCode = PSCode & "Add-Type -TypeDefinition $VBCode " & _

            "-Language VisualBasic"

          PSCode = PSCode & vbCrLf

          PSCode = PSCode & "$VB = new-Object VBCode.VB"

          PSCode = PSCode & vbCrLf

 

          '-Execute the different modules-------------------------------

            PSCode = PSCode & "[VBCode.VB]::Hello1()"

            PSCode = PSCode & vbCrLf

            PSCode = PSCode & "$VB.Hello2(""Stefan"")"

            PSCode = PSCode & vbCrLf

            PSCode = PSCode & "$VB.Hello3(""Stefan"")"

 

          PS.Execute(PSCode)

          MsgBox PS.OutputString(), vbOkOnly, "VB# results"

 

        End  If

        Set PS = Nothing

      Else

        MsgBox "Can't create ActiveXPoSH", vbOkOnly, "Important hint"

      End If

 

    End If

 

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

 

At first we read the source of the library in the variable VBCode. Now we insert this content in the context of the PowerShell script code inside the variable PSCode. At last we execute the code and it runs perfect.

 

Now it is very easy to code dotNET language classes and to use this classes multiple, e.g. in your dotNET projects and inside SAP GUI Scripting.

 

Also you can use this way with GuiXT. GuiXT offers with the commands CallVBS and CallVBSAsync full access to VBScript. With GuiXT you can change the SAP Screens without any modifications in the SAP backend. The combination between GuiXT, SAP GUI Scripting and Sapiens PowerShell bridge to the dotNET functionalities offers new horizons of possiblities on presentation server development.

 

Cheers

Stefan

Automation of SAP Netweaver portal

$
0
0

'Automating the SAP netweaver portal - The Everest of Automation!

'

'There are a few articles on the web discussing the automation of the SAP Portal - some even saying its a myth.

'

'Ok it is possible using VBA..(Excel). Could be adapted for vb script.

'

'This assumes you have some knowledge of HTML DOM and general automation.

'

'

'1. Get the URL of your portal. Sometimes the portal window does not display the address bar.

' 1st try to get the URL by right clicking on IE and select properties the URL should be displayed.

' If not, this code will also get the URL of a window with "Home - SAP NetWeaver Portal" (depending on your env).

'Open a portal and run this function.

 

 

Debug.Print oGetPortal.LocationURL

 

Function oGetPortal( _

Optional sWindowTitle AsString = "Home - SAP NetWeaver Portal" _

) AsObject

 

 

   Set objShellApp = CreateObject("Shell.Application")

   ForEach objWindow In objShellApp.Windows

  DoEvents

   If LCase(objWindow.LocationName) = LCase(sWindowTitle) Then

   Set oGetPortal = objWindow

   ExitFor

   EndIf

   Next

   Set objShellApp = Nothing

   Set objWindow = Nothing

EndFunction

 

 

'2 For automation you probably want to create a new instance of the IE portal rather than attach to

'an existing window. The Portal often runs on an intranet.

'In windows 7 the IE object automatically detaches from intranet pages - not very useful for automation.

'

'So the below code works around this issue & should work on earlier windows versions and non intranet pages

'it also opens up the portal in an IE window with an address bar and is easier to get access to the IE developer tools.

 

 

Debug.Print oGetLatestPortal.LocationURL

 

PrivateDeclareSub Sleep Lib"kernel32" (ByVal dwMilliseconds AsLong)

PrivateDeclareFunction GetForegroundWindow Lib"user32" () AsLong

Function oGetLatestPortal( _

  Optional sURL AsString = "http://myportalpath/portal#", _

  Optional sWindowTitle AsString = "Home - SAP NetWeaver Portal") AsObject

 

   Dim IE As InternetExplorer

   Set IE = New InternetExplorer

  

  IE.Navigate sURL

   Dim hwnd AsLong

  hwnd = GetForegroundWindow() ' get latest IE window

   Set IE = Nothing  ' work around for windows 7 issue

 

  i = 0

   DoWhile i < 10And IE IsNothing

 

  i = i + 1

   Set objShellApp = CreateObject("Shell.Application")

   ForEach objWindow In objShellApp.Windows

  DoEvents

   If LCase(objWindow.LocationName) = LCase(sWindowTitle) Then

       If objWindow.hwnd = hwnd Then'active IE window if more than one with same title

                Set IE = objWindow

       EndIf

     EndIf

   Next

  DoEvents

  Sleep 100

   Loop

 

 

   If IE IsNothingThen

  MsgBox "nothing"

ExitFunction

  End If

 

   Set oGetLatestIE = IE

 

EndFunction

 

'3. Wait for IE page to load. You cannot do any automation until after

'the page is loaded. This function returns true if the page or frames top level is loaded (frames discussed later)

 

Debug.Print lWait(oGetLatestPortal)

 

Function lWait(LOIE AsObject) AsBoolean

  Dim t1 AsLong

  Dim t2 AsLong

  OnErrorResumeNext

  t1 = Timer

  t2 = t1 + 60

  Do

   If Timer > t2 Then lWait = False: ExitFunction

  If VarType(LOIE.Document) = vbString ThenExitDo

  Loop

  Do

   If Timer > t2 Then lWait = False: ExitFunction

  If LOIE.Busy = FalseThenExitDo

  Loop

  Do

   If Timer > t2 Then lWait = False: ExitFunction

  If VarType(LOIE.Document.readyState) = "C"ThenExitDo

  Loop

  Do

   If Timer > t2 Then lWait = False: ExitFunction

  If LOIE.Document.readyState = "complete"ThenExitDo

  Loop

  lWait = True

EndFunction

 

 

'4. Find what you wat to click on by using developer tools in IE8+ (F12) with the window you just opened using the above code.

'Use the IE inspect tool (arrow) to click on the field or link/field/button you want to automate. This will

'expand the HTML DOM and show the HTML tag corresponding to the field. If you can see the tag you can automate

'it! But it can be tricky.

'

'5. Clicking on a link. Now that you have open a portal window you want to do something usually click on a link.

'Using the developer tools in IE. Find the link you want. If the link you want is inside a HTML form or frame

'tag see further on.

 

 

lWait IE

Set link = IE.Document.getElementById("MyLink_1_1") ' Can be a div or anchor

link.focus 

link.click

 

' Waiting for elements to appear.

''

' Even though you call lWait and IE is ready, the portal may be doing things. eg.

' displaying spinners (etc) '

 

' ' Wait for spinner  - if a spinner appears you need to wait until it goes (if not skip this) . The spinner is also known as 'wheel of death' by end users. 

' The parameter you pass will usually be the document of the frame see frames (below). Make sure the spinner id is  "ur-loading"

''Again use IE developer tools to find the spinner it can be a little tricky to do. Tip : open IE developer tools F12 and view something that is

'slow like the change history then click on the spinner using the developer tools arrow. You may have to move your mouse around a bit and highlight it.

 

Function WaitForSpinner(iedoc AsObject) AsBoolean

' note, IEdoc can be IE.Document, SubFrame.contentWindow.Document or SubForm.Document (discussed later)

  Dim ctrl AsObject 

  Do

Set ctrl = iedoc.getElementById("ur-loading")

if ctrl is nothing ThenExitFuntion

If ctrl.getAttribute("style").display = "none" ThenExitDo

sleep 500

  Loop

EndFunction

'

' Sometimes you must wait for the element to appear

'Note elements can be forms, frames, links or fields or anything.

' safer way to get a element that will wait until it appears

Dim element AsObject

Dim t1 AsLong

Dim t2 AsLong

 

t1 = Timer

t2 = t1 + 10' secs

 

While element IsNothing

  DoEvents

   If Timer > t2 Then

  MsgBox "timeout"

   ExitDo

   EndIf

' note, IEdoc can be IE.Document, SubFrame.contentWindow.Document or SubForm.Document (discussed later)

 

   Set element = IEdoc.getElementById("elementid")

 

Wend

 

'If you still have problems try to get an element preceeding the element you want

'Use the VB debugger and also put sleeps in and use while loops as shown also you must get any

' forms or frames preceeding the element.

'

'

'

'6. Elements in Forms or Frames

'If you still can't get the element by elementbyid or by looping through getElementsByTagName,

'It could be because the field you want is in a form or frame.

'You should get a reference to any forms or frame preceeding the element first. Use F12 developer tools

'to find out if there are any precedding forms or frames.

 

 

'6 a.HTML frames

'Get an obj reference to a html frame

 

Dim subframe1 AsObject

' Assuming you have any preceeding Forms or Frames

Set subframe1 = IE.Document.getElementById("frameid") ' example

 

lWait subframe1.contentWindow

 

'Once you get a obj reference to a frame you must get the sub document

'before you can do any further searches

 

Dim myframedocument AsObject

Set myframedocument = subframe1.contentWindow.Document

 

Set subframe2 = myframedocument.getElementById("frameid2") ' example

 

'

'6b HTML forms

'

'A HTML Form is similar, again you must get any preceeding Forms or Frames

Dim subform AsObject

Set subform = IE.Document.getElementById("formid") ' example

 

Dim myformdocument AsObject

Set myformdocument = subform.Document

 

Set mylink = myformdocument.getElementById("mylink") ' example

 

'6c info popups'

' Sometimes a message box appears - eg like 'Changes have been made do you want to save?'

' Which requires a 'button' to be pressed. These message boxes aren't javascript alerts they are Html based which means

' we can automate them! Once the popup appears again hit IE8+ F12  (developer tools) and move you mouse over the popup

' and select a field item to get the element id. Note, you might have try a few times as can be hard for developer tools to highlight popup items.

' Once you select an item on the popup you will notice in the DOM in developer tools that the popup is actually an iframe, get the frame's id..

 

Dim subframe1 AsObject

Set subframe1 = IE.Document.getElementById("frameid") ' id of 'popup'

lWait subframe1.contentWindow

 

' Next get document DOM of iframe

Dim myframedocument AsObject

Set myframedocument = subframe1.contentWindow.Document

 

' Next press a button - popup buttons are anchors.

''To get the button id you might have to use developer tools , to dig through the DOM if you can't select it with a mouse.

' Buttons will be and anchor at the botton of the iframe inside a div with footer in the id.

'If you still can't get the element by elementbyid try using getElementsByTagName,

 

Set link = myframedocument.getElementById("anchor id") ' example

link.focus

link.click

 

'7.Dynamic Content. In the portal HTML elements id's can change depending on the context ie whether certain

'sections are data driven or due to different user's role, certain elements are displayed. In the previous

'example Link_1_1 might be a different menu option on one users login to another. So in these cases

'you need to write more generic code. 2 examples.

'

' using a tags attributes

For k1 = 0To IE.Document.links.Length - 1

   If IE.Document.links.Item(k1).getAttribute("title") = "Show Attachments"Then

 

 

IE.Document.links.Item(k1).Click

ExitFor

 

   EndIf

 

Next k1

 

 

' Loop through a table looking for a link's screen text

Set oTbl = IE.Document.getElementById("myNavigationTable")

Set oTBody = oTbl.getElementsByTagName("TBODY").Item(0)

Set oTRow = oTBody.getElementsByTagName("TR").Item(0)

Set oTds = oTRow.getElementsByTagName("TD")

 

ForEach oTd In oTds

  DoEvents

   If InStr(oTd.innertext, "Link Text") > 0Then

   Set link = oTd.getElementsByTagName("A").Item(0)

   ExitFor

   EndIf

 

Next oTd

link.Click

 

 

 

'8.If you hit a back button element on a page you might have to

're-establish VB objects in your code as sometimes they lose reference.

'

'9.Finally this is not a turn key solution - ideally a function could be written to find a control

'by searching the DOM tree handling all frames and forms and waits

'

'I hope this post helps

Interactive and dynamic Excel VBA template - SAP GUI Scripting -

$
0
0

Introduction:

 

SAP GUI Scripting can be used for many small and intermediate batches for mass maintenance tasks (P-/Q- and D-Systems) and quality testing (Q-Systems) in SAP.

To reduce development workload or modify a lot of code for different SAP GUI recordings I saw a need for having an Excel VBA template which can cover a lot of requirements.

 

Features:

 

  • Easy to use (One-Button-Solution).
  • Excel functions and options can be used for data preparation and consolidation in front of starting update procedure.
  • During initialization all existing and non-busy SAP sessions got displayed (UI-Listbox). So we are able to select a specific session for Excel VBA adoption.
  • Data from SAP can easily imported into Excel worksheet (Data from ALV-list, fields, result list, status messages, error messages,… and so on).
  • Only SAP GUI Scripting recording code need to integrate into VBA module ‘SAP_1_PROCESS’.
  • More columns as data source or destination for field data can be added. Last two columns are reserved for procedure usage. This is achieved by using a data-array which got ‘Redim’ during process according to used rows and columns.
  • Log-function is integrated (for SAP messages like statusbar Messages or free-text).

 

Prepare Excel VBA template:

  1. Step: Create folder on your desktop (or somewhere else) => folder name is up to you.
  2. Step: Store below text-files into this folder: Please be aware that text-file 'Modules_All.txt' need to split into four text-files named 'SAP_1_Process', 'SAP_2_Functions'. SAP_3_Public_Subs' and 'Module1'! Start and end of module specific coding is marked and must removed before saving of single text-file. First line in this files must be Attribute VB_Name = "SAP_1_Process", Attribute VB_Name = "SAP_2_Functions" and Attribute VB_Name = "SAP_3_Public_Subs". As I can´t upload more than three files you Need to split Modules_All.txt on your own and save files in folder.
    1. SAP_1_Process.txt
    2. SAP_2_Functions.txt
    3. SAP_3_Public_Subs.txt
    4. Userform1_frm.txt
    5. Userform1_frx.txt
    6. Module1.txt
  3. Step: Create a new Excel workbook and store this in same folder as text-files. You can choice every name you want. My suggestion is ‘Prepare_WB.xlsx’.
  4. Step: Now go into VBE of Excel ( ALT + F11) => insert Module => open text-file ‘Module1.txt’ => Select all and copy => paste into new module from Excel workbook.
  5. Step: Execute macro ‘prepare_worksheet’ (Reference to sapfewse.oxs will done utomatically. This require Folder-structure ENVIRON("PROGRAMFILES") & "\SAP\FRONTEND\SAPgui\sapfewse.oxs"). If you have an different Destination please add manual.
  6. Step: Remove ‘Module1’ from macro-enabled workbook and save.
  7. Done

 

Textfile_before_Split.png

Textfile_after_Split.png

Folder_Prepare.png

After_Prepare.png

VBE_Reference.png

VBA_sapfewse.ocx.png

 

Usage of Excel VBA template (MM03_VBA_SAP_SCRIPTING_V1.xlsm):

 

This Excel template have for demonstration purposes SAP GUI Scripting integrated for getting MM03 data from ‘stor. loc. stck’-tab => ‘Qty. Unrestricted’ + “UoM’ + ‘Material description’ data.

 

  1. Step: Fillin ‘Materialnumber’ + ‘Company Code’ + ‘Storage location’ combination used in your system. As error handling is integrated for ‘Company Code’ + ‘Storage location’ combination you can test this as well.
  2. Step: Press button ‘Run macro ‘SAP_PROCESS’’
  3. Step: All open and Scripting-enabled SAP sessions got displayed in a Userform-Listbox
  4. Step: Select one session and press ‘Enter’ or Commandbutton
  5. Done: Script got executed and you will get data into Excel according to your input data combination (Materialnumber/CoCode/Storage location).

 

WS_SAP_PROCESS.png

SAP_SESSIONS.png

 

Important data structure information:

All data from Excel worksheet ‘SAP_PROCESS’ got stored into data-array ‘arr_SAP_Data’. This Array is defined with same number range as our used worksheet range. Starting from row ‘2’ up to last used row and all used columns (remember that last two columns are reserved for procedure process).

arr_SAP_Data(lngCounter, (lng_Col + 0))

 

=> lngCounter is current executed row in worksheet. (lng_col +0) define column ‘1’

=> (lng_col +1) is second column

=> and so on.

 

When you add or delete columns please save workbook immediately.

Conclusion:

 

Feel free to use this template for your requirements by modify coding in ‘SAP_1_Process’-module. But be aware that I am not responsible for any issues, inconsistencies or other incidents which can cause by using this template. Feel free to ask if you Need any additional information. But do not expect any support for your purposes and requirements. Hope this will give you some lights how SAP GUI Scripting can make your daily tasks much smoother.

How to Create an SAP Server Program with Freestyle BASIC Script Language (FBSL)

$
0
0

Hello community,

 

nearly a half year I develop the COM Connector (CCo), look here.

Since over a month I develop for Freestyle BASIC Script Language (FBSL) an ABAP interface called FbslX, look here.

 

And now I switch my perspective a little bit. Now I use FBSL as "normal" script language with SAP NetWeaver RFC library to connect an SAP system. Here I use also CCo.

 

FBSL is the first BASIC like script language which I know, with which it is possbile to create SAP server programs. Here my example code:


//-Begin----------------------------------------------------------------

 

  //-Directives---------------------------------------------------------
    #AppType Console
    #Option Strict
   
  //-Includes-----------------------------------------------------------
    #Include <Windows.inc>
    #Include <sapnwrfc.inc>

 

  //-ABAPCall-----------------------------------------------------------
    Function ABAPCall(%rfcHandle, %funcHandle, %errorInfo)
      ? "ABAPCall"
      Return 0
    End Function

 

  //-Main---------------------------------------------------------------
    Sub Main()

 

      //-Variables------------------------------------------------------
        Dim %SAP, %hRfc, %hDesc, %rc, %hCon

 

      SAP = CreateObject("COMNWRFC")
      If SAP Then
        CallMethod(SAP, ".About")
        hDesc = GetValue("%d", SAP, ".RfcCreateFunctionDesc(%s)", _
          "ABAPCall")
        If hDesc Then
       
          rc = GetValue("%d", SAP, ".RfcInstallServerFunction(%s, %d, %d)", _
            "", hDesc, AdressOf ABAPCall)

          If rc = RFC_OK Then
         
            hCon = GetValue("%d", SAP, ".RfcRegisterServer(%s)", _
              "program_id=FBSLSERVER, gwhost=ABAP, gwserv=sapgw00")
            If hCon Then
           
              While rc = RFC_OK Or rc = RFC_RETRY
             
                rc = GetValue("%d", SAP, ".RfcListenAndDispatch(%d, %d)", _
                  hCon, 1)
                 
                Select Case rc
                  Case 0
                    OutputDebugString("RFC_OK")
                  Case 14
                    OutputDebugString("RFC_RETRY")
                End Select 
               
                Sleep(256)
             
              Wend
           
            End If
         
          End If
       
          CallMethod(SAP, ".RfcDestroyFunctionDesc(%d)", hDesc)
        End If
        ReleaseObject(SAP)
      End If
  
    End Sub

 

//-End------------------------------------------------------------------

 

You can call this script from ABAP via the following example code:


"-Begin-----------------------------------------------------------------

  Program ZTEST.

    Call Function 'ABAPCall' Destination 'FBSLSERVER'.

 

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

 

You must customize the FBSLSERVER with the TAC SM59 and that's all.

 

In my opinion offers this possibility absolut new horizons. So it is possible to use FBSL scripts as SAP server programs without any other steps, like e.g. compiling etc., or big IDEs or script environments. FBSL is extrem compact and powerful.  You can change the script easily via an simple editor and use it from SAP application server via an ABAP program. I have been searching a long time for this kind of solution.

 

Hope toinspireotherprogrammers.

 

Cheers

Stefan


New Class GuiInputControl in SAP GUI Scripting with SAP GUI for Windows 7.40

$
0
0

Hello community,

 

a few days ago SAP presented the new version of SAP GUI for Windows here. With this new version we get also a new version of SAP GUI Scripting API. The new SAP GUI Scripting API includes a new class, called GuiInputControl. Here the complete interface of the new class:

 

' Interface Name : ISapInputControlTarget

' Class Name : GuiInputControl

' ClassID : {31233701-DF39-49F7-A641-16CAB0C9C5F0}

Interface IDBind ISapInputControlTarget

  Member Call SetFocus()

  Member Call Visualize(In On As Integer, Opt In InnerObject As Variant) As Integer

  Member Call DumpState(In InnerObject As WString) As IDispatch

  Member Call ShowContextMenu()

  Member Call FindById(In Id As WString, Opt In Raise As Variant) As IDispatch

  Member Call FindByName(In Name As WString, In Type As WString) As IDispatch

  Member Call FindByNameEx(In Name As WString, In Type As Long) As IDispatch

  Member Call FindAllByName(In Name As WString, In Type As WString) As IDispatch

  Member Call FindAllByNameEx(In Name As WString, In Type As Long) As IDispatch

  Member Call SelectContextMenuItem (In FunctionCode As WString)

  Member Call SelectContextMenuItemByText(In Text As WString)

  Member Call SelectContextMenuItemByPosition(In PositionDesc As WString)

  Member Call SetInputControlText(In ISapInputControlTarget As WString) As Integer

  Member Call GetInputControlText() As WString

  Member Call Submit()

  Member Call GetLabelText() As WString

  Member Call GetButtonTooltip() As WString

  Member Call GetNumberOfEntries() As Long

  Member Call GetHistoryEntryText(In ISapInputControlTarget As Long) As WString

  Member Call IsHistoryOpend() As Integer

  Member Call GetSelectedHistoryItem() As WString

  Member Get Name() As WString

  Member Get Type() As WString

  Member Get TypeAsNumber() As Long

  Member Get ContainerType() As Integer

  Member Get Id() As WString

  Member Get Parent() As IDispatch

  Member Get Text() As WString

  Member Let Text()

  Member Get Left() As Long

  Member Get Top() As Long

  Member Get Width() As Long

  Member Get Height() As Long

  Member Get ScreenLeft() As Long

  Member Get ScreenTop() As Long

  Member Get Tooltip() As WString

  Member Get Changeable() As Integer

  Member Get Modified() As Integer

  Member Get IconName() As WString

  Member Get AccTooltip() As WString

  Member Get AccLabelCollection() As IDispatch

  Member Get AccText() As WString

  Member Get AccTextOnRequest() As WString

  Member Get ParentFrame() As IDispatch

  Member Get IsSymbolFont() As Integer

  Member Get DefaultTooltip() As WString

  Member Get Children() As IDispatch

  Member Get SubType() As WString

  Member Get CurrentContextMenu() As IDispatch

  Member Get Handle() As Long

  Member Get AccDescription() As WString

  Member Get OcxEvents() As IDispatch

  Member Get DragDropSupported() As Integer

End Interface


Unfortunately was the documentation not updated.


Cheers

Stefan


How to use FBSL inside SAPUI5 via JavaScript in Internet Explorer

$
0
0

Hello community,

 

I presented here FBSL in the ABAP context, and here an example how to use C code inside ABAP.

I presented here ScriptX, a wrapper library, and here how to use SAP GUI Scripting in the context of FBSL.

 

Here now another perspective how to use Freestyle BASIC Script Language in the context of SAPUI5:

 

<!doctype html>

 

<html>

 

  <head>

 

    <meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1" />

    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

 

    <script src="resources/sap-ui-core.js"

      id="sap-ui-bootstrap"

      data-sap-ui-libs="sap.ui.commons"

      data-sap-ui-theme="sap_bluecrystal">

    </script>

 

    <script type="text/javascript">

 

      var oButton = new sap.ui.commons.Button();

      oButton.setText("Press me");

      oButton.attachPress(handleButtonClicked);

 

      function handleButtonClicked() {

         RunFBSL('FBSLScript', 'MsgBox.fbs', 'Map001');

      }

 

      oButton.placeAt("content")

 

    </script>

 

    <script id="FBSLScript" type="text/plain">

//-Begin----------------------------------------------------------------

 

  //-Directives---------------------------------------------------------

    #Option Strict

    #AppType GUI

 

  //-Includes-----------------------------------------------------------

    #Include <Include\Windows.inc>

 

  //-Sub RC-------------------------------------------------------------

    Sub RC(ByVal FileMapName As String, ByVal RetCode As String)

 

      //-Variables------------------------------------------------------

        Dim hMMF As Long

        Dim Buffer As Long

        Dim Temp As String

       

      hMMF = OpenFileMapping(FILE_MAP_ALL_ACCESS, 0, FileMapName)

      If hMMF Then

        Buffer = MapViewOfFile(hMMF, FILE_MAP_ALL_ACCESS, 0, 0, 0)

        If Buffer Then

          Poke(Buffer, RetCode)

          UnmapViewOffile(Buffer)

        End If

        CloseHandle(hMMF)

      End If

 

    End Sub

 

  //-Main---------------------------------------------------------------

    Sub Main()

 

      //-Variables------------------------------------------------------

        Dim FileMapName = "Map001"

 

      RC(FileMapName, MsgBox(0, "Is this cool?", "FBSL Question", _

        MB_YESNO))

 

    End Sub

 

//-End------------------------------------------------------------------

    </script>

 

    <script type="text/javascript">

 

    //-Sub RunFBSL------------------------------------------------------

      function RunFBSL(FBSLScriptName, FBSLFileName, FileMapName) {

 

        //-Variables----------------------------------------------------

          var oScriptX, hFileMap, rc, rcStr;

 

        //-Main---------------------------------------------------------

          if (navigator.appName == 'Microsoft Internet Explorer') {

          //if (window.ActiveXObject) {

            try {

              oScriptX = new ActiveXObject("ScriptX");

              if (typeof(oScriptX) == 'object') {

                oScriptX.ExtractFbslExe();

                oScriptX.ExtractFbslWinInc();

                hFileMap = oScriptX.FileMapCreate(FileMapName, 4);

                if (hFileMap != 0) {

                  oScriptX.WriteFile(FBSLFileName,

                    document.getElementById(FBSLScriptName).text);

                  rc = oScriptX.Shell("Fbsl.exe", FBSLFileName, 1, 1);

                  rcStr = oScriptX.FileMapRead(FileMapName, 4);

                  oScriptX.DeleteFileA(FBSLFileName);

                  oScriptX.DeleteDirectory("Include");

                  oScriptX.DeleteFileA("Fbsl.exe");

                  alert(rcStr);

                  rc = oScriptX.FileMapClose(hFileMap);

                }

                oScriptX = null;

              }

            }

            catch (exc) {

              alert(exc.message);

            }

          }

          else {

            alert("Your Browser doesn't support ActiveXObject");

          }

      }

 

    </script>

 

  </head>

 

  <body class="sapUiBody" role="application">

    <div id="content" />

  </body>

 

</html>

 

The implementation is primarily in JavaScript language. It is the standard button example of SAPUI5, but extended with the function RunFBSL. RunFBSL checks at first the browser environment. This example works only with Microsoft Internet Explorer on a Windows platform. Then it uses the ScriptX library to extract the FBSL environment and to execute the FBSL script. The FBSL script is implemented in the HTML file, look at the ID FBSLScript. The interprocess communication between FBSL interpreter and SAPUI5 environment happens about file mapping.

Certainly I know that the platform independence of UI5 is lost with this step. But if you are sure, that your UI5 environment is primarily used on desktop environments, it is a big profit to combine the possibilities.

 

Enjoy it.

 

Cheers

Stefan

How to Use Python Inside ABAP

$
0
0

Hello community,

 

in the last time I presented a way to integrate BASIC-style script language inside ABAP here. To demonstrate that the these procedures work with other scripting languages too, I take the same methods and use it with Python language. Also I will show that it is possible to use the same ways with more volumminous environments. So I contain a complete Python environment inside ABAP and unpack it at the runtime of my ABAP program and in the context of the ABAP program I create a Python script an use it inside ABAP.

 

Steps

  1. Downloading of Python 2.7.5 from http://www.python.org/.
  2. Installation of Python in the standard default directory C:\Python27.
  3. Copying of python27.dll from c:\Windows\system32 into C:\Python27.
  4. Creating of a multi part RAR archive with a part size of max. 8,000,000 bytes. So I get three RAR archives.
  5. Creating of three ABAP function modules with BinFile2ABAP which contains these RAR archives.
  6. Creating of three function groups and upload of the function modules inside this groups.
    Hint: It is not possible to store more than 65,535 literals in one function group. So it is necessary to create for each function module its own function group.
  7. Upload of zScripXDll function module from here. It contains ScriptX ActiveX library which builds the bridge between ABAP and the scripting language.

 

With these preparations you build the possibility to use Python inside ABAP.

 

ABAP Test Program


"-Begin-----------------------------------------------------------------
  Program ZSCRIPTX.

 

    "-Constants---------------------------------------------------------
      Constants CrLf(2) Type c Value %_CR_LF.
      Constants SW_SHOWNORMAL Type i Value 1.

 

    "-Variables---------------------------------------------------------
      Data oScriptX Type OLE2_OBJECT.
      Data Buffer Type String Value ''.
      Data WorkDir Type String Value ''.
      Data FileName Type String Value ''.
      Data rc Type i Value 0.
      Data hFileMap Type i Value 0.
      Data RetCode Type String Value ''.

 

    "-Macros------------------------------------------------------------
      Define _.
        Concatenate Buffer &1 CrLf Into Buffer.
      End-Of-Definition.

 

      Define Flush.
        Call Function 'AC_SYSTEM_FLUSH' Exceptions Others = 1.
      End-Of-Definition.

 

    "-Main--------------------------------------------------------------
      Create Object oScriptX 'ScriptX'.

      If sy-subrc <> 0 Or  oScriptX-Handle = 0 Or oScriptX-Type <> 'OLE2'.
        Call Function 'ZSCRIPTXDLL'.
        Create Object oScriptX 'ScriptX'.
      EndIf.

 

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

        Call Method Of oScriptX 'About'.
        Flush.

 

        "-Create multi part archive files-------------------------------
          Call Function 'ZPYTHON27PART1RAR'.
          Call Function 'ZPYTHON27PART2RAR'.
          Call Function 'ZPYTHON27PART3RAR'.

 

        "-Unpack archive------------------------------------------------
          Call Method Of oScriptX 'Unrar' Exporting
            #1 = 'Python27.part1.rar'.
          Flush.

 

        "-Delete multi part archive files-------------------------------
          Call Method Of oScriptX 'DeleteFile' Exporting
            #1 = 'Python27.part1.rar'.
          Call Method Of oScriptX 'DeleteFile' Exporting
            #1 = 'Python27.part2.rar'.
          Call Method Of oScriptX 'DeleteFile' Exporting
            #1 = 'Python27.part3.rar'.
          Flush.

 

        Call Method Of oScriptX 'FileMapCreate' = hFileMap
          Exporting #1 = 'SAP001' #2 = 64.

        Flush.

 

        If hFileMap <> 0.

 

"-Python Script begin---------------------------------------------------

 

  "-External libraries--------------------------------------------------
_ 'import ctypes'.
_ 'import sys'.

 

  "-Constants-----------------------------------------------------------
_ 'FILE_MAP_ALL_ACCESS = 30'.

 

  "-Main----------------------------------------------------------------
_ 'print "Python version ", sys.version'.
_ 'print "Hello World from Python"'.
_ 'var_inp = raw_input("Enter something: ")'.
_ 'print "You entered: ", var_inp'.

 

  "-Transfer the input to the memory map file---------------------------
_ 'hMMF = ctypes.windll.kernel32.OpenFileMappingA(FILE_MAP_ALL_ACCESS, \'.
_ '  0, "SAP001")'.
_ 'if hMMF <> 0:'.
_ '  buffer = ctypes.windll.kernel32.MapViewOfFile(hMMF, \'.
_ '    FILE_MAP_ALL_ACCESS, 0, 0, 0)'.
_ '  if buffer <> 0:'.
_ '    ctypes.cdll.msvcrt.strcpy(buffer, var_inp)'.
_ '    rc = ctypes.windll.kernel32.UnmapViewOfFile(buffer)'.
_ '  rc = ctypes.windll.kernel32.CloseHandle(hMMF)'.

 

_ 'raw_input("Press any key...")'.

 

"-Python Script end-----------------------------------------------------

 

          "-Get SAP GUIs work directory---------------------------------
            Call Method cl_gui_frontend_services=>get_sapgui_workdir
              Changing SAPWORKDIR = WorkDir Exceptions Others = 1.

 

          "-Create Python script file-----------------------------------
            Concatenate WorkDir '\Python27\Test.py' Into FileName.
            Call Method Of oScriptX 'WriteFile' Exporting #1 = FileName
              #2 = Buffer.
            Flush.

 

          "-Execute Python script---------------------------------------
            Call Method Of oScriptX 'Shell' = rc Exporting
              #1 = 'Python27\python.exe' #2 = 'Python27\Test.py'
              #3 = SW_SHOWNORMAL #4 = 1.
            Flush.

 

          "-Read the input from the memory map file---------------------
            Call Method Of oScriptX 'FileMapRead' = RetCode
              Exporting #1 = 'SAP001' #2 = 64.
            Flush.

 

          "-Destroy memory map file-------------------------------------
            Call Method Of oScriptX 'FileMapClose' = rc
              Exporting #1 = hFileMap.
            Flush.

 

          "-Delete Python environment-----------------------------------
            Call Method Of oScriptX 'DeleteDirectory' Exporting
              #1 = 'Python27'.
            Flush.

 

          "-Write the content of the memory map file--------------------
            Write: / RetCode.

 

        EndIf.

 

        Free Object oScriptX.

      EndIf.

 

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

 

zPython.jpg

 

Benefits

  1. Zero install, only copy.
  2. No admin rights necessary.
  3. All activities are in the user space only.
  4. These methods works perfect in protected and restricted environments.
  5. ABAP function modules contains all you need.
  6. No admin activities necessary. All you need you get with a simple call of an ABAP function module.

 

Addendum

2014/11/19 - Look here for an update.

 

Good scripting.

 

Cheers

Stefan

Scripting Tracker - Development Tool for SAP GUI Scripting

$
0
0

Hello community,

 

over two years ago I presented here the lite version of Scripting Tracker. Scripting Tracker is a utility and a replacement to the SAP GUI Scripting Development Tools. It is a SAP GUI analyzer and recorder on SAP GUI Scripting base. Now I decided to make all features of Scripting Tracker free available. In this case it means that the recording module is also free available from now.

 

tracker001.jpg

The analyzer shows a clearly arranged tree with all SAP sessions and its scripting objects. Also it shows for each scripting object, after the selection in the tree with a single mouse click, a lot of technical details like e.g. ID, position etc.

tracker002.jpg

With the recorder the program offers the possibility to record, edit and execute your SAP GUI activities in Visual Basic, AutoIt, MiniRobot or PowerShell script language. E.g. with the + button you enriches the source with information comment lines about the transaction, title, dynpro - program name and screen number - and the session number. With Scripting Tracker you have full visual control about the creating code, now it couldn't be easier to use SAP GUI Scripting.

 

You can find Scripting Tracker here.

 

Comments are welcome.

 

Cheers

Stefan

How To Find Out Permission To Access RFC

$
0
0

Hello community,

 

sometimes it could be useful to know the RFC permission of an SAP system. Here a tiny script to find it out via the standard ActiveX library wdtfuncu and the RFC function RFC_PING. If the RFC access is allowed, you get a true value. This script should run on any system with a normal SAP GUI for Windows installation.

 

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

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Sub Main------------------------------------------------------------

    Sub Main()

 

      '-Variables-------------------------------------------------------

        Dim SAPFunc, Connection, SAPConnection, PingFunc, retPing

        Dim exceptPing

 

      '-Get SAP.Functions-----------------------------------------------

        Set SAPFunc = CreateObject("SAP.Functions.Unicode")

        If Not IsObject(SAPFunc) Then

          MsgBox "CreateObject(SAP.Functions.Unicode) failed", _

            vbOkOnly, "Error"

          Exit Sub

        End If

 

      '-Get SAP.LogonControl connection---------------------------------

        Set Connection = SAPFunc.Connection()

        If Not IsObject(Connection) Then

          MsgBox "SAPFunc.Connection failed", vbOkOnly, "Error"

          Exit Sub

        End If

 

      '-Connect SAP system----------------------------------------------

        SAPConnection = Connection.Logon(0, vbFalse)

 

      If SAPConnection <> 0 Then

 

        '-Call ABAP function module RFC_PING----------------------------

          Set PingFunc = SAPFunc.Add("RFC_PING")

          If IsObject(PingFunc) Then

            retPing = PingFunc.Call()

            If retPing = False Then

              exceptPing = PingFunc.Exception()

              MsgBox CStr(exceptPing), vbOkOnly, "Result"

            Else

              MsgBox CStr(retPing), vbOkOnly, "Result"

            End If

          End If

 

        '-Logoff--------------------------------------------------------

          Connection.Logoff()

      Else

        MsgBox "Connection.Logon failed", vbOkOnly, "Error"

      End If

 

    End Sub

 

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

    Main()

 

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

 

Here the same script in AutoIt.

 

;-Begin-----------------------------------------------------------------

 

  ;-Directives----------------------------------------------------------

    AutoItSetOption("MustDeclareVars", 1)

 

  ;-Includes------------------------------------------------------------

    #Include <MsgBoxConstants.au3>

 

  ;-Sub Main------------------------------------------------------------

    Func Main()

 

      ;-Variables-------------------------------------------------------

        Local $SAPFunc, $Connection, $SAPConnection, $PingFunc, $retPing

        Local $exceptPing

 

      ;-Get SAP.Functions-----------------------------------------------

        $SAPFunc = ObjCreate("SAP.Functions.Unicode")

        If Not IsObj($SAPFunc) Then

          MsgBox($MB_OK, "Error", "ObjCreate(SAP.Functions.Unicode) failed")

          Return

        EndIf

 

      ;-Get SAP.LogonControl connection---------------------------------

        $Connection = $SAPFunc.Connection()

        If Not IsObj($Connection) Then

          MsgBox($MB_OK, "Error", "SAPFunc.Connection failed")

          Return

        EndIf

 

      ;-Connect SAP system----------------------------------------------

        $SAPConnection = $Connection.Logon(0, False)

 

      If $SAPConnection <> 0 Then

 

        ;-Call ABAP function module RFC_PING----------------------------

          $PingFunc = $SAPFunc.Add("RFC_PING")

          If IsObj($PingFunc) Then

            $retPing = $PingFunc.Call()

            If $retPing = False Then

              $exceptPing = $PingFunc.Exception()

              MsgBox($MB_OK, "Result", String($exceptPing))

            Else

              MsgBox($MB_OK, "Result", String($retPing))

            EndIf

          EndIf

 

        ;-Logoff--------------------------------------------------------

          $Connection.Logoff()

      Else

        MsgBox($MB_OK, "Error", "Connection.Logon failed")

      EndIf

 

    EndFunc

 

  ;-Main----------------------------------------------------------------

    Main()

 

;-End-------------------------------------------------------------------

 

Cheers

Stefan

Tip: How to Check Whether Your Script Runs in SAP GUI Context

$
0
0

Hello community,

 

today I want to present the possibility to check whether your script runs in SAP GUI context. My example uses CCo, the COM Connector for the RFC library, but you can use also other ways to call a RFC function module (FM). I use the RFC FM RFC_IS_GUI_ON. As you can see I call the FM two times, one time without a SAP GUI connection and the other time with SAP GUI connection (USE_SAPGUI). The FM delivers Y if it runs in SAP GUI context. I check the return value and show a message box with the result.

 

Here the Visual Basic Script example:

 

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

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Constants-----------------------------------------------------------

    Const RFC_OK = 0

 

  '-Variables-----------------------------------------------------------

    Dim SAP, hRFC, rc, hFuncDesc, hFunc, Answer, cnt

 

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

    Set SAP = CreateObject("COMNWRFC")

    If IsObject(SAP) Then

 

      Do

 

        Select Case cnt

          Case 0

            '-Without SAP GUI-------------------------------------------

              hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

                "CLIENT=001, USER=BCUSER")

          Case 1

            '-With SAP GUI----------------------------------------------

              hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

                "CLIENT=001, USER=BCUSER, USE_SAPGUI=2")

        End Select

 

        If hRFC Then

 

          hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "RFC_IS_GUI_ON")

          If hFuncDesc Then

            hFunc = SAP.RfcCreateFunction(hFuncDesc)

            If hFunc Then

              If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then

                rc = SAP.RfcGetChars(hFunc, "ON", Answer, 1)

                If Answer = "Y" Then

                  MsgBox "GUI is on"

                Else

                  MsgBox "GUI is not on"

                End If

              End If

              rc = SAP.RfcDestroyFunction(hFunc)

            End If

          End If

 

          rc = SAP.RfcCloseConnection(hRFC)

        End If

 

        cnt = cnt + 1

      Loop Until cnt = 2

 

      Set SAP = Nothing

    End If

 

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

 

Here the AutoIt example, but only with one non-GUI call:

 

;-Begin-----------------------------------------------------------------

 

  ;-Directives----------------------------------------------------------

    AutoItSetOption("MustDeclareVars", 1)

 

  ;-Constants-----------------------------------------------------------

    Const $RFC_OK = 0

 

  ;-Variables-----------------------------------------------------------

    Dim $SAP, $hRFC, $hFuncDesc, $hFunc, $Answer

 

  ;-Main----------------------------------------------------------------

    $SAP = ObjCreate("COMNWRFC")

    If IsObj($SAP) Then

 

      $hRFC = $SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

        "CLIENT=001, USER=BCUSER")

      If $hRFC Then

 

        $hFuncDesc = $SAP.RfcGetFunctionDesc($hRFC, "RFC_IS_GUI_ON")

        If $hFuncDesc Then

          $hFunc = $SAP.RfcCreateFunction($hFuncDesc)

          If $hFunc Then

            If $SAP.RfcInvoke($hRFC, $hFunc) = $RFC_OK Then

              $SAP.RfcGetChars($hFunc, "ON", $Answer, 1)

              If $Answer = "Y" Then

                MsgBox(0, "", "GUI is on")

              Else

                MsgBox(0, "", "GUI is not on")

              EndIf

            EndIf

            $SAP.RfcDestroyFunction($hFunc)

          EndIf

        EndIf

 

        $SAP.RfcCloseConnection($hRFC)

      EndIf

      $SAP = 0

    EndIf

 

;-End-------------------------------------------------------------------

 

Enjoy it.

 

Cheers

Stefan

Tip: How to Get a Function Module Interface and Documentation

$
0
0

Hello community,

 

today I want to present the possibility to get the interface and the documentation of a function module (FM). My example uses CCo, the COM Connector for the RFC library, but you can use also other ways to call a RFC function module (FM). I use the RFC FMs RFC_GET_FUNCTION_INTERFACE and RFC_FUNCTION_DOCU_GET. The first example in Visual Basic Script uses only RFC_GET_FUNCTION_INTERFACE. It opens a box to input the name of the FM and shows as result a part of the interface in a message box.

 

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

 

  '-Directives----------------------------------------------------------

    Option Explicit

 

  '-Constants-----------------------------------------------------------

    Const RFC_OK = 0

 

  '-Variables-----------------------------------------------------------

    Dim SAP, hRFC, rc, hFuncDesc, hFunc, hTable, RowCount, i, Row

    Dim charBuffer, strText, FuncName

 

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

    Set SAP = CreateObject("COMNWRFC")

    If IsObject(SAP) Then

 

      hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _

        "CLIENT=001, USER=BCUSER")

      If hRFC Then

 

        FuncName = UCase(InputBox("Name of the Function Module"))

 

        hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "RFC_GET_FUNCTION_INTERFACE")

        If hFuncDesc Then

          hFunc = SAP.RfcCreateFunction(hFuncDesc)

          If hFunc Then

            rc = SAP.RfcSetChars(hFunc, "FUNCNAME", FuncName)

            If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then

              If SAP.RfcGetTable(hFunc, "PARAMS", hTable) = RFC_OK Then

                rc = SAP.RfcGetRowCount(hTable, RowCount)

                rc = SAP.RfcMoveToFirstRow(hTable)

                For i = 1 To RowCount

                  Row = SAP.RfcGetCurrentRow(hTable)

                  rc = SAP.RfcGetChars(Row, "PARAMCLASS", charBuffer, 1)

                  strText = strText & Trim(charBuffer) & " "

                  rc = SAP.RfcGetChars(Row, "PARAMETER", charBuffer, 30)

                  strText = strText & Trim(charBuffer) & " "

                  rc = SAP.RfcGetChars(Row, "PARAMTEXT", charBuffer, 79)

                  strText = strText & Trim(charBuffer) & " "

                  rc = SAP.RfcGetChars(Row, "OPTIONAL", charBuffer, 1)

                  strText = strText & Trim(charBuffer) & vbCrLf

                  If i < RowCount Then

                    rc = SAP.RfcMoveToNextRow(hTable)

                  End If

                Next

                MsgBox strText, vbOkOnly, FuncName & " Interface"

              End If

            End If

            rc = SAP.RfcDestroyFunction(hFunc)

          End If

        End If

 

        rc = SAP.RfcCloseConnection(hRFC)

      End If

 

      Set SAP = Nothing

    End If

 

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

 

The next example in AutoIt uses both FMs. Also I programmed a tiny GUI.

 

0116_GetFMDocuInterface.jpg

 

In the Main function I define the GUI and the event loop. The function GetFMInterface delivers the interface of a FM, as the example above, and the function GetFMDocu delivers the documentation of the FM. With the button Copy to Clipboard you can transfer the generated content into other applications.

 

;-Begin-----------------------------------------------------------------

 

  ;-Directives----------------------------------------------------------

    AutoItSetOption("MustDeclareVars", 1)

 

  ;-Includes------------------------------------------------------------

    #Include <MsgBoxConstants.au3>

    #Include <StringConstants.au3>

    #Include <GUIConstantsEx.au3>

    #Include <FontConstants.au3>

    #Include <StaticConstants.au3>

    #Include <EditConstants.au3>

 

  ;-Constants-----------------------------------------------------------

    Const $RFC_OK = 0

 

  ;-Function GetFMDocu--------------------------------------------------

    Func GetFMDocu($Conn, $FuncName)

 

      ;-Variables-------------------------------------------------------

        Local $SAP, $hRFC, $hFuncDesc, $hFunc, $txt = "", $i

        Local $hTable = 0, $RowCount = 0, $Row, $charBuffer = ""

 

      $SAP = ObjCreate("COMNWRFC")

      If IsObj($SAP) Then

 

        $hRFC = $SAP.RfcOpenConnection($Conn)

        If $hRFC Then

 

          $hFuncDesc = $SAP.RfcGetFunctionDesc($hRFC, _

            "RFC_FUNCTION_DOCU_GET")

          If $hFuncDesc Then

            $hFunc = $SAP.RfcCreateFunction($hFuncDesc)

            If $hFunc Then

              $SAP.RfcSetChars($hFunc, "FUNCNAME", $FuncName)

              If $SAP.RfcInvoke($hRFC, $hFunc) = $RFC_OK Then

                If $SAP.RfcGetTable($hFunc, "FUNCDOCU", $hTable) = _

                  $RFC_OK Then

                  $SAP.RfcGetRowCount($hTable, $RowCount)

                  $SAP.RfcMoveToFirstRow($hTable)

                  For $i = 1 To $RowCount

                    $Row = $SAP.RfcGetCurrentRow($hTable)

                    $SAP.RfcGetChars($Row, "PARAMETER", $charBuffer, 30)

                    $txt = $txt & $charBuffer & " "

                    $SAP.RfcGetChars($Row, "TDLINE", $charBuffer, 132)

                    $txt = $txt & StringStripWS($charBuffer, _

                      $STR_STRIPTRAILING) & @CRLF

                    If $i < $RowCount Then

                      $SAP.RfcMoveToNextRow($hTable)

                    EndIf

                  Next

                EndIf

              EndIf

              $SAP.RfcDestroyFunction($hFunc)

            EndIf

          EndIf

 

          $SAP.RfcCloseConnection($hRFC)

        EndIf

        $SAP = 0

      EndIf

 

      Return $txt

 

    EndFunc

 

  ;-Function GetFMInterface---------------------------------------------

    Func GetFMInterface($Conn, $FuncName)

 

      ;-Variables-------------------------------------------------------

        Local $SAP, $hRFC, $hFuncDesc, $hFunc, $hTable = 0, $i

        Local $RowCount = 0, $charBuffer = "", $txt = "", $Row

        Local $intBuffer = 0

 

      $SAP = ObjCreate("COMNWRFC")

      If IsObj($SAP) Then

 

        $hRFC = $SAP.RfcOpenConnection($Conn)

        If $hRFC Then

 

          $hFuncDesc = $SAP.RfcGetFunctionDesc($hRFC, _

            "RFC_GET_FUNCTION_INTERFACE")

          If $hFuncDesc Then

            $hFunc = $SAP.RfcCreateFunction($hFuncDesc)

            If $hFunc Then

              $SAP.RfcSetChars($hFunc, "FUNCNAME", $FuncName)

              If $SAP.RfcInvoke($hRFC, $hFunc) = $RFC_OK Then

                If $SAP.RfcGetTable($hFunc, "PARAMS", $hTable) = _

                  $RFC_OK Then

                  $SAP.RfcGetRowCount($hTable, $RowCount)

                  $SAP.RfcMoveToFirstRow($hTable)

                  For $i = 1 To $RowCount

                    $Row = $SAP.RfcGetCurrentRow($hTable)

                    $SAP.RfcGetChars($Row, "PARAMCLASS", $charBuffer, 1)

                    $txt = $txt & $charBuffer & " "

                    $SAP.RfcGetChars($Row, "PARAMETER", $charBuffer, 30)

                    $txt = $txt & $charBuffer & " "

                    $SAP.RfcGetChars($Row, "OPTIONAL", $charBuffer, 1)

                    $txt = $txt & $charBuffer & " "

                    $SAP.RfcGetChars($Row, "EXID", $charBuffer, 1)

                    $txt = $txt & $charBuffer & " "

                    $SAP.RfcGetInt($Row, "INTLENGTH", $intBuffer)

                    $txt = $txt & StringFormat("%04i", $intBuffer) & " "

                    $SAP.RfcGetChars($Row, "PARAMTEXT", $charBuffer, 79)

                    $txt = $txt & StringStripWS($charBuffer, _

                      $STR_STRIPTRAILING) & @CRLF

                    If $i < $RowCount Then

                      $SAP.RfcMoveToNextRow($hTable)

                    EndIf

                  Next

                EndIf

              EndIf

              $SAP.RfcDestroyFunction($hFunc)

            EndIf

          EndIf

 

          $SAP.RfcCloseConnection($hRFC)

        EndIf

        $SAP = 0

      EndIf

 

      Return $txt

 

    EndFunc

 

 

  ;-Sub Main------------------------------------------------------------

    Func Main()

 

      ;-Variables-------------------------------------------------------

        Local $hGUI, $Quit = False, $IDGenerate, $Conn, $IDCopy

        Local $FuncName, $IDFuncName, $Interface, $IDInterface, $Docu

        Local $IDASHOST, $IDSYSNR, $IDCLIENT, $IDUSER, $IDPASSWD

 

      $hGUI = GUICreate("Function Module Documentation and " & _

        "Interface Viewer", 800, 800)

 

      ;-GUI-------------------------------------------------------------

        GUICtrlCreateLabel("ASHOST:", 10, 15, 60, 24, $SS_RIGHT)

        $IDASHOST = GUICtrlCreateInput("ABAP", 80, 10, 70, 24)

        GUICtrlCreateLabel("SYSNR:", 160, 15, 60, 24, $SS_RIGHT)

        $IDSYSNR = GUICtrlCreateInput("00", 230, 10, 70, 24)

        GUICtrlCreateLabel("CLIENT:", 310, 15, 60, 24, $SS_RIGHT)

        $IDCLIENT = GUICtrlCreateInput("001", 380, 10, 70, 24)

        GUICtrlCreateLabel("USER:", 460, 15, 60, 24, $SS_RIGHT)

        $IDUSER = GUICtrlCreateInput("BCUSER", 530, 10, 70, 24)

        GUICtrlCreateLabel("PASSWORD:", 640, 15, 70, 24, $SS_RIGHT)

        $IDPASSWD = GUICtrlCreateInput("minisap", 720, 10, 70, 24, _

          $ES_PASSWORD)

        GUICtrlCreateLabel("Function Module", 10, 49, 100, 24)

        $IDFuncName = GUICtrlCreateInput("BAPI_USER_CREATE", 100, 44, _

          580, 24)

        $IDGenerate = GUICtrlCreateButton("Generate", 690, 44, 100, 24)

        $IDInterface = GUICtrlCreateEdit("", 10, 78, 780, 678)

        GUICtrlSetFont($IDInterface, 10, $FW_NORMAL, 0, "Courier New")

        $IDCopy = GUICtrlCreateButton("Copy to Clipboard", _

          640, 766, 150, 24)

 

      ;-Show GUI--------------------------------------------------------

        GUISetState(@SW_SHOW, $hGUI)

 

      ;-GUI Event Loop--------------------------------------------------

        Do

          Switch GUIGetMsg()

            Case $IDGenerate

              $FuncName = StringUpper(GUICtrlRead($IDFuncName))

              If $FuncName <> "" Then

                $Conn = "ASHOST=" & GUICtrlRead($IDASHOST) & ", " & _

                        "SYSNR=" & GUICtrlRead($IDSYSNR) & ", " & _

                        "CLIENT=" & GUICtrlRead($IDCLIENT) & ", " & _

                        "USER=" & GUICtrlRead($IDUSER) & ", " & _

                        "PASSWD=" & GUICtrlRead($IDPASSWD)

                $Docu = "Documentation" & @CRLF & _

                  GetFMDocu($Conn, $FuncName) & @CRLF

                $Interface = "Interface" & @CRLF & _

                  GetFMInterface($Conn, $FuncName)

                GUICtrlSetData($IDInterface, $Docu & $Interface, "")

              EndIf

            Case $IDCopy

              ClipPut(GUICtrlRead($IDInterface))

            Case $GUI_EVENT_CLOSE

              $Quit = True

          EndSwitch

        Until $Quit = True

 

      ;-Destroy GUI-----------------------------------------------------

        GUIDelete($hGUI)

 

    EndFunc

 

  ;-Main----------------------------------------------------------------

    Main()

 

;-End-------------------------------------------------------------------

 

Enjoy it.

 

Cheers

Stefan


Table Export Excell with PHP (Charts and Table)

$
0
0


System Requirements

 

-Apache Web Server

-PHP

-SAPRFC (PHP Addon)

-PHPExcell

 

Capture.JPG

Capture.JPG

1-) Download PHPExcell library

 

Download Link :  https://phpexcel.codeplex.com/releases/view/119187

 

2-) Download and Install SAPRFC

Download Link : SAPRFC Homepage

  • Installation

  1) Extract zip file saprfc-$VERSION$-$PHP_VERSION$.zip

  2) Copy php-saprfc.dll to your extensions directory (e.g. C:\PHP\extensions)

  3) Edit php.ini file (in windows system dircetory, e.g. C:\WINNT, C:\WINDOWS)

  and add line: 'extension=php_saprfc.dll'

  4) Copy librfc32.dll (from SAPGUI install CD) to the windows system

  directory or simple install SAPGUI on your machine.


3-) Creating SAP Table

 

Capture.JPG

    We have added the time in the (H.i) format database. Example : 01.00 , 03.00 . You must add them in this way.Otherwise, the application will not work correctly.

 

Example :

 

SAP TABLE - TIME -PHP APPLICATION CONVERT
01.0001:00
08.0008:00

 

4-) Create Function Module

 

The Function Module is attached.

 

File : ZREPORT_ASCENDINGDATE.txt

 

The important line in the function module :

SELECT * FROM (QUERY_TABLE) INTO <WA> WHERE (OPTIONS) ORDER BY TIME ASCENDING .

This function module is edited from RFC_READ_TABLE .

 

5-) Build PHP Application

 

PHP files is attached.

 

File : connect.txt

File : excellreport.txt

 

You must edit connect.php .

How to Create a Transactional SAP Server Applications with Freestyle BASIC Script Language (FBSL)

$
0
0

Hello community,

 

nearly two years I develop the COM Connector (CCo), look here.

 

Since over a year I develop for Freestyle BASIC Script Language (FBSL) an ABAP Interface, called ScriptX, look here.

 

FBSL is the first BASIC like script language I know, with which is it possbile to create SAP server programs, my first example you can find here.


Here now my example code how to create a transactional SAP server application with FBSL and CCo. It is not really a complete example, but it shows the basically function.

 

//-Begin----------------------------------------------------------------

 

  //-Directives---------------------------------------------------------

    #AppType Console

    #Option Strict

 

  //-Includes-----------------------------------------------------------

    #Include <Include\Windows.inc>

    #Include "sapnwrfc.inc"

 

  //-onCheckFunction----------------------------------------------------

    Function onCheckFunction(%rfcHandle, %tid)

      ? "onCheckFunction"

      Return RFC_OK

    End Function

 

  //-onCommitFunction---------------------------------------------------

    Function onCommitFunction(%rfcHandle, %tid)

      ? "onCommitFunction"

      Return RFC_OK

    End Function

 

  //-onRollbackFunction-------------------------------------------------

    Function onRollbackFunction(%rfcHandle, %tid)

      ? "onRollbackFunction"

      Return RFC_OK

    End Function

 

  //-onConfirmFunction--------------------------------------------------

    Function onConfirmFunction(%rfcHandle, %tid)

      ? "onConfirmFunction"

      Return RFC_OK

    End Function

 

  //-ABAPCall-----------------------------------------------------------

    Function ABAPCall(%rfcHandle, %funcHandle, %errorInfo)

      ? "ABAPCall"

      Return RFC_OK

    End Function

 

  //-Main---------------------------------------------------------------

    Sub Main()

 

      //-Variables------------------------------------------------------

        Dim %SAP, %hRfc, %hDesc, %rc, %hCon

 

      SAP = CreateObject("COMNWRFC")

      If SAP Then

 

        CallMethod(SAP, ".About")

 

        rc = GetValue("%d", SAP, ".RfcInstallTransactionHandlers(%s, _

          %d, %d, %d, %d)", "", AdressOf onCheckFunction, _

          AdressOf onCommitFunction, AdressOf onRollbackFunction, _

          AdressOf onConfirmFunction)

 

        hDesc = GetValue("%d", SAP, ".RfcCreateFunctionDesc(%s)", _

          "ABAPCall")

 

        If rc = RFC_OK And hDesc Then

    

          rc = GetValue("%d", SAP, ".RfcInstallServerFunction(%s, %d, %d)", _

            "", hDesc, AdressOf ABAPCall)

 

          If rc = RFC_OK Then

      

            hCon = GetValue("%d", SAP, ".RfcRegisterServer(%s)", _

              "program_id=FBSLSERVER, gwhost=ABAP, gwserv=sapgw00")

            If hCon Then

        

              While rc = RFC_OK Or rc = RFC_RETRY

          

                rc = GetValue("%d", SAP, ".RfcListenAndDispatch(%d, %d)", _

                  hCon, 1)

              

                Select Case rc

                  Case RFC_OK

                    OutputDebugString("RFC_OK")

                  Case RFC_RETRY

                    OutputDebugString("RFC_RETRY")

                End Select 

            

                Sleep(256)

          

              Wend

        

            End If

      

          End If

    

          CallMethod(SAP, ".RfcDestroyFunctionDesc(%d)", hDesc)

        End If

 

        ReleaseObject(SAP)

      End If

 

    End Sub

 

//-End------------------------------------------------------------------

 

The difference between this example and the normal SAP server application here are the onCheckFunction, onCommitFunction, onRollbackFunction and onCommitFunction as well as the RfcInstallTransactionHandlers function. This function registers the on...Functions which are called on the different moments of the operation.

 

You can call this script from ABAP via the following example code:

 

"-Begin-----------------------------------------------------------------

  Program ZTEST.

 

    Call Function 'ABAPCall'

      In Background Task

      Destination 'FBSLSERVER'.

    If sy-subrc <> 0.

      Rollback Work.

    EndIf.

    Commit Work.

 

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

 

Also you must customize the FBSLSERVER with the TAC SM59 and that's all.

SM59.jpg

After you call the FBSL transactional SAP server from ABAP you see in SM58 the status of the tRFC.

 

SM58.JPG

Mark the line and press F6 to execute the LUW. Now you see in your FBSL server application the function calls.

 

FBSL.JPG

Even if I am repeating myself, on this way it is possible to use FBSL scripts as transactional SAP server programs without any other steps, like e.g. compiling etc., or big IDEs or script environments. You can change the script easily via a simple editor and use it from SAP application server via an ABAP program. These are the best conditions for prototyping, to create fast and simple complex simulations of external server applications.

 

The suggestion to create this example comes from the new edition of the book SAP Interface Programming - you can find here an introduction.

 

Hope toinspireotherprogrammers.

 

Enjoy it.

 

Cheers

Stefan


SAP GUI Scripting in the Context of NetWeaver Business Client, a New Perspective

$
0
0

Hello community,

we see at the DSAG (German SAP User Group) the NetWeaver Business Client (NWBC) as replacement in the near future for the SAP GUI for Windows with the SAP Logon. From this point I considered the SAP GUI Scripting with NWBC for Desktop. At first I installed the NWBC 4.0 PL 4 and configured the application server. It runs well and I directed my attention to the SAP GUI Scripting.

 

First of all, it works. But there are some differences to SAP GUI Scripting inside SAP GUI for Windows.

 

1. If I open a second NWBC Client window and use the method Connections from the Application object with the property Count, I get not more than one connection. SAP GUI Scripting uses only the first NWBC Client window. Look here: http://scn.sap.com/thread/3323820

 

2. The correct entry in the running object table (ROT) for the SAP GUI Scripting inside NWBC is SAPGUISERVER.

 

3. If I record a SAP GUI Script with NWBC, it sets SapGuiAuto = GetObject("SAPGUI"). If I start this script from Windows Explorer, it runs in a normal SAP GUI for Windows session. I think it should be SapGuiAuto = GetObject("SAPGUISERVER").

 

4. In the NWBC is no Ok-Code-Field visible. It is possible to use it with SAP GUI Scripting because it is in the scripting object hierarchy, but it is not possible to record something with it in NWBC.

 

5. In the NWBC is no Toolbar[1] visible and not useable. Older SAP GUI Scripts will not work and there is no equivalent.

 

My momentary conclusion: SAP GUI Scripting in the context of NWBC offers not the same possibilities as in SAP GUI for Windows context now. We will see what will happen in the future development of NWBC in this sector, I am curious.

 

To be continued...

 

Cheers
Stefan

How to Build an HTA/HTML UI to Code and Execute ABAP Reports

$
0
0

Hello community,

 

a longer time ago I introduced CCo (COM Connector) here. Later I presented here the possibility how to program and run an ABAP Report with the scripting language VBScript and CCo. Here is now a development with the same possibility and additional an UI to code the ABAP report. It is a hypertext application.

 

<html>

  <head>

 

    <title>
      Execute an ABAP Report
    </title>

 

    <hta:application applicationname="ABAPReport" id="ABAPReport"
      singleinstance="yes" border="thick" borderStyle="sunken"
      version="1.0" />

 

    <script language="VBScript">

 

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

 

      '-Constants-------------------------------------------------------
        Const RFC_OK = 0

 

      '-ABAPExec--------------------------------------------------------
        Sub ABAPExec()

 

          '-Variables---------------------------------------------------
            Dim SAP, hRFC, rc, hFuncDesc, hFunc, ABAP, i, hRow, hTable
            Dim RowCount, charBuffer, Result

 

          document.Output.Result.value = ""

 

          Set SAP = CreateObject("COMNWRFC")
          If Not IsObject(SAP) Then
            Exit Sub
          End If

 

          hRFC = SAP.RfcOpenConnection( _
            "ASHOST=" & document.ConnParams.ASHost.value & ", "  & _
            "SYSNR=" & document.ConnParams.SysNr.value & ", " & _
            "CLIENT=" & document.ConnParams.Client.value & ", " & _
            "USER=" & document.ConnParams.User.value)
          If hRFC = 0 Then
            Set SAP = Nothing
            Exit Sub
          End If

 

          hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, _
            "RFC_ABAP_INSTALL_AND_RUN")
          If hFuncDesc = 0 Then
            rc = SAP.RfcCloseConnection(hRFC)
            Set SAP = Nothing
            Exit Sub
          End If

 

          hFunc = SAP.RfcCreateFunction(hFuncDesc)
          If hFunc = 0 Then
            rc = SAP.RfcCloseConnection(hRFC)
            Set SAP = Nothing
            Exit Sub
          End If

 

          '-Writes the report into the PROGRAM table--------------------
            If SAP.RfcGetTable(hFunc, "PROGRAM", hTable) = RFC_OK Then
              ABAP = Split(document.ABAP.Report.value, vbCrLf)
              For i = 0 To UBound(ABAP) - 1
                If Trim(ABAP(i)) <> "" Then
                  hRow = SAP.RfcAppendNewRow(hTable)
                  rc = SAP.RfcSetChars(hRow, "LINE", ABAP(i))
                End If
              Next
            End If

 

          If SAP.RfcInvoke(hRFC, hFunc) = RFC_OK Then
            '-Gets the result from the WRITES table---------------------
              If SAP.RfcGetTable(hFunc, "WRITES", hTable) = RFC_OK Then
                rc = SAP.RfcGetRowCount(hTable, RowCount)
                rc = SAP.RfcMoveToFirstRow(hTable)
                For i = 1 To RowCount
                  hRow = SAP.RfcGetCurrentRow(hTable)
                  rc = SAP.RfcGetChars(hRow, "ZEILE", charBuffer, 256)
                  Result = Result & Trim(charBuffer) & vbCrLf
                  If i < RowCount Then
                    rc = SAP.RfcMoveToNextRow(hTable)
                  End If
                Next
                '-Shows the result in the output area-------------------
                  document.Output.Result.value = Result
              End If
          End If

 

          rc = SAP.RfcDestroyFunction(hFunc)
          rc = SAP.RfcCloseConnection(hRFC)
          Set SAP = Nothing

 

        End Sub
       
      '-onLoad----------------------------------------------------------
        Sub Window_onLoad()
          window.moveTo 25,25
          window.resizeTo 680,710
        End Sub

 

    </script>

 

  </head>

 

  <body>

    <h1>
      Execute an ABAP Report
    </h1>

 

    <form action="ConnParams.htm" name="ConnParams">
      <p>
        ASHost:
        <input name="ASHost" type="text" size="10" maxlength="10"
          value="ABAP">
        SysNr.:
        <input name="SysNr" type="text" size="2" maxlength="2"
          value="00">
        Client:
        <input name="Client" type="text" size="3" maxlength="3"
          value="001">
        User:
        <input name="User" type="text" size="12" maxlength="12"
          value="BCUSER">
      </p>
    </form>

 

    <input type="button" value="Execute ABAP Report"
      onClick='ABAPExec()'>
   
    <form action="ABAP.htm" name="ABAP">
      <p>
<textarea name="Report" cols="72" rows="18" wrap="hard">

"-Begin-----------------------------------------------------------------
  Report zTest Line-Size 72.

 

  Write: 'Hello World from'.
  Write: sy-sysid.

 

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

</textarea>
      </p>
    </form>

 

    <form action="Output.htm" name="Output">
      <p>
        <textarea name="Result" cols="72" rows="9" wrap="soft" readonly>
      </textarea>
      </p>
    </form>

 

  </body>

</html>

 

ABAP1.jpg

As you can see it is very easy to build an external editor for ABAP reports, with the possibilities of HTML and CCo.

 

Cheers

Stefan

Control Visualizer

$
0
0

Hello community,

 

we all know the good old Scripting Wizard, which is not longer supported since Windows 7 and SAP GUI for Windows 7.20 PL?.

 

But SAP offers a Control Visualizer, maybe a replacment.

 

If you press the buttons  Ctrl  +  Shift  +  Z at the same time, it opens an additional window, called CMyControl Visualizer.

 

Hint: It is the Z key on keyboard with German keyboard layout.

 

Visualizer.jpg

You got the field name, the style, the content and some other technical stuff about the selected control.

I am not really sure if this is a replacment, but it seems a little bit.

 

Hint: It works not with any screen and it is not very stable.

 

 

Addition 2015/07/14:

It still works with the actual version of the SAP GUI for Windows 7.40 PL 3.

 

visualizer.JPG

 

Cheers

Stefan

Viewing all 100 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>