Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape, CAD, maker project and design.

First time visiting? Here are some places to start:

  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

How can I assign a LookUp Table result to variable when both live in an array?

Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
There's a good chance I'm over complicating this but when I tuck a lookup table inside an array, I'm having issues assigning its resulting value to a variable that lives in the array.  This variable would then be used 'globally' to drive a sketch, feature, etc.  I've edited the standing Onshape lookup table example below:

FeatureScript 951;import(path : "onshape/std/geometry.fs", version : "951.0");
const oz is ValueWithUnits = 29.5735 * centimeter ^ 3;export const sizeTable = {        "name" : "region",        "displayName" : "Region",        "default" : "EU",        "entries" : {                "EU" : {                        "name" : "size",                        "displayName" : "Size",                        "default" : "medium",                        "entries" : {                                "small" : 8 * oz,                                "medium" : 12 * oz,                                "large" : 16 * oz                            }                    },                "US" : {                        "name" : "size",                        "displayName" : "Size",                        "default" : "large",                        "entries" : {                                "medium" : 16 * oz,                                "large" : 32 * oz,                                "supersize" : 64 * oz                            }                    }            }    };
annotation { "Feature Type Name" : "Soda" }export const soda = defineFeature(function(context is Context, id is Id, definition is map)    precondition    {        annotation { "Item name" : "", "Item label template" : "#(#inputname) = #inputvalue1", "Driven query" : "query", "UIHint" : ["COLLAPSE_ARRAY_ITEMS", "NO_PREVIEW_PROVIDED"] }        definition.array_Vars is array;
        for (var arrayVar in definition.array_Vars)        {            annotation { "Name" : "Var Name", "Default" : "VAR1", "UIHint" : "SHOW_LABEL" }            arrayVar.inputname is string;            annotation { "Name" : "Def Value" }            isLength(arrayVar.inputvalue1, LENGTH_BOUNDS);            annotation { "Name" : "Entities", "Filter" : SketchObject.NO, "MaxNumberOfPicks" : 1, "UI Hint" : ["ALWAYS_HIDDEN", "CONTROL_VISIBILITY", "REMEMBER_PREVIOUS_VALUE"] }            arrayVar.query is Query;
            annotation { "Name" : "Soda size", "Lookup Table" : sizeTable }            arrayVar.sizeTable is LookupTablePath;
        }    }    {
        for (var arrayVar in definition.array_Vars)        {            println(arrayVar.sizeTable);            var selectedRegion = arrayVar.sizeTable.region;            var selectedSize = arrayVar.sizeTable.size;            var size = sizeTable.entries[selectedRegion].entries[selectedSize];            println(size);            setVariable(context, arrayVar.inputname, arrayVar.inputvalue1);            //setVariable(context, arrayVar.inputname, arrayVar.size);        }
    });

Best Answer

Answers

  • MBartlett21MBartlett21 Member Posts: 1,401 EDU
    @Caleb_Kehoe
    Can you share a link or what you are trying to do? 
    MB - I make FeatureScripts: view FS (My FS's have "Official" beside them)
  • Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
    I can't make the document public but the modified example above technically shows the format I'm trying to achieve;  I'd like to have the variable name and value all kept in one place (the array) where it's the lookup table providing the value for the variable.  println() is telling me that the lookup table is working well within the array, I'm just having issues assigning the value to the variable above it.  The expanded version of this code has a few arrays to specify a few variables, all within one custom feature.  The variable value will be used to manipulate a sketch dimension. 
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,162
    @Caleb_Kehoe

    I don't quite understand your question.  When you say "globally" are you just trying to use that value within the scope of this feature?  Or are you trying to make it so that after a user runs your feature, they have access to that value in subsequent features of the Part Studio? 

    Also, it is very hard to read your code blocks.  When I paste them in, they paste just fine.  Not sure what the problem is, but here is a gif of me pasting in your code:



    And how the code should look when pasted in:
    FeatureScript 951;
    import(path : "onshape/std/geometry.fs", version : "951.0");
    
    const oz is ValueWithUnits = 29.5735 * centimeter ^ 3;
    export const sizeTable = { "name" : "region", "displayName" : "Region", "default" : "EU", "entries" : { "EU" : { "name" : "size", "displayName" : "Size", "default" : "medium", "entries" : { "small" : 8 * oz, "medium" : 12 * oz, "large" : 16 * oz } }, "US" : { "name" : "size", "displayName" : "Size", "default" : "large", "entries" : { "medium" : 16 * oz, "large" : 32 * oz, "supersize" : 64 * oz } } } };
    
    annotation { "Feature Type Name" : "Soda" }
    export const soda = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Item name" : "", "Item label template" : "#(#inputname) = #inputvalue1", "Driven query" : "query", "UIHint" : ["COLLAPSE_ARRAY_ITEMS", "NO_PREVIEW_PROVIDED"] }
            definition.array_Vars is array;
            for (var arrayVar in definition.array_Vars)
            {
                annotation { "Name" : "Var Name", "Default" : "VAR1", "UIHint" : "SHOW_LABEL" }
                arrayVar.inputname is string;
    
                annotation { "Name" : "Def Value" }
                isLength(arrayVar.inputvalue1, LENGTH_BOUNDS);
    
                annotation { "Name" : "Entities", "Filter" : SketchObject.NO, "MaxNumberOfPicks" : 1, "UI Hint" : ["ALWAYS_HIDDEN", "CONTROL_VISIBILITY", "REMEMBER_PREVIOUS_VALUE"] }
                arrayVar.query is Query;
    
                annotation { "Name" : "Soda size", "Lookup Table" : sizeTable }
                arrayVar.sizeTable is LookupTablePath;
            }
        }
        {
            for (var arrayVar in definition.array_Vars)
            {
                println(arrayVar.sizeTable);
                var selectedRegion = arrayVar.sizeTable.region;
                var selectedSize = arrayVar.sizeTable.size;
                var size = sizeTable.entries[selectedRegion].entries[selectedSize];
                println(size);
                setVariable(context, arrayVar.inputname, arrayVar.inputvalue1);
                //setVariable(context, arrayVar.inputname, arrayVar.size);
            }
        });

    Are you pasting the code into another program before pasting it in here?  You should be able to just start a new "code" block and then paste the whole feature studio into it.  Let me know your workflow and we can figure out where the trouble is.
    Jake Rosenfeld - Modeling Team
  • Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
    Hey @Jake_Rosenfeld, I now understand why my posted code always had format/display issues.  Instead of creating the code block before pasting as you show, I would paste the code and then hit the 'code' format dropdown.  Thanks for the tip.

    When you say "globally" are you just trying to use that value within the scope of this feature?  Or are you trying to make it so that after a user runs your feature, they have access to that value in subsequent features of the Part Studio? 

    Yes, I use the term 'globally' to mean that I can use this created variable in the Part Studio (in all subsequent features).  In addition, it would be very nice to display the value within the feature (before the feature is exited) so that the user can see the resulting value associated with the lookup table options.  In simplest form, I'm trying to create a 'driven' text box/display box for an assigned variable value - in this case all happening in an array.


  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,162
    @Caleb_Kehoe

    To do this, I would use editing logic (as discussed in the other thread) to change the value of the driven parameter in the dialog, then use setVariable() in the body of your feature to set the global variable.  If you want that 'driven' parameter to not be editable by the user, you can use the 'READ_ONLY' UIHint.

    Jake Rosenfeld - Modeling Team
  • Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
    Okay Jake, I can get the variable value assigned using setVariable() and the "UIHint" : "READ_ONLY" worked out nicely but I'm still having issues sending the lookup table resulting value to the driven.  I feel as though it's something about array items that I'm not understanding well.  For example, in the code I posted above, I was trying to set the variable equal to "arrayVar.size" instead of the "size" alone because I thought it was an array item (because I defined it in an array).  So now, down in the Editing Logic Function, I'm just trying to assign the arrayVar[i].inputvalue1 equal to the "size" with no luck.

    FeatureScript 951;
    import(path : "onshape/std/geometry.fs", version : "951.0");
    
    export const sizeTable = {
            "name" : "region",
            "displayName" : "Region",
            "default" : "EU",
            "entries" : {
                    "EU" : {
                            "name" : "size",
                            "displayName" : "Size",
                            "default" : "medium",
                            "entries" : {
                                    "small" : 8 * millimeter,
                                    "medium" : 12 * millimeter,
                                    "large" : 16 * millimeter
                                }
                        },
                    "US" : {
                            "name" : "size",
                            "displayName" : "Size",
                            "default" : "large",
                            "entries" : {
                                    "medium" : 16 * millimeter,
                                    "large" : 32 * millimeter,
                                    "supersize" : 64 * millimeter
                                }
                        }
                }
        };
    
    annotation { "Feature Type Name" : "Soda", "Editing Logic Function" : "DialogChanges" }
    export const soda = defineFeature(function(context is Context, id is Id, definition is map)
        precondition
        {
            annotation { "Item name" : "", "Item label template" : "#(#inputname) = #inputvalue1", "Driven query" : "query", "UIHint" : ["COLLAPSE_ARRAY_ITEMS", "NO_PREVIEW_PROVIDED"] }
            definition.array_Vars is array;
    
            for (var arrayVar in definition.array_Vars)
            {
                annotation { "Name" : "Var Name", "Default" : "VAR1", "UIHint" : "SHOW_LABEL" }
                arrayVar.inputname is string;
                annotation { "Name" : "Driven Value", "UIHint" : "READ_ONLY" }
                isLength(arrayVar.inputvalue1, LENGTH_BOUNDS);
                annotation { "Name" : "Entities", "Filter" : SketchObject.NO, "MaxNumberOfPicks" : 1, "UIHint" : ["ALWAYS_HIDDEN", "REMEMBER_PREVIOUS_VALUE"] }
                arrayVar.query is Query;
    
                annotation { "Name" : "Soda size", "Lookup Table" : sizeTable }
                arrayVar.sizeTable is LookupTablePath;
    
            }
        }
        {
    
            for (var arrayVar in definition.array_Vars)
            {
                println(arrayVar.sizeTable);
                var selectedRegion = arrayVar.sizeTable.region;
                var selectedSize = arrayVar.sizeTable.size;
                var size = sizeTable
    .entries[selectedRegion]
    .entries[selectedSize];
                println(size);
                //setVariable(context, arrayVar.inputname, arrayVar.inputvalue1);
                setVariable(context, arrayVar.inputname, size * 2);
            }
    
        });
    
    export function DialogChanges(context is Context, id is Id, oldDefinition is map, definition is map, isCreating is boolean, specifiedParameters is map) returns map
    {
        if (oldDefinition.array_Vars != definition.array_Vars) // this means if the value has been changed by the user
        {
            for (var i = 0; i < size(definition.array_Vars); i += 1)
            {
                definition.array_Vars[i].inputvalue1 = definition.size;
                println(definition.size);
            }
        }
        return definition;
    }
    

    I tried a couple variations on that ELF without any luck as well. i.e. 

    if (oldDefinition.selectedRegion != definition.selectedRegion) || (oldDefinition.selectedSize != definition.selectedSize)
    {
    ...


  • Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
    Thanks, @Jake_Rosenfeld .  I appreciate the explanation and insight.  Works great!
  • kevin_o_toole_1kevin_o_toole_1 Onshape Employees, Developers, HDM Posts: 411
    @Jake_Rosenfeld
    Yep, generally the recommendation is to not use configurable parameters to drive editing logic.

    For example, let's say definition.input is used in editing logic to set the value of definition.computedInput whenever definition.input changes. If someone configures definition.input, then changes the configuration, the editing logic won't run, even though definition.input has changed.

    This isn't an issue if no one configures your input parameter. So, one solution is just to make sure the driving parameter is not configurable. You can do this by adding "UIHint" : "UNCONFIGURABLE" to the parameter annotation.

    In your case, array parameters are currently not configurable anyway, so there's no issue at all! If you want to really future-proof your feature you can add "UIHint" : "UNCONFIGURABLE" to the inputname parameter, to ensure configuring is blocked even when we implement the ability to configure array parameters.

  • Caleb_KehoeCaleb_Kehoe Member, HDM Posts: 28 PRO
    Thanks for the add, Kevin.  I've been curious of that UIHint and this use completely makes sense.
Sign In or Register to comment.