vlookup

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

Parents
  • 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,

    Due to some other commitments it may take until Friday before I can take a look.

    Regards,

    Volker

       

  • No problem, thank you for your time Volker.

    I was having some troubles making the table work so I took a different approach. I created a function with the values of the table in a nested list that, given the "names" of the column and line, it returns the correct value from the table. This works fine until the moment I take the script and create a user generated feature. Because it is using a scripted function, i need to use an "include file" transaction to go get the function before I can use the feature in a new session. It would be good to be able to remove this extra step, so any help with the table is still very appreciated.
  • 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 Pedro,
    Did you have an opportunity to review my response and have you made progress?
    Regards,
    Volker

       

  • 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

Reply
  • 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

Children
No Data