Dynamic component count to text file

You have only deleted the instance in the model entities. The definition remains in the definition list.

You need to purge unused component definitions.

OR… you can insert

  next if number < 1

… into the iterator block that writes the report lines:

total = 0
matches.each {|definition|
  number = definition.count_used_instances
  next if number < 1
  total += number
  attribute = definition.get_attribute(dictionary_name, 'lenz').to_l
  height = Sketchup.format_length( attribute )
  @report << format( DATALINE, definition.name, height, number )
}

Thanks for the solution.

I also try to get attributes like the material that is used.

But when you do something like this i don’t work:

attribute = definition.get_attribute(dictionary_name, ‘material’)
material = Sketchup.format_material( attribute )

Thanks

Because there is no method named “format_material” in the Sketchup module.
Ref: http://www.sketchup.com/intl/en/developer/docs/methods#index_f

Referring to the Material section of:
Dynamic Components Guide: Dynamic component predefined attributes
There are 4 possible formats, but they are all String formats.

  attribute = definition.get_attribute(dictionary_name, 'material')
  if attribute.is_a?(String) && !attribute.empty?
    material = attribute
  else
    material = ""
  end

Nice that is working only thing that happens when I Load a component from my local server that it gives as result the default material. Underneath is the code I use to Load a column. The first column picks up the material right and the second one also. But when the are in the drawing the first column has the right material but the second one the default color. When I put the part redraw under the second column it makes a new component of it (#1) so there must be something wrong in my code?

model = Sketchup.active_model
definitions = model.definitions
componentdefinition = definitions.load ( "Z:/Algemeen 2015/Systeemvloer/Tekeningen/Sketchup/enkelzijdige kolom.skp" )
defn = componentdefinition

defn.set_attribute 'dynamic_attributes' , 'material' , 'blue'
defn.set_attribute 'dynamic_attributes', 'materiallabel', 'blue'
defn.set_attribute 'dynamic_attributes', 'materialformlabel', 'RAL kleur'
defn.set_attribute 'dynamic_attributes', 'materialunits', 'STRING'
defn.set_attribute 'dynamic_attributes', 'materialaccess', 'TEXTBOX'

 #First column------------------------------------------------------------------------------------
defn = model.active_entities.add_instance( defn, [0+1*3.937,0,0] )

 # redraw

dcs = $dc_observers.get_latest_class
dcs.redraw_with_undo(defn)

 #Second column------------------------------------------------------------------------------------

defn = componentdefinition
defn = model.active_entities.add_instance( defn, [200,0,0] )

I am not even going to try to read your code, until you wrap it correctly for the forum. (The forum is swallowing certain characters.)

Refer to this post above for instructions:
http://forums.sketchup.com/t/dynamic-component-count-to-text-file/20979/15

Sorry for that I have done what you said

No. That is the way the Dynamic Components extension works. If you change a dynamic attribute for an instance, the extension “makes it unique” by creating a new definition and adding “#1”, or “#2”, … etc.

Okay, thank you.

Your hidden attributes are not named correctly.

Here is some more sample code for you to study:

module VanLion
  class << self

    def laden_kleur_comp( filepath, compfile, kleur )

      comppath = File.join( filepath, compfile )

      model = Sketchup.active_model
      deflist = model.definitions

      dynatts = 'dynamic_attributes'
      
      gevonden = deflist.find_all {|d|
        !d.image? && !d.group? && d.path == comppath
      }
      zelfde = nil
      if !gevonden.empty?
        zelfde = gevonden.find {|d|
          d.attribute_dictionary(dynatts) &&
          d.get_attribute(dynatts,'color') == kleur
        }
      end
      
      if gevonden.empty? || zelfde.nil?
        begin
          defn = deflist.load( comppath )
        rescue IOError => error
          if !File.exist?(filepath)
            UI.messagebox("Ongeldige component mappad.")
          elsif !File.exist?(comppath)
            UI.messagebox("Ongeldige component bestandsnaam.")
          else
            UI.messagebox("IO Fout: "<<error.message)
          end
          defn = nil
        end
      else
        defn = zelfde
      end

      if defn

        maak = true
        dict = defn.attribute_dictionary( dynatts, maak )
        
        if dict['color'].nil?
          dict['_color_access']=    'TEXTBOX'
          dict['_color_label']=     'Color'
          dict['_color_error']=     'null'
          dict['_color_formlabel']= 'RAL Kleur'
          dict['_color_formula']=   'null'
          dict['_color_formulaunits']= 'STRING'
          dict['_color_units']= 'STRING'
        end
        dict['color']= kleur

        if dict['material'].nil?
          dict['_material_error']=   'null'
          dict['_material_formula']= 'Color'
          dict['_material_label']=   'Materiaal'
        end
        dict['material']= kleur

      end

      # return the component definition
      return defn

    end ###

    def maken_kleur_kolom(
      kleur    = 'blue',
      filepath = 'Z:/Algemeen 2015/Systeemvloer/Tekeningen/Sketchup',
      compfile = 'enkelzijdige kolom.skp'
    )
      model = Sketchup.active_model
      model.start_operation('Kleur Kolom',true)
      #
      ###
        #
        standaard = 'blue'

        cdefn = laden_kleur_comp( filepath, compfile, kleur )
        model.abort_operation if cdefn.nil?

        aents = model.active_entities
        insts = aents.grep(Sketchup::ComponentInstance)

        dynatts = 'dynamic_attributes'
        herhalen = false
        succes = model.place_component( cdefn, herhalen )

        if succes
          inew = aents.grep(Sketchup::ComponentInstance) - insts
          inst = inew.first
          if ( kleur != standaard &&
          cdefn.get_attribute(dynatts,'color') != standaard )
            inst.set_attribute(dynatts,'color',kleur)
            # redraw
            dcs = $dc_observers.get_latest_class
            dcs.redraw_with_undo(inst)
          end
          return inst
        else
          return nil
        end
        #
      ###
      #
      model.commit_operation
      #
    end ###

    def test()
      # First column -------------------------------------------------------------
      maken_kleur_kolom()
      # Second column ------------------------------------------------------------
      maken_kleur_kolom('red')
    end

  end
end

[File attachment removed. An updated version (with comments added is posted below.]

Well thank you for the example code. I give it a try tomorrow and going to study it. More and more i’m going to know how ruby and sketchup work.

I will Let you know when I tried everything :slight_smile:

Hi Dan,

I have run the code but every result is Nill. Tried some other thing but also not working.

Is this code looking for the compfile that is already loaded or do i have to add an insert point in your code so it’s going to add the compfile to the drawing?

Thanks

You need to run the VanLion.test() method from the console.

Or add a right-click mouse context menu item.

UI.add_context_menu_handler do |popup|
  popup.add_item("Test Maken Kolom Kleur") { VanLion.test() }
end

It will want you to place a blue column, then a red column, using model#place_component(). This API call works just like using the Component Manager, except the code chooses the component definition, instead of the user.

In the laden_kleur_comp() method, it is supposed to first search the “In Modell” component definition list.
IF it finds a match the match is used. If not, it loads a new definition from disk.

But I could not test it, a I do not have the same path on my computer, nor do I have a column component file.

Refer to the laden_kleur_comp() method:


  # See if definition can be found in deflist.
  # Matches FOUND are an array, which might be empty:
  gevonden = deflist.find_all {|d|
    !d.image? && !d.group? && d.path == comppath
  }

  zelfde = nil # same = nil
  
  if !gevonden.empty?
  # If the found (set of components) is not empty,
  # search the set for first one that has the SAME color.
  # Results are nil if no match is found:
    zelfde = gevonden.find {|d|
      d.attribute_dictionary(dynatts) &&
      d.get_attribute(dynatts,'color') == kleur
    }
  end
  
  if gevonden.empty? || zelfde.nil?
  # IF the found (set of components) is empty,
  # OR one with same color could not be found:
    begin
      defn = deflist.load( comppath )
    rescue IOError => error
      # {{snip}} error messageboxes
      defn = nil
    end
  else
    defn = zelfde
  end

Here is an updated file with the above comments added:

vanlion_load_kleur_kolom.rb (3.6 KB)

YOU should comment the rest of the file as an exercise in learning.

UI.add_context_menu_handler do |popup|
  popup.add_item("Test Maken Kolom Kleur") { VanLion.test() }
end

This code is working well. It loads a new column that is going to be red.

The other code gives only the following result: Nil result (no result returned or run failed)
So when i load the file it’s got still a default color, white. I sent you the DC maybe i did something wrong.

Enkelzijdige kolom.skp (328.7 KB)

“This code”, uses “the other code”. So …

… does not make any sense.

You will need to figure out what you are doing correct and incorrect. This is the way to really learn.

If this “Enkelzijdige kolom.skp” is already a DC, then it should already have the DC attributes existing, and those attributes should not need creating in method laden_kleur_comp().

So, you have basically confused me, as to what you are trying to do.


This thread is supposed to be about outputting the component count to the text report. I answered that, so I am going to step out of this topic now.

You will need to find the answer yourself, or hire a programmer to solve whatever it is you need to get done.

Yes I think we had a misunderstanding. I Just saw the problem why the color was not right reported in the count list and was default when I loaded it. Strange I didn’t saw this before. The component name was: enkelzijdige kolom and the dynamic component strangly: t1. So I can get everything to work now. Sorry! And thanks for al the support every code is usable for me