Hi everyone,
I'm having a table, 1st column is the input variable and all the other columns are different outputs. I was looking of a way to do some sorte of a vlookup (like in excel) and get the correct output according to the input i choose. Any ideas?
Thanks
Hi Pedro, The most likely solution is to use a keyed table. Information about record and table types are in the GC help under GCScript Programming > Components of the GCScript Language > Fundamental Types > Record and Table Types (here the relevant excerpt, especially the lookup/conversion table example at the bottom): The Table Type
A table is an associative collection of keys and values. In some other programming languages, this kind of collection is called a dictionary.
One way to define a table is “in line”. The general form is:
{[keyExpression]=valueExpression, [keyExpression]=valueExpression, … }
Note that each keyExpression is enclosed in square brackets. That's what distinguishes table-creation notation from record-creation notation.
Each keyExpression and valueExpression may resolve to a value of any type. (Only those resultant values are stored in the table.)
Here’s an example:
table tab = {[5]='five', [line01]=line01.Length, ['how now']='brown cow', [Sqrt(16)]=Series(1,10,1)}
Alternatively, we can construct a table programmatically:
table tab = {}; tab.Add(5, 'five'); tab.Add(line01, line01.Length); tab.Add('how now', 'brown cow'); double key = Sqrt(16); int[] value = Series(1,10,1); tab.Add(key, value);
Regardless of how it’s been created, you can use a table instance in the same way we would use a list, except that the index key can be any object rather than (necessarily) an integer:
Print(tab['how now']); // Prints "brown cow". Print(tab[4]}; // Prints "{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}". tab[line01] = point02.X;
One purpose of a table is to preserve a set of values so that they can be compared later. For example:
// Create and populate the table. global table lineLengths = {}; // Create an empty table. var lines = Nodes(n => n is Line); // Get all of the Line nodes in the GC model. foreach (line in lines) // Add the length of each line to the table, lineLengths.Add(line, line.Length); // keyed by the line, itself. // Do something that causes one or more lines to change. // Then, afterwards... foreach (line in table.Keys()) // Step through all of the keys in the table, which are { // (still) all of the Line nodes we're interested in. var diff = line.Length – lineLengths[line]; // If the line's length has changed, show if (diff != 0) // the difference in the script console.. PrintFormat("The length of {0} has changed by {1}.", line, diff); }
Another purpose of a table is to serve as a lookup/conversion table. For example:
global table casementSizes = { // Each key is a casement model number. Each value is a record // providing the height and width dimensions of that model. [1824]={height=2.0, width=1.5}, [1828]={height=2.4, width=1.5}, [1836]={height=3.0, width=1.5}, ... (etc.) ... };; // Subsequently, we might enter the following expression into the YTranslation property of // one of our Point nodes. (Imagine we also have an Expression node named "casementNumber".) casementSizes[casementNumber].Height
HTH, Volker
Hi Volker,
Yes, immediately after I posted this question I did a search for table on the help files and found about the table types. I've been trying to use this type since, but I'm struggling. Maybe you can help me.
I created a table WES with 3 keys WES[0], WES[1/3] and WES[2/3]. Now I'm trying to have an input "m" that drives the key - something like "WES[m].value" . This is working fine if i write just a function, but if for example, i use it as a coordinate for a point it stops working. I'm sending you a GCT if you don't mind taking a look.
Thank you
https://communities.bentley.com/cfs-file/__key/communityserver-discussions-components-files/360/Descarregador2.gct
Hi Pedro,
Looking at your script Descarregador2.gct I don't see where you declare the table WES. At the same time I see that you use the table WES if it were a Structure (e.g. WES[m].r1Hd). IF you intend WES[m] to have the value r1HD, then you need somewhere (probably in a Script Transaction) to declare the table (table WES = { };) and later a statement like WES.Add(m, r1HD). Then, accessing WES[m] will yield the value of r1HD, so you'd just need to use WES[m] to retrieve r1HD. This means a statement like double r1 = WES[m] * H; should be valid. This works, if m is the same value when adding the table entry and when retrieving it. If there is the slightest deviation between the value of m used when adding an entry to WES[m], i.e. WES.Add(m, r1HD); and the value of m when retrieving the entry of WES[m], then you may get an error for attempting to access a table entry that does not exist.
In the attached GCT, transaction 7 declares table WES, transaction 8 defines a function to Add an entry to a table and uses it in functionCall1 to add an entry to WES based on the inputs from m and H0, and transaction 9 adds expression01, retrieving the value of H0 based on the key m from table WES.
HTH,
Volker
https://communities.bentley.com/cfs-file/__key/communityserver-discussions-components-files/360/Descarregador2a.gct
Hi Volker, I'm sorry for the waiting. I was diverted to an other project, but I'm back now.
Regarding our problem:
I thought I had the table declared, I'm not sure why it didn't go through. Anyway, before you answered I found a workaround for this situation, but I'm sure I didn't do it the best way. I tried to organize my work a little bit and I'm sending you an other file that has 5 transactions:
1) I used your file as an example to declare and build the table WES
2) I used a function to simulate the table WES
Suppress 1) or 2) at a time to see how the model reacts
3) Generates the actual model using table WES as a lookup.
4) Creates a user generated feature that is the end goal.
5) Places this new feature using the same inputs has the original model in 3).
My problems are:
- I can't use the declared table in the model. When you suppress 2 all the nodes that use the table give errors.
- If I use my "workaround" - suppress 1 - the generated node type doesn't work as expected.
- I'm planing to use this generated node in other files. With this "workaround" I have to call the function through a transaction in every new model. I would like to avoid this if possible, so I would prefer to actually declare the table within the node.
I hope I was clear. Thank you for the help.
https://communities.bentley.com/cfs-file/__key/communityserver-discussions-components-files/360/TableProblem.gct