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?
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.
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.
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.
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
}
}
...
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.
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 !
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…