ckepner
February 12, 2020, 3:52pm
1
Hi,
I’m trying to create a python script for creating a printset from a selected revision by winforms combobox.
The error on line 123 where I’d like to find the sheets that a specific revision is on.
if r.Id not in revisionsOnSheet:
Error reads:
File “< string >” line 123, in < module >
AttributeError: ‘str’ object has no attribute ‘Id’
Any advice on how to achieve this?
Also, any advice on modifying Revit to create printset would be appreciated as well!
See code below
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import System
from System import Array
from System.Collections.Generic import *
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
from System.Drawing import Point
from System.Drawing import Point, Icon, Color
from System.Windows import Forms
from System.Windows.Forms import Application, Form, Label
from System.Windows.Forms import DialogResult, GroupBox, FormBorderStyle
from System.Windows.Forms import ComboBox, Button, DialogResult
elements = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
RevNames=[]
for i in elements:
RevNames.append(i.Name)
class RevisionSelectionForm(Form):
def __init__(self):
self.Text = 'Revision Print Set'
self.label = Label()
self.label.Text = "Select Revision"
self.label.Location = Point(50, 50)
self.label.Height = 30
self.label.Width = 200
self.count = 0
cb = ComboBox()
cb.Width = 200
cb.Height = 20
cb.Location = Point(15,20)
cb.DataSource = RevNames
self.cb = cb
button = Button()
button.Text = 'Select Revision'
button.Location = Point(15,60)
button.Width = cb.Width
button.Height = 25
button.Click += self.button_click
self.Width = cb.Width + 50
self.Height = 150
self.Controls.Add(cb)
self.Controls.Add(button)
def button_click(self, sender, event):
self.selected = self.cb.SelectedValue
self.DialogResult = DialogResult.OK
self.Close()
def show(self):
self.ShowDialog()
form = RevisionSelectionForm()
Application.Run(form)
SelectedRev = form.selected
sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
revisionsOnSheet = []
for i in sheets:
revisionsOnSheet = i.GetAdditionalRevisionIds()
for r in SelectedRev:
if r.Id not in revisionsOnSheet:
revisionsOnSheet.Add(r.Id)
else:
continue
OUT = revisionsOnSheet
Hi ckepner,
The value within the combobox is the Name of the revision (which is a string)
And here you are trying to get the id of a string. You need to figure out which revision the user has selected, from the combobox and get the Id of the revision, not the name of the revision.
Hope it helps.
Cascarino
1 Like
ckepner
February 13, 2020, 4:36am
3
Thank you, that helped.
Now, I’m trying to get the Id of the revision now but it’s not working. Can you tell me what going on?
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)
import System
from System import Array
from System.Collections.Generic import *
import clr
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
from System.Drawing import Point
from System.Drawing import Point, Icon, Color
from System.Windows import Forms
from System.Windows.Forms import Application, Form, Label
from System.Windows.Forms import DialogResult, GroupBox, FormBorderStyle
from System.Windows.Forms import ComboBox, Button, DialogResult
elements = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
RevNames=[]
for i in elements:
RevNames.append(i.Name)
class RevisionSelectionForm(Form):
def __init__(self):
self.Text = 'Revision Print Set'
self.label = Label()
self.label.Text = "Select Revision"
self.label.Location = Point(50, 50)
self.label.Height = 30
self.label.Width = 200
self.count = 0
cb = ComboBox()
cb.Width = 200
cb.Height = 20
cb.Location = Point(15,20)
cb.DataSource = RevNames
self.cb = cb
button = Button()
button.Text = 'Select Revision'
button.Location = Point(15,60)
button.Width = cb.Width
button.Height = 25
button.Click += self.button_click
self.Width = cb.Width + 50
self.Height = 150
self.Controls.Add(cb)
self.Controls.Add(button)
def button_click(self, sender, event):
self.selected = self.cb.SelectedValue
self.DialogResult = DialogResult.OK
self.Close()
def show(self):
self.ShowDialog()
form = RevisionSelectionForm()
Application.Run(form)
SelectedRev = form.selected
sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
revisionlist = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
def filter_list(revisionlist, search_str):
passed = []
for element in revisionlist:
name = element.Name
if search_str in name:
passed.append(element)
return passed
rev1 = [UnwrapElement(rev1) for rev1 in revisionlist if rev1 is not None]
SelRevEle = filter_list(rev1, SelectedRev)
def ProcessList(_func, _list):
return map( lambda x: ProcessList(_func, x) if type(x)==list else _func(x), _list )
def GetElement(id):
docM = DocumentManager.Instance.CurrentDBDocument
return docM.GetElement(id)
revIds = []
for i in sheets:
revIds.append(list(i.GetAllRevisionIds()))
revisions = ProcessList(GetElement, revIds)
# get revision name
RevNames2=[]
for i in revisions:
RevNames2.append(i.Description)
#Assign your output to the OUT variable
OUT = RevNames2
Here you are creating a list with the Revision Ids on all sheets and updating the variable.
You would then need to use that variable with a “SetAdditionalRevisionsIds” Method
Link to it on Revit API docs (I really hope this works as I haven’t sent a link on this site before.
https://www.revitapidocs.com/2020/376a4009-17f7-af8e-8c32-d95243ad8e9e.htm
I will try running the script later today to confirm if it really works. I like the idea, we could definitely use it at my company. I hope you don’t mind
Regards,
Cascarino
I think even simpler than that, you need to indent your code where you are trying to get the revisions Id’s.
Currently from the code posted, there isn’t an indent following the line of code after the :
It needs to be like such.
Hope this helps!
ckepner
February 13, 2020, 3:39pm
6
I didn’t post the code correctly. It was indented.
I’m trying to get the string name of the revisions so i can filter it by the string name of the selected revision. I thought append(i.Name) would produce a string name for all elements but it’s giving me an error.
Sounds good, I did some snooping through an archilab node that grabs the properties of a revision and pasted some of the code from there into yours and I was able to grab the revision description.
The node I went into was from ArchiLab - “Revision Properties”, it looks like he set up definitions to obtain most every parameter from a revision.
Hope this helps!
Hi ckepner,
I am sorry for leading down the incorrect path with “SetAdditionalRevsionIDs”, I had misread your intentions for the script
As Patrick indicated, you can easily get the Description of a revision by using:
Revision.Description
Furthermore, I refer you to the below post when you do begin the process of creating the ViewSet:
https://forum.dynamobim.com/t/create-sheetset-from-sheet-grouping/1217
Hello, a revised code (unless i didn’t understand the 1st post )
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class RevisionSelectionForm(Form):
def __init__(self, RevNames):
self.revname = RevNames
self.Text = 'Revision Print Set'
self.label = System.Windows.Forms.Label()
self.label.Text = "Select Revision"
self.label.Location = Point(50, 50)
self.label.Height = 30
self.label.Width = 200
self.count = 0
self.cb = System.Windows.Forms.ComboBox()
self.cb.Width = 200
self.cb.Height = 20
self.cb.Location = Point(15,20)
self.cb.DataSource = self.revname
self.button = System.Windows.Forms.Button()
self.button.Text = 'Select Revision'
self.button.Location = Point(15,60)
self.button.Width = self.cb.Width
self.button.Height = 25
self.button.Click += self.button_click
self.Width = self.cb.Width + 50
self.Height = 150
self.Controls.Add(self.cb)
self.Controls.Add(self.button)
def button_click(self, sender, event):
self.selected = self.cb.SelectedValue
self.Close()
def filter_list(revisionlist, search_str):
passed = None
for element in revisionlist:
name = element.Name
if search_str == name:
passed = element
return passed
sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
revisionlist = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
RevNames = [x.Name for x in revisionlist]
form = RevisionSelectionForm(RevNames)
form.ShowDialog()
SelectedRev = form.selected
SelRevEle = filter_list(revisionlist, SelectedRev)
sheetToPrint = []
for i in sheets:
revIds = i.GetAllRevisionIds()
if SelRevEle.Id in revIds:
sheetToPrint.append(i)
#or
#outsheet.append(i.Name)
OUT = sheetToPrint
ckepner
February 14, 2020, 5:24pm
10
Thank you guys for your help. The code is almost complete.
Currently it has no problem creating a new View Set.
It does not work if I want to add a sheet to an existing View Set.
Now I’m trying to find a way to replace an existing View Set if there already is a View Set with the same name.
See code below:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class RevisionSelectionForm(Form):
def __init__(self, RevNames):
self.revname = RevNames
self.Text = 'Revision Print Set'
self.label = System.Windows.Forms.Label()
self.label.Text = "Select Revision"
self.label.Location = Point(50, 50)
self.label.Height = 30
self.label.Width = 200
self.count = 0
self.cb = System.Windows.Forms.ComboBox()
self.cb.Width = 200
self.cb.Height = 20
self.cb.Location = Point(15,20)
self.cb.DataSource = self.revname
self.button = System.Windows.Forms.Button()
self.button.Text = 'Select Revision'
self.button.Location = Point(15,60)
self.button.Width = self.cb.Width
self.button.Height = 25
self.button.Click += self.button_click
self.Width = self.cb.Width + 50
self.Height = 150
self.Controls.Add(self.cb)
self.Controls.Add(self.button)
def button_click(self, sender, event):
self.selected = self.cb.SelectedValue
self.Close()
def filter_list(revisionlist, search_str):
passed = None
for element in revisionlist:
name = element.Name
if search_str == name:
passed = element
return passed
sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
revisionlist = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
RevNames = [x.Name for x in revisionlist]
form = RevisionSelectionForm(RevNames)
form.ShowDialog()
SelectedRev = form.selected
SelRevEle = filter_list(revisionlist, SelectedRev)
sheetToPrint = []
for i in sheets:
revIds = i.GetAllRevisionIds()
if SelRevEle.Id in revIds:
sheetToPrint.append(i)
viewSet = ViewSet()
for vs in sheetToPrint:
view = UnwrapElement(vs)
viewSet.Insert(view)
printManager = doc.PrintManager
printManager.PrintRange = PrintRange.Select
viewSheetSetting = printManager.ViewSheetSetting
viewSheetSetting.CurrentViewSheetSet.Views = viewSet
trans = Transaction(doc, "Create View/Sheet Set")
trans.Start()
try:
viewSheetSetting.SaveAs(SelectedRev)
msg = "Sheet set '" + SelectedRev + "' created."
except:
msg = "Failed to create sheet set"
trans.Commit()
#Assign your output to the OUT variable.
OUT = msg
ckepner
February 14, 2020, 8:12pm
11
Figured out how to save over an existing view set.
verify if there is already a viewset with the name
delete that viewset
create the new viewset
Thank you all for your help. Code is complete. Now I’m trying to import it into Revit macros for implementation with the project team.
Any suggestions on cleaning up the code is welcomed of course.
See code below:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
clr.AddReference("System.Drawing")
clr.AddReference("System.Windows.Forms")
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *
class RevisionSelectionForm(Form):
def __init__(self, RevNames):
self.revname = RevNames
self.Text = 'Revision Print Set'
self.label = System.Windows.Forms.Label()
self.label.Text = "Select Revision"
self.label.Location = Point(50, 50)
self.label.Height = 30
self.label.Width = 200
self.count = 0
self.cb = System.Windows.Forms.ComboBox()
self.cb.Width = 200
self.cb.Height = 20
self.cb.Location = Point(15,20)
self.cb.DataSource = self.revname
self.button = System.Windows.Forms.Button()
self.button.Text = 'Select Revision'
self.button.Location = Point(15,60)
self.button.Width = self.cb.Width
self.button.Height = 25
self.button.Click += self.button_click
self.Width = self.cb.Width + 50
self.Height = 150
self.Controls.Add(self.cb)
self.Controls.Add(self.button)
def button_click(self, sender, event):
self.selected = self.cb.SelectedValue
self.Close()
def filter_list(revisionlist, search_str):
passed = None
for element in revisionlist:
name = element.Name
if search_str == name:
passed = element
return passed
sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
revisionlist = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Revisions).WhereElementIsNotElementType().ToElements()
RevNames = [x.Name for x in revisionlist]
form = RevisionSelectionForm(RevNames)
form.ShowDialog()
SelectedRev = form.selected
SelRevEle = filter_list(revisionlist, SelectedRev)
filterview = FilteredElementCollector(doc).OfClass(ViewSheetSet).GetElementIterator()
filterview.Reset()
viewexists = None
sheetToPrint = []
for i in sheets:
revIds = i.GetAllRevisionIds()
if SelRevEle.Id in revIds:
sheetToPrint.append(i)
# remove viewset if already exists
for f in filterview:
if f.Name == SelectedRev:
viewexists = f
break
if viewexists != None
TransactionManager.Instance.EnsureInTransaction(doc)
doc.Delete(viewexists.Id)
TransactionManager.Instance.TransactionTaskDone()
viewexists = None
# create viewset
if viewexists == None:
viewSet = ViewSet()
for v in sheetToPrint: (viewSet.Insert(v))
printManager = doc.PrintManager
printManager.PrintRange = PrintRange.Select
viewSS = printManager.ViewSheetSetting
try:
TransactionManager.Instance.EnsureInTransaction(doc)
viewSS.CurrentViewSheetSet.Views = viewSet
viewSS.SaveAs(SelectedRev)
TransactionManager.Instance.TransactionTaskDone()
msg = "Sheet set '" + SelectedRev + "' created."
except:
msg = "The ViewSet could not be created"
#Assign your output to the OUT variable.
OUT = msg
3 Likes
Another way to set the ViewSheetSet with this function
def setViewSheetSet(viewSet):
printManager = doc.PrintManager
printManager.PrintRange = PrintRange.Select
viewSheetSetting = printManager.ViewSheetSetting
viewSheetSetting.CurrentViewSheetSet.Views = viewSet
collSheetSet = FilteredElementCollector(doc).OfClass(ViewSheetSet).WhereElementIsNotElementType().ToElements()
dictSheetSet = {x.Name : x for x in collSheetSet}
TransactionManager.Instance.EnsureInTransaction(doc)
if SelectedRev not in dictSheetSet:
viewSheetSetting.SaveAs(SelectedRev)
else:
sheetSet = dictSheetSet.get(SelectedRev)
doc.Delete(sheetSet.Id)
doc.Regenerate()
viewSheetSetting.SaveAs(SelectedRev)
TransactionManager.Instance.TransactionTaskDone()
return viewSheetSetting.CurrentViewSheetSet
where viewSet is define by:
viewSet = ViewSet()
for i in sheets:
revIds = i.GetAllRevisionIds()
if SelRevEle.Id in revIds:
viewSet.Insert(i)
1 Like