How to define button value in popup? - windows

I've create a VBScript popup with OK and Cancel buttons. How do I value the OK button?
Basically I want :
If OK button = True Then
' statement
Else
End If
I've tried to declare intbutton= 1, then
intbutton = objshell.popup"..."
but I get a syntax error.

You're getting a syntax error because in VBScript (and VBA and VB6) all Function calls must use parenthesis when capturing return values (unlike Sub calls which must not use parenthesis unless you're using Call syntax - yes, I think VBScript's syntax is dumb).
You're also missing the other parameters to the function: nSecondsToWait, strTitle, and nType. Note that those additional parameters are optional, so leave nothing in the nSecondsToWait parameter space.
VBScript has built-in constants for the arguments you're wanting, they are:
vbOK
vbOKCancel
vbAbortRetryIgnore
vbYesNoCancel
vbYesNo
vbRetryCancel
You can use them like so:
Dim result
result = shell.Popup( "Mesage text goes here", , "Window title", vbOKCancel )
If result = vbOK Then
' something here
End If

Related

How to create description object model at runtime in uft/qtp?

thank you for taking a look on this question. Just wondering if there is a best approach to create description object model at runtime. My code fails
Object doesn't support this property or method: 'Browser(...).page(...).WebButton'
FunctionCreateDescObjAt_RunTime(StrBrowserNme,StrBrwsrTitle,StrObject,StrPgeNme,StrPgtitle,StrObjectName,index)`
'create a description object for Browser & Page`
Set WebBrwsrDesc= Description.Create
WebBrwsrDesc("application version").value= "Internet Explorer.*"
If StrBrowser<>"" Then
WebBrwsrDesc("name").value=StrBrowserNme
WebBrwsrDesc("title").value=StrBrwsrTitle
End If
Set WebPageDesc= Description.Create
WebPageDesc("name").value=StrPgeNme
WebPageDesc("title").value=StrPgtitle
' 'Based on the type of object, execute the condition`
Select Case StrObject`
Case "WebButton"
Set WebBtnDes= Description.Create
WebBtnDes("html tag").value="INPUT"
WebBtnDes("name").value=StrObjectName
WebBtnDes("micclass").value="button"
WebBtnDes("index").value=index
'Browser("title:=.*","name:=.*").page("title:=.*","name:=.*").WebButton(WebBtnDes).fnWebButtonClick
Browser(WebBrwsrDesc).page(WebPageDesc).WebButton(WebBtnDes).click
end select
End Function
I am making a call from action
CreateDescObjAt_RunTime "Account Login","Your Store", "WebButton", "", "Account Login", "Login", "" And this is failing. However if I un comment this line & comment problem line, it works
Browser("title:=.*","name:=.*").page("title:=.*","name:=.*").WebButton(WebBtnDes).fnWebButtonClick
Could you please help me with the right approach? thanks
If you want to set a generic browser and page you can simply use a statement similar to the line you have commented:
Dim objPage : Set objPage = Browser("class:=browser").Page("title:=.*")
The line above will create a page object that you can work with.
Check the parameters being passed to your function to make sure you are correctly identifying your browser and page.
For the part of your actual object, which you want to create at runtime, you need to create a Description object, then look for the ChildObjects of your main object (in this case, your page) and store it to a collection. After that you can check whether or not your object is found. So your Select Case part would be something like this:
Select Case StrObject
Case "WebButton"
' This is just a description of your object, not your actual object
Dim descButton : Set descButton = Description.Create
descButton("html tag").value="INPUT"
descButton("name").value=StrObjectName
descButton("micclass").value="button"
descButton("index").value=index
' In the following statement you are looking for all child objects
' of your page that matches with your description, and storing it
' into the collButton collection
Dim collButton : Set collButton = Browser("class:=browser").Page("title:=.*").ChildObjects(descButton)
If collButton.count > 0 Then ' Now you are checking if any object was found
' There are many ways to get the button object that you want.
' Here I'm just assuming you want the first one, but you could iterate
' into the collection to make sure you have the right one
Dim objButton : Set objButton = collButton(0) ' I'm getting the first item, which is in index 0 of your collection
objButton(0).Click ' This object already have the whole Browser().Page().WebButton() identified, so no need to use it
Else
MsgBox "No WebButton found. Please check your Description object"
End If
' Your other cases...
End Select
MicClass of a Webbutton Can't be button. It should be WebButton
' You are using following
WebBtnDes("micclass").value="button"
It Should be : WebButton
'Anyway Describing Description Object
Set ObjButton=Description.Create
ObjButton("MiCClass").value="WebButton"
ObjButton("name").value=strButtonName
ObjButton("htmlid").value=strHtmlId
Set ObjButton= Browser().page().ChildObject(ObjButton)

Classic ASP Type Mismatch with If Then Statement

Can someone please tell me why this is tossing a Type Mismatch using Classic ASP error?
If (strPaidByPO = True) OR (arrResult(0) = "1") Then
'Do Stuff
Else
'Do Other stuff
End if
arrResults is an Array and strPaidByPO is a variable.
Thanks,
Before the If statement type the following (I think you may be making assumptions about the Types).
Call Response.Write(TypeName(strPaidByPO) & "<br />")
Call Response.Write(TypeName(arrResult) & "<br />")
Call Response.Flush()
If your variables are of the type you expected you should get the following output
Boolean
Variant()
Also you might receive this if your Array is multidimensional in which case you need to specify all the dimensions.
The other possibility is arrResult(0) contains something other than a String. In which case use TypeName(arrResult(0)) to check what that is.
Try this and see result based on which you can correct your script:
response.write(cStr(strPaidByPO) & "- My strPaidByPO value<br>")
response.write(arrResult(0) & "- My Array value")
If (strPaidByPO = True) OR (cStr(arrResult(0)) = "1") Then
'Do Stuff
Else
'Do Other stuff
End if
but if your strPaidByPO contain values other then true - false (Boolean) you need to review your approach to this completely. For example if strPaidByPO is NULL or empty your script will trough you an error like you described.

pass arguments to function from one unit to another in testcomplete and how to call it

i am facing a vb script run time error saying "wrong number of arguments or invalid property assignment".
'useunit
sub in unita
call unita.testsub(param1,param2)
end sub
'sub in unitb
sub testsub(param1,param2)
.....
end sub
After USEUNIT you need to specify the name of the unit whose functions you will use in this unit. So, change your code in the following way:
unita
'USEUNIT unitb
sub main
dim param1
dim param2
param1="Test"
param2="Complete"
call unitb.testsub(param1,param2)
end sub
unitb
sub testsub(param1,param2)
Log.Message(param1 & param2)
end sub
I believe that
call unita.testsub(param1,param2)
should be
call unitb.testsub(param1,param2)
i found this from the oficial forums
Execute "Call UnitName.SubWithParams(1, ""string"", True)" ' Using syntax with the Call keyword and parentheses
Execute "UnitName.SubWithParams 1, ""string"", True" ' Syntax without the Call keyword and parentheses
res = Eval("UnitName.FunctionWithParams(1, ""string"", True)")
' Inserting parameter values dynamically
strFunctionCall = aqString.Format("UnitName.FunctionWithParams(%d, ""%s"", %s)", 42, "string", CStr(True))
res = Eval(strFunctionCall)
but still donot know how exactly should we pass the parameters

VB6 how to get the selected/checked control in a control array

I have to modify a VB6 app and am repeatedly beating my head against a wall over control arrays.
I know that the event handler for the array includes its index value and I can set some variable there, but i should be able to directly access the selected radio button in an array of OptionButton. Currently I'm doing this
For i = 0 To optView.Count - 1
If optView.Item(i).value = True Then
currIndex = i
Exit For
End If
Next
Is this really my only option?
Yes, this is our only option. The control array object does not contain any selecting logic (which makes sense, as "selected" might mean different things for different controls). The only change I'd make is replacing the For with For Each.
Another way to do this that I have used. Write a function, and then call the function, passing in the control name, to return the index number. Then you can reuse this in the future especially, if you add it to a module (.bas).
Function f_GetOptionFromControlArray(opts As Object) As Integer
' From http://support.microsoft.com/KB/147673
' This function can be called like this:
' myVariable = f_GetOptionFromControlArray(optMyButtons) 'Control syntax OK
' myVariable = f_GetOptionFromControlArray(optMyButtons()) 'Array syntax OK
On Error GoTo GetOptionFail
Dim opt As OptionButton
For Each opt In opts
If opt.Value Then
f_GetOptionFromControlArray = opt.Index
Exit Function
End If
Next
GetOptionFail:
f_GetOptionFromControlArray = -1
End Function

How to gracefully exit from the middle of a nested subroutine when user cancels?

(I'm using VB6 but I imagine this comes up in most other languages.)
I've got a GUI button that calls a routine that takes a minute or two to complete. I want impatient users to be able to click on the button a second time to have it gracefully exit out of the routine at any point.
I used a static variable to make this work pretty well (see code below), but I'm cleaning up the project and I want to put the For/Next loop into its own function, since it's required in several different places in the project.
But doing that would break my static flag embedded in the for/next, so I need to make some changes. Before I do something hare-brained with public (global) variables, I thought I'd ask what other (smarter, perhaps actually CS educated) people have done when faced with this problem.
So basically my question is how do I replicate this:
Private Sub DoSomething_Click()
Static ExitThisSub As Boolean ' Needed for graceful exit
If DoSomething.Caption = "Click To Stop Doing Something" Then
ExitThisSub = False ' this is the first time we've entered this sub
Else ' We've re-entered this routine (user clicked on button to stop it)
ExitThisSub = True ' Set this so we'll see it when we exit this re-entry
Exit Sub '
End If
DoSomething.Caption = "Click To Stop Doing Something"
For i = 0 To ReallyBigNumber
Call DoingSomethingSomewhatTimeConsuming
If ExitThisSub = True Then GoTo ExitThisSubNow
DoEvents
Next
' The next line was missing from my original example,
' prompting appropriate comments
DoSomething.Caption = "Click To Do Something"
Exit Sub
ExitThisSubNow:
ExitThisSub = False ' clear this so we can reenter later
DoSomething.Caption = "Click To Do Something"
End Sub
When I move the for/next loop to its own function?
I'm thinking I'll change ExitThisSub to a public variable QuitDoingSoManyLongCalculations that will exit the new for/next sub and then the DoSomething_Click in the same way.
But I always feel like an amateur (which I am) when I use global variables - is there a more elegant solution?
Well you could declare the variable at module level in the forms as private.
That is not a global but a module level variable.
Then you could pass it to the function you create and check it in the function.
But be careful with the DoEvents. It basically means allow the windows message loop to process messages. This means that not only can the user click your button again, they can close the form and do other things. So when you are in this loop you'll need to set a module level variable anyway as you'll need to check for it in a QueryUnload of the form and in any event handlers.
You can also use the Tag property of the control itself to store a flag of sorts. But I don't consider that more elegant.
I also prefer to use two different buttons. Just hide one and show the other. That way your cancel code and run code are separated in different event handlers.
To expand on my answer here is some sample code that handles the unloading aspect.
Here if you stop via the x it prompts you. If you kill via task manager, it dies gracefully.
Option Explicit
Private Enum StopFlag
NotSet = 0
StopNow = 1
StopExit = 2
End Enum
Private m_lngStopFlag As StopFlag
Private m_blnProcessing As Boolean
Private Sub cmdGo_Click()
Dim lngIndex As Long
Dim strTemp As String
m_lngStopFlag = StopFlag.NotSet
m_blnProcessing = True
cmdStop.Visible = True
cmdGo.Visible = False
For lngIndex = 1 To 99999999
' check stop flag
Select Case m_lngStopFlag
Case StopFlag.StopNow
MsgBox "Stopping - Last Number Was " & strTemp
Exit For
Case StopFlag.StopExit
m_blnProcessing = False
End
End Select
' do your processing
strTemp = CStr(lngIndex)
' let message loop process messages
DoEvents
Next lngIndex
m_lngStopFlag = StopFlag.NotSet
m_blnProcessing = False
cmdGo.Visible = True
cmdStop.Visible = False
End Sub
Private Sub cmdStop_Click()
m_lngStopFlag = StopFlag.StopNow
End Sub
Private Sub Form_Load()
m_blnProcessing = False
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Select Case UnloadMode
Case vbFormControlMenu, vbFormCode
If m_blnProcessing Then
Cancel = True
If MsgBox("Unload Attempted - Cancel Running Process?", vbOKCancel + vbDefaultButton1 + vbQuestion, "Test") = vbOK Then
m_lngStopFlag = StopFlag.StopExit
End If
End If
Case Else
m_lngStopFlag = StopFlag.StopExit
Cancel = True
End Select
End Sub
You need some kind of shared variable so that your for loop and your button can communicate. I'd put the for loop (and its associated code) in a command object. My VB is rusty but I think you can declare Modules with their own 'global' variables and functions. You can move all the code into a module and just check the global variable as you do now.
My main concern with the code sample you've posted has nothing to do with user-cancelling but rather everything else: you check your running state by reading the button text instead of doing that the other way around (set the button text because of the running state, which should be stored in a variable); you use a GOTO to exit your for loop instead of a break (does VB have breaks?) and you put your cleanup code outside the normal flow, when it seems to me that it could be run regardless of whether the user cancelled or not.
One possible alternative is to offload your heavy-work function to a new Thread. Then you can either directly kill that thread if the user wants to cancel, or you can send a message to the thread.
Toggling via button name, as you are doing above, is a pretty commonly seen trick though, and pretty safe if you only have a couple of button states.
I've always used a global boolean variable like bUserPressedCancel, along with DoEvents within a loop. Elegant, smelegant, it works.
I agree with Mr Shiny that testing against the value of a caption is not a great idea. If you change the text on the button in the designer, you'll break the code. Better not to rely on the wording of the text for your code to work.
Works until you need to do localization or any other thing else that require the UI to be changed independently of the logic. I would use the Tag property or a private module level variable . Then you can vary the caption independently from the logic.
If it was me I'd use 2 buttons - one to GO and one to STOP. The STOP button is made visible when you click GO. The Click event for STOP simply hides itself - that's it.
Your loop can then simply check to see if the STOP button is still visible. If it's not, that means it was clicked and you should break out.
Your controls are static objects with form scope...

Resources