Hi everyone! I’m trying to update a ColorSchemeEntry. I’ve grabbed the scheme, and the entry, and I’ve changed the color, but running scheme.UpdateEntry(entry) in a transaction doesn’t seem to do anything. I understand color schemes are updated asynchronously, so is there some way to entice Revit to update? (I've read over the api docs remarks, they're slightly confusing: ColorFillScheme Class on revitapidocs ).
Code below shows where the magic (should) happen. I’ve tested before and after the "entry.Color = DB.Color" line and the color is definitely being changed, it’s just not being updated in the scheme. I'm not getting any errors, the transaction commits, but the scheme doesn't seem to update. 🤔
scheme.CanUpdateEntry(entry) passes as well, so I’m allowed to update the entry… any ideas are welcome and appreciated! Oh yeah, this forum post got me where I am now, it was very helpful! Thanks sofia! https://forums.autodesk.com/t5/revit-api-forum/creating-color-schemes-through-the-api-revit-2022/td-...
Thanks!
with DB.Transaction(doc, 'Update {} Color'.format(entry_name)) as t:
t.Start()
entry.Color = DB.Color(color.red, color.green, color.blue)
if scheme.CanUpdateEntry(entry):
scheme.UpdateEntry(entry)
t.Commit()
Solved! Go to Solution.
Solved by sdcartmell. Go to Solution.
Some Revit database modifications do not take effect until the command has terminated.
In the worst case, some modification are ignored until Revit itself 'touches' the modified object in some way or other.
Have you found any possibility to interact with the colour scheme in the UI that triggers Revit to realise that it has been updated?
If nothing else helps, I would suggest creating a complete minimal self-contained reproducible case for the development team to analyse:
https://thebuildingcoder.typepad.com/blog/about-the-author.html#1b
Hi Jeremy,
Thanks for getting back to me and sorry for my delayed reply.
I am investigating options set the color scheme to a view in the background or to place a color scheme legend on a view before or after making the entry color change to get revit to recognize the change. I might also try deleting the old entry and creating a new entry with the new color, though that seems like an extreme workaround.
I haven't yet tried to create a minimal self-contained reproducible case as described on your website because of the dependencies I am using my script, but if I continue to hit a wall I will attempt to make a simplified macro.
If you or anyone else is interested in looking into this, here's the script workflow:
List Color Schemes for user
> User selects scheme
List Entries of selected Scheme for user
> User selects Entry to update
List set of company-vetted colors
> User selects new color for entry
Apply new color to entry and update entry in scheme
Repeat or Exit
Obviously a simplified version could just grab the first scheme and the first entry and then set the selected entry to black solid fill or something easily noticeable to demonstrate a change in the entry.
Thanks for your time.
I got it after tinkering. I totally avoided UpdateEntry as it didn't seem to actually do anything. Here's the workflow (new stuff in bold )
List Color Schemes for user
> User selects scheme
List Entries of selected Scheme for user
> User selects Entry to update
List set of company-vetted colors
> User selects new color for entry
Behind the scenes:
Collect info from old entry
Collect rooms (or spaces) that have parameter associated with entry
Clear content from Parameter in Rooms (or spaces) to free up entry so it can be removed
Remove Entry
Create New Entry with existing info and new color
Set content of Parameter in Rooms (or spaces) to associate them with Entry
Here's the python code of that Behind the Scenes bit:
with revit.TransactionGroup('Update {} Color'.format(entry_name)):
#get info from entry
sname = selected.GetStringValue()
stype = selected.StorageType
fpatId = selected.FillPatternId
#get rooms that have this entry
rooms = get_dept_match_rooms(entry_name, get_rooms())
#clear param to 'free up' entry for deletion
#transaction, exit on failure
delete_department(entry_name, rooms)
#remove entry
if scheme.CanRemoveEntry(selected):
#transaction, exit on failure
remove_entry(scheme, selected)
#make new entry with new color (or other info)
#transaction, exit on failure
make_entry(scheme, stype, fpatId, color, sname)
#set those rooms back to have correct dept
set_room_dept(rooms, entry_name) #transaction
Here is a method that you can use without needing to delete and add, but the entry can't be in use. So you would have to remove it still from Rooms, but I think that is just the name, the color I don't think would do that.
Here is how to update the color:
scheme = UnwrapElement(IN[0])
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
entries = scheme.GetEntries()
update = []
for entry in entries:
clr = Color(125,125,125)
entry.Color = clr
scheme.UpdateEntry(entry)
TransactionManager.Instance.TransactionTaskDone()
OUT = scheme
#My input here in a single ColorFillScheme
scheme = UnwrapElement(IN[0])
#Get all Entries from Scheme
entires = scheme.GetEntries()
#Empty List to store upated entries
update = []
#Loop each entry (Test Case here so all of them)
for entry in entries:
#I am trying to update the name, but othe props would be same
name = entry.GetStringValue()
name += " TEST"
#Set the New Value on the entity
entry.SetStringValue(name)
#The SetEntries() method takes a List of Entries so that why we use this
update.append(entry)
TransactionManager.Instance.TransactionTaskDone()
#This will update values of the entries including the name or color values.
OUT = scheme.SetEntries(update)
I came across this post after struggling to modify ColorFillScheme elements.
It does seem possible to update entities, even if they are in use. As spage posted - you can use the SetEntries method. The trick is to collect all entities (even if they aren't modified) in a list and use this in the argument (i.e. - colorscheme.SetEntries( colorscheme.GetEntries()) doesn't do anything).
UpdateEntry either throws an error or doesn't change anything.
Here's some example code and the results:
using (Transaction trans = new Transaction(doc, "tmp"))
{
trans.Start();
var list = new List<ColorFillSchemeEntry>();
foreach (var e in colorscheme.GetEntries())
{
var val = e.GetStringValue();
if (val == "A")
{
e.Color = new Color(255, 0, 0);
e.FillPatternId = patternid;
}
else if (val == "B")
{
e.IsVisible = false;
}
list.Add(e);
}
colorscheme.SetEntries(list);
trans.Commit();
}
Can't find what you're looking for? Ask the community or share your knowledge.