Using one variable for multiple items data in descriptive programming - hp-uft

I know that with Descriptive programming you can do something like this:
Browser("StackOverflow").Page("StackOverflow").Link("text:=Go To Next Page ", "html tag:=A").Click
But is it possible to create some kind of string so I can assign more than one data value and pass it as single variable? I've tried many combinations using escape characters and I always get error.
For example in the case above, let's say I have more properties in the Page object, so I'd normally have to do something like this:
Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")...etc...
But I'd like to pass "name:=StackOverflow", "html id:=PageID" as a single variable, so when writing many objects I'd only have to write:
Browser(BrowserString).Page(PageString).WebEdit("name:=asdfgh")
And the first part would remain static, so if the parents' data needs to be modified I'd only have to modify two variables and not all the objects created in all libraries.
Is it possible?
If I was not clear enough please let me know.
Thank you in advance!

I think what you're looking for is UFT's Description object
This allows you finer grained control on the description since in descriptive programming all values are regular expressions but with Description you can turn the regular expression functionality off for a specific property.
Set desc = Description.Create()
desc("html tag").Value = "A"
desc("innertext").Value = "More information..."
desc("innertext").RegularExpression = False
Browser("Example Domain").Navigate "www.example.com"
Browser("Example Domain").Page("Example Domain").WebElement(desc).Click
If you want to represent this with plain string then it's a bit more of a problem, you can write a helper function but I'm not sure I would recommend it.
Function Desc(descString)
Set ret = Description.Create()
values = Split(descString, "::")
For Each value In values
keyVal = Split(value, ":=")
ret(keyVal(0)).Value = keyVal(1)
Next
Set Desc = ret
End Function
' Usage
Browser("StackOverflow").Page("StackOverflow").WebElement(Desc("html tag:=H2::innertext:=some text")).Click
Further reading about descriptive programming.

As an alternative to Motti's excellent answer, you could also Set a variable to match your initial descriptive object and then extend it as required:
Set myPage = Browser("StackOverflow").Page("name:=StackOverflow", "html id:=PageID")
after which you can then use
myPage.WebEdit("name:=asdfgh")
throughout the rest of the code, so long as the myPage object stays in scope...

Related

Fetch value from XML using dynamic tag in ESQL

I have an xml
<family>
<child_one>ROY</child_one>
<child_two>VIC</child_two>
</family>
I want to fetch the value from the XML based on the dynamic tag in ESQL. I have tried like this
SET dynamicTag = 'child_'||num;
SET value = InputRoot.XMLNSC.parent.(XML.Element)dynamicTag;
Here num is the value received from the input it can be one or two. The result should be value = ROY if num is one and value is VIC if num is two.
The chapter ESQL field reference overview describes this use case:
Because the names of the fields appear in the ESQL program, they must be known when the program is written. This limitation can be avoided by using the alternative syntax that uses braces ( { ... } ).
So can change your code like this:
SET value = InputRoot.XMLNSC.parent.(XMLNSC.Element){dynamicTag};
Notice the change of the element type as well, see comment of #kimbert.

Access an JSON object value - used path contains an dynamic value

I like to access a specific JSON object value, where the access path contains a dynamic value. The dynamic value is calculated beforehand during the dialog process.
How can I do this in a "set property" node? I did not find a good working approach.
Here my approach, which leads to no useful result.
=user.api_content.prediction.intents.${virtualagent.intent}.score
Thanks
Which language are you using? You should be able to just address it directly without a string designator. For example, here is how I get the score for the top intent, where intent is a variable property. You would just want to get it via the [] notation instead of the . notation.
var intent = LuisRecognizer.topIntent(recognizerResult);
if (recognizerResult.intents[intent].score < 0.5) {
intent = 'None';
}

How to WRITE a structure?

How can I do the following:
data: ls_header type BAPIMEPOHEADER.
" fill it
write ls_header.
currently I'm getting an error because write can not parse the complex type to a string. Is there a simple way to get this code running in abap?
You could use something like:
DATA: g_struct TYPE bapimepoheader.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE g_struct TO FIELD-SYMBOL(<f>).
IF sy-subrc NE 0.
EXIT.
ENDIF.
WRITE: / <f>.
ENDDO.
Perhaps not exactly the answer you expect: If you list each field.
This can be done quite easy via the Pattern-mask in SE38:
Select the Write-pattern:
Enter the structure you want:
Select the fields
Confirm with "Copy"
Confirm and you get
WRITE: bapimepoheader-po_number,
bapimepoheader-comp_code,
bapimepoheader-doc_type,
bapimepoheader-delete_ind,
bapimepoheader-status,
bapimepoheader-creat_date,
bapimepoheader-created_by,
bapimepoheader-item_intvl,
bapimepoheader-vendor,
bapimepoheader-langu,
bapimepoheader-langu_iso,
bapimepoheader-pmnttrms,
bapimepoheader-dscnt1_to,
bapimepoheader-dscnt2_to,
bapimepoheader-dscnt3_to,
bapimepoheader-dsct_pct1,
bapimepoheader-dsct_pct2,
bapimepoheader-purch_org,
bapimepoheader-pur_group,
bapimepoheader-currency,
bapimepoheader-currency_iso,
bapimepoheader-exch_rate,
bapimepoheader-ex_rate_fx,
bapimepoheader-doc_date,
bapimepoheader-vper_start,
bapimepoheader-vper_end,
bapimepoheader-warranty,
bapimepoheader-quotation,
bapimepoheader-quot_date,
bapimepoheader-ref_1,
bapimepoheader-sales_pers,
bapimepoheader-telephone,
bapimepoheader-suppl_vend,
bapimepoheader-customer,
bapimepoheader-agreement,
bapimepoheader-gr_message,
bapimepoheader-suppl_plnt,
bapimepoheader-incoterms1,
bapimepoheader-incoterms2,
bapimepoheader-collect_no,
bapimepoheader-diff_inv,
bapimepoheader-our_ref,
bapimepoheader-logsystem,
bapimepoheader-subitemint,
bapimepoheader-po_rel_ind,
bapimepoheader-rel_status,
bapimepoheader-vat_cntry,
bapimepoheader-vat_cntry_iso,
bapimepoheader-reason_cancel,
bapimepoheader-reason_code,
bapimepoheader-retention_type,
bapimepoheader-retention_percentage,
bapimepoheader-downpay_type,
bapimepoheader-downpay_amount,
bapimepoheader-downpay_percent,
bapimepoheader-downpay_duedate,
bapimepoheader-memory,
bapimepoheader-memorytype,
bapimepoheader-shiptype,
bapimepoheader-handoverloc,
bapimepoheader-shipcond,
bapimepoheader-incotermsv,
bapimepoheader-incoterms2l,
bapimepoheader-incoterms3l.
Now you can make a simple replacement of bapimepoheader with ls_header and you have an output of all fields of the structure.
Maybe this is not elegant and you must adapt your report, if the structure changes. But I like this way, because often I don't need all fields and I can select the fields in an easy way.
I know two ways, one is procedural, the other is oop.
Here is the procedural approach.
Select the structure's fields (or whatever else You might need ) from the data-dictionary table DD03L into a local internal table.
Loop over the table into a work-area
Check, whether current field is a flat single datatype, and if so,
Assign component workarea-fieldname of structure ls_header into anyfieldsymbol
Write anyfieldsymbol
Do You need the code ?
Class CL_ABAP_CONTAINER_UTILITIES was specially introduced for that by SAP.
Use FILL_CONTAINER_C method for output the structure in a WRITE manner:
DATA: ls_header type BAPIMEPOHEADER.
CALL METHOD CL_ABAP_CONTAINER_UTILITIES=>FILL_CONTAINER_C
EXPORTING
IM_VALUE = ls_header
IMPORTING
EX_CONTAINER = DATA(container)
EXCEPTIONS
ILLEGAL_PARAMETER_TYPE = 1
others = 2.
WRITE container.
You can write your structure to a string and then output the string. Same method idoc segments are created.

Use embedded string as variable name

I have a YAML file that uses the encoding __firstname__ as a placeholder which signifies that an existing method firstname should be used, rather than the literal string in a subsequent process.
I am trying to understand the most ruby way to to do this. Basically, I need to extract the part between the underscores and send it to an object. Here is pseudocode:
variable = '__firstname__'
if variable is prefixed and suffixed with underscores
result = object.send(variable.removeunderscores)
else
result = variable
end
puts result
I was about to write this procedurally like this, but this is the type of thing that I think ruby can less clunkily if only I knew the language better.
What is a clean why to write this?
There's nothing wrong with verbose code if it's clear to read IMO.
I'd do something like this using String#start_with? and String#end_with?:
variable = '__firstname__'
if variable.start_with?("__") && variable.end_with?("__")
result = object.send(variable[2...-2])
else
result = variable
end

Error "object doesn't support this property or method: dbrowser.GetRoProperty"

I was trying to run below script, but it's giving me an error that says:
object doesn't support this property or method: "dbrowser.GetRoProperty"
SystemUtil.Run "iexplore.exe","http://usps.com/"
Set dbrowser = description.Create
dbrowser ("micclass").value = "Browser"
dbrowser("openurl").value = "https://www.usps.com"
dbrowser("title").value = "USPS - The United States Postal Service (U.S. Postal Service)"
print(dbrowser.getroproperty("title"))
Your dbrowser object is of type Description not Browser you need to create a Browser object based on this description. Replace the last line with:
Print Browser(dbrowser).GetROProperty("title")
Note, there are two changes here
Using Browser(dbrowser)
Removing the parens from the print sub.
Edit: also note that descriptions are regular expressions by default so the parens in the title may cause problems, you should mark it as not regex.
dbrowser("title").RegularExpression = False
Description.Create is used to create a 0-based Properties collection object. The variable dbrowser is preceded by the Set statement. Usage of Set statement binds an object as a reference to another object. Therefore, dbrowser becomes an object reference to the description object represented by Description.Create
A description object does not have a stand-alone use, but coupled with the ChildObjects method, it becomes an extremely powerful approach in dealing with AUT’s objects .For More Info, check link
So the code should be like
SystemUtil.Run "iexplore.exe","http://usps.com/"
wait(10)
Set dbrowser = description.Create
dbrowser ("micclass").value = "Browser"
dbrowser("openurl").value = "https://www.usps.com"
dbrowser("title").value = "USPS.*" ''Using Regular Expression here
Set colObject = Desktop.ChildObjects( dbrowser )
Print (colObject(0).GetROProperty("title"))

Resources