Yes no Parameter in Schedule filter

Hi All

Can abny one help me here please to set parameter value in schedule filter via dynamo.

Been on it all day and keep getting error tried all i found but without a joy.

image

image

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


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


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


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


from System.Collections.Generic import *


# Import ToDSType(bool) extension method
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

Views = IN[0]
FieldId = IN[1]


Filters = list()
for Id in FieldId:
F = ScheduleFilter( ScheduleFieldId( Id ),ScheduleFilterType.NotEqual)
Filters.append(F)

TransactionManager.Instance.EnsureInTransaction( doc )

 for View, Filter in zip( Views, Filters):
 ( UnwrapElement( View ).Definition ).InsertFilter( Filter,0 )

TransactionManager.Instance.TransactionTaskDone()

OUT = IN[0]
1 Like

Hello,
Working with Schedules fields is a bit of track game in the Revit API :grin:

try this (this script replace a exist boolean value filter)

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

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

toDoList = lambda x : x if hasattr(x, '__iter__') else [x]
lstView = toDoList(UnwrapElement(IN[0]))
nameParaFilter = IN[1]
valueBool = IN[2]
	
def findFilter(paraName, scheduleDef):
	filterCount = scheduleDef.GetFilterCount()
	for idx in range(filterCount):
		schedFilter = scheduleDef.GetFilter(idx)
		field_Id = schedFilter.FieldId 
		field = scheduleDef.GetField(field_Id)
		if field.GetName() == paraName:
			return idx, schedFilter		
	return None, None	

TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstView:
	if v.ViewType == ViewType.Schedule:
		scheduleDef = v.Definition 
		idx, schedFilter = findFilter(nameParaFilter, scheduleDef)
		if idx is not None:
			if valueBool:
				schedFilter.SetValue(1)
			else:
				schedFilter.SetValue(0)
			scheduleDef.SetFilter(idx, schedFilter)
TransactionManager.Instance.TransactionTaskDone()		
	
OUT = lstView
2 Likes

Hi Thanks for your time.

my goal is to create filter with value as per screen shot. Is that possible??

Regards

Hi what do you mean by "per screenshot " ?

Hi thanks for your time again.

I want to create filter with dynamo. Not get filter from schedule and then change it.

I want to be able to create filter field using Yes/No parameters

image

hello
here is the script completed with the addition of a method for creating a filter

Updated code here

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

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

toDoList = lambda x : x if hasattr(x, '__iter__') else [x]
lstView = toDoList(UnwrapElement(IN[0]))
nameParaFilter = IN[1]
valueBool = IN[2]
	
def findFilter(paraName, scheduleDef):
	filterCount = scheduleDef.GetFilterCount()
	for idx in range(filterCount):
		schedFilter = scheduleDef.GetFilter(idx)
		field_Id = schedFilter.FieldId 
		field = scheduleDef.GetField(field_Id)
		if field.GetName() == paraName:
			return idx, schedFilter		
	return None, None	
	
def createFilter(paraName, scheduleDef):
	#sub foncion
	def checkField(fieldToAdd):
		fieldIds = scheduleDef.GetFieldOrder()	
		for fieldId in fieldIds:
			if scheduleDef.GetField(fieldId).GetSchedulableField() == fieldToAdd:
				return fieldId
		return None		
	#main function			
	fieldToAdd = None
	#get GetSchedulableField by Name
	lstAvailbleField = scheduleDef.GetSchedulableFields()
	for schField in lstAvailbleField:
		if schField.GetName(doc) == paraName:
			fieldToAdd = schField
			break
	#check if field is already added and find the corresponding fieldId
	fieldId = checkField(fieldToAdd)
	if fieldId is not None:
		return fieldId
	else:	
		#if not found add the corresponding field
		scheduleDef.AddField(ScheduleFieldType.Instance, fieldToAdd.ParameterId )
		doc.Regenerate()
		#then return the corresponding fieldId
		return checkField(fieldToAdd)

TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstView:
	if v.ViewType == ViewType.Schedule:
		scheduleDef = v.Definition 
		idx, schedFilter = findFilter(nameParaFilter, scheduleDef)
		if idx is not None:
			if valueBool:
				schedFilter.SetValue(1)
			else:
				schedFilter.SetValue(0)
			scheduleDef.SetFilter(idx, schedFilter)
		else:
			fieldId = createFilter(nameParaFilter, scheduleDef)
			if valueBool:
				newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 1)
			else:
				newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 0)		
			scheduleDef.AddFilter(newSchFilter)		
			
TransactionManager.Instance.TransactionTaskDone()		
	
OUT = lstView
6 Likes

Top man

Thanks!!!

Out of curiosity, can a schedule field be adjusted with a script similar to this. Say the filter is XXXX.YYY.ZZZ, and you want to change XXXX to AAAA, while leaving the .YYY.ZZZ untouched? I am just starting to generate the basics of this and just want to know if it is feasible in your opinion at least.

Hello @Mike.Meyers
It should be possible, better to start a new topic with screenshots for better understanding

1 Like

Thank you sir, let me give it some due diligence first before I open a thread. I am inexperienced enough I just wanted to make sure it was possible before spending too much time attempting it.

Hello!
I have a problem with a same type of filter but i do not manage Python. I’ve try your scrypt but i don’t know how to adapt it for my situation. Can you help me, please?
PS. Filter ID Appartment work if i start two times dynamo

Hi @k.khisamova ,
try to add a Transaction.End node

Note:
It’s better to start a new topic, than digging up an old

@c.poupin ,
Sorry, I don’t know how to start it :slight_smile:
Unforchenatly it doesn’t work


Tableau par lgt.dyn (343.4 KB)

can you share a simple Rvt file for test ?

Hello!
Here you find Simple RVT file (2022) for test
SIMPLE RVT.rvt (7.7 MB)

@k.khisamova
here is the fixed code

[image]

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

# Import DocumentManager and TransactionManager
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

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

toDoList = lambda x : x if hasattr(x, '__iter__') else [x]
lstView = toDoList(UnwrapElement(IN[0]))
nameParaFilter = IN[1]
valueBool = IN[2]
	
def findFilter(paraName, scheduleDef):
	filterCount = scheduleDef.GetFilterCount()
	for idx in range(filterCount):
		schedFilter = scheduleDef.GetFilter(idx)
		field_Id = schedFilter.FieldId 
		field = scheduleDef.GetField(field_Id)
		if field.GetName() == paraName:
			return idx, schedFilter		
	return None, None	
	
def createFilter(paraName, scheduleDef):
	#sub foncion
	def checkField(fieldToAdd):
		fieldIds = scheduleDef.GetFieldOrder()	
		for fieldId in fieldIds:
			if scheduleDef.GetField(fieldId).HasSchedulableField:
				if scheduleDef.GetField(fieldId).GetSchedulableField() == fieldToAdd:
					return fieldId
		return None		
	#main function			
	fieldToAdd = None
	#get GetSchedulableField by Name
	lstAvailbleField = scheduleDef.GetSchedulableFields()
	for schField in lstAvailbleField:
		if schField.GetName(doc) == paraName:
			fieldToAdd = schField
			break
	#check if field is already added and find the corresponding fieldId
	fieldId = checkField(fieldToAdd)
	if fieldId is not None:
		return fieldId
	else:	
		#if not found add the corresponding field
		scheduleDef.AddField(ScheduleFieldType.Instance, fieldToAdd.ParameterId )
		doc.Regenerate()
		#then return the corresponding fieldId
		return checkField(fieldToAdd)

TransactionManager.Instance.EnsureInTransaction(doc)
for v in lstView:
	if v.ViewType == ViewType.Schedule:
		scheduleDef = v.Definition 
		idx, schedFilter = findFilter(nameParaFilter, scheduleDef)
		if idx is not None:
			if valueBool:
				schedFilter.SetValue(1)
			else:
				schedFilter.SetValue(0)
			scheduleDef.SetFilter(idx, schedFilter)
		else:
			fieldId = createFilter(nameParaFilter, scheduleDef)
			if valueBool:
				newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 1)
			else:
				newSchFilter = ScheduleFilter(fieldId, ScheduleFilterType.Equal, 0)		
			scheduleDef.AddFilter(newSchFilter)		
			
TransactionManager.Instance.TransactionTaskDone()		
	
OUT = lstView
1 Like

@c.poupin ,
Thank you so much! its perfect! :blush:

1 Like