Retrieving Values from Schedules

hi everyone im having a bit of trouble understanding how schedules work with dynamo, I’ve looked around on the primer but can seem to find anything up to date that would help me. I am trying to retrieve values from schedules that exist within our project that I can use later on in the script for a calculation but im not having much luck, any help would be appreciated.

So far I have only been able to retrieve fields from a schedule but not the value/s in the schedules I have imported into dynamo.

These are the schedules on the sheet that I managed to get into dynamo, the two gray schedules on the right have the values that I am trying to retrieve.

Im trying to do this without using any packages

Schedules are basically a view with a list of elements. The fields in a schedule are representations of selected parameters from those corresponding elements and thusly the values are the parameter values. So your dynamo script would need to get the walls and then get the parameter value from the corresponding parameter of the wall. You can use the schedule to get the exact walls that are being scheduled. (what @Nick_Boyts said) lol

2 Likes

Keep in mind what a Revit schedule is: it’s just a view of filtered elements and their parameter values. If you want to get all the values in the schedule then you need to get those values from the elements that are shown in the schedule. You can get all elements in view from a schedule to get the filtered elements and then get the parameter values based on the scheduled parameters.
Edit: (What @staylor said)

If you decide to use a custom package, you can use Orchid to get the schedule table data directly. Or you can rebuild that functionality in python by using the API to get all the schedule table data cell by cell.

2 Likes

Here’s a quick and dirty schedule scraper using the ViewSchedule.Export() method and python tempfile module. Takes the schedule name as the python node input and you can use the ViewScheduleExportOptions() to adjust what is captured.
Notes:
If you need to set the ColumnHeaders property to ExportColumnHeaders.None use 0.
IronPython2 does not have the csv module

import csv
import tempfile

import clr

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

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument

bip =  ElementId(BuiltInParameter.VIEW_NAME)
pfrf = ParameterFilterRuleFactory.CreateEqualsRule(bip, IN[0])
epf = ElementParameterFilter(pfrf)

schedule = (
    FilteredElementCollector(doc)
    .OfClass(ViewSchedule)
    .WherePasses(epf)
    .FirstElement()
)

with tempfile.TemporaryDirectory() as td:
    filename = schedule.Name + ".tsv"
    vseo = ViewScheduleExportOptions()
    vseo.Title = False
    vseo.HeadersFootersBlanks = False
    schedule.Export(td, filename, vseo)
    
    with open(td + "\\" + filename, mode='r', encoding='utf-8-sig') as tsv:
        data = list(csv.reader(tsv, dialect="excel-tab"))
    
    OUT = data

1 Like

Thank you everyone, schedules being treated as views is very insightful. Without using a package is there a way for me retrieve the grand total area calculated at the bottom of the schedule (one to the left) in a more straight forward way? or would I have to retrieve the area parameters from all the wall types in the schedule and add them all up to recreate the grand total?

This is the first time I’m using dynamo for something like this and there is this gnawing feeling in the back of my mind that there is a more straightforward way that I’m missing… I’m kind of scratching my head a bit since the calculations have already been done in the views, its just a matter of finding a way of getting those calculated values into Dynmao without my colleagues having to install a package and scaring them away from Dynamo

This is correct. A schedule is just a list of values. The totals are calculated on the fly, they’re not associated with any real object. Getting all the values from the walls in the schedule is the most direct way to recreate those totals. Again, you could get the table data and sift through all the cells but that’s actually more work than just recreating the calculations yourself.

1 Like

As The Building Coder noted, a schedule is a view - so you can use a FilteredElementCollector to get all the elements. You can change the BuiltInParameter in the area function below to the value you want to collect.

import clr

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

clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager


def area(element):
    return element.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble()
    
    
doc = DocumentManager.Instance.CurrentDBDocument

bip =  ElementId(BuiltInParameter.VIEW_NAME)
pfrf = ParameterFilterRuleFactory.CreateEqualsRule(bip, IN[0])
epf = ElementParameterFilter(pfrf)

schedule = (
    FilteredElementCollector(doc)
    .OfClass(ViewSchedule)
    .WherePasses(epf)
    .FirstElement()
)

schedule_elements = (
    FilteredElementCollector(doc, schedule.Id)
    .WhereElementIsNotElementType()
    .ToElements()
)

OUT = sum(map(area, schedule_elements))