Ruby Script Help

Hi Guys,

I have been getting used to creating dynamic components and with your help, I have found out that it is impossible to change a common attribute on multiple components. At some stage, I intend to learn Ruby but at the moment it is beyond me.

My question is if I have a dynamic component called Month with an attribute Current_Month, and a lot of dynamic components that have an attribute Month, how difficult would it be to write a script that would update the Month attribute to the value of the Current_Month attribute and how can I attach the script to the attributr Month?

Thanks.

If you just want to change a single time (arbitrary) attributes for multiple entities, you can use Attribute Inspector, select all entities and set the value for “Current_Month”.

If you want to link the dynamic components so that they set/update to the same attribute value, you could use a Ruby script, but keep in mind that this is technically not good design because:

  • Dynamic components that you download from 3D Warehouse only depend on the capabilities of the Dynamic Components extension (and the attributes defined in the component).
  • Your components would additionally depend on the presence of your “external” script, otherwise they won’t work. They only work on the exact same setup as you have. They would only save effort for you.
2 Likes

Here is a Ruby Script that may help you.

The script looks at all component definitions present in your SketchUp Model. If it contains the Attribute Dictionary “dynamic attributes”, and the parameter named “current_month” , the script will provide this parameter with the specified value in the script.

Ruby Script
     mod = Sketchup.active_model # Open model

    # Dynamic Components Attribute Dictionary
    DC_DICT ||= "dynamic_attributes"

    mod.definitions.each{ |compo_definition|
    if compo_definition.attribute_dictionaries[DC_DICT] != nil
        if compo_definition.attribute_dictionaries[DC_DICT].keys.include?("current_month")
            compo_definition.set_attribute(DC_DICT, 'current_month', "November")
        end
    end
    }

As @Aerilius has already said, it is useful to use the Attribute Inspector.
With this extension you can see which key / values ​​the dynamic component consists of.

Also check out the Ruby documentation on the Attribute Dictionaries and the Attribute Dictionary.

Hi Aerilius,

I found that when I select the entities, which have more than one attribute, and update them it changes the values of all of the attributes not just the one that I want to change.

There does not appear to be a way to do this without a ruby script from my limited understanding.

Hi Nick,

Thank you for your help.
I couldn’t access the script as the post was deleted.

Sorry, something went wrong. But now the post is visible again. :smiley:

Nick you are a star. Thank you very much. How do I run a ruby script from within Sketchup?

I often use the “Ruby Code Editor” extension from Alex Schreyer.

You can download this extension from the Extension Warehouse.
https://extensions.sketchup.com/extension/07d36510-4de5-49c5-ba63-5cf254c98b2b/ruby-code-editor

But you can also run Ruby code using SketchUp Ruby Console. You can access this console via the Window menu.

1 Like

Thanks Nick

Hi Nick,

I got an error and I have no idea what it means

Try seeing of most dynamic attributes are associated with component-instances rather than their component-definition ??

Hi Tig,

Thank you but I have no idea what that means.

You posted some code which examined component-definitions [unfortunately not the text but a screen shot !]

If that were adjusted to inspect the component’s instances it will give a different result.
Here’s some ‘cod-code’ to add in and try…

...
mod.definitions.each{|defn|
  next if defn.group? ### ? or can groups have DC attribs ??
  next if defn.image?
  defn.instances.each{|inst|
    if inst.attribute_dictionaries && inst.attribute_dictionaries[DC_DICT] && inst.attribute_dictionaries[DC_DICT].keys.include?(" B_CURRENT_MONTH")
      inst.set_attribute(DC_DICT, " B_CURRENT_MONTH", "Jan")
    end
  }
}
...

Thank you for doing this Tig. Where does the code need to be inserted? I have attached the file of code.MONTH_UPDATE.rb (556 Bytes)

Replace all of your code in the

mod.definitions.each{|...|
...
}

block of code…

I’m happy to help… but I’m not re-writing your code for you - albeit short…

Thank you Tig. I really appreciate your help.

Hi Tig,

I updated the script - I am not a Ruby script coder sorry- and it complained that defn.is_group? method doesn’t exist so I commented it out. The script ran but didn’t update the attribute.


MONTH_UPDATE4.rb (629 Bytes)

The script I recently shared looped through the component definitions.

But there is also another way to automatically provide the components with the correct data.
First select the components whose values ​​you want to adjust, and then run the Ruby script below.
This will then provide the selected component instances with the correct value if it contains the correct Dynamic Attribute.

Ruby script
    mod = Sketchup.active_model # Open model
    sel = mod.selection # Current selection

    # Dynamic Components Attribute Dictionary
    dc_dict = "dynamic_attributes"
    # Attibute Dictionary Key to fill
    key = "current_month"
    # New Attribute Dictionary Key value
    key_value = "November"

    sel.grep(Sketchup::ComponentInstance).each do |compo_instance|
        if compo_instance.attribute_dictionaries && compo_instance.attribute_dictionaries[dc_dict] && compo_instance.attribute_dictionaries[dc_dict].keys.include?(key)
            compo_instance.set_attribute(dc_dict, key, key_value)
        end
    end

Sorry about that ! :flushed:
I’ve correct my cod-code back in the earlier post.
It should be defn.group? etc - but I mistyped it as .is_group?
You need to do the same fix for .image? too…

Thanks Tig