require 'sketchup.rb'
model = Sketchup.active_model
entities = model.entities
components = entities.grep(Sketchup::ComponentInstance)
unique_items = Hash.new { |hash, key| hash[key] = { count: 0, layers: [] } }
# Collect unique components
components.each do |component|
name = component.name
name = '#isimsiz#' if name.empty?
unique_items[name][:count] += 1
unique_items[name][:layers] << component.layer.name
end
if unique_items.length > 0
# Create dialog box.
dialog = UI::HtmlDialog.new({
:dialog_title => "MALZEME LİSTESİ VE ADETLERİ",
:preferences_key => "GroupComponentSummary",
:scrollable => true,
:resizable => true,
:width => 600,
:height => 300,
:min_width => 100,
:min_height => 100,
:max_width => 2200,
:max_height => 1200
})
# Create table and populate each column with its own value.
table = "<table style='width: 1000px; font-family: arial;' table border='0' align= 'center' cellspacing= '1' table cellpadding= '10'>"
table += "<tr><th colspan='10' bgcolor= 'grey' height='50'>BİNA RAPORU</th></tr>"
table += "<tr><th height='50' align= 'left' style='font-size: 14px; width: 10%;'>KATMAN</th><th align= 'left' style='font-size: 14px; width: 20%; '>MALZEME İSMİ</th><th align= 'left' style='font-size: 14px; width: 2%;'>ADET</th><th align= 'left' style='font-size: 14px; width: 10%;'>DURUMU</th><th align= 'left' style='font-size: 14px; width: 5%;'>FİYAT</th><th align= 'left' style='font-size: 14px; width: 25%;'>AÇIKLAMA</th><th align= 'left' style='font-size: 14px;'>MARKA</th><th align= 'left' style='font-size: 14px;'>İNTERNET SİTESİ</th></tr>"
unique_items.each do |name, data|
count = data[:count]
layers = data[:layers]&.uniq&.join(', ') || ''
component = components.find { |c| c.name == name }
if component
# Get price from component attributes
price = component.get_attribute('SU_DefinitionSet', 'price') || ''
item_type = 'bileĹźen'
else
price = '0'
item_type = 'isimsiz bileĹźen'
end
table += "<tr height='25' bgcolor= 'D3 D3 D3'><td>#{layers}</td><td>#{name}</td><td>#{count}</td><td>#{item_type}</td><td>#{price}</td><td></td><td></td><td>#{}</td></tr>"
end
table += "</table>"
dialog.set_html(table)
dialog.show
else
UI.messagebox("Bileşen bulunamadı.")
end
I want to create a command, like “generate report,” that I can use with a single command. However, when I try to call the “price” value dependent on the component, the table box appears empty. The same applies to the “url” and “owner” values. Can someone help me with this?
Don’t use String.+=
. Use String.<<
(append) instead. iE …
table = String.new
# later in the code ...
table << %[
<table style='width: 1000px; font-family: arial;' table border='0'
align= 'center' cellspacing= '1' table cellpadding= '10'>
]
… etc. …
Try getting the attribute from the instance’s definition …
# Get price from component attributes
price = component.definition.get_attribute('SU_DefinitionSet', 'price') || ''
1 Like
model = Sketchup.active_model
entities = model.entities
components = entities.grep(Sketchup::ComponentInstance)
components.each do |component|
name = component.name
price = component.definition.get_attribute('SU_DefinitionSet', 'price').to_f || ''
if name.empty?
puts "No İnstance Name"
elsif price.nil?
puts "#{name} - no entry value"
else
puts "#{name} - VALUE: #{price}"
end
end
Thank you for your response. First of all, I am a beginner in coding. These are the values that I reached as a result of my research. I simplified my code to find the source of the problem. However, no matter what I do, I cannot display the “price” value in the “ruby console”. I don’t want to give up.

This is mainly because the attribute key is "Price"
not "price"
, so #get_attribute
is returning nil
and nil.to_f
evaluates to 0.0
(which is a kind of silent failure built into the #to_f
method to prevent an exception that would cause code to stop executing. It is up to you [the coder] to code defensively and test return values for validity that makes sense in each scenario.)
Also, be aware that String#to_f
also returns 0.0
when it does not begin with valid numeric characters. So, an empty String
also returns 0.0
…
"".to_f
#=> 0.0
Also, you do not need the || ''
expression after calling #get_attribute
.
Use the 3rd argument to set the default return value, as in …
cdef = component.definition
price = cdef.get_attribute('SU_DefinitionSet', 'Price', '0.0')
In this pattern you ensure that the return value stored as price
will always be a String
.
It is often not good practice to have statements or methods that return various types. Although it is common in Ruby for methods to return nil
upon failure, (and the API does this many places,) the code then needs to check for nil
return immediately after such a call.
But as shown above in the case of #get_attribute
you can avoid the nil
validity test because it is built-into the method if you use the 3rd argument.
Your code has an elsif price.nil?
clause that will always eval to false
(as you wrote it,) because price
would be a Float
or an empty String
.
So this works for me …
model = Sketchup.active_model
entities = model.entities
components = entities.grep(Sketchup::ComponentInstance)
components.each do |component|
name = component.name
cdef = component.definition
price = cdef.get_attribute('SU_DefinitionSet', 'Price', '0.0')
name = "No İnstance Name" if name.empty?
puts "#{name} - VALUE: #{price}"
end
1 Like
Thank you very much. I ran the code in the console and it retrieved the values exactly as I wanted. I customized the code to my needs, and now it works perfectly.
1 Like