Set schedule background and text color for each cell based on cell value

Hello there,

I been trying to change the style (background and text color) of individual cells based on their value in a Revit area schedule with Python. I want the values lower than -2.0 in a red color, the values between -2.0 and 2.0 in a green color and the rest regular black.

Although I managed to get the value per cell and the style settings, adjusting the style settings changed the whole table to the new color and not just the cells I wanted to.

Does anybody know how to fix this?

Dynamo script:

Python script:

import sys
import clr

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

schedule_view = UnwrapElement(IN[0])

color_white = Autodesk.Revit.DB.Color(255,255,255)
color_black = Autodesk.Revit.DB.Color(0,0,0)
color_red = Autodesk.Revit.DB.Color(255,0,0)
color_blue = Autodesk.Revit.DB.Color(0,0,255)
color_green = Autodesk.Revit.DB.Color(0,255,0)
color_yellow = Autodesk.Revit.DB.Color(255,255,0)

# Get table data
table = schedule_view.GetTableData()
section = table.GetSectionData(SectionType.Body)
rows = section.NumberOfRows
columns = section.NumberOfColumns
output = []

def styleoptions(style, color_bg, color_tx):
	new_style = style
	override = new_style.GetCellStyleOverrideOptions()
	new_override = override
	new_override.BackgroundColor = True
	new_override.FontColor = True
	new_style.BackgroundColor = color_bg
	new_style.TextColor = color_tx
	new_style.SetCellStyleOverrideOptions(new_override)
	return new_style

for row in range(1,rows):
	cell_text = section.GetCellText(row,5) # Get Cell value
	cell_text = cell_text[:-3].replace(",",".") # Convert value to float
	try: 
		cell_text = float(cell_text)
		TransactionManager.Instance.EnsureInTransaction(doc)
		style = section.GetTableCellStyle(row,5)
		if cell_text < -2.0:
			style_new = styleoptions(style, color_white, color_red)
			section.SetCellStyle(style_new)
		elif cell_text <= 2.0:
			style_new = styleoptions(style, color_white, color_green)
			section.SetCellStyle(style_new)
		else:
			style_new = styleoptions(style, color_white, color_black)
			section.SetCellStyle(style_new)
		TransactionManager.Instance.TransactionTaskDone()
	except: cell_text = None
		
	output.append(cell_text)

OUT = output

@Bart Looks like what you are trying to perform is not yet possible through API as suggested in the posts below.

Thanks for your reply. I have seen these posts, but most of them are posted years ago, so I thought (hoped :wink:) maybe something changed in the past years.

For now I found the solution in another way, definately not ideal, but works for now. I created three seperate schedule, one for the values, one for the red colors and one for the green color. I aligned these on a sheet and voila.


I would not recommend this way, because if you change a filter in a schedule, it does not change the other schedules, but it works for now for me. Sometimes you have to be creative in Revit :slight_smile:.

1 Like