I am displaying a list of items using a SAP ABAP column tree model, basically a tree of folder and files, with columns.
I want to load the sub-nodes of folders dynamically, so I'm using the EXPAND_NO_CHILDREN event which is firing correctly.
Unfortunately, after I add the new nodes and items to the tree, the folder is automatically collapsing again, requiring a second click to view the sub-nodes.
Do I need to call a method when handling the event so that the folder stays open, or am I doing something else wrong?
* Set up event handling.
LS_EVENT-EVENTID = CL_ITEM_TREE_CONTROL=>EVENTID_EXPAND_NO_CHILDREN.
LS_EVENT-APPL_EVENT = GC_X.
APPEND LS_EVENT TO LT_EVENTS.
CALL METHOD GO_MODEL->SET_REGISTERED_EVENTS
EXPORTING
EVENTS = LT_EVENTS
EXCEPTIONS
ILLEGAL_EVENT_COMBINATION = 1
UNKNOWN_EVENT = 2.
SET HANDLER GO_APPLICATION->HANDLE_EXPAND_NO_CHILDREN
FOR GO_MODEL.
...
* Add new data to tree.
CALL METHOD GO_MODEL->ADD_NODES
EXPORTING
NODE_TABLE = PTI_NODES[]
EXCEPTIONS
ERROR_IN_NODE_TABLE = 1.
CALL METHOD GO_MODEL->ADD_ITEMS
EXPORTING
ITEM_TABLE = PTI_ITEMS[]
EXCEPTIONS
NODE_NOT_FOUND = 1
ERROR_IN_ITEM_TABLE = 2.
It's been a while since I've played with SAP, but I always found the SAP Library to be particularly helpful when I got stuck...
I managed to come up with this one for you:
http://help.sap.com/saphelp_nw04/helpdata/en/47/aa7a18c80a11d3a6f90000e83dd863/frameset.htm, specifically:
When you add new nodes to the tree model, set the flag ITEMSINCOM to 'X'.
This informs the tree model that you want to load the items for that node on demand.
Hope it helps?
Your code looks fine,
I would use the method ADD_NODES_AND_ITEMS myself if I were to add nodes and items ;)
Beyond that, try to call EXPAND_NODE after you added the items/nodes and see if that helps.
Related
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.
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.
I created an ALV TREE report, using cl_gui_alv_tree, that has 3 levels. I'm also implementing an event handler for when he double clicks a node.
My problem is that I want to take some actions only when he double clicks a node that is a root node. The event 'node_double_click' gives a node_key, but that's the index of the displayed table. How could I achieve this?
The node ID is not an index, it's the ID you assigned to the node when adding it to the tree.
If possible, I'd suggest switching to CL_SALV_TREE - not only because it is documented
and supported by SAP, but also because it comes with some query methods that are quite handy. These methods are documented as well. You can use, for example, GET_NODE to retrieve a node by its ID and then use GET_PARENT to check whether the node in question is a top-level node or has a parent node it is attached to.
I created a pattern for myself, which i am using.
lv_parent1 = node_key.
while lv_parent1 ne go_Main_tree->C_VIRTUAL_ROOT_NODE.
CALL METHOD go_main_tree->get_parent
EXPORTING
i_node_key = lv_parent1
IMPORTING
e_parent_node_key = lv_parent1.
lv_hierlevel = lv_hierlevel + 1 .
ENDWHILE.
if lv_hierlevel > 2.
“ do what You want to do
endif.
I am having an odd problem with data loading which I don't understand, and I am hoping someone can explain to me what is going on, and perhaps how to accomplish my task more directly.
I am building a website using the technologies listed in the subject of this question.
I have a set of objects - each object has several properties (Name, ID, etc.) and a collection (ICollection<>) of other objects. So just looking at the tree of objects and their collections, it looks like this:
Tab
-TabRows
--Sections
---SectionRow
----Article
(So each tab has one or more tabrows, each tabrow has one or more sections, and so on. Each sub-object has a link back the parent, so each sectionrow has a SectionID, each Section has a TabRowID, etc.)
OK, so given that structure, consider this code:
// GET api/Tab/5
public Tab GetTab(int id)
{
var tab = db.Tabs.FirstOrDefault(t => t.TabId == id);
var tabrows = db.TabRows.ToList();
var sections = db.Sections.ToList(); // This makes the tabRow.Sections populate
var sectionrows = db.SectionRows.ToList();
var articles = db.Articles.ToList();
return tab;
}
So here is what happens. When the first line (var tab =...) executes, I get a tab object, but the TabRows collection is empty. (It is not null because the constructor instantiates it).
When the second line (var tabrows =...) executes, tab.TabRows suddenly populates. tab.TabRows.Sections is empty.
When the third line executes, tab.TabRows.Sections suddenly populates.
And so on.
I am assuming this is some sort of "lazy loading" on behalf of Linq, or perhaps one of the other technologies. But I don't know them well enough to figure it out.
Is there a way to re-write this so that I can just call line 1 and basically have everything auto-populate without having to individually reference every single object in every single collection?
Lazy loading is enabled by default and eager loading disabled. Entity framework allows you to hint at eager loading using the include statements. Your statement will become something like this.
var tab = db.Tabs.FirstOrDefault(t => t.TabId == id).Include("TabRows");
or as Include(t => t.TabRows);
Take a look at this link for more information.
In your case you would need to handle nested includes as well. Which means you would be better off taking another Model (your class) structured as follows
Tabs -> Containing a List<TabRows> -> containing a List<Sections> etc.
You would then need to re-write the linq so it populates the entire Model including the nested entities using nested includes.
As a side note, too many of these inner joins might slow down your querying and so consider indexed views on your DB side if and when possible
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!