DOORS DXL issue looping through a filtered dataset - filter

I have a script in which I filter the data in a module by a certain attribute value. When I then loop through these objects, for now, I am displaying the absolute number of the objects in an infoBox. However, the script is displaying absolute numbers of objects that are not in the dataset. Upon further investigation, I found that the extra absolute numbers were for each table within the entire module. I can't figure out why the script would include these tables when they are not in the filtered module data. I have even tried manually filtering the module on this attribute value then use the "Tools -> Edit DXL" to loop through the resulting items and it still displays the numbers for the tables that are not included. Why would it do this?
Here's my code:
bm2 = moduleVar
Filter fltr = contains(attribute "RCR_numbers", sRCRNum, false);
filtering on;
set(bm2, fltr);
for oObj in document(bm2) do {
absNum = oObj."Absolute Number";
infoBox("Object #" absNum ".");
}
I have also tried removing the document cast so it says "for oObj in bm2 do" instead, but this doesn't change the output. Why is the code giving me objects that are not in the filter? Any help would be greatly appreciated since this is a high priority issue for my project and I'm out of ideas myself.
Chris

In the DOORS 9.6.1 DXL Reference Manual you can see that:
for object in document
Assigns the variable o to be each successive
object in module. It is equivalent to the for object in module loop,
except that it includes table header objects, but not the row header
objects nor cells.
So, you must either use for object in module or, within your existing loop, test the hidden attribute TableType - this will be set to TableNone for anything that is not part of a table, table headers included.

Related

UFT: Problem in extracting data from excel file and input in the application dynamically

I am facing issues in performing certain actions based on the value in the excel file cell data.
Actions like if value is "NORMAL" then click Container type = Normal (radio button)
Similarly the Unit Container Value
Following is my code:
I am getting this error while performing action .WebElement("Container_Type_Normal").Click
Your error is because you can't start a line with . unless your within a with - and i can't see a with in your function. (i also don't recommend using a with as the can cause needless confusion)
The .webelement object is a catch-all type of object that is the child of other web objects or .page. You need this to be a full and valid path to the object, by this i mean start with browser().page().
You have a couple of options:
You can either make this a full path to your object based on the object repository:
Browser("<<OR Browser name>>").Page("<<OR Page name>>").WebElement("<<Your webelement name>>".click
For this, look at your OR and insert your names.
Or, option 2, you can use descriptive programming:
Browser("CreationTime:=0").Page("index:=0").WebElement("text:=" & fieldValue,"index:=0").click
That will take the browser that was created first (Creation time 0), the only page it has and the first (index 0) web element that contains your text (text is field value).
I'm assuming that you only have one browser, and that the first element that contains the text you want is what you want to click. You may need to add more layers too this or
A good approach is to mirror what is OR or use the object spy to ensure these properties are correct.

getDispalyValue('field_name') is not working when in a UI Macro

I have a UI macro that fetches a list of records and displays them into a table above some form fields. I'm not using an embedded list because I want the table to read-only and so far, haven't found a way to make an embedded list read.
In my macro I have :
<g2:evaluate var="jvar_records" object="true" >
var gr = new GlideRecord(Tables.PTC);
gr.query();
gr;
</g2:evaluate>
<j2:while test="$[jvar_records.next()]">
<tr class="$[jvar_class]">
<td>$[jvar_records.getValue('arrival_date')]</td>
<td>$[jvar_records.getValue('departure_date')]</td>
<td>$[jvar_records.getDisplayValue('certifier')]</td>
<td>$[jvar_records.getDispalayValue('trip.depart_reason_code')]</td>
</tr>
</j2:while>
The field certifier and trip are Reference fields, that I want to get the dispaly value of. But they keep coming back as empty in the macro. It works in a background-script just fine.
If I just get the value jvar_records.getValue('certifier') it correctly gives me the sys_id.
What am I missing?
Am relatively certain that, outside of the <g2: evaluate> tag, Jelly is constrained to client side API. Client side GlideRecord doesn't have a getDisplayValue function.
What I would do is have your g2:evaluate actually loop through the records and build an array of normal JavaScript objects with just the values you will need, then return that array of objects as opposed to returning the GlideRecord object with query results.

Is there a generic way to access objects in UFT

My task is to check the value of data from the global data sheet within different UIs, each of them having lots of data.
My idea was to do this in a generic way.
I create a array with the objects name, which corresponds with the name of the data sheet column
And then I just compare the content
Browser("").Page("").GENERIC_TYPE(label).GetROProperty("value") = datasheet.GetParameter(label)
Is there such a Generic Type that works for WebEdit and WebList?
You can use WebElement and this is generic as all elements on the page are web elements.
If you are reading the objects from OR, then you might have to update the element type to WebElement and it's tidious (if you are dealing with multiple objects). So the alternative way is using the below approach.
Browser("").Page("").WebElement("xpath:=//*[#common_attribute=" + element_attribute_value + "]").GetROProperty("value") = datasheet.GetParameter(label)

$ORDER vs counting to scan global range

I have a choice between two ways of scanning through a key level in a large global array and am trying to figure out if one method is more efficient than the other.
This is a vendor supplied application and database on the Intersystems Caché database platform. It is written in the old MUMPS style and does not use any of Caché's object persistence functions: all data is stored in globals directly and any indexes are application maintained.
There is a common convention for repeating data elements attached to entities where the first record will contain a count of child records and then each child record is numbered sequentially at the next key level. For example:
^GBDATA(12345,100)="3"
^GBDATA(12345,100,1)="A^Record"
^GBDATA(12345,100,2)="B^Record"
^GBDATA(12345,100,3)="C^Record"
Where "12345" is the entity key, and "100" is one of the attached detail types. Note that the first "100" record with no other keys has the count of subrecords. There could be anywhere between 0 and hundreds of subrecords attached. The entities are often very wide and there is a lot of other data besides this subrecord type (not shown in example).
Given an entity key, I want to scan through all the subrecords of one type. Would it be faster to use $ORDER to go through the subkeys or to use a FOR loop to anticipate the key values? Does it matter?
$ORDER method:
SET EKEY=12345
SET SEQ=""
FOR
{
SET SEQ=$ORDER(^GBDATA(EKEY,100,SEQ), 1, ROWDATA)
QUIT:SEQ=""
WRITE ROWDATA,!
}
FOR count method:
SET EKEY=12345
SET LIM=^GBDATA(EKEY,100)
FOR SEQ=1:1:LIM
{
WRITE ^GBDATA(EKEY,100,SEQ),!
}
Does anyone know how $ORDER vs $GET is implemented internally in Caché?
I'm having trouble testing this empirically since we only have one production instance with appropriate data and I can't take it offline to clear the cache. I'm most interested in from-disk performance as opposed to from-cache performance.
You could use %SYS.MONLBL to figure out definitively. My guess is that $ORDER is slightly better.
http://docs.intersystems.com/cache20122/csp/docbook/DocBook.UI.Page.cls?KEY=GCM_monlbl
In regards to your question, "Does anyone know how $ORDER vs $GET is implemented internally in Caché?" The two are completely different functions.
$Order is used for the direction that you're going in when reviewing your ^Global.
$Get is used to pull the data within the ^Global. Below is an example of it's use. I use Cache ObjectScript; however, this should give you a general idea
Global Structure
^People(LastName,FirstName)="Phone"
Global Data
^People(Doe,John)="1035001234"
^People(Smith,Jane)="7405241305"
^People(Wood,Edgar)="7555127598"
Code Sample
SET LASTNAME=0
FOR QUIT:LASTNAME?." " DO
.SET LASTNAME=$ORDER(^People(LASTNAME)) QUIT:LASTNAME?." "
.SET FIRSTNAME=0
.FOR QUIT:FIRSTNAME?." " DO
..SET FIRSTNAME=$ORDER(^People(LASTNAME,FIRSTNAME)) QUIT:FIRSTNAME?." "
..SET PHONE=$GET(^People(LASTNAME,FIRSTNAME))
In the sample provided above, it will start with the first record within the ^People global and then start with the first record within the last name by utilizing $Order. It will then $Get the data for the ^People(LASTNAME,FIRSTNAME) node, which is the phone number.
For some samples and reference areas, check out the following links:
$Get Information
$Order Information

How do I swap items in a VB6 collection?

If I have a collection of forms (myForms) and I want to switch the position of two forms in the collection (say items 3 and 4 for example), I would expect that the following code would work:
Dim temp as Form
Set temp = myForms(3)
Set myForms(3) = myForms(4)
Set myForms(4) = temp
But that doesn't work. It fails at the third line with the error "Controls property is read only." If I change the line to:
myForms(3) = myForms(4)
I get a type mismatch error instead.
If myForms is a standard collection:
Dim myForms as New Collection
(which is actually different from the controls collection) and you've added the forms using:
myForms.Add frmOne, myForms.Add frmTwo
etc then (yes) you do need to use the Add and Remove methods because of the way the collection references the added objects.
Otherwise the interpretation is that you actually want to replace one form with another and this is not allowed. You can't say:
Set frmOne = frmTwo
unless these are actually variables of type Form.
Why do you need to switch the order? Are you referencing the item numbers somewhere? Would using a Dictionary to collect the forms and reference them by a key be useful?
PS. The type mismatch is simply because both items are objects and need to be 'Set'.
You can't actually swap around items in the controls collection in VB6. You need to use the Add and Remove functions associated with each. Check out this article:
http://support.microsoft.com/kb/190670
Hope this helps!

Resources