So I am trying to use dictionaries to create entries of
[Schedule.Name,Sheet.Name]
Is there any way to use dictionaries to summarize schedules that way, or am I missing something?
I.e.
add “FooSchedule”,“Sheet1”
add “FooSchedule”,“Sheet2”
Add “BarSchedule”,“Sheet1”
So when I look up the key name “FooSchedule” it returns “Sheet1,Sheet2”.
I am this close to creating a def() that appends based on a key name- but I am hoping dictionaries will do it for me.
~TIA
Code to schedule schedules:
#!python3 ##Code pre-directive untested!
##Apsis0215 R Allen 2022-09-28 CPy3
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument ##Current Document
import Revit
from Autodesk.Revit.DB import FilteredElementCollector,ScheduleSheetInstance,ViewSchedule
from Autodesk.Revit.DB import Transaction ##For outside and inner transactions
import Autodesk.Revit.DB as ARDB
import System.Collections.Generic ##For dictionary
SchSht=System.Collections.Generic.Dictionary[System.String,System.Object]()
def Views_Remove_ViewTemplates(Views): ##To remove view templates in list views
viewlist = []
for view in Views:
if view.IsTemplate == False: ##If Is Template = false then
viewlist.append(view) ##Add to return list
return viewlist ##Return list of views (Not view templates)
PlacedSchedules = FilteredElementCollector(doc).OfClass(ScheduleSheetInstance).WhereElementIsNotElementType().ToElements()
PlacedSchedulesID=[VID.ScheduleId for VID in PlacedSchedules]
AllSchedules = FilteredElementCollector(doc).OfClass(ViewSchedule).WhereElementIsNotElementType().ToElements()
AllSchedulesID =[VID.Id for VID in AllSchedules]
##https://stackoverflow.com/questions/33577790/exclude-items-from-list-of-lists-python
SchedNotPlaced=[element for element in AllSchedulesID if element not in PlacedSchedulesID]
SchedNotPlaced=[doc.GetElement(VSHID) for VSHID in SchedNotPlaced]
SchedNotPlaced = Views_Remove_ViewTemplates(SchedNotPlaced)
out=[]
for sch in PlacedSchedules:
Sht=None
Sht=doc.GetElement(sch.get_OwnerViewId())
out.append([sch.Name,Sht]) ##<<<<<<<<This is where I have tried to append or add key+Value but I cannot get the syntax right.
OUT=out
Def is something like this:
I am sure this will be fraught with its own issues… : (
def AddByKey(objSch as ARDB.ViewSchedule,objSht as ARDB.ViewSheet, MyList[]):
for each opair in MyList: ##For each item in the MyList with is a list of ([ViewSchedule,CiewSheet])
if opair[0].Name = objSch.Name: ##If the name matches the item [0].Name [Viewschedule.name] then
opair[1].Append(objSht) ##Add the sheet to that sublist.
break
return MyList
Hi,
you can use List as values
an example
2 Likes
Ah thanks~the Syntax isn’t “intuitive” (yet? ), and that helped immensely!
Having an issue where the additional schedules E.g. “<Revision Schedule> ###” which have been lumped together under “<Revision schedule>” aren’t appending(). There should be 20+ sheet “<Revision schedule>” listed and only the 1st is showing. Maybe dictionaries don’t support lists as values?
Tried:
##SNIP##
##Roll up all "Revision schedules" in section without numeric suffix
else: ##Revision schedule
if "<Revision Schedule>" not in SchDict: ##Key not in dictionary
SchDict["<Revision Schedule>"]=[sht] ##Add new "<Revision Schedule>" key
else:
ol=SchDict["<Revision Schedule>"]
ol.append(sht)
SchDict["<Revision Schedule>"]=[ol] ##Add under "<Revision Schedule>"
##SNIP##
but that didn’t work to reset the key’s value to a new [list].
Also tried a cast to an array:
SchDict=System.Collections.Generic.Dictionary[System.String,System.Collections.ArrayList]()
But that didn’t work either.
Here is the code - ‘mostly’ working : )
#!python3 ##Code pre-directive untested!
##Apsis0215 R Allen 2022-11-22-CPy3-R22
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument ##Current Document
import Revit
from Autodesk.Revit.DB import FilteredElementCollector,ScheduleSheetInstance,ViewSchedule
from Autodesk.Revit.DB import Transaction ##For outside and inner transactions
import Autodesk.Revit.DB as ARDB
import System.Collections.Generic ##For dictionary
SchDict=System.Collections.Generic.Dictionary[System.String,System.Object]()
def Views_Remove_ViewTemplates(Views): ##To remove view templates in list views
viewlist = []
for view in Views:
if view.IsTemplate == False: ##If Is Template = false then
viewlist.append(view) ##Add to return list
return viewlist ##Return list of views (Not view templates)
PlacedSchedules = FilteredElementCollector(doc).OfClass(ScheduleSheetInstance).WhereElementIsNotElementType().ToElements()
PlacedSchedulesID=[VID.ScheduleId for VID in PlacedSchedules]
AllSchedules = FilteredElementCollector(doc).OfClass(ViewSchedule).WhereElementIsNotElementType().ToElements()
AllSchedulesID =[VID.Id for VID in AllSchedules]
##https://stackoverflow.com/questions/33577790/exclude-items-from-list-of-lists-python
SchedNotPlaced=[element for element in AllSchedulesID if element not in PlacedSchedulesID] ##Get schedile IDs to comp
SchedNotPlaced=[doc.GetElement(VSHID) for VSHID in SchedNotPlaced] ##Convert back to schedule
SchedNotPlaced = Views_Remove_ViewTemplates(SchedNotPlaced)
##https://forum.dynamobim.com/t/python-dictonnary-with-sheets-list/83380/2
for Sch in PlacedSchedules:
sht=None
sht=doc.GetElement(Sch.get_OwnerViewId())
##Dictionaries don't like <CLASSES> or <Id>'s - have to use .Name : (
if Sch.Name.find("<Revision Schedule>") == -1: ##if not a ,Revision schedule>" then
if Sch.Name not in SchDict: ##Key not in dictionary
SchDict[Sch.Name]=[sht] ##Set 1st key with value
else:
SchDict[Sch.Name].append (sht) ##Append key to current value
##Roll up all "Revision schedules" in section without numeric suffix
else: ##Revision schedule
if "<Revision Schedule>" not in SchDict: ##Key not in dictionary
SchDict["<Revision Schedule>"]=[sht] ##Add new "<Revision Schedule>" key
else:
SchDict["<Revision Schedule>"].append (sht) ##Add under "<Revision Schedule>"
##Schedules not placed
for Sch in SchedNotPlaced: ##Flipped form name/sheet to "Not placed"/Schedule
if "Not Placed" not in SchDict: ##Key not in dictionary
SchDict["Not Placed"] = [Sch] ##Set 1st key with value
else:
SchDict["Not Placed"].append(Sch) ##Append key to current value
OUT=SchDict ##sorted(SchDict,SchDict.Keys)
Keys must be unique and will overwrite their associated values if you just update them. It’s easier to group your values by key first and then create the key, value pairs just once.
I’ve done this pretty easily by creating a list of unique schedules and using that to filter and group all the sheets by their corresponding schedule instance. Then I just create the key, value pair after each unique schedule has been filtered.
3 Likes
Seems like I am going backwards there : )
settling on lists where the first element in the list is the schedule and the remaining elements are the sheets. The Types have been taken out as I once the Schedule Sheet to a View Schedule before returning the SchArr (Schedule array):
#!python3 ##Code pre-directive untested!
##Apsis0215 R Allen 2022-11-22-CPy3-R22
import clr
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument ##Current Document
import Revit
from Autodesk.Revit.DB import FilteredElementCollector,ScheduleSheetInstance,ViewSchedule
from Autodesk.Revit.DB import Transaction ##For outside and inner transactions
import Autodesk.Revit.DB as ARDB
import System.Collections.Generic ##For dictionary
#SchDict=System.Collections.Generic.Dictionary[System.String,System.Collections.IList]()
SchArr=[]
def Views_Remove_ViewTemplates(Views): ##To remove view templates in list views
viewlist = []
for view in Views:
if view.IsTemplate == False: ##If Is Template = false then
viewlist.append(view) ##Add to return list
return viewlist ##Return list of views (Not view templates)
PlacedSchedules = FilteredElementCollector(doc).OfClass(ScheduleSheetInstance).WhereElementIsNotElementType().ToElements()
PlacedSchedulesID=[VID.ScheduleId for VID in PlacedSchedules]
AllSchedules = FilteredElementCollector(doc).OfClass(ViewSchedule).WhereElementIsNotElementType().ToElements()
AllSchedulesID =[VID.Id for VID in AllSchedules]
##https://stackoverflow.com/questions/33577790/exclude-items-from-list-of-lists-python
SchedNotPlaced=[element for element in AllSchedulesID if element not in PlacedSchedulesID] ##Get schedile IDs to comp
SchedNotPlaced=[doc.GetElement(VSHID) for VSHID in SchedNotPlaced] ##Convert back to schedule
SchedNotPlaced = Views_Remove_ViewTemplates(SchedNotPlaced)
##https://forum.dynamobim.com/t/python-dictonnary-with-sheets-list/83380/2
Sch=PlacedSchedules.pop() ##Pop one off to prime
sht=doc.GetElement(Sch.get_OwnerViewId()) ##Get sheet from ID
SchArr=[[Sch,sht]] ##Schedule Array: the list of sublists primed with 1st element
rev=[]
for Sch in PlacedSchedules: ##For each additional place schedule
sht=None ##Set sheet for placed schedule
sht=doc.GetElement(Sch.get_OwnerViewId()) ##Get SHEET from owner view ID
#sos=doc.GetElement(Sch.ScheduleId) ##Get source schedule
found=False ##REset found
if doc.GetElement(Sch.ScheduleId).Name.find("<Revision Schedule>") == -1: ## Not a revision schedule
for ssch in SchArr: ##Existing list of schedules
if ssch[0].Name == Sch.Name: ##If Schedule name = data pair element 0 name (schedule)#
ssch.append(sht) ##Append to data pair[1] (Array of sheets)
found=True ##Found=true
break ##to for Sch... ##Break to outer loop
if not found:
SchArr.append([Sch,sht])
else: ##Is a revision schedule - stack those together
rev.append([Sch,sht]) ##Separate list ofr sequential revision schedules on sheets
##SchArr.extend(rev) ##Extend Schedule array: with revision schedules
#################################################################
for Sch in SchArr: ##convert schedule on sheet to schedule viewSet all the schedules to the original schedule object not the schedule on sheet object
Sch[0]=doc.GetElement(Sch[0].ScheduleId)
##SchArr.sort
OUT=SchArr
With this I can export those views to an excel or create generic annotation placeholder sheets with them to schedule.
Guess dictionaries aren’t the best choice for this.
Output looks like this:
[
[
ScheduleView(Name = A11_RR-SUMMARY_IPC_ ), ##Schedule View
Sheet(Name = OVERALL OCCUPANCY AND EGRESS PLAN ), ##Sheet ref 1
Sheet(Name = OVERALL OCCUPANCY AND EGRESS PLAN ) ##Sheet Ref 2
],
[
ScheduleView(Name = • DATA - SHEETS • ), ##Next Schedule View
Sheet(Name = Start Up - Project Data ) ##Sheet ref (osched on only one sheet here#
]
]