question

Jacek Diakun avatar image
1 Like"
Jacek Diakun asked Matthew Gillespie edited

How to get row/column number by the header field of a Global Table?

Hello,

I would like to get row/column number by the header field of a table.

Let's suppose we have a global table with 5 rows of the following header fields:

Product1
Product2
Product3
Product4
Product5

Product1 is the header field of first row, Product2 is the header field of second row, etc.

How to determine the row number based on the name of its header? For example that row number with header "Product3" is 3? I searched throught the functions for global tables (https://answers.flexsim.com/articles/19553/global-tables-75.html) and no of the functions presented there seems to do what I want.

Is there any smart way to do this operation?

Regards,

Jack

FlexSim 17.0.13
global table
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Matthew Gillespie avatar image
2 Likes"
Matthew Gillespie answered Matthew Gillespie edited

Accessing Cell Values by Header Names

If you're trying to use the header names to access the value of a specific cell in the table, the new Table API lets you do that directly:

//Getting the value
double value = Table("GlobalTable1")["Product3"]["ColumnName"];

//Setting the value
Table("GlobalTable1")["Product3"]["ColumnName"] = 5;

//The Table("TableName") constructor was added in 17.1, so in 17.0 you'd do this:
Table table = reftable("GlobalTable1");
double value = table["Product3"]["ColumnName"];

- Note that this method is slower than using a row number since it loops through every row until it finds one with the matching name.

Accessing Cell by Header Names (Node tables only) (17.1 and later)

For a node table, you can also use the header names to access the node corresponding to a specific cell of the table

Table("GlobalTable1").cell("Product3","ColumnName")

You can then find the rank of this node or its parent to get the column and row number

treenode cell = Table("GlobalTable1").cell("Product3","ColumnName");
int columnNumber = cell.rank;
int rowNumber = cell.up.rank;

Loop with getRowHeader method

You can also just loop through rows until you find the header:

string rowName = "Row 2";
Table table = Table("GlobalTable1");    	//reftable("GlobalTable1") in 17.0
for(int i = 1; i <= table.numRows; i++) {
	if(table.getRowHeader(i) == rowName)
		return i;
}
· 3
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Jacek Diakun avatar image Jacek Diakun commented ·

Dear Matthew,

Thank you very much for your answer. What I asked about and what I wanted to know is included in second part of your answer.

Regards,

Jack

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Jacek Diakun commented ·

What are you using the row number for? The most common use of a function like this is to find a specific cell in the table, which is why I started with that example.

0 Likes 0 ·
Jacek Diakun avatar image Jacek Diakun commented ·

Generally it can be used for automatically assignment values according to the row number of the given header field.

For example - we have 100 types of product and the names of product types are in header fields:

Product001

Product002

...

Product100

That way one could i.e. assign item color (using colorarray() function) according to the row number of the product type (Product001 -> row number = 1 -> color of item = red; Product002 -> row number = 2 -> color of item = green; etc.). Another potential way of use is assigning output port number in the same way (Product001 -> row number = 1 -> output port = 1; Product002 -> row number = 2 -> output port = 2; etc.).

Jack

0 Likes 0 ·
Jason Lightfoot avatar image
3 Likes"
Jason Lightfoot answered Matthew Gillespie commented

For node based tables you can use:

getrank(node(<rowname>,<tablenode>))

to find a row name, and for a column heading:

getrank(node(<columnname>,first(<tablenode>)))
· 3
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Jason Lightfoot avatar image Jason Lightfoot ♦♦ commented ·

Hmm someone didn't like that. Let me explain the syntax so you can understand it.

<tablenode> denotes the node containing data as given by reftable() for global tables, or the root/containing node for a non-global table.

The <> signs delimit parameter placeholders that you must replace with the relevant parameter value and type, so in this case <columnname> must be replaced with something like "MyColumnName" and for a global table you'd replace <tablenode> with reftable("MyGlobalTable") or for a table on an object, label(<object>,"MyLabelTable") - where again you'd replace <object> with the correct type and value you're interested in.

It's older code that doesn't use dot syntax, but it is the most concise (and prior to 17 was quicker than a flexscript search).

Lastly, a node based table is one that is constructed from a subnode for each row and cell - that's why that code works. It would not work for a table that uses bundle data.

0 Likes 0 ·
Lucas Klein avatar image Lucas Klein commented ·

Even tough it is in the old syntax, does exactly what I was looking for. Thanks!

0 Likes 0 ·
Matthew Gillespie avatar image Matthew Gillespie ♦♦ Lucas Klein commented ·

You can do this exact thing in dot syntax as well

table.find("Row2").rank
table.first.find("Col2").rank
3 Likes 3 ·