Getting Unspecified error in QTP - vb.net

I'm trying to execute the below script in QTP which opens F12 developer option on a webpage and checks the network data for 404 error by verifying the Network data weblist. But I get an "Unspecified error" while executing the line
If trim(Browser("creationtime:=0").WinListView("regexpwndtitle:=Summary View ListView Control").GetSubItem(rcount,4))="404" then
Can you please advise Why I get this error.
Code:
Browser("creationtime:=0").highlight
Set WshShell = CreateObject("WScript.Shell")
WshShell.SendKeys "{F12}"
wait 20
Browser("creationtime:=0").WinListView("regexpwndtitle:=Summary View ListView Control").Click
wait 2
WshShell.SendKeys "{F5}"
Browser("creationtime:=0").Refresh
wait 20
totalcount= Browser("creationtime:=0").WinListView("regexpwndtitle:=Summary View ListView Control").GetItemsCount
For rcount = 1 to totalcount-1
If trim(Browser("creationtime:=0").WinListView("regexpwndtitle:=Summary View ListView Control").GetSubItem(rcount,4))="404" then
flag=true
Exit for
End if
next
If flag Then
msgbox "404 is present in row "&rcount
else
msgbox "404 is not present"
End If

Related

The control could not be found by id. SAP GUI bug?

I am trying to automate SAP data extraction using scripting. The problem I am facing is a recorded script in SAP isn't working when I'm running it, when I use findById("id") method it comes out that cannot be found, however the tabs are there.
The idea is to move between the tabs (using session.findById("id").Select) to extract info in that panels. Use a list of Purchase Orders (PO's), make a loop and extract the information, it's simple.
However, these tabs aren't found randomly. Sometimes it works, sometimes it is not found. All PO's (if I do it manually) have tabs with the data, but in the script it doesn't work.
For example:
The red box is the tabs that I am trying to select
Output of the recorded script (just moving between tabs):
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
If IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End If
session.findById("wnd[0]").resizeWorkingPane 183,24,false
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:0015/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT13").select
' Extract info
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:0019/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT15").select
' Extract info
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:0015/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT18").select
' Extract info
Error:
The control could not be found by id.
I'm using:
My theory, the tab is hidden and doesn't find it, that I would have to use the arrows to move, however when I use the arrows at the time of making the script recording, it simply doesn't add them to the code.
Sorry for my English, and thanks in advance for your time.
I can only offer a workaround on this phenomenon.
for example:
...
for i = 1 to 99
on error resume next
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:00" & right("0" & cstr(i),2) & "/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT13").select
if err.number = 0 then exit for
on error goto 0
next
on error goto 0
' Extract info
for i = 1 to 99
on error resume next
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:00" & right("0" & cstr(i),2) & "/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT15").select
if err.number = 0 then exit for
on error goto 0
next
on error goto 0
' Extract info
for i = 1 to 99
on error resume next
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:00" & right("0" & cstr(i),2) & "/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT18").select
if err.number = 0 then exit for
on error goto 0
next
on error goto 0
' Extract info
Regards,
ScriptMan
Ah yes, my favorite SAP screen: ME23N. Who knows what the SAPLMEGUI:00XX will be! But, if you find the element by it's name you'll never run into this problem. Additionally, this solves the problem of the tab you want not being there; because, depending on the line item of the PO, who knows what tabs will be available.
Here's how I get over this every time, without fail.
In your sub procedure use the function below. If the tab is there it will select it and return true and you can continue extracting your data. You need the tab text and the name of the tab strip.
You can find the name of the tab strip easily. Look at what has been recorded. It has the "tabs" prefix.
session.findById("wnd[0]/usr/subSUB0:SAPLMEGUI:0015/subSUB3:SAPLMEVIEWS:1100/subSUB2:SAPLMEVIEWS:1200/subSUB1:SAPLMEGUI:1301/subSUB2:SAPLMEGUI:1303/tabsITEM_DETAIL/tabpTABIDT13")
Public Sub Main()
If IsTabThere("ITEM_DETAIL", "Account Assignment") = True Then
' Extract info
End If
If IsTabThere("ITEM_DETAIL", "Purchase Order History") = True Then
' Extract info
End If
End Sub
Public Function IsTabThere(ByVal tabStripName As String, ByVal tabText As String) As Boolean
Dim userArea As Object
Dim tabStrip As Object
Dim tabToSelect As Object
Set userArea = session.FindById("wnd[0]/usr")
Set tabStrip = userArea.FindByName(tabStripName, "GuiTabStrip").Children
For Each tabToSelect In tabStrip
If tabToSelect.Text = tabText Then
tabToSelect.Select
IsTabThere = True
' Will exit here if the tab was selected and return true
Exit Function
End If
Next
IsTabThere = False
End Function
Hope this makes your day. Good luck!
If your interested in making your script more dynamic checkout my answer on this post. I explain how to get started using the SAP GUI Scripting API.
how-to-run-sap-gui-script-from-excel-macro

VBA SAP occasional error Control ID Not Found

In the below code I am extracting data from SAP. In a few SAP reports I am running, occasionally data is not available, in which a pop up box appears, displaying
No Data Exists For Chosen Selection
I've implemented the below error handling strategy, which works fine when debugging and stepping into the code, but running in totality I receive this error on the asterik denoted line:
The Control Could Not Be Found By ID
session.findById("wnd[0]/tbar[1]/btn[8]").press
On Error GoTo ResumeInterCompany
**If session.findById("wnd[1]/tbar[0]").Text = "No data exists for chosen selection" Then**
GoTo TroubleShootInterCompany
End If
Any suggestions. I can provide more relevant code if need be.
My workaround is as follows:
session.findById("wnd[0]/tbar[1]/btn[8]").press
On Error Resume next
myText = "x"
err.clear
myText = session.findById("wnd[1]/tbar[0]").Text
if err.number <> 0 then myText = ""
on error goto 0
If myText = "No data exists for chosen selection" Then
GoTo TroubleShootInterCompany
End If
Regards,
ScriptMan

VBA - Application.EnableCancelKey is acting somehow strange

Pretty much the question is the following - why in the immediate window I get this:
Application.EnableCancelKey = 2
?Application.EnableCancelKey
1
The last line should be 2 or am I missing something?
Thanks!
Edit:
The basis is that the enum xlErrorHandler states that "The interrupt is sent to the running procedure as an error, trappable by an error handler set up with an On Error GoTo statement.", you need an error handler to use that enum (xlErrorHandler or 2).
Since some statements are not possible within the immediate window, and On Error GoTo is one of these statements, you cannot have an error handler in the immediate window and thus change the value of the EnableCancelKey to 2. Hence Excel switches it automaticaly to 1, giving you the value 1 when you ask it to display the value.
The only solution would be to use a sub.
Original reply:
Ok, I used the code in the documentation provided on the MSDN and edited a few things to test it with the following code.
To explain shortly I stopped the execution by pressing just once the "ESC" button and thus preventing the textbox to be exited. You can watch in the Immediate Window that the last EnableCancelKey has changed in value normaly.
Sub Test1()
Debug.Print " Before execution result : " & Application.EnableCancelKey
On Error GoTo handleCancel
Application.EnableCancelKey = 2 'xlErrorHandler
Debug.Print " Regular execution result : " & Application.EnableCancelKey
For x = 1 To 10000 ' Do something 1,000,000 times (long!)
Debug.Print "Test"
Next x
handleCancel:
If Err = 18 Then
Debug.Print "Aborted macro result : " & Application.EnableCancelKey
MsgBox "You cancelled"
End If
End Sub
Hope this helps, I got the result expected.
You have to write an Error Handler to get the 2 value, else the code cannot catch the error, that's why you get the 1 every time you were executing the macro.
Since the description of the enum xlErrorHandler states that "The interrupt is sent to the running procedure as an error, trappable by an error handler set up with an On Error GoTo statement.", you need an error handler to use that enum.
With this it should work:
Sub test2()
On Error GoTo theEnd
Application.EnableCancelKey = 2
Debug.Print Application.EnableCancelKey
theEnd:
End Sub

Run-time error when canceling a 'Save As' dialog displayed via VBA

I have a macro that formats a document in a certain way, and then saves it, using ActiveDocument.Save.
However, sometimes the document is not already saved, and in some cases I don't want to save it. Unfortunately, clicking 'Cancel' when the 'Save As' dialogue is displayed is causing a run-time error (4198) -
Command failed
Does anyone know how I can prevent this from happening? Thanks.
Please try the following by adding some error handling instructions:
On Error Resume Next 'to omit error when cancel is pressed
ActiveDocument.Save
If Err.Number <> 0 Then 'optional, to confirmed that is not saved
MsgBox "Not saved"
End If
On Error GoTo 0 'to return standard error operation
Updated: Now
1. Tests if the file has been previously saved or not
2. If the fileis unsaved, a controlled process is used to show the SaveAs dialog
to either save the file, or handle the Cancel
code
Dim bSave As Boolean
If ActiveDocument.Path = vbNullString Then
bSave = Application.Dialogs(wdDialogFileSaveAs).Show
If Not bSave Then MsgBox "User cancelled", vbCritical
Else
ActiveDocument.Save
End If
for vsto developers, please go here
if (Globals.ThisAddIn.Application.ActiveDocument.Path == String.Empty)
{
Word.Dialog dlg;
Object timeout = 3000;
dlg = Globals.ThisAddIn.Application.Dialogs[
Word.WdWordDialog.wdDialogFileSaveAs];
int result = dlg.Display(ref timeout);
}
else
{
Globals.ThisAddIn.Application.ActiveDocument.Save();
}
The result will store which button is pressed (0- cancel, 1- ok, 2- close)

is it possible for VBA to detect the error and give a prompt that data not available instead of giving error message?

I have created a GUI that will setup the pivot table.
For example, I click button1 it will run and setup the pivot table.
When I click button3, it will have a run time error 1004 because it does not have the value in the data. So is it possible to let VBA accept that error and show a prompt that that data is not available?
By the way, I'm using this
ActiveSheet.PivotTables("PivotTable1").PivotFields("Test").CurrentPage = "Data1"
to setup the pivot table.
There are 3 different variables; Data1, Data2, Data3. If Data3 is not available, it will show the error but I want to have a prompt to show that it is not available.. If you know how to do it, please share it with me! Thank you!
Yes. For that you need to do appropriate error handling. See this sample code.
Sub Sample()
On Error GoTo Whoa
'<Your REST OF THE CODE>
LetsContinue:
Exit Sub
Whoa:
'~~> This gives the exact desription and the error number of the error
MsgBox "Description : " & Err.Description & vbNewLine & _
"Error Number : " & Err.Number
'~~> This part resumes the code without breaking it :)
Resume LetsContinue
End Sub
I would just do this:
On Error Resume Next ' Don't stop execution when an error occurs.
ActiveSheet.PivotTables("PivotTable1").PivotFields("Test").CurrentPage = "Data1"
If Err.Number <> 0 Then ' Can also check for a specific error number instead
'Oops! An error occured.
MsgBox "Data isn't available."
Err.Clear
End If
On Error GoTo 0 ' Go back to stoping execution when an error occurs.