Ruby Script Help

I tried but could not reproduce it. When an attribute is not common among the selected entities (not existing or has different values), and I create or modify its value, only this attribute is transferred to all selected entities, but other (grayed) attributes stay unchanged. This seems to work correctly as intended.

Is this what you did?

It may also be a misunderstanding in usage of the extension or side effects with dynamic components’ own attribute observing system.

Hi Tig,

It didn’t work. Could it be that the attribute B_CURRENT_MONTH is set to be selected from a list with options “Jan”, “Feb” etc but returns 1,2,3 etc. I have tried to set it to “Nov”, 11 and “11”.

Hi Aerilius,

What I have are components that have the same definition in terms of attributes. So they all contain the attribute B_CURRENT_MONTH. I want to be able to change only this value across all the components without changing any of the other data.

I can not select all of them and then change the attribute in the Component Attribute dialogue as you can only select one component to change at a time.

I can not change it via the Component Options dialogue as it changes the data for all the attributes.

In your screenshot B_CURRENT_MONTH is set to an integer e.g. 6
Your ruby-code sets it to a string e.g. ‘Nov’ which is nit going to work…
So set it to a number like 11 [note with no “”]

BUT what you are missing in the ruby-side is something to force the DC to update after the changes !
e.g. something like this

undo = false ### choose ?
pbar_visible = false
ent = inst #i.e. some entity like the instance to update...
begin
  ldc=$dc_observers.get_latest_class()
  if undo
    ldc.method(:redraw_with_undo).call(ent, pbar_visible)
  else ### most likely
    ldc.determine_movetool_behaviors(ent)
    DCProgressBar::clear()
    ldc.method(:redraw).call(ent, pbar_visible)
    DCProgressBar::clear()
    ldc.refresh_dialogs()
  end
 rescue TypeError => e
  p e
 end
# suppresses nil to float conversion error that happens
# when redraw is called directly with true 2nd arg ?
###
 mod.active_view.refresh ### update view
 # return true ### to show nested commit_operation, only IF called from within a method

Thanks Tig,

Where do I insert this? After the line that updates the attribute or at the end of the script?

Since it needs to work on the instance add it in the ‘block’ that processes inst and when the if test is true…

... .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", 11)
     ### add code to refresh inst HERE
    
     ###
    end
  }

Alternatively create a method, then call that within the block to make it easier to debug…

def self.redrawer(mod, ent, undo=false,  pbar_visible=false)
  ent = inst #i.e. some entity like the instance to update...
  begin
    ldc=$dc_observers.get_latest_class()
    if undo
      ldc.method(:redraw_with_undo).call(ent, pbar_visible)
    else ### most likely
      ldc.determine_movetool_behaviors(ent)
      DCProgressBar::clear()
      ldc.method(:redraw).call(ent, pbar_visible)
      DCProgressBar::clear()
      ldc.refresh_dialogs()
    end
   rescue TypeError => e
     p e
   end
# suppresses nil to float conversion error that happens
# when redraw is called directly with true 2nd arg ?
###
 mod.active_view.refresh ### update view
 # return true ### to show nested commit_operation, only IF called from within a method

THEN in the main code… change it so it redraws…

...
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", 11)
      self.redrawer(mod, inst, undo=false,  pbar_visible=false) ### force inst to redraw
    end
  }
...

Remember this is only untested cod-code and there are undoubtedly much better ways to do all of this - e.g. you could make mod @mod once so other related methods use it with passing it explicitly etc…

Sorry Tig, If I have made the changes correctly it didn’t work.


MONTH_UPDATE4.rb (1.5 KB)

Try this RB…
Read its contents and understand them before proceeding.

I’ve packaged it better in a module GreyDC and you now née to use GreyDC.run() in the Ruby Console to run it.
That way it’ll be easier to debug.
I also tied some unnecessary Constants and made an @mod variable so it apples to both of your methods…

Untested, so report back with issues…
MONTH_UPDATE4[TIG].rb (1.8 KB)

Hi Tig,

I really do appreciate this. I have never used Ruby so it is all new including the Console. This is the result when it ran.

All we know so far is that the RB loaded and set up a variable referencing the definitions…

We need a lot more info…
Are we looking at an instance of the component ?
Are we looking for a variable called B_CURRENT_MONTH ?

Can I suggest you look to see what attributes an instance has, and list them so we know what’s what ??
e.g. just after

@mod.definitions.each{|defn|
add in a line after
defn.attribute_dictionaries[dc_dict].keys.each{|k| puts"#{defn} - #{k}"}

and after defn.instances.each{|inst| add
instn.attribute_dictionaries[dc_dict].keys.each{|k|puts"'{defn} - #{instn} - #{k}"}

Then we’ll see what’s attached to what…

Hi Tig,

The screen shot shows the attributes for one of the instances - Gaura lindheimeri The Bride <P_S_PLANTS_TREE#112> after the script ran.
The attribute to change is B_CURRENT_MONTH which is set to 6. This is a selectable attribute with values “Jan”,“Feb”, …,“Dec” that translate to 1,2,…,12. This value is used to hide sub-components of the main component based on a simple IF statement.
Each instance has a lot of attributes. Most are static month values that do not change once they are set for the invidivdual instance. There are also material options that get switched depending on the value of the B_CURRENT_MONTH value and whether it is within an interval defined by the start and end month attributes
MONTH_UPDATE4_TIG.rb (2.0 KB)
.

Hi Tig,

I hope that you are well. Did you get a chance to look at why this didn’t work?

Thanks

The screenshot you posted returns an error because you must somehow pass a component to the method…
Without an example SKP it’s awkward to see what’s what.
You could give me a SKP to test your code on… send it by PM on the forum…

I have PM’d you.