sketchucation logo sketchucation
    • Login
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    🛣️ Road Profile Builder | Generate roads, curbs and pavements easily Download

    Importing Bulk Attribute Values from CSV

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 3 Posters 1.9k Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • sdmitchS Offline
      sdmitch
      last edited by

      Perhaps if you would share a sample model containing the dynamic component and a sample .csv file.

      Nothing is worthless, it can always be used as a bad example.

      http://sdmitch.blogspot.com/

      1 Reply Last reply Reply Quote 0
      • H Offline
        hank
        last edited by

        Sure! Here is a simple wall DC that I wanted to bring in a large list of wall assemblies:

        A basic wall dynamic component

        and here is the list of assemblies I put together in a spreadsheet - you will see that I added the "&" separator and "=" value indicator right in the spreadsheet because I was being lazy about the string cleanup...

        A list of assemblies for commercial construction

        And for convenience, here is the ruby file too!

        ruby CSV attribute importer

        1 Reply Last reply Reply Quote 0
        • TIGT Offline
          TIG Moderator
          last edited by

          A few somewhat random comments...

          Please enclose your Ruby code inside your own module.

          Do not use 'global' variables [$xxx].
          Using instance-variables [@xxx] will work within your module across its various methods...
          Although as far as I can see the $xxx ones you've made are only used in one method anyway, so they are unnecessary.

          The various DC attributes belong to each component's definition - not to the model - UNLESS that entire model is itself a DC...

          TIG

          1 Reply Last reply Reply Quote 0
          • H Offline
            hank
            last edited by

            Thanks TIG... will do. Any idea about the problem I mentioned?

            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              The DC dictionary attached to the model reports as this:
              ` Sketchup.active_model.attribute_dictionaries['dynamic_attributes'].each_pair{|k,v| puts "#{k} = #{v}" }

              _formatversion = 1.0
              _has_movetool_behaviors = 0.0
              _hasbehaviors = 1.0
              _lastmodified = 2017-06-04 23:49
              _lengthunits = INCHES
              _lenx_label = LenX
              _lenx_nominal = 766.4475123076386
              _leny_access = LIST
              _leny_formlabel = THICKNESS
              _leny_label = LenY
              _leny_nominal = 6.500000000000207
              _leny_options = &--------------INTERIOR--------------=0&1.500 : 0.625 GWB | 0.875 METAL FRAMING=1.500&3.125 : 0.625 GWB | 2.500 METAL FRAMING=3.125&4.250 : 0.625 GWB | 3.625 METAL FRAMING=4.250&6.625 : 0.625 GWB | 6.000 METAL FRAMING=6.625&8.625 : 0.625 GWB | 8.000 METAL FRAMING=8.625&4.875 : 0.625 GWB | 3.625 METAL FRAMING | 0.625 GWB =4.875&7.250 : 0.625 GWB | 6.000 METAL FRAMING | 0.625 GWB =7.250&9.250 : 0.625 GWB | 8.000 METAL FRAMING | 0.625 GWB =9.250&5.250 : 0.625 GWB | 3.625 METAL FRAMING | 0.500 CBB | 0.500 TILE=5.250&7.625 : 0.625 GWB | 6.000 METAL FRAMING | 0.500 CBB | 0.500 TILE=7.625&9.625 : 0.625 GWB | 8.000 METAL FRAMING | 0.500 CBB | 0.500 TILE=9.625&6.125 : 0.625 GWB | 0.625 GWB | 3.625 METAL FRAMING | 0.625 GWB | 0.625 GWB =6.125&8.500 : 0.625 GWB | 0.625 GWB | 6.000 METAL FRAMING | 0.625 GWB | 0.625 GWB =8.500&10.500 : 0.625 GWB | 0.625 GWB | 8.000 METAL FRAMING | 0.625 GWB | 0.625 GWB =10.500&7.625 : 7.625 CMU =7.625&11.625 : 11.625 CMU =11.625&8.875 : 0.625 GWB | 7.625 CMU | 0.625 GWB =8.875&12.875 : 0.625 GWB | 11.625 CMU | 0.625 GWB =12.875&--------------EXTERIOR--------------=0&5.875 : 0.625 GWB | 3.625 METAL FRAMING | 0.625 FRGWB | 1.000 FIN=5.875&8.250 : 0.625 GWB | 6.000 METAL FRAMING | 0.625 FRGWB | 1.000 FIN=8.250&10.250 : 0.625 GWB | 8.000 METAL FRAMING | 0.625 FRGWB | 1.000 FIN=10.250&6.625 : 0.625 GWB | 3.625 METAL FRAMING | 0.750 PLYWOOD | 0.625 FRGWB | 1.000 FIN =6.625&9.000 : 0.625 GWB | 6.000 METAL FRAMING | 0.750 PLYWOOD | 0.625 FRGWB | 1.000 FIN =9.000&11.000 : 0.625 GWB | 8.000 METAL FRAMING | 0.750 PLYWOOD | 0.625 FRGWB | 1.000 FIN =11.000&9.500 : 0.625 GWB | 3.625 METAL FRAMING | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =9.500&11.875 : 0.625 GWB | 6.000 METAL FRAMING | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =11.875&13.875 : 0.625 GWB | 8.000 METAL FRAMING | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =13.875&9.875 : 0.625 GWB | 7.625 CMU | 0.625 FRGWB | 1.000 FIN=9.875&13.875 : 0.625 GWB | 11.625 CMU | 0.625 FRGWB | 1.000 FIN=13.875&13.500 : 0.625 GWB | 7.625 CMU | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =13.500&17.500 : 0.625 GWB | 11.625 CMU | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =17.500&13.875 : 0.625 GWB | 8.000 CMU | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =13.875&10.250 : 0.625 GWB | 8.000 TILT WALL | 0.625 FRGWB | 1.000 FIN=10.250&10.250 : 0.625 GWB | 8.000 TILT WALL | 0.625 FRGWB | 1.000 FIN=10.250&13.875 : 0.625 GWB | 8.000 TILT WALL | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =13.875&13.875 : 0.625 GWB | 8.000 TILT WALL | 0.625 FRGWB | 1.000 AIR | 3.625 BRICK =13.875
              _leny_units = DEFAULT
              _lenz_access = TEXTBOX
              _lenz_formlabel = WALL_HEIGHT
              _lenz_label = LenZ
              _lenz_nominal = 120.0
              _lenz_units = DEFAULT
              _name = WALL_COMMERCIAL
              _scaletool_formlabel = ScaleTool
              _scaletool_label = ScaleTool
              _scaletool_units = STRING
              lenx = 174.3749999999994
              leny = 7.625
              lenz = 120
              scaletool = 124`

              I assume that you don't want this block of text associated with one 'key' ??

              You need to construct your CSV in a way that gives what you want.
              When you read it to make 'lines' you can iterate each 'line', using chomp! to snip off the \n carriage-return.
              You can then use split at ',' to access various key/value pairs ??

              At the moment I am unclear about what it is you want to end up with after running your code...
              Perhaps trying a very simple version first will help ???

              TIG

              1 Reply Last reply Reply Quote 0
              • H Offline
                hank
                last edited by

                That key is actually EXACTLY what I want. I just had to do it by hard coding the $input argument in set_attribute($input,$att_string) to read "_leny_options" (a string) in order to get it to work. When I feed in $input from UI.inputbox it comes creates a separate new key called ["_leny_options"] with brackets and quotes around it. That is the problem - somehow I need to format $input so this does not happen.

                The reason I want that key to be so long is because this is what I want the drop-down to look like:

                screenshot

                peripheral information...

                drop-down attributes are stored in a &key1=value1&key2=value2&key3=value3... format in the dictionary

                and

                UI.inputbox will present a drop-down if given 4 arguments and the 3rd argument is a bar separated list.

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by

                  I understand how a drop-down list is constructed for a DC.
                  Now I see beyond your complexity...

                  How about this ?

                  def set_attribute(key_in=nil, value_in='')
                    return unless key_in
                    Sketchup.active_model.set_attribute("dynamic_attributes", key_in.to_s, value_in.to_s )
                  end
                  

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    hank
                    last edited by

                    Thanks TIG. I'll give that a try.

                    Of course you do... that info is for anyone else reading this thread and having a similar struggle as I did.

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      hank
                      last edited by

                      Alright @TIG, I re-wrote this script trying to comply with your suggestions and it worked! Thank you for your help!

                      Here is the updated script for your entertainment:

                      
                      require 'sketchup.rb'
                      module AttModuleTop
                      	module AttModuleBottom
                      		class<<self
                      			def list_att()
                      				model = Sketchup.active_model
                      				attrdicts = model.attribute_dictionaries
                      				attrdict = attrdicts["dynamic_attributes"]
                      				if(!attrdict)
                      					UI.messagebox("AttTools is intended for use within Dynamic Component Files only")
                      				else
                      					@prompts = ["What attribute to overwrite"]
                      					@defaults = [""]
                      					@list = []
                      					@option_pairs = ""
                      					option_string = "select attribute to overwrite"
                      					attrdict.each{|key,value|
                      						@option_pairs += "key; #{key} | value; #{value}\n"
                      						option_string += "|#{key}"
                      					}
                      					@list << option_string
                      				end
                      			end
                      			def replace_att()
                      				list_att()
                      				new_prompt = "What should it be set to?"
                      				@prompts << new_prompt
                      				input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
                      				set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], input[1] )
                      				UI.messagebox('succesfully set ' + input[0] + ' to ' + set_result + '!')
                      			end
                      			def load_att()
                      				list_att()
                      				input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
                      				att_string = ""
                      				csv=UI.openpanel("Choose CSV File...")
                      				lines=IO.readlines(csv)
                      				lines.each{|line|
                      					line.chomp!
                      					next if line.empty?
                      					new_line = line.gsub(",", " ") #replace commas
                      					new_line = new_line.gsub("  ", "") #replace double spaces
                      					new_line = new_line.gsub("   ", "") #replace double spaces (again)
                      					new_line = new_line.gsub("& ", "&") #replace double spaces (again)
                      					new_line = new_line.gsub("= ", "=") #replace double spaces (again)
                      					att_string += new_line.to_s 
                      				}
                      				set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], att_string.to_s )
                      				UI.messagebox('succesfully set ' + input[0] + ' to ' + set_result + '!', MB_MULTILINE)
                      			end
                      			def report_att()
                      				list_att()
                      				if(@option_pairs)
                      					UI.messagebox(@option_pairs, MB_MULTILINE)
                      					#puts @option_pairs
                      				end
                      			end
                      		end # end of class
                      	end # end of module AttModuleBottom
                      end # end of module AttModuleTop
                      
                      # menus ##############################################################
                      
                      if( not file_loaded?("att_tools.rb") )
                      	main_menu = UI.menu("Plugins").add_submenu("Att Tools")
                      	main_menu.add_item("Load Attributes") {(AttModuleTop;;AttModuleBottom;;load_att)}
                      	main_menu.add_item("Replace Attribute") {(AttModuleTop;;AttModuleBottom;;replace_att)}
                      	main_menu.add_item("Report Attributes") {(AttModuleTop;;AttModuleBottom;;report_att)}
                      end
                      file_loaded("att_tools.rb")
                      
                      
                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        hank
                        last edited by

                        BTW, the answer to the original question was that

                        
                        input = UI.inputbox(@prompts, @defaults, @list, "Select Attribute Target")
                        
                        

                        returns an array of values because typically the inputbox would present more than 1 option. In my case there was only one input or prompt so when I put input into

                        
                        set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input, att_string.to_s )
                        
                        

                        I was actually sending in an array and thus setting a new key in the format ["whatever user put into inputbox"]. Even .to_s did not seem to help...

                        
                        set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input.to_s, att_string.to_s )
                        
                        

                        The answer was to get the first item in the array like so:

                        
                        set_result = Sketchup.active_model.set_attribute("dynamic_attributes", input[0], att_string.to_s )
                        
                        
                        1 Reply Last reply Reply Quote 0
                        • 1 / 1
                        • First post
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement