Quantcast
Channel: Scripting Languages
Viewing all 60 articles
Browse latest View live

How to use Batch Input with Excel via CCo

$
0
0

Hello community,

 

Batch Input is a consolidated method for automatic mass input of data. You can find more information about Batch Input here and here.

 

Here now an example how to use Batch Input with VBA in Excel and the COM Connector (CCo).

 

The sub procedure Record stores all activities in an Excel table, look at the image below. It calls the function module BDC_RECORD_TRANSACTION.

The sub procedure Replay reads the activities from the Excel table and executes it via the function module RFC_CALL_TRANSACTION_USING.

 

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

'-

'- Visual Basic for Application Excel program to use SAP Batch Input

'- resp. Batch Data Communication (BDC)

'-

'- Author: Stefan Schnell

'-

'-----------------------------------------------------------------------

 

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

    Option Explicit

 

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

    Const RFC_OK = 0

 

  '-Sub Record----------------------------------------------------------

  '-

  '- Records the given transaction code and stores the activities in

  '- the given Excel table.

  '-

  '---------------------------------------------------------------------

    Sub Record(TCode As String, TableName As String)

 

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

        Dim SAP As CCo.COMNWRFC

        Dim hRFC As Long

        Dim hFuncDesc As Long

        Dim hFunc As Long

        Dim rc As Integer

        Dim hTable As Long

        Dim RowCount As Long

        Dim i As Integer

        Dim hRow As Long

        Dim charBuffer As String

 

      Set SAP = CreateObject("COMNWRFC")

      If IsObject(SAP) Then

 

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

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

        If hRFC Then

 

          hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, _

            "BDC_RECORD_TRANSACTION")

          If hFuncDesc Then

 

            hFunc = SAP.RfcCreateFunction(hFuncDesc)

            If hFunc Then

 

              rc = SAP.RfcSetChars(hFunc, "TCODE", TCode)

              rc = SAP.RfcSetChars(hFunc, "MODE", "A")

              rc = SAP.RfcSetChars(hFunc, "UPDATE", "A")

              rc = SAP.RfcSetChars(hFunc, "AUTHORITY_CHECK", "X")

 

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

 

                rc = SAP.RfcGetTable(hFunc, "DYNPROTAB", hTable)

                rc = SAP.RfcGetRowCount(hTable, RowCount)

                rc = SAP.RfcMoveToFirstRow(hTable)

 

                Worksheets(TableName).Cells.Clear

                For i = 1 To RowCount

                  hRow = SAP.RfcGetCurrentRow(hTable)

                  rc = SAP.RfcGetChars(hRow, "PROGRAM", charBuffer, 40)

                  Worksheets(TableName).Range("A" & CStr(i)) = _

                    Trim(charBuffer)

                  rc = SAP.RfcGetChars(hRow, "DYNPRO", charBuffer, 4)

                  Worksheets(TableName).Range("B" & CStr(i)) = _

                    "'" & Trim(charBuffer)

                  rc = SAP.RfcGetChars(hRow, "DYNBEGIN", charBuffer, 1)

                  Worksheets(TableName).Range("C" & CStr(i)) = _

                    Trim(charBuffer)

                  rc = SAP.RfcGetChars(hRow, "FNAM", charBuffer, 132)

                  Worksheets(TableName).Range("D" & CStr(i)) = _

                    Trim(charBuffer)

                  rc = SAP.RfcGetChars(hRow, "FVAL", charBuffer, 132)

                  Worksheets(TableName).Range("E" & CStr(i)) = _

                    "'" & Trim(charBuffer)

                  If i < RowCount Then

                    rc = SAP.RfcMoveToNextRow(hTable)

                  End If

                Next

 

              End If

 

              rc = SAP.RfcDestroyFunction(hFunc)

            End If

 

          End If

 

          rc = SAP.RfcCloseConnection(hRFC)

        End If

 

        Set SAP = Nothing

      End If

 

    End Sub

 

  '-Sub Replay----------------------------------------------------------

  '-

  '- Replays the given transaction code with the activities from the

  '- given Excel table, in the specified mode.

  '-

  '- Modes: A = All screens are displayed

  '-        E = Screens are not displayed, except if an error occurs

  '-        N = Screens are not displayed

  '-        P = Same as N, but if a breakpoint is reached the classic

  '-            debugger is used

  '-

  '---------------------------------------------------------------------

    Sub Replay(TCode As String, TableName As String, Mode As String)

 

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

        Dim SAP As CCo.COMNWRFC

        Dim hRFC As Long

        Dim hFuncDesc As Long

        Dim hFunc As Long

        Dim rc As Integer

        Dim hTable As Long

        Dim i As Integer

        Dim hRow As Long

 

      Set SAP = CreateObject("COMNWRFC")

      If IsObject(SAP) Then

 

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

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

        If hRFC Then

 

          hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, _

            "RFC_CALL_TRANSACTION_USING")

          If hFuncDesc Then

 

            hFunc = SAP.RfcCreateFunction(hFuncDesc)

            If hFunc Then

 

              rc = SAP.RfcSetChars(hFunc, "TCODE", TCode)

              rc = SAP.RfcSetChars(hFunc, "MODE", Mode)

              rc = SAP.RfcGetTable(hFunc, "BT_DATA", hTable)

              rc = SAP.RfcDeleteAllRows(hTable)

 

              For i = 1 To Worksheets(TableName).UsedRange.Rows.Count

                hRow = SAP.RfcAppendNewRow(hTable)

                rc = SAP.RfcSetChars(hRow, "PROGRAM", _

                  Worksheets(TableName).Range("A" & CStr(i)))

                rc = SAP.RfcSetChars(hRow, "DYNPRO", _

                  Worksheets(TableName).Range("B" & CStr(i)))

                rc = SAP.RfcSetChars(hRow, "DYNBEGIN", _

                  Worksheets(TableName).Range("C" & CStr(i)))

                rc = SAP.RfcSetChars(hRow, "FNAM", _

                  Worksheets(TableName).Range("D" & CStr(i)))

                rc = SAP.RfcSetChars(hRow, "FVAL", _

                  Worksheets(TableName).Range("E" & CStr(i)))

              Next

 

              rc = SAP.RfcInvoke(hRFC, hFunc)

 

              rc = SAP.RfcDestroyFunction(hFunc)

            End If

 

          End If

 

          rc = SAP.RfcCloseConnection(hRFC)

        End If

 

        Set SAP = Nothing

      End If

 

    End Sub

 

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

    Sub Main()

 

      Record "SE16", "Tabelle1"

 

      Replay "SE16", "Tabelle1", "A"

 

    End Sub

 

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

 

After the recording the table looks like this:

BdcRecorder001.jpg

It is exactly the same as in the Transaction Recorder SHDB:

BdcRecorder002.jpg

But now you have the possibility to modify the table easily, e.g. to duplicate entries - Excel-like.

 

Enjoy it.

 

Cheers

Stefan


SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

SpiderBasic (JavaScript) Language in the Context of SAP Web Application Server

$
0
0

Hello community,

at first I want to introduce SpiderBasic.


 

An introduction to SpiderBasic

 

SpiderBasic is a web client-side programming language based on established BASIC rules. Its main purpose is to allow development of very complex windowed based web applications. It provides a large commandset to handle complex and reactive GUI and many more in a coherent manner. Learning SpiderBasic is very easy. You can find SpiderBasic here.

 

SpiderBasic is a compiler which generates optimized JavaScript, which needs a modern browser to run (HTML5). As a compiler, it has strong typing and various checks that JavaScript doesn't provide, allowing robust code construction. SpiderBasic supports structured programming, it is not object oriented. It provides flexible namespace support and many other features.


SpiderBasic offers a very powerful and effective IDE with syntax highlighting, code completion and much more features. Years of experience is accumulated in this IDE.

001.jpg


SpiderBasic offers a wide range of libraries to use different functions easily:
2D Drawing,
Drawing, Array, Cipher, Date, Debugger, Desktop, Dialog, File, Font, Gadget, Http, Image, JSON, List, Map, Math, Memory, Menu, Regular Expression, Requester, Runtime, Sort. String, System, Toolbar, Window and XML.
Also multimedia libraries: Joystick, Keyboard, Mouse, Screen, Sprite and Sound.

 

The syntax is easy and the possibilities are huge with the "advanced" functions that have been added to this language like structures, procedures, dynamic lists and much more. For the coder, there are no problems gaining access to external third party libraries.


You can download a free version of SpiderBasic here.

 

 

SAP and SpiderBasic

 

You can upload the SpiderBasic framework with the report BSP_UPDATE_MIMEREPOS in the SAP MIME repository. You find the SpiderBasic framework in the directory spiderbasic/libraries/javascript. After this step you can upload your html page as bsp application in the SE80 and also your javascript file. Here an SpiderBasic example of gadgetoverviews:

 

<!DOCTYPE html>

<html>

<head>

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

<meta charset="utf-8">

<title>SpiderBasic</title>

<script type="text/javascript">var spider = {}; spider.nbModules = 0; spider.nbLoadedModules = 0;</script>

 

<script type="text/javascript">

var Path = "/SAP/BC/BSP/SAP/PUBLIC/spiderbasic/libraries/javascript";

document.write("<script type='text/javascript' data-main='" + Path + "/main.js' src='" + Path + "/require.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/library.js'><\/script>");

</script>

<script type="text/javascript">var dojoConfig = { locale: 'en',  async: 1 }; </script>

<script type="text/javascript">

document.write("<link rel='stylesheet' href='" + Path + "/dijit/themes/flat/flat.css' type='text/css' />");

document.write("<link rel='stylesheet' href='" + Path + "/dgrid/css/dgrid.css' />");

document.write("<link rel='stylesheet' href='" + Path + "/cbtree/icons/cbtreeIcons.css' type='text/css' />");

document.write("<link rel='stylesheet' href='" + Path + "/cbtree/icons/fileIconsMS.css' type='text/css' />");

document.write("<script type='text/javascript' src='" + Path + "/xdate.dev.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/canvas-toBlob.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/FileSaver.js'><\/script>");

document.write("<link rel='stylesheet' href='" + Path + "/themes/blue/window.css' type='text/css' />");

</script>

 

<script type="text/javascript" src="gadgetoverview.js"></script>

 

<link rel="icon" type="image/png" href=""/>

 

</head>

 

<body class="flat" id="spiderbody">

 

</body>

</html>

 

Here the result in the SAP environment:

spiderbasic011.jpg

 

Communication between SAP and SpiderBasic

 

Here a SpiderBasic code to communicate with an SAP system via WebService with the function module RFC_READ_TABLE. You can find a step by step guide to create this WebService here.

 

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

 

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

    EnableExplicit

 

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

    Enumeration

      #MainWin

      #tUser

      #User

      #tPassword

      #Password

      #tTableName

      #TableName

      #btnReadTable

      #XMLTree

      #XML

    EndEnumeration

 

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

    Global wsurl.s = "http://ABAP:8080/sap/bc/srt/rfc/sap/ztest/001/" +

      "ztest/rfc_read_table"

 

  ; Sub FillTree--------------------------------------------------------

    Procedure FillTree(CurrentNode.i, CurrentSublevel.i)

 

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

        Protected NodeName.s, ChildNode.i

 

      If XMLNodeType(CurrentNode) = #PB_XML_Normal

        ChildNode = ChildXMLNode(CurrentNode)

        NodeName = GetXMLNodeName(CurrentNode)

        If ChildNode <> 0

          AddGadgetItem(#XMLTree, -1, NodeName, 0, CurrentSublevel)

        Else

          If Trim(GetXMLNodeText(CurrentNode)) <> ""

            AddGadgetItem(#XMLTree, -1, NodeName + " = " +

              GetXMLNodeText(CurrentNode), 0, CurrentSublevel)

          Else

            AddGadgetItem(#XMLTree, -1, NodeName, 0, CurrentSublevel)

          EndIf

        EndIf

        While ChildNode <> 0

          FillTree(ChildNode, CurrentSublevel + 1)     

          ChildNode = NextXMLNode(ChildNode)

        Wend       

      EndIf

 

    EndProcedure

 

  ; Sub btnReadTableHandler---------------------------------------------

    Procedure btnReadTableHandler()

 

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

        Protected User.s, Password.s, id.s, basicauth.s

        Protected soaprequest.s

        Protected answer.s, MainNode.i

 

      User = GetGadgetText(#User)

      Password = GetGadgetText(#Password)

      id = User + ":" + Password

      !v_basicauth = "Basic " + btoa(v_id)

 

      soaprequest = "<?xml version='1.0' encoding='UTF-8'?>" +

        "<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' " +

        "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +

        "xmlns:xs='http://www.w3.org/2001/XMLSchema'>" +

        "<env:Body>" +

        "<ns1:RFC_READ_TABLE xmlns:ns1='urn:sap-com:document:sap:rfc:functions'>" +

        "<DATA />" +

        "<FIELDS />" +

        "<OPTIONS />" +

        "<QUERY_TABLE>" + GetGadgetText(#TableName) + "</QUERY_TABLE>" +

        "<DELIMITER>~</DELIMITER>" +

        "</ns1:RFC_READ_TABLE>" +

        "</env:Body>" +

        "</env:Envelope>"

 

      !$.ajax({

      !  type: "POST",

      !  url: v_wsurl,

      !  contentType: 'text/xml',

      !  dataType: 'xml',

      !  headers: {

      !    'Authorization': v_basicauth,

      !    'Accept': '*/*'

      !  },

      !  data: v_soaprequest,

      !  success: processSuccess,

      !  error: processError

      !});

 

      !function processSuccess(data, textStatus, jqXHR) {

      !  if (textStatus == "success") {

      !    spider.debug.Print(textStatus);

      !    v_answer = jqXHR.responseText;

           If ParseXML(#XML, answer)

             If XMLStatus(#XML) = #PB_XML_Success

               MainNode = MainXMLNode(#XML)     

               If MainNode

                 ClearGadgetItems(#XMLTree)

                 FillTree(MainNode, 0)

               EndIf            

             EndIf

           EndIf

      !  }

      !}

 

      !function processError(jqXHR, textStatus, errorThrown) {

      !  spider.debug.Print(textStatus);

      !}   

 

    EndProcedure

 

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

    If OpenWindow(#MainWin, 10, 10, 480, 640, "RfcReadTable")

 

      TextGadget(#tUser, 10, 10, 100, 24, "User:")

      StringGadget(#User, 110, 10, 150, 24, "BCUSER")

      TextGadget(#tPassword, 10, 44, 100, 24, "Password:")

      StringGadget(#Password, 110, 44, 150, 24, "minisap", #PB_String_Password)

      TextGadget(#tTableName, 10, 78, 100, 24, "Tablename:")

      StringGadget(#TableName, 110, 78, 150, 24, "USR01")

      ButtonGadget(#btnReadTable, 10, 112, 250, 24, "ReadTable")

      TreeGadget(#XMLTree, 10, 146, 460, 484)

 

      BindGadgetEvent(#btnReadTable, @btnReadTableHandler())

 

    EndIf

 

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

 

We create a SOAP request and sent it via POST to an SAP system. The response is catched with the function processSuccess and the result is shown in the TreeGadget.

 

The WebService can easily create in TAC SE80.

 

Here the corresponding HTML code:

 

<html>

<head>

<meta charset="utf-8"/>

<title>SpiderBasic</title>

<script type="text/javascript">var spider = {}; spider.nbModules = 0; spider.nbLoadedModules = 0;</script>

 

<script type="text/javascript">

var Path = "/SAP/BC/BSP/SAP/PUBLIC/spiderbasic/libraries/javascript";

document.write("<script type='text/javascript' data-main='" + Path + "/main.js' src='" + Path + "/require.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/library.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/debug.js'><\/script>");

</script>

<script type="text/javascript">var dojoConfig = { async: 1 }; </script>

<script type="text/javascript">

document.write("<link rel='stylesheet' href='" + Path + "/dijit/themes/flat/flat.css' type='text/css' />");

document.write("<link rel='stylesheet' href='" + Path + "/dgrid/css/dgrid.css' />");

document.write("<link rel='stylesheet' href='" + Path + "/cbtree/icons/cbtreeIcons.css' type='text/css' />");

document.write("<link rel='stylesheet' href='" + Path + "/cbtree/icons/fileIconsMS.css' type='text/css' />");

document.write("<script type='text/javascript' src='" + Path + "/xdate.dev.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/canvas-toBlob.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "/FileSaver.js'><\/script>");

document.write("<script type='text/javascript' src='" + Path + "'/wgxpath.install.js'><\/script>");

document.write("<link rel='stylesheet' href='" + Path + "/themes/blue/window.css' type='text/css' />");

</script>

 

<script type="text/javascript" src="spiderbasic.js"></script>

 

<link rel="icon" type="image/png" href=""/>

 

</head>

 

<body class="flat" id="spiderbody">

 

</body>

</html>

 

 

Here the result with the content of the table USR01 in a tree structure:

spiderbasic012.jpg

 

Conclusion

 

SpiderBasic offers a lot of possibilities to create web based applications easily. It can be also easily seamless integrate in an SAP environment and it runs problem-free in the context of the SAP Web Application Server. Also it can communicate via the standards mechanisms with an SAP system. These are good conditions for an intensive consideration. Try it and let us know your results.

 

 

Enjoy it.

 

Cheers

Stefan

SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

Help Us to Help You - Information Which Helps to Support

$
0
0

Hello community,

 

often it is difficult to support users which posts questions here, because basically information are missing. Here a tiny script which detects a few technical information which are often of interest in the context of support. Add this information to your post and it is easier to support you. All you have to do is to set the filename - the red marked line -, to drag and drop the script on your session and to copy and paste the information from the file into your post.

 

The information looks e.g. like this:

Transaction          : SE80

Program              : SAPLSEO_CLEDITOR

ScreenNumber         : 300

CodePage             : 4110

GuiCodePage          : 4110

I18NMode             : False

Language             : EN

IsLowSpeedConnection : False

 

Help us to help you.

 

Cheers

Stefan

 

 

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

 

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

    Option Explicit

 

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

    Sub Main()

 

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

        Dim SapGuiAuto, application, connection, session, info

        Dim oFSO, oFile, FileName

 

      If Not IsObject(application) Then

        Set SapGuiAuto = GetObject("SAPGUI")

        Set application = SapGuiAuto.GetScriptingEngine

      End If

 

      If Not IsObject(connection) Then

        Set connection = application.Children(0)

      End If

 

      If Not IsObject(session) Then

        Set session = connection.Children(0)

      End If

 

      Set info = session.Info

 

      FileName = "C:\Dummy\Info.txt"

      Set oFSO=CreateObject("Scripting.FileSystemObject")

      Set oFile = oFSO.CreateTextFile(FileName, True)

      oFile.Write "Transaction          : " & _

        Info.Transaction & vbCrLf

      oFile.Write "Program              : " & _

        Info.Program & vbCrLf

      oFile.Write "ScreenNumber         : " & _

        CStr(Info.ScreenNumber) & vbCrLf

      oFile.Write "CodePage             : " & _

        CStr(Info.CodePage) & vbCrLf

      oFile.Write "GuiCodePage          : " & _

        CStr(Info.GuiCodePage) & vbCrLf

      oFile.Write "I18NMode             : " & _

        CStr(Info.I18NMode) & vbCrLf

      oFile.Write "Language             : " & _

        CStr(Info.Language) & vbCrLf

      oFile.Write "IsLowSpeedConnection : " & _

        CStr(Info.IsLowSpeedConnection) & vbCrLf

      oFile.Close

 

    End Sub

 

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

    Main

 

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

SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

Control SaveAs Dialog with AutoIt

$
0
0

Hello community,

 

a few times we discuss here the necessity to control Windows dialogs e.g. like SaveAs in the context of SAP GUI Scripting. For those dialogs offers SAP GUI Scripting no possibilities to control that. So it is necessary to control it by ourself by indirect means. Holger Köhn presented a VBA solution here. Here now an equivalent solution for AutoIt.


A few interesting findings:

  • FindWindowEx works not in any case, it is possible to use EnumChildWindows function.
  • The Save button from the SaveAs dialog delivers in the German version the text Open (Ö&ffnen) - weird.
  • It seems that the dialogs are version and language dependent.

 

The code shows different access methods to find a handle of a control resp. window - FindWindow, FindWindowEx and EnumChildWindows - with AutoIt. I thinks this code is a good base to implement an individual solution for your use case.

 

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

 

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

    AutoItSetOption ("MustDeclareVars" , 1)

 

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

    #Include "C:\Language\AutoIt\Include\SendMessage.au3"

    #Include "C:\Language\AutoIt\Include\WinAPI.au3"

    #Include "C:\Language\AutoIt\Include\WinAPISys.au3"

    #Include "C:\Language\AutoIt\Include\WindowsConstants.au3"

    #Include "C:\Language\AutoIt\Include\MsgBoxConstants.au3"

    #Include "C:\Language\AutoIt\Include\GuiButton.au3"

    #Include "C:\Language\AutoIt\Include\Array.au3"

    #Include "C:\Language\AutoIt\Include\GuiEdit.au3"

 

  ;-Function _WinAPI_FindWindowEx---------------------------------------

    Func _WinAPI_FindWindowEx($hWndParent, $hWndChildAfter, _

      $sClassName, $sWindowName)

      Local $aResult = DllCall("user32.dll", "hwnd", "FindWindowExW", _

        "hWnd", $hWndParent, "hWnd", $hWndChildAfter, _

        "wstr", $sClassName, "wstr", $sWindowName)

      If @error Then Return SetError(@error, @extended, 0)

      Return $aResult[0]

    EndFunc

 

  ;-Sub Auto_SaveAs_SAP-------------------------------------------------

  ;

  ; Function checked with SAP 7.31 SP 4 and Dialog Box in SE80 to save

  ; source code as local file on a German version of Windows 7 with

  ; AutoIt 3.3.14.2

  ;

  ; Important hint: FindWindowEx works not in any case, so it is

  ;                 possible to use instead EnumChildWindows

  ;

  ;---------------------------------------------------------------------

    Func Auto_SaveAs_SAP($FileName)

 

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

        Local $i

 

      ;Get the handle of the Save As Dialog Box

      Local $hWin = _WinAPI_FindWindow ("#32770", "Speichern unter")

      If $hWin = 0 Then

        MsgBox($MB_OK, "", "Save As Window Not Found")

        Return

      EndIf

 

      ;Get the handle of ComboBoxEx32

      Local $hChildRet = _WinAPI_FindWindowEx($hWin, 0, "ComboBoxEx32", "")

      If $hChildRet = 0 Then

        MsgBox($MB_OK, "", "ComboBoxEx32 Not Found")

        Return

      EndIf

 

      ;Get the handle of the Main ComboBox

      $hChildRet = _WinAPI_FindWindowEx($hChildRet, 0, "ComboBox", "")

      If $hChildRet = 0 Then

        MsgBox($MB_OK, "", "ComboBox Window Not Found")

        Return

      EndIf

 

      ;Get the handle of the Edit

      Local $hChildArray = _WinAPI_EnumChildWindows($hChildRet)

      $hChildRet = $hChildArray[1][0]

      If $hChildRet = 0 Then

        MsgBox($MB_OK, "", "Edit Window Not Found")

        Return

      EndIf

 

      _WinAPI_SetForegroundWindow($hWin)

      _WinAPI_BringWindowToTop($hWin)

 

      ;fillin FileName in 'Save As' Edit

      _GUICtrlEdit_SetText($hChildRet, $FileName)

 

      ;Get the handle of the Save Button in the Save As Dialog Box

      $hChildArray = _WinAPI_EnumChildWindows($hWin)

      For $i = 0 To UBound($hChildArray, $UBOUND_ROWS) - 1

        If $hChildArray[$i][1] = "Button" Then

         ;The Save Button gets as Window Text Open - Crazy

          If _GUICtrlButton_GetText($hChildArray[$i][0]) = "Ö&ffnen" Then

            $hChildRet = $hChildArray[$i][0]

          EndIf

        EndIf

      Next

 

      ;Check if we found it or not

      If $hChildRet = 0 Then

        MsgBox($MB_OK, "", "Save Button in Save As Window Not Found")

        Return

      EndIf

 

      ;Press Save-button

      _SendMessage($hChildRet, $BM_CLICK, 0, 0)

 

    EndFunc

 

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

    Func Main()

      Auto_SaveAs_SAP("Test.txt")

    EndFunc

 

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

    Main()

 

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

 

Hint: You can find here WinSpy++, a phantastic freeware tool analyze the UI, controls, handles and many more.

 

Enjoy it.

 

Cheers

Stefan

Use SAP GUI Scripting with Native PowerShell

$
0
0

Hello community,

 

a few days ago I presented here the new version of Scripting Tracker. The new version supports now native PowerShell code generating.

 

Here an example of a PowerShell script from a logon process.

001.jpg

You see the SAP GUI for Windows screen and the recorded script inside Scripting Tracker. With Scripting Tracker it is seamless possible to switch in the PowerShell ISE and here you find the complete code. Now you can use all the possibilities of the ISE like single step debugging or examination of variables.

 

Scripting Tracker uses a COM bridge for the communication with SAP GUI Scripting, which I presented here. On this way it is possible to generate code which is nearly similar to well known VBScript.

 

Here an example of an activity in an tree control in VBScript:

session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").expandNode "0000000003"

session.findById("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell").selectedNode = "0000000004"

 

Here the same example in PowerShell:

$ID = Invoke-Method $session "findById" @("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell")

Invoke-Method $ID "expandNode" @("0000000003")

$ID = Invoke-Method $session "findById" @("wnd[0]/usr/cntlIMAGE_CONTAINER/shellcont/shell/shellcont[0]/shell")

Set-Property $ID "selectedNode" @("0000000004")

 

The comparisation shows that code in VBScript contains one line for one activity and PowerShell two lines. The code generation creates for findById one call of Invoke-Method and with the returned ID it calls the next activity e.g. like expandNode.

002.jpg

In some cases the code generation creates well known code like

$ID.elementAt(3).width = 19

which should sets the width of the third column of the table control.

But the method elementAt doesn't work in this context, it is necessary to replace it with Item like

$ID.Item(3).width = 19

which works perfectly.

003.jpg

Since version 5, which I presented here, offers PowerShell new language features like classes.

 

It has many advantages more to use PowerShell instead VBScript with SAP GUI Scripting:

  1. PowerShell is the actual Scripting language in Windows environments.
  2. It is available on all Windows systems without further installations.
  3. It is in further development.
  4. Its security mechanisms are technically mature.
  5. PowerShell offers an Integrated Scripting Environment (ISE) e.g. for single step debugging.
  6. etc.

 

Enjoy it.

 

Cheers

Stefan


Tip: Show Hidden Members of VBA

$
0
0

Hello community,

 

if you press F2 in the VBA Environment the object browser will be opened. With a mouse right click in the element list box a pull down menu will be opened. In this menu you can activate the item "Show hidden elements" (Verborgene Elemente anzeigen). If it is activated some classes and elements are visible, e.g. like ObjPtr, StrPtr and VarPtr from the invisible class _HiddenModule. It is very interesting to find other members from other libraries, e.g. in the GuiCtrlAbapEditor which has an undocumented change event.

 

001.jpg

 

Enjoy it.

 

Cheers

Stefan

SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

How to Store a Binary File in a Script

$
0
0

Hello community,

 

a longer time ago I presented here the possibility to contain binary files in ABAP function modules or as JSON code. With the same technic it is possible to store binary files in a script source, like AutoIt script or VBA. Here an AutoIt program BinFile2Script which offers this possibility. You can create a subroutine which contains the binary code and with the call of this subroutine the binary code is written to disc.

 

Here an AutoIt example:

001.JPG

 

Here an VBA example:

002.JPG

You can copy the whole code into the clipboard and paste it into your development environment.

 

The AutoIt program is an attachment to this post.

 

Enjoy it.

 

Cheers

Stefan

SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

A Word about RFC-Security in the Context of Calls from Scripting Languages

$
0
0

Hello community,

 

every once in awhile in discussions with script programmers I think it is unclear that remote function calls (RFC) is not an open gate. It seems that script programmers commonly believed that RFCs are medicine to heal every or almost every problem, but, even if it seems obvious, it isn't.

 

An RFC-enabled function module offers an interface which is accessible from non-ABAP programs, like a scripting language.

 

The first check which the SAP system performs automatically, if an RFC-enabled function module is called, is to check the S_RFC authorization object. If your user profile doesn't contain this authorization object you can't call an RFC-enabled function module - and there is no way around. In  a normal case a dialog user doesn't have this object, it is primary for communication or key users.

 

SAP offers a lot of RFC-enabled function modules, e.g. like RFC_READ_TABLE. Each of this RFC-enabled function modules contains an authority check, this means each function module calls VIEW_AUTHORITY_CHECK to check whether the user is allowed to perform the action. The profile of an user stores the possible authorization objects. If your user profile doesn't contain a necessary authorization object you can call the RFC-enabled function module, but the function module raises an exception.

 

Last but not least it is possible that the security audit log of an SAP system is enabled - transaction code SM19 to administer the security audit log and SM20 to analyse it. It logs each RFC connection and function call.

AuditLog.jpg

As we see it is a good and secure compound. The user identification of a programmer, which uses in a scripting language an RFC, must have the correct authorization objects, otherwise it is not possible to use an RFC-enabled function module. As we see it is more or less complex to get and set the correct authorization objects and it is not a good idea to set the SAP_ALL profile to any user.

 

If RFC-enabled function modules are to be used with a scripting language on a production system it is the right way to set the authorization objects with tact to open the gate not more or less than necessary. And we as a script programmer must be sensitive for this requirement.

 

Cheers

Stefan

You Know What They Say About Old Dogs or...

$
0
0

Why It Is Recommended To Use The ActiveX Controls No Longer

 

 

Hello community,

 

to communicate with an SAP system many scripting or VBA programmers uses the ActiveX controls from the SAP GUI for Windows. There are wdtfuncU.ocx with the class ID SAP.Functions.Unicode, wdtaocxU.ocx, wdobapiU.ocx and wdtlogU.ocx. They are part of the SAP GUI for Windows installation. All these ActiveX controls have a dependency to the classic RFC library librfc32u.dll. The classic RFC library is since the 1st of April 2016 out of support and it is since this date not longer available in the SAP store. But it is furthermore a component of the actual SAP GUI for Windows installation, version 7.40 patchlevel 8. So it is available as part of the SAP GUI for Windows installation. A communication to an SAP system via the ActiveX controls without the classic RFC library is not possible.

 

In a few discussions with programmers I see that they want to use these ActiveX controls in new projects. The main reasons for this decision are

  • that the libraries are available without an additional installation on any system and
  • that there are a lot of examples in the internet available.

But I think there are powerful arguments against the using of ActiveX controls in new projects:

  • The dependency to the classic RFC library, which is definitely deprecated.
  • There will be no further development of the ActiveX controls.
  • It is not possible to use newer ABAP function modules, which uses tables in export parameters.
  • The ActiveX controls has no future.

 

I think we should not be comfortable and we should not decide to use this old fashion technology, otherwise we rob us a lot of future possibilities. I can only recommend to use alternatives. Software is used mostly for longer than is generally assumed. From the viewpoint of maintainability and ability of further development it is not good to develop a new project with this kind of technology.

 

Cheers

Stefan

Brief Contemplation: Is Script Programming Really Programming?

$
0
0

Hello community,

 

let us clarify in this context first what is technically the difference between a programming language and a scripting language? I do not know a specific definition, so in my eyes is the difference that a programming language compiles the source code to a machine code and run on the hardware of the underlying operating system. Scripting languages does not require an explicit compilation step and interprets the source code. The concepts of the languages itself are more or less identically, like control conditions, variables, loops, etc. The performance difference between this kind of languages is actually minimal, because modern hardware and scripting engines interpretes the code on the fly very fast. It seems that the only difference is that a programming language can create an executable binary which runs natively on the operating system, while a scripting language needs a runtime environment. But Java and the dotNET languages needs also a runtime environment. You see, this can be an academic discussion. Last but not least can we say that the difference is very small, the frontiers between programming and scripting languages is blurred. From this perspective one can say clearly, script programming is really programming.

 

Cheers

Stefan


Basico

$
0
0

basico_00.PNG

basico.png

Dear SAP Consultants,

 

I am pleased to announce you the first release of Basico, a SAP Notes Manager for SAP Consultants.

 

The main goal of this application is to help the SAP Consultant to download SAP Notes, categorize them by tasks and, find them quickly. Another goal is allow you to share SAP Notes with other fellows.

 

You must own a S-User if you want to use this application.

 

Please, note that this application is not a substitute of Launchpad. This application just uses one of the OData services that Launchpad provides. And it does by using your own browser (at this moment only the Firefox browser is supported).


Current features:

  • Import/Download SAP Notes
  • Export SAP Notes to: plain text, CSV and, JSON format (useful if you  want to share your SAP Notes)
  • Bookmarks
  • Browse SAP Notes in Launchpad
  • Search by SAP Note ID, Component, Category, etc...
  • Views: view your SAP Notes by components, by tasks or only those bookmarked

 

As this is an announcement I don't want to bore you with details. If someone is interested in them, please, read this post from my blog.

 

If you wanna give it a try, you can read the installation instructions in this page.


Disclaimer: this is a experiment, a programming exercise. Actually, this application is in an early stage of development so take into account that can have bugs.

 

This software is not linked, affiliated, related or endorsed in any way by any division or subsidiary of SAP® AG.



Hope you enjoy it.

 

 

P.S.: This post was also published in LinkedIn.

SAP VB Scripting and GuiXT Blog

$
0
0

Using VB Scripting at work in SAP Accounts Receivable, with each script, I find new challenges and code that needs to be implemented to meet end user needs such as adding a button to execute a script: scn.sap.com/thread/1526174, runnning a script in a child session: scn.sap.com/thread/2035084 and use of SAP GuiXT to change the appearance of a screen without compromising the database: scn.sap.com/docs/DOC-48796. The resources available in SCN to meet these challenges are terrific. Marrying up SAP with a computer programming language that has been in use for a number of years (VB) today still can save significant processing time for end users. In the case of GuiXT, make use of SAP screens so much easier for new and even experienced users. I wanted to create this blog to collate this great information and contribute to the extensive knowledge sharing on SCN.

How To Use NCo With PowerShell 5 Classes Feature

$
0
0

Hello community,

 

I presented here the possibility to use NCo with Microsofts scripting language PowerShell. Here now examples how to use NCo with PowerShell 5 and the new classes language feature. You can find more information about classes in PowerShell here.

 

 

1st example - Ping:

 

#-Begin-----------------------------------------------------------------

 

  <#

    .Synopsis

      Calls PING of an SAP system.

    .Description

      Calls the function module RFC_PING and the build-in function

      Ping of the .NET connector.

  #>

 

  #-Function Get-Destination--------------------------------------------

    Function Get-Destination($cfgParams) {

      If (("SAP.Middleware.Connector.RfcDestinationManager" -as [type]) -ne $null){

        Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

      }

    }

 

  #-Class NCo-----------------------------------------------------------

    Class NCo {

 

      #-Constructor-----------------------------------------------------

        NCo() {

 

          [String]$ScriptDir = $PSScriptRoot

 

          If ([Environment]::Is64BitProcess) {

            [String]$Path = $ScriptDir + "\x64\"

          }

          Else {

            [String]$Path = $ScriptDir + "\x86\"

          }

 

          [String]$File = $Path + "sapnco.dll"

          Add-Type -Path $File

          [String]$File = $Path + "sapnco_utils.dll"

          Add-Type -Path $File

 

        }

 

      #-Method GetDestination-------------------------------------------

        Hidden [Object]GetDestination() {

 

          #-Verbindungsparamter-----------------------------------------

            $cfgParams = `

              New-Object SAP.Middleware.Connector.RfcConfigParameters

            $cfgParams.Add($cfgParams::Name, "TEST")

            $cfgParams.Add($cfgParams::AppServerHost, "ABAP")

            $cfgParams.Add($cfgParams::SystemNumber, "00")

            $cfgParams.Add($cfgParams::Client, "001")

            $cfgParams.Add($cfgParams::User, "BCUSER")

 

            $SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString

            $ptrPasswd = `

              [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)

            $Passwd = `

              [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)

            $cfgParams.Add($cfgParams::Password, $Passwd)

 

          Return Get-Destination($cfgParams)

 

        }

 

      #-Method ExecutePing----------------------------------------------

        ExecutePing() {

 

          $destination = $This.GetDestination()

 

          #-Metadata----------------------------------------------------

            $rfcFunction = `

              $destination.Repository.CreateFunction("RFC_PING")

 

          #-Variant 1: Call function module-----------------------------

            Try {

              $rfcFunction.Invoke($destination)

              Write-Host "Ping successful"

            }

            Catch {

              Write-Host "Exception" $_.Exception.Message "occured"

            }

 

          #-Variant 2: Call build-in function---------------------------

            Try {

              $destination.Ping()

              Write-Host "Ping successful"

            }

            Catch {

              Write-Host "Exception" $_.Exception.Message "occured"

            }

 

        }

 

    }

 

  #-Sub Main------------------------------------------------------------

    Function Main () {

      $NCo = [NCo]::new()

      $NCo.ExecutePing()

    }

 

  #-Main----------------------------------------------------------------

    If ($PSVersionTable.PSVersion.Major -ge 5) {

      Main

    }

 

#-End-------------------------------------------------------------------

 

 

2nd example - RFC_SYSTEM_INFO:

 

#-Begin-----------------------------------------------------------------

 

  <#

    .Synopsis

      Calls RFC_SYSTEM_INFO of an SAP system.

    .Description

      Calls the function module RFC_SYSTEM_INFO and writes the result

      on the screen.

  #>

 

  #-Function Get-Destination--------------------------------------------

    Function Get-Destination($cfgParams) {

      If (("SAP.Middleware.Connector.RfcDestinationManager" -as [type]) -ne $null){

        Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

      }

    }

 

  #-Class NCo-----------------------------------------------------------

    Class NCo {

 

      #-Constructor-----------------------------------------------------

        NCo() {

 

          [String]$ScriptDir = $PSScriptRoot

 

          If ([Environment]::Is64BitProcess) {

            [String]$Path = $ScriptDir + "\x64\"

          }

          Else {

            [String]$Path = $ScriptDir + "\x86\"

          }

 

          [String]$File = $Path + "sapnco.dll"

          Add-Type -Path $File

          [String]$File = $Path + "sapnco_utils.dll"

          Add-Type -Path $File

 

        }

 

      #-Method GetDestination-------------------------------------------

        Hidden [Object]GetDestination() {

 

          #-Verbindungsparamter-----------------------------------------

            $cfgParams = `

              New-Object SAP.Middleware.Connector.RfcConfigParameters

            $cfgParams.Add($cfgParams::Name, "TEST")

            $cfgParams.Add($cfgParams::AppServerHost, "ABAP")

            $cfgParams.Add($cfgParams::SystemNumber, "00")

            $cfgParams.Add($cfgParams::Client, "001")

            $cfgParams.Add($cfgParams::User, "BCUSER")

 

            $SecPasswd = Read-Host -Prompt "Passwort" -AsSecureString

            $ptrPasswd = `

              [Runtime.InteropServices.Marshal]::SecureStringToBStr($SecPasswd)

            $Passwd = `

              [Runtime.InteropServices.Marshal]::PtrToStringBStr($ptrPasswd)

            $cfgParams.Add($cfgParams::Password, $Passwd)

 

          Return Get-Destination($cfgParams)

 

        }

 

      #-Method GetSystemInfo--------------------------------------------

        GetSystemInfo() {

 

          $destination = $This.GetDestination()

 

          #-Metadata----------------------------------------------------

            $rfcFunction = `

              $destination.Repository.CreateFunction("RFC_SYSTEM_INFO")

 

          #-Call function module----------------------------------------

            Try {

              $rfcFunction.Invoke($destination)

 

              $Export = $rfcFunction.GetStructure("RFCSI_EXPORT")

 

              #-Get information-----------------------------------------

                Write-Host $Export.GetValue("RFCHOST")

                Write-Host $Export.GetValue("RFCSYSID")

                Write-Host $Export.GetValue("RFCDBHOST")

                Write-Host $Export.GetValue("RFCDBSYS")

 

            }

            Catch {

              Write-Host "Exception" $_.Exception.Message "occured"

            }

 

        }

 

    }

 

  #-Sub Main------------------------------------------------------------

    Function Main () {

      $NCo = [NCo]::new()

      $NCo.GetSystemInfo()

    }

 

  #-Main----------------------------------------------------------------

    If ($PSVersionTable.PSVersion.Major -ge 5) {

      Main

    }

 

#-End-------------------------------------------------------------------

 

RFC_SYSTEM_INFO.JPG

 

Hint: To bypassing unresolved errors of not available types inside the class I use a tiny trick, I externalize the code in a function - e.g. in this case Get-Destination.

 

Enjoy it.

 

Cheers

Stefan

How To Use SAP HANA ABAP Source Search via PowerShell

$
0
0

Hello community,

 

here a tiny example how to use SAP HANA ABAP Source Search via PowerShell. After my question here, in the ABAP in Eclipse forum, I see how easy it is to use the ABAP Source Search from outside an SAP system. After the activation of the business function SRIS_SOURCE_SEARCH is it also possible with only one http get request to use it.

 

 

#-Begin-----------------------------------------------------------------


  $User = "BCUSER"

  $Password = Read-Host -Prompt "Passwort" -AsSecureString

  $Cred = New-Object System.Management.Automation.PSCredential($User, $Password)

 

  $System = "http://nsp.mysystem.de:8650/"

  $TextSearch = "sap/bc/adt/repository/informationsystem/textsearch"

  $SearchString = "?searchString=Record"

  $Params = "&searchFromIndex=1&searchToIndex=10"

 

  $RequestURI = $System + $TextSearch + $SearchString + $Params

  [XML]$SearchResult = Invoke-RestMethod -Uri $RequestURI -Credential $Cred -Method Get

 

  $Cnt = $SearchResult.textSearchResult.textSearchObjects.textSearchObject.Count

  For ($i = 0; $i -lt $Cnt; $i++ ) {

    $Obj = $SearchResult.textSearchResult.textSearchObjects.textSearchObject[$i]

    Write-Host $Obj.adtMainObject.description " - " $Obj.adtMainObject.name 

  }


#-End-------------------------------------------------------------------

 

 

In my example I search the word Record with a maximum of 10 hits.

 

ABAPSourceSearchPowerShell.jpg

 

Enjoy it.

 

Cheers

Stefan

How To Use Single Sign On (SSO) With COM Connector (CCo)

$
0
0

Hello community,

 

here an example how to us Single Sign On (SSO) with CCo. In the function RfcGetPartnerSSOTicket - the name is equivalent to the function in the NWRFC library - I use the ABAP function module SUSR_CHECK_LOGON_DATA to get the ticket. With this ticket is it now easy possible to log on to other systems. In my example I log on to another system and to the same system again.

 

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

 

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

    Option Explicit

 

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

    Const RFC_OK = 0

 

  '-RfcGetPartnerSSOTicket----------------------------------------------

    Function RfcGetPartnerSSOTicket(SAP, hRFC, UserID, PassWd)

 

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

        Dim rc, hFuncDesc, hFunc, Ticket

 

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

      If hFuncDesc = 0 Then

        rc = SAP.RfcCloseConnection(hRFC)

        Exit Function

      End If

 

      hFunc = SAP.RfcCreateFunction(hFuncDesc)

      If hFunc = 0 Then

        rc = SAP.RfcCloseConnection(hRFC)

        Exit Function

      End If

 

      rc = SAP.RfcSetChars(hFunc, "AUTH_METHOD", "P")

      rc = SAP.RfcSetChars(hFunc, "USERID", UserID)

      rc = SAP.RfcSetChars(hFunc, "PASSWORD", PassWd)

 

      Ticket = Space(2048)

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

        rc = SAP.RfcGetChars(hFunc, "TICKET", Ticket, 2048)

      End If

 

      rc = SAP.RfcDestroyFunction(hFunc)

 

      RfcGetPartnerSSOTicket = Trim(Ticket)

 

    End Function

 

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

    Sub Main()

 

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

        Dim SAP, UserID, PassWd, hRFC, rc, Ticket

 

      Set SAP = CreateObject("COMNWRFC")

      If Not IsObject(SAP) Then

        Exit Sub

      End If

 

      SAP.GetUserPasswordDialog " for NSP", UserID, PassWd

 

      hRFC = SAP.RfcOpenConnection("ASHOST=NSP, SYSNR=00, CLIENT=001, " & _

        "USER=" & UserID & ", PASSWD=" & PassWd)

      If hRFC = 0 Then

        Set SAP = Nothing

        Exit Sub

      End If

 

      Ticket = RfcGetPartnerSSOTicket(SAP, hRFC, UserID, PassWd)

 

      rc = SAP.RfcCloseConnection(hRFC)

 

      SAP.UsePwdRequest = 0

 

      hRFC = SAP.RfcOpenConnection("ASHOST=NST, SYSNR=01, CLIENT=001, " & _

        "MYSAPSSO2=" & Ticket)

      If hRFC Then

        MsgBox "Connected to NST via SSO"

        rc = SAP.RfcCloseConnection(hRFC)

      End If

 

      hRFC = SAP.RfcOpenConnection("ASHOST=NSP, SYSNR=00, CLIENT=001, " & _

        "MYSAPSSO2=" & Ticket)

      If hRFC Then

        MsgBox "Connected to NSP via SSO"

        rc = SAP.RfcCloseConnection(hRFC)

      End If

 

      Set SAP = Nothing

 

    End Sub

 

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

    Main

 

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

 

The method GetUserPasswordDialog opens a dialog to get the user name and the password. On this way it is now very easy in VBScript to get those kind of data.

 

Enjoy it.

 

Cheers

Stefan

Viewing all 60 articles
Browse latest View live


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