How to implement indirection - powerquery

How does one indirectly refer to anything? In my case it's a column name. The "Field Access" section of the language doc left me with no clue.
For example
let
OriginalStrings = "some string with {tkn1} and/or {tkn2}"
,ParamTable = [tkn1 = "this", tkn2 = "that"]
,Result = List.Accumulate(Record.FieldNames(ParamTable),OriginalStrings
,(txt,current) => Text.Replace(txt,"{"&current&"}",ParamTable[current]))
in
Result
This results in: Field 'current' of record not found. What I want is the value of 'current' as an identifier and not the literal.
The code above should result in "some string with this and/or that"

Similar to my answer here, Expression.Evaluate may work for what you're after.
Replace ParamTable[current] with
Expression.Evaluate("ParamTable["&current&"]", [ParamTable=ParamTable])
Check out the Expression.Evaluate() and non global environments section of this article for more clarity about the environment argument.

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.

Using one variable for multiple items data in descriptive programming

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...

String Replace Ruby

I am trying to play around my codes in ruby.
Here's what I got:
name = "Rol"
title = name
name = "Sam"
puts name
puts title
OUTPUT:
Sam
Rol
name = "Rol"
title = name
name.replace("Sam")
puts name
puts title
OUTPUT:
Sam
Sam
Basically I wondering why when I use reassignment equal sign it changes just the variable name and left the title with the old value. However upon using the replace method, it changes the value of both?
Any explanation in layman's term on this? Newbie in ruby here.
The simple layman terms are:
Assignments change variables.
Mutation methods change objects.
Variables and objects are different things in Ruby. Each variable is a label that points to an object. Each method call is sent to an object. For convenience we often simplify discussion, because it is easy to say "The name is 'Sam'" when in detail we mean "The value stored in the String object pointed to by the name variable is 'Sam'"
In your first example:
The line name = "Rol" creates a new String object from the literal "Rol" and points the local variable name at it.
The line title = name points the local variable title to the same String object.
The line name = "Sam" creates a new String object from the literal "Sam" and points the local variable name at it. Now name and title point to different String objects.
At this point there are two independent String variables, with two different variables pointing at them, so any uses of them remain separate.
In your second example:
The line name = "Rol" creates a new String object from the literal "Rol" and points the local variable name at it.
The line title = name points the local variable title to the same String object.
The line name.replace("Sam") modifies the object. It doesn't matter which variable you used to access the object in the first place. title.replace("Sam") would have identical results, since it refers to the same object.
The answer is very simple.
When you call:
title = name
then both variables: title and name have reference to the same object, which is next modified by:
name.replace("Sam")
String#replace replaces the content of the string referenced by name. However, it works at reference level as opposite to = that assigns a new String object to the left variable.
name is assigned to title, which means at that point in time both variables point to the same memory allocation. Since replace replaces the referenced string, the change is effectively propagated to both.
You get a better sense if you compare the object_id of the values. In the case of the assignment, the object ID changes because you effectively create and assign a new object:
name = "Rol"
title = name
name.object_id
# => 70336016119860
title.object_id
# => 70336016119860
name = "Sam"
name.object_id
# => 70336016085020
title.object_id
# => 70336016119860
For the case of replace, instead, the object_id doesn't change because you change the value directly without creating a new object.
name = "Rol"
title = name
name.object_id
# => 70336003479640
title.object_id
# => 70336003479640
name.replace("Sam")
name.object_id
# => 70336003479640
title.object_id
# => 70336003479640

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

linq expression for string array always results in "The name 'result' does not exist in the current context"

I'm trying to get certain keys from the Request.Form.AllKeys string array by using the following:
var result = keys.Where(key => key.StartsWith("added"));
The result is "The name 'result' does not exist in the current context" no matter what I do.
I've also tried:
var result = (from keys in Request.Form.AllKeys
where keys.StartsWith("added")
select keys).ToArray();
Same thing.
I'm new to Linq and Lambda expressions and all, so please forgive the ignorance.
Regards,
Jacques
I found the answer to my question: Delayed execution.
When I actually executed the code and then followed it up by using result.Any() the expression was executed and turned out the correct results.

Resources