Welcome to the Revit Ideas Board! Before posting, please read the helpful tips here. Thank you for your Ideas!
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Schedule Reference Level for Pipes, Ducts, Conduit

Schedule Reference Level for Pipes, Ducts, Conduit

With the release of Revit 2020, the ability to schedule Fittings, Accessories, and Equipment by Level was added, but the "Reference Level" parameter is still not available in schedules for Pipes, Ducts, and Conduits. This should be made available so we can have the full ability to filter/group schedules by level.


This should be available for all MEP categories and when something is copied between levels it needs to update the Reference level instead of sticking to the level it was copied from which makes the schedules inaccurate.


If you're trying to schedule levels and elevations, also check out this idea:


basically: it doesn't work (properly) when you nest your family (shared) into another family. 


We can't distinguish the pipe, duct & conduit level wise in schedule for a high rise building. It will be very much helpful if we get an option in schedule to segregate the items by their reference level.

Tags (5)

@sujanc: This seems like a brilliant idea. I second it for structural items as well. It would be so useful to create structural schedules and material take-offs by building levels. Very useful for contractors and suppliers.


This is actually possible if you feel like trying a macro, and you can add a project parameter.  Here are the steps:


1.  Start the macro manager (you may have to check your security settings.)

2.  In the Macro Manager (MM) window, hit the "Create Module" button.

3. Name the module "SetMEPElevations".  (Spelling and keeping capitalization the same is critical on these names - C# is case sensitive, and close doesn't cut it.  You can also change the naming later once you get it working, if you want to.)

4.  Make sure the language is "C#" and select OK.

5.  A code window will open up.  Delete the contents and paste the following in the window:


 * Created by SharpDevelop.

 * To change this template use Tools | Options | Coding | Edit Standard Headers.
using System;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;

namespace SetMEPElevations
	public partial class ThisApplication
		private void Module_Startup(object sender, EventArgs e)


		private void Module_Shutdown(object sender, EventArgs e)


		#region Revit Macros generated code
		private void InternalStartup()
			this.Startup += new System.EventHandler(Module_Startup);
			this.Shutdown += new System.EventHandler(Module_Shutdown);
		public void SetMEPElevationsMacro()
					//Get references to revit and the current open file
			UIDocument uidoc = this.ActiveUIDocument;
            Document doc = this.ActiveUIDocument.Document;
            int n = 0;
            //get all the conduits
            ElementClassFilter conduitFilter = new ElementClassFilter(typeof(Conduit));
            ElementCategoryFilter conduitCategoryfilter = new ElementCategoryFilter(BuiltInCategory.OST_Conduit);
            LogicalAndFilter conduitInstancesFilter = new LogicalAndFilter(conduitFilter, conduitCategoryfilter);
			//get all the pipes
			ElementClassFilter ductFilter = new ElementClassFilter(typeof(Pipe));
			ElementCategoryFilter pipeCategoryfilter = new ElementCategoryFilter(BuiltInCategory.OST_PipeCurves);
            LogicalAndFilter pipeInstancesFilter = new LogicalAndFilter(ductFilter, pipeCategoryfilter);
			//get all the ducts
			ElementClassFilter pipeFilter = new ElementClassFilter(typeof(Duct));
            ElementCategoryFilter ductCategoryfilter = new ElementCategoryFilter(BuiltInCategory.OST_DuctCurves);
            LogicalAndFilter ductInstancesFilter = new LogicalAndFilter(pipeFilter, ductCategoryfilter);
			//Combine the three filters
			LogicalOrFilter conduitsandPipesFilter = new LogicalOrFilter (conduitInstancesFilter, pipeInstancesFilter);
			LogicalOrFilter allItemsFilter = new LogicalOrFilter (conduitsandPipesFilter, ductInstancesFilter);
			//put the items in a collector
			FilteredElementCollector collector = new FilteredElementCollector(doc);
			ICollection<ElementId> allIds = collector.WherePasses(allItemsFilter).ToElementIds();	
			//TaskDialog.Show("All Items size", allIds.Count.ToString());
			//Go through each item in the lists
			Transaction myTransaction = new Transaction(doc);
            myTransaction.Start("Set Conduit Elevations");
            foreach (ElementId id in allIds)
            		//Get the element from the id
					Element e = doc.GetElement(id);
                    //Get the elements level        
                	String ConduitElevationString = e.get_Parameter(BuiltInParameter.RBS_START_LEVEL_PARAM).AsValueString();
					//Get the Project Parameter for the current element
                	Parameter ConduitElevationParam = e.LookupParameter("MyConduitElevation");
                	//if the elevation is vaild, then set the project parameter to the elements level;
                	if (ConduitElevationString != null)
            	catch (Exception ex)
            		//something went wrong with an element - skip that element and continue
       			}//end foreach
               if (n != 0)
               	string mymessage = "There were " + n.ToString () + " elements that could not have their elevation set.";
               	TaskDialog.Show("Revit Macro Message", mymessage);
	}//end partial class
}//end namespace

6.  On the "Build Menu" (in the code window) select build solution.  You will get a warning, but you should not get any errors. (Tested on revit 2018-2020)

7.  Go back to the macro manager window, and highlight the "SetMEPElevationsMacro".  The run button should be enabled.  Press run, and you should get a message that X number of elevations could not be set.   Press OK.  Don't worry about the message box - that means the code is working and the hard part is done.

8.  Now we have to make a project parameter.  Again spelling and capitalization is critical.  It has to be called MyConduitElevation to match the code.  (If you want to change the name later, you can, but you have to change the macro code to match.

8A.  Select project paramaters under the manage tab. 

8B.  Select "Add".   Name the parameter as noted above.  Select  "Project Parameter",  "Text"  for the type, and select "Values can vary by group instance".  IN the Categories list, select "conduits", "ducts", and "pipes".  (See the example window image I've attached.)

8C.  Select OK.

9.  Now you can add the "MyConduitElevation" parameter to your schedules. If you go to the edit fields, it will appear in the drop down list.

10.  They will all be empty to start, but if you run the macro again, it should fill in all the elevations, and you shouldn't get a message box that says elevations couldn't be set.


If you change elevations, or add more items, you will have to re-run the macro.  But that's pretty easy.  On a file with 5000 items, it took about 30 seconds to run the first time, and it only took about 5 seconds to update a few changed elevations. 


You will have to add the project parameter to every file you use this in, so you might want to add it in your template.


Let me know if this helps out.  




I couldn't attach the images in the idea forum.   So I started another post here:


Community Visitor

how create a duct schedule per floor?

Status changed to: Accepted

Congrats! We think this is a great idea, so we've decided to add it to our roadmap. Thanks for the suggestion!


The Factory


@kimberly.fuhrman thank you for the update


Yes, the Level parameter is really necessary in a pipe schedule.
And if the pipe and pipe fitting can be scheduled in one table, it would be better. So as duct and duct fitting, cable tray , conduit.

Status changed to: Implemented

We are pleased to say that this has been implemented in Revit 2023! Thank you for your contribution to improving Revit!

 -The Factory


Why did cable trays end up left out?!

Can't find what you're looking for? Ask the community or share your knowledge.

Submit Idea  

Forma Design Contest

Technology Administrators