cancel
Showing results for 
Search instead for 
Did you mean: 

VBA to 'Stop Transaction' using Windows API

07-19-2021 1:53 PM
ianj14 Explorer
1211 views 2 comments Go to solution
SAP Managed Tags
Subscribe

Hi,

I would like to be able to stop a transaction running in SAP GUI using VBA.

I've seen threads which solve the problem of stopping a transaction by destroying the session the transaction is running in, but this causes issues where my session management system which needs to keep the session running for reuse.

I would therefore like to be able to cause the 'Stop Transaction' option to trigger as per the top left window menu.

As there appears to be no 'Stop Transaction' command on a given session object within the VBA/script system, can anyone help me with using the Windows API to trigger the option, but, and this is crucial, without using SendKeys. Too many other things happening on screen for that to be in any way reliable.

TIA

Accepted Solutions (1)

Accepted Solutions (1)

ianj14
Explorer
0 Likes

This is my code below:


Private Declare PtrSafe Function FindWindowA Lib "user32.dll" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function GetSystemMenu Lib "user32" (ByVal hWnd As LongPtr, ByVal bRevert As Long) As LongPtr
Private Declare PtrSafe Function GetMenuItemCount Lib "user32" (ByVal hMenu As LongPtr) As Long
Private Declare PtrSafe Function GetMenuItemInfoA Lib "user32" (ByVal hMenu As LongPtr, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) As Long
Private Declare PtrSafe Function SendMessageA Lib "user32" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr

Public Const MIIM_STRING As Integer = &H40
Public Const MIIM_ID = &H2
Public Const WM_COMMAND = &H111
Public Const WM_SYSCOMMAND = &H112

Public Type MENUITEMINFO
    cbSize As Long
    fMask As Long
    fType As Long
    fState As Long
    wID As LongPtr
    hSubMenu As Long
    hbmpChecked As Long
    hbmpUnchecked As Long
    dwItemData As Long
    dwTypeData As String
    cch As Long
End Type

Public Function RunMenuItemByString(ByVal sMenuItem As String, _
                                    ByVal sWindowClass As String, _
                                    ByVal sWindowText As String, _
                                    ByVal iCommandType As Integer) As Boolean

    Dim hWnd As LongPtr, hMenu As LongPtr, lpMenuItemID As LongPtr

    Dim lngMenuItemCount As Long, lngMenuItem As Long, lngResultMenuItemInfo As Long

    Dim typMI As MENUITEMINFO

    Dim s As String

    Dim blnRet As Boolean

    hWnd = FindWindowA(sWindowClass, sWindowText)

    hMenu = GetSystemMenu(hWnd, 0&)

    lngMenuItemCount = GetMenuItemCount(hMenu)

    For lngMenuItem = 0 To lngMenuItemCount - 1

        typMI.cbSize = Len(typMI)
        typMI.dwTypeData = String$(255, " ")
        typMI.cch = Len(typMI.dwTypeData)
        typMI.fMask = MIIM_STRING Or MIIM_ID
        lngResultMenuItemInfo = GetMenuItemInfoA(hMenu, lngMenuItem, 1, typMI)
        s = Trim$(typMI.dwTypeData)
        lpMenuItemID = typMI.wID
        If InStr(1, s, sMenuItem, vbTextCompare) > 0 Then
            blnRet = SendMessageA(hWnd, iCommandType, lpMenuItemID, 0&) = 0
            Exit For
        End If

    Next lngMenuItem

    RunMenuItemByString = blnRet

End Function

Public Function TestRunMenuItemByString()

    lpHwndSAPSession = oSAPSession.FindById("wnd[0]").Handle

    sWindowText = GetWindowText(lpHwndSAPSession)

    TestRunMenuItemByString = RunMenuItemByString("Stop Transaction", "SAP_FRONTEND_SESSION", sWindowText, WM_SYSCOMMAND)

End Function

The TestRunMenuItemByString function can be used only after a session is started, and will only work if there is actually a transaction executing. You will need to figure out how to reference your sap session object (oSAPSession) in order to use the Handle value from it.

The declarations should work in both 32 bit and 64 bit versions of VBA and the LongPtr has been used for the handle (h) and pointer (lp) variables to reflect this.

This was tested in Microsoft Access, but I see no reason why it shouldn't work in VBA in other Office applications. I can't vouch for it being adaptable for VBScript.

Answers (1)

Answers (1)

ianj14
Explorer

Ok, so I figured this out. My code for it is somewhat customised, so I'll need to make it more generic before posting it. Hopefully that won't take too many days...