Schedulefilter.FieldId

I’m trying to collect the filtering on schedules by the standard nodes.
The node Schedulefilter.FieldId does not seem to work properly.

As you can see on the image The field numbers do not match the fields index number, but they do match the fields in revit ofcourse.

The only thing I can Imagine is that somewhere the lists went corrupt by being thrown from project to project … +2000
The amount of project parameters available on this particular document is imense though …

Someone please help me. I’m new and try to use as much standard nodes as possible to get going.

It is because at some point (when the filter was applied) there were values in the schedule. As fields are removed, the ID of the filter stays.

FieldId does not relate to index or column position. It’s just an identifier based on how many parameters have been added to the schedule. In fact, if you add Param1 and Param2 to your schedule as Ids 0 and 1, if you removed and re-added Param2, it would actually get a new Id of 3.

1 Like

Ok. So the message will be to dig into the API and fetch some usefull parameters compared to thos guy. Can i collect the code behind a standard node to start from here?

| Nick_Boyts Regular
December 7 |

  • | - |

FieldId does not relate to index or column position. It’s just an identifier based on how many parameters have been added to the schedule. In fact, if you add Param1 and Param2 to your schedule as Ids 0 and 1, if you removed and re-added Param2, it would actually get a new Id of 3.

You cannot access the code in a standard node. I’d start with the API member for ScheduleFilters.
https://www.revitapidocs.com/2020/2c2fc999-859e-169b-d958-ee248d9d74b7.htm

That’s what I meant. But there’s a code behind a node, right? I’ll dog into it further. Thx for the reply

| Nick_Boyts Regular
December 7 |

  • | - |

You cannot access the code in a standard node. I’d start with the API member for ScheduleFilters.
https://www.revitapidocs.com/2020/2c2fc999-859e-169b-d958-ee248d9d74b7.htm

Not really sure why, but I was not able to get the DB element from the Fields Node and therefore none of the Methods or properties I tried to get after was working. @solamour

I ended up doing all of it in python to get the Name, Field Id, and Field Index for the values in a schedule. With these things you should be able to get the relationship you are after.

schedule fields.dyn (19.4 KB)

I need this to work on all of my schedules at once.
Input for this schedul

So in fact I need a list of my listed schedules and not from 1 index.
How do I embed this in a Python script?

I’ve tried the following:

  1. change UnwrapElement to UnwrapElements
  2. try to create a map on the output map(elements (but the script seems to only take 1 index as an input, really)
  3. in the OUT I tried to state element, element,[f.FieldId for f in fields], but also only works on 1 element.
    image

I guess this is something basic I don’t understand about coding and you encounter a lot if you do so.

Hope someone can help me here just as quickly!

You have to loop through each schedule individually as an input and as its collected output(s).

For one schedule:

schedule = UnwrapElement(IN[0])
     *do stuff to schedule*
OUT = *schedule output*

For multiple schedules:

schedules = UnwrapElement(IN[0])
output = []
for schedule in schedules:
     *do stuff to schedule*
     output.append(*schedule outputs*)
OUT = output
3 Likes

Hi,
as DB.ScheduleField doesn’t inherit from DB.Element I don’t think UnwrapElement() is useful
I found 2 solutions in this particular case

  • using the property Name of Revit.Schedules.ScheduleField

  • using the internal property ‘InternalScheduleField’ of ‘Revit.Schedules.ScheduleField’ to get DB.ScheduleField object with Reflection, then using GetName()
    It’s not ideal, but it’s a solution

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

lstscheduleField = IN[0]
e = lstscheduleField[0]
invokeObj = clr.GetClrType(e.GetType()).InvokeMember('InternalScheduleField', 
                                                    BindingFlags.InvokeMethod | \
                                                    BindingFlags.GetProperty | \
                                                    BindingFlags.Instance | \
                                                    BindingFlags.Public | \
                                                    BindingFlags.NonPublic, 
                                                    None, 
                                                    e, 
                                                    None)
OUT = invokeObj.GetType(), invokeObj.GetName()
2 Likes

Hi Nick,
I made this out of your answer. Have been searching for quite some time to see the logic but maybe I need basic coding insight :expressionless:

#Preparing input from dynamo to revit
items = UnwrapElement(IN[0])
element = UnwrapElement(items)

#Do some action in a Transaction
output = []
	for element in items:
		TransactionManager.Instance.EnsureInTransaction(doc)
		order = element.Definition.GetFieldOrder()
		fields = [element.Definition.GetField(o) for o in order]
		TransactionManager.Instance.TransactionTaskDone()
	output.append([f.FieldId for f in fields])

OUT = output

As the error says, you have an unnecessary indent. You only indent what’s inside the loop, so you don’t need to indent the for element in items: line.

Thanks for the informatoin @c.poupin, great work as always!
I think i would rather just use a quick filtered element collector and avoid the issue. :smiley:

2 Likes

Here is how you can get what you are after

#Sean Page
#https://www.linkedin.com/in/sean-page-aia-ncarb-leed-ap-b06b0041/
#2021
import clr

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

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *

clr.AddReference('System')
from System.Collections.Generic import List

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

#Preparing input from dynamo to revit
schedules = UnwrapElement(IN[0])
fieldIds = []
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)
for schedule in schedules:
    order = schedule.Definition.GetFieldOrder()
    fields = [schedule.Definition.GetField(o) for o in order]
    fieldIds.append([f.FieldId for f in fields])

TransactionManager.Instance.TransactionTaskDone()

OUT = fieldIds

1 Like

Not by far what it needs to be.
I expect a list with sublists instead of a list on 1 element as in FieldID in the image.

Still Thanks for looking at this thread!

Look at my response. The output.append line needs to be indented. Right now your only getting a list of the last schedule, not a list of lists.

1 Like

Thanks guys!