Access ViolationException with placing model groups

Dear Dynamo Specialists,

I have the following warning.

It occurs with the following script:

import clr
import math
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument
TransactionManager.Instance.EnsureInTransaction(doc)
active_view = doc.ActiveView

#receive windows
windows = UnwrapElement(IN[0][0])
points = IN[0][2]

#receive groups marks
all_groups = FilteredElementCollector(doc).OfClass(Group).ToElements()
groupnames = IN[0][1]
groups = [x for x in all_groups if x.Name in groupnamen]

#place groups
groups_placed = []
for a, b in zip(windows, groups):
    groups_placed_sub = []
    for c in a:
        #receive type
        typeid_group = b.GetTypeId()
        grouptype = doc.GetElement(typeid_group)
        #place
        point = XYZ(0, 0, 0)
        group_instance = doc.Create.PlaceGroup(point, grouptype)
        groups_placed_sub.append(group_instance)
        
        
    groups_placed.append(groups_placed_sub)

TransactionManager.Instance.TransactionTaskDone()
OUT = groups_placed


There are a lot of nodes before this node to create a curtain wall, create a group. Change type name, orientatie of the groups. Now this note places existing groups on point zero, later to place to another point. What could i fix? The strange thing is that when the code gives a error, change something as object name and run again. Then the code will run, and at the undo button i see two times Dynamo … Script. I think memory is to full?

Thanks in advance!

The Revit database is fairly stable so you don’t need to wrap your entire code inside a transaction, and my guess is that you have transactions in other nodes which are still open

Start by placing a Transaction.End node on the windows input before it gets to the script

Update the code to enact the transaction where you modify the document

TransactionManager.Instance.EnsureInTransaction(doc)
group_instance = doc.Create.PlaceGroup(point, grouptype)
TransactionManager.Instance.TransactionTaskDone()

There is a typo groups = [x for x in all_groups if x.Name in groupnamen]

Using the Group Class is going to get every instance in the document so you are possibly going to place multiples of new instances

Unless windows and groups lists are the same length the zip function will truncate one of the lists.

You can get the GroupType directly via name like this using the get_Name() method

names = ["Bandstand Balustrade", "Bleachers Continuous"]

group_types = FilteredElementCollector(doc).OfClass(GroupType).ToElements()

OUT = [gt for gt in group_types if gt.get_Name() in names]
1 Like

Thanks Mike!

The problem with Transactions is solved!
How to fix the multiple groups placement, because the groups are placed 5x to much.
And the list of groups are 5 groups, so this multiple come via this way.

How to fix this?

import clr
import math
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

active_view = doc.ActiveView

#receive windows
windows = UnwrapElement(IN[0][0])
points = IN[0][2]

#receive groups marks
group_types = FilteredElementCollector(doc).OfClass(GroupType).ToElements()
groupnames = IN[0][1]
groups = [gt for gt in group_types if gt.get_Name() in groupnames]

#place groups
groups_placed = []
for a in range(len(groups)):
    if groups[a] is not None:
        groups_placed_sub = []
        for b in range(len(windows[a])):
            if points[a][b]:
                TransactionManager.Instance.EnsureInTransaction(doc)
                group_instance = doc.Create.PlaceGroup(XYZ(0, 0, 0), groups[a])
                TransactionManager.Instance.TransactionTaskDone()
                groups_placed_sub.append(groups[a])
        if groups_placed_sub:
            groups_placed.append(groups_placed_sub)

OUT = groups_placed

When i run the script in the bottom the code place to much instances of the group types.
I tried break, but then the list became wrong (only first item). When i dont use break there will be place to much items (155 instead of 31).

Could anyone help me?

import clr
import math
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

#receive windows
points = IN[0][2]

#receive groups marks
group_types = FilteredElementCollector(doc).OfClass(GroupType).ToElements()
groupnames = IN[0][1]
groups = [gt for gt in group_types if gt.get_Name() in groupnames]

TransactionManager.Instance.EnsureInTransaction(doc)
groups_placed = []
for a in range(len(groups)):
    groups_placed_sub = []
    for b in range(len(points[a])):
        
        group_instance = doc.Create.PlaceGroup(XYZ(0, 0, 0), groups[a])
        
        groups_placed_sub.append(b) 
        #break
    groups_placed.append(groups_placed_sub)

TransactionManager.Instance.TransactionTaskDone()
OUT = groups

Hi @rlandkroon I merge your new topic here

Have you tried using the zip() function?

for groupType, point in zip(groups, points ):
    group_instance = doc.Create.PlaceGroup(point, groupType)
    groups_placed_sub.append(group_instance)

Then I receive this:

The groups have 6 group types.
The points have 6 sublist with points where groups have to be placed.

import clr
import math
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

#receive windows
points = IN[0][2]

#receive groups marks
group_types = FilteredElementCollector(doc).OfClass(GroupType).ToElements()
groupnames = IN[0][1]
groups = [gt for gt in group_types if gt.get_Name() in groupnames]

#create group sublists
groups_type = []
for a in range(len(groups)):
    group_type_sub = []
    for b in range(len(points[a])):
        if points[a]:
            group_type_sub.append(groups[a])
    if group_type_sub:
        groups_type.append(group_type_sub)

#flatten list
groupstypes_flat = [x for sub in groups_type for x in sub]
points_flat = [x for sub in points for x in sub]

TransactionManager.Instance.EnsureInTransaction(doc)

groups_placed = []
for x, y in zip(points_flat, groupstypes_flat):
    group_instance = doc.Create.PlaceGroup(x, y)
    groups_placed.append(group_instance)

TransactionManager.Instance.TransactionTaskDone()

OUT = groups_placed

When i do this:

The code create 155 items, instead of 31 that the groups_placed contain in OUT.

import clr
import math
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

#receive windows
points = IN[0][2]

#receive groups marks
group_types = FilteredElementCollector(doc).OfClass(GroupType).ToElements()
groupnames = IN[0][1]
groups = [gt for gt in group_types if gt.get_Name() in groupnames]

#create group sublists
groups_type = []
for a in range(len(groups)):
    group_type_sub = []
    for b in range(len(points[a])):
        if points[a]:
            group_type_sub.append(groups[a])
    if group_type_sub:
        groups_type.append(group_type_sub)

#flatten list
groupstypes_flat = [x for sub in groups_type for x in sub]
points_flat = [x for sub in points for x in sub]

TransactionManager.Instance.EnsureInTransaction(doc)

groups_placed = []
for x, y in zip(points_flat, groupstypes_flat):
    group_instance = doc.Create.PlaceGroup(XYZ(0,0,0), y)
    groups_placed.append(group_instance)

TransactionManager.Instance.TransactionTaskDone()

OUT = groups_placed


synthaxis should look more like this

for groupType, array_point in zip(groups, array_array_points ):
    temp = []
    for point in array_point:
        group_instance = doc.Create.PlaceGroup(point, groupType)
        temp.append(group_instance)
    groups_placed_sub.append(temp)