How to resolve "hierarchy is locked" in script

Hello,

in my assebly I have a component “NioAblage” (not ok storage)
a componet named “Kundenteil” (customer part)
the “nioAblage” has a link “Drawer1”
and there are frames by the name of “Frame_Px” where x is a number
and ComponentContainers by the name “Container_Partx” where x is a number
The containers positions are set to the frames
I want to add “Kundenteil” to the containers.

I created a script to achive this:

from vcScript import *

comp = getComponent()


# GLOBAL
_app = getApplication()


def insertPartIntoContainer(containing_component, part_name, frame_name="Frame", container_name="ComponentContainer"):
  '''
  iserts a part into a container to be transferred on a WPC
  
  'containing_component': the component where the part is to be added 
  'part_name': the name of the part to be added to the containing_component
  'frame_name': the name of the frame/position where the part is to be added (if multiple), usually only 'Frame'
  'container_name': The name of the container the part is to be added to  (if multiple), usually only 'ComponentContainer'
  '''
  print("containing component: "+ str(containing_component)+ " " + containing_component.Name)
  part = _app.findComponent(part_name)
  newPart = _app.cloneComponent(part)
  print("new part: "+ str(newPart)+ " " + newPart.Name)
  frame = containing_component.findFeature(frame_name) 
  print("frame:    "+ str(frame)+ " " + frame.Name)
  pos = frame.PositionMatrix
  newPart.PositionMatrix  = pos   
  #node=containing_component.findNode("UpperDrawer")
  #print("upper drawer: " + str(node) + " " + node.Name)
  targetContainer = containing_component.getBehaviour(container_name) #node.getBehaviour(container_name)
  print("container: "+ str(targetContainer)+ " " + targetContainer.Name)
  targetContainer.grab(newPart)


partName = "Kundenteil" 
targetFrameName = "Frame_P1"
containerName = "Container_Part1"    

# remove excess parts 
for num in range(1,10):
  delete_name = partName +" #"+str(num)
  delete_component= _app.findComponent(delete_name)
  if (delete_component is not None):
    print("found component to delete:" +delete_component.Name)
    _app.deleteComponent(delete_component)

insertPartIntoContainer(comp, partName, targetFrameName, containerName)          
comp.rebuild() 

When the script is run, everything works as expected up to the point there it should actually place the new part into the container.

found component to delete:Kundenteil #2
containing component: <vcComponent object at 0x000001C702117658> NioAblage
new part: <vcComponent object at 0x000001C702117A48> Kundenteil #2
frame:    <vcFrameFeature object at 0x000001C71C162238> Frame_P1
container: <vcComponentContainer object at 0x000001C7021178F8> Container_Part1
Traceback (most recent call last):
  File "NioAblage::ProvidePartsScript", line 46, in <module>
  File "NioAblage::ProvidePartsScript", line 31, in insertPartIntoContainer
RuntimeError: Exception occurred during method execution: Attempted to change node hierarchy when hierarchy is locked.

I moved the script and components and Frames around from the root component (“NioAblage”) to the drawer (using the commented node instead of the conating_component) and back, but I always get the “hierarchy is locked”

Can someone tell me why that is and to get the parts to be finally placed into the containers?
I use a similar script with the Python Feeder Template, where I add parts to a work piece carrier. I get no exception there.

Thanks

So when is the insertPartIntoContainer function actually called? If you have the call like that in the root level of the script it will get run when the script is compiled during e.g. layout loading and such.

There are some limitations that hierarchy can’t be modified during loading and maybe in certain event handlers because it would break things for other logic. You’ll need to run your code in an appropriate event like OnFinalize, OnRun or something.

1 Like

Thanks, putting it into OnRun worked.