Make Grey Key Schedule Values False

This came up in the office and I thought it was fun…

I don’t know of a native Revit way to do it.

image


import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Assign input to the IN variables
scheduleKeyWord = IN[0]

doc = DocumentManager.Instance.CurrentDBDocument

# Start the Transaction
TransactionManager.Instance.EnsureInTransaction(DocumentManager.Instance.CurrentDBDocument)

projectViews = FilteredElementCollector(doc).OfClass(View).ToElements()

#get all the view schedules
for view in projectViews:
    if not view.IsTemplate and view.ViewType == ViewType.Schedule: 
        if scheduleKeyWord in view.Name: 
            schedule = view


element = FilteredElementCollector(doc, schedule.Id).ToElements()

#we want as many false values as there are empty values
output = []

params = []
for i in element:
    params.append(i.Parameters)
    for param in params:
    #    output.append(param.StorageType)
        iterator = param.ForwardIterator()
        iterator.Reset()
        while iterator.MoveNext():
            p = iterator.Current
            type = p.Definition.ParameterType
            if type == ParameterType.YesNo:
                value = p.AsInteger()
                if value == 0:
                    p.Set(0)
                    name = p.Definition.Name
                    type = p.Definition.ParameterType
                    value = p.AsValueString()
                    output.append([name,type,value])
 

# End the Transaction
TransactionManager.Instance.TransactionTaskDone()

# Assign your output to the OUT variable
OUT = schedule, output
5 Likes

This is one of the silly things Revit does. When you have a Yes/No field, it comes in as Null (so really Yes/No has 3 possible values, Yes/No/Null.

However, once you set the value to True (or False) - it can never return to Null. And actually having null would be a handy thing to have in a lot of cases. It can be used as QQA/QC to show those items that need a decision. As it is - you get a blank, a Yes and a No on the schedule. Often it would be nice to have a Yes, No, back to < blank > toggle at the user level - because we want it blank. So everyone ends up putting additional parameters in to do an X or something in anther field that responds to True. It would also be nice to have the schedule format Yes/No as X / Blank or Square or Circle.

You can’t even use the ClearValue() method to set it back to null. Kinda sucks.

Note:
also we can check the ‘grey state’ (the parameter has no assigned value) with HasValue property (only get)

1 Like

Good morning. I have been using your Python Script in my Revit 2022 project. however, I am unable to run the graph in 2024. I got this message…

I am not familiar with Python so any help would be extremely appreciated.
Thank you :slight_smile:

Where the 3 dots on the python node are, press it and change the engine to ironpython2 maybe?

Hi pyXam, i tried all Python engine versions and I get the same warning. Thanks for the suggestion, but unfortunately it didn’t work.

Hi @hanyiwamura ,

here is the updated code

import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Import RevitAPI
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

# Import DocumentManager and TransactionManager
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Assign input to the IN variables
scheduleKeyWord = IN[0]

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument
app = uiapp.Application
sdkNumber = int(app.VersionNumber)

# Start the Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

filterView = System.Predicate[System.Object](lambda v : not v.IsTemplate and scheduleKeyWord in v.Name)
schedule = FilteredElementCollector(doc).OfClass(ViewSchedule).WhereElementIsNotElementType().ToElements().Find(filterView)


element = FilteredElementCollector(doc, schedule.Id).ToElements()

#we want as many false values as there are empty values
output = []

params = []
for i in element:
    for p in i.Parameters:
        if sdkNumber < 2022:
            type_p = p.Definition.ParameterType
            is_bool_parameter = type_p == ParameterType.YesNo
        else:
            type_p = p.Definition.GetDataType()
            is_bool_parameter = type_p == SpecTypeId.Boolean.YesNo
        if is_bool_parameter and p.AsInteger() == 0 and not p.IsReadOnly and not p.HasValue:
            p.Set(0)
            name = p.Definition.Name
            value = p.AsValueString()
            output.append([name,type_p,value])

# End the Transaction
TransactionManager.Instance.TransactionTaskDone()

# Assign your output to the OUT variable
OUT = schedule, output
1 Like

Thank you sooo much! This is such a time saver! :blush:

social_linkedin.png_185c51b9-6a4e-4d93-b595-a8fa6156f546.png

social_instagram.png_78758dd1-6b41-4645-8ffa-7ebd4c88758c.png

1 Like