How to add schedule fields with python?

Hello I am trying to add fields to schedules of Revit, I do not have a clue how to add fields because dozens of warnings in the trial, I believe depends on the type of the parameter if it is builtin, shared,project, family shared parameter…I find it too hard so maybe someone can show some lights on that in this forum?

I ended up with a mess of code like that:

		# Define the order of the fields
		fields_order = ['Type', 'Mark', 'System Abbreviation']
		# Define a dictionary to map field names to BuiltInParameter values
		built_in_params = {
			'Type': BuiltInParameter.ELEM_TYPE_PARAM,
			'Mark': BuiltInParameter.ALL_MODEL_MARK,
			'System Abbreviation': BuiltInParameter.RBS_SYSTEM_ABBREVIATION_PARAM
		}
# Loop over each schedule
		for views_name in schedules_dict.Keys:
			schedule_data = schedules_dict[views_name]
			for schedule_name in schedule_data.Keys:
				schedule = schedule_data[schedule_name]
				schedule_def = schedule.Definition
				# Get the existing field names of the schedule
				existing_fields = [schedule_def.GetField(i).GetName() for i in range(schedule_def.GetFieldCount())]
				# Iterate through the fields order
				for field_name in fields_order:
					if field_name not in existing_fields:
						# Check if the field is schedulable
						param_elem = None
						for param_id in schedule.Parameters:
							if param_id == BuiltInParameter.INVALID:
								continue
							param_elem = doc.GetElement(ElementId(param_id.AsInteger()))
							param_ref = Reference(param)
							if param and param.Name == field_name and schedule_def.IsSchedulableField(param_ref):
								param_elem = param
								break
						if param_elem:
							# Add the field to the schedule
							if isinstance(param_elem, BuiltInParameter):
								# Handle BuiltInParameter fields
								field_index = schedule_def.AddField(param_elem)
							else:
								# Handle shared parameter fields
								shared_param = param_elem.GetDefinition().GetSharedParameter(schedule.Document)
								if shared_param:
									binding_map = schedule.Document.ParameterBindings
									param_elem_id = shared_param.Id
									if param_elem_id in binding_map:
										param_binding = binding_map[param_elem_id]
										if isinstance(param_binding, DefinitionBindingMap):
											param_def = param_binding.RevitElement
											if isinstance(param_def, SharedParameterElement):
												param_elem_id = param_def.ParameterId
									field_index = schedule_def.AddField(param_elem_id)
							schedule_def.GetField(field_index).IsHidden = False

Whilst I’m not going to get time to help specifically, some tips in future for python (on forums, and generally - this helps me too when I work this way).

  • Write a script for one element only
  • Turn that into a function
  • Loop as needed, and apply the function within the loop

This helps people on the forums as well as we don’t really need to work within the loop structure to solve the core issue that way.

At least there is an example, and the code functions used, I would need to reformulate and simplify to one item or flatten list input.

1 Like

I understand, this is more a coding tip as I can see you’re usually using Python. Typically solving it for one element is much easier versus getting stuck into loops or nested loops.

1 Like