When I enter a custom attribute manually, it normally accepts any information, lowercase letter with uppercase letter, numbers, but when I use this script to insert the attribute, if I use uppercase letters it generates an error in the attribute afterwards:
ERROR: Unable to get property ‘value’ from undefined or null reference @ /components.js[309]
I tried to create the g10PorJan attribute through the script and it generates this error, if I put everything in lower case, g10porjan works normally.
But if you go manually in the component and type g10PorJan, it also works.
How to make the script create g10PorJan without error?
module Attriperso
def self.wrap_selection(entities)
return if entities.empty?
entities.grep(Sketchup::ComponentInstance).each do |entity|
attribute_name = UI.inputbox(["Digite o nome do atributo"], ["NovoAtributo"], "Nome do Atributo")
if attribute_name
attribute_name = attribute_name[0].strip
entity.set_attribute "dynamic_attributes", attribute_name, "-"
entity.set_attribute "dynamic_attributes", "_#{attribute_name}_units", "_user"
entity.set_attribute "dynamic_attributes", "_#{attribute_name}_formulaunits", "CENTIMETERS"
$dc_observers.get_latest_class.redraw_with_undo(entity)
end
end
end
end
No, this is frivolous as attribute_name is already a string.
The KEYS in the "dynamic_attributes" dictionaries must be lowercase. - CORRECTED (Twice) -
dict = "dynamic_attributes"
entities.grep(Sketchup::ComponentInstance) do |inst|
results = UI.inputbox(
["Digite o nome do atributo"], ["NovoAtributo"], "Nome do Atributo"
)
next unless results
attribute_form = results[0].strip
attribute_label = attribute_form.gsub(/(\s+)/,'_')
attribute_key = attribute_label.downcase
# DC attributes are defined upon the definition for components,
# (but on the instance for groups):
definition = inst.definition
# The user sees the form label with spaces:
definition.set_attribute( dict, "_#{attribute_key}_formlabel", attribute_form )
# The internals use the attribute label in formulae with underscores:
definition.set_attribute( dict, "_#{attribute_key}_label", attribute_label )
definition.set_attribute( dict, "_#{attribute_key}_access", "TEXTBOX" )
definition.set_attribute( dict, "_#{attribute_key}_units", "DEFAULT" )
definition.set_attribute( dict, "_#{attribute_key}_formulaunits", "CENTIMETERS" )
# This is the default attribute value:
definition.set_attribute( dict, attribute_key, "1")
$dc_observers.get_latest_class.redraw_with_undo( inst )
end
Note that #grep is an iterator method so you do not need to call #each on it’s results.
Use next instead of if to save an indentation block within iterators and make code more readable.
You CAN use capital letters in the formlabel or label (ie, what the user sees in the dialog.)
However, the key for the actual value of the attribute will be the lowercase "_#{attribute_key}_label" value.
In the example I gave above, I had set the value to attribute_key but it also can beattribute_label (as long as any spaces are converted to underscore.) In fact, attribute_key also must have no spaces.
I’ll correct the example above rather than post it again.
This is the way that the author of the DC extension wrote the code and the way that it works.
As you have found, violate how the code works and then it does not work anymore.
It does not matter that the attribute dictionary keys are all lowercase as the user never sees any of the keys directly, especially keys beginning with "_" (underscore) as they are hidden. The author did this I suppose to ensure text matching which is important as a mismatch would cause an error.
By the way, I just noticed that this attribute is set to have numeric units settings. What if the user wants to create a STRING attribute ?
attribute_name is renamed to: attribute_key (This is the substring that is inserted into dictionary keys.)
attribute_label, what the user sees in the form as the label for the value editbox, is now: attribute_form
(This is exactly as entered in the inputbox with spaces.)
attribute_label is now only the name used in formulae to get this attribute’s value (from another attribute’s formula.)
This is what you would were thinking of as the attribute “name”. It must have whitespace replaced with underscore.
Dan, thanks again.
I’ll explain, we build many dynamic components, we have a portal with several subscribers, and in the production of components, we standardize several attribute names to facilitate visual identification during the process.
As many things we do are repetitive, I’m creating a plugin for internal use, which facilitates our creation of components.
One of the buttons is the one I put the code here.
As we have to set it to centimeters in every attribute, and also that the display in is the user’s measurement, then I created this button, it works perfectly, but there is this problem of not capitalizing the letters, which breaks our pattern of development.
But since we already use the default of every field having the first letter in capitals in all the attributes that we create in all components, I would need the plugin button to be able to place the attributes just as we place them manually.
I edited the example above. Did you see this ? Did you try it as edited ?
It now uses the attribute label as it is entered in your inputbox.
I see that the attribute labels actually begin with a listing order prefix like "b0", not a capital letter.
If you wish your code to do similar, then the code will need to prepend the listing order prefix onto both the attribute_key and attribute_label variables.
Better to start your own topic, since this one is already solved!
You are using the wrong tool to inspect your IFC attributes. The DC extension does not handle properly as you can see above posts.
You can perhaps use, Attribute Inspector, Attribute Helper, Attribute Editor.… from Extension warehouse