Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member212650
Participant

'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 title containing "Portal" (depending on your env).

'Open a portal and run this function.

Debug.Print oGetPortal.LocationURL

Function oGetPortal( _

Optional sWindowTitle As String = "Portal" _

) As Object

   Set objShellApp = CreateObject("Shell.Application")

   For Each objWindow In objShellApp.Windows

  DoEvents

  Debug.Print objWindow.locationname ' Displays window titles

   If InStr(LCase(objWindow.locationname), LCase(sWindowTitle)) > 0 Then

   Set oGetPortal = objWindow

   Exit For

   End If

   Next

   Set objShellApp = Nothing

   Set objWindow = Nothing

End Function

'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. Use the URL you get from oGetPortal.LocationURL

' Your must set a reference in the VBA IDE to Microsoft internet explorer controls (VBA IDE -> Tools -> references

' For intranet portals InternetExplorerMedium is needed - if this does not work see oGetLatestPortal following


Function oOpenPortal( _

  Optional sURL As String = "http://myportalpath/portal") As Object

' set a reference to Microsoft internet explorer controls

   Dim IE As InternetExplorerMedium

   Set IE = New InternetExplorerMedium

  IE.Navigate sURL

   Set oOpenPortal = IE

End Function




' Skip this section if the above works

' In windows 7 the IE object automatically detaches from intranet pages (see above code fixes this issue) 

'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

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Declare Function GetForegroundWindow Lib "user32" () As Long

Function oGetLatestPortal( _

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

  Optional sWindowTitle As String = "Home - SAP NetWeaver Portal") As Object

   Dim IE As InternetExplorer

   Set IE = New InternetExplorer

  IE.Navigate sURL

   Dim hwnd As Long

  hwnd = GetForegroundWindow() ' get latest IE window

   Set IE = Nothing  ' work around for windows 7 issue

  i = 0

   Do While i < 10 And IE Is Nothing

  i = i + 1

   Set objShellApp = CreateObject("Shell.Application")

   For Each 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

       End If

     End If

   Next

  DoEvents

  Sleep 100

   Loop

   If IE Is Nothing Then

  MsgBox "nothing"

Exit Function

  End If

   Set oGetLatestPortal = IE

End Function

'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 As Object) As Boolean

  Dim t1 As Long

  Dim t2 As Long

  On Error Resume Next

  t1 = Timer

  t2 = t1 + 60

  Do

   If Timer > t2 Then lWait = False: Exit Function

  If VarType(LOIE.Document) = vbString Then Exit Do

  Loop

  Do

   If Timer > t2 Then lWait = False: Exit Function

  If LOIE.Busy = False Then Exit Do

  Loop

  Do

   If Timer > t2 Then lWait = False: Exit Function

  If VarType(LOIE.Document.readyState) = "C" Then Exit Do

  Loop

  Do

   If Timer > t2 Then lWait = False: Exit Function

  If LOIE.Document.readyState = "complete" Then Exit Do

  Loop

  lWait = True

End Function

'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 As Object) As Boolean

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

  Dim ctrl As Object

  Do

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

if ctrl is nothing Then Exit Funtion

If ctrl.getAttribute("style").display = "none" Then Exit Do

sleep 500

  Loop

End Function

'

.

' 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 As Object

Dim t1 As Long

Dim t2 As Long

t1 = Timer

t2 = t1 + 10 ' secs

While element Is Nothing

  DoEvents

   If Timer > t2 Then

  MsgBox "timeout"

   Exit Do

   End If

' 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 As Object

' 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 As Object

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 As Object

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

Dim myformdocument As Object

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 As Object

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

lWait subframe1.contentWindow

' Next get document DOM of iframe

Dim myframedocument As Object

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 = 0 To IE.Document.links.Length - 1

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

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

Exit For

   End If

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")

For Each oTd In oTds

  DoEvents

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

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

   Exit For

   End If

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

2 Comments
Labels in this area