Quick way to renumber doors, grids, and family instances

A friend asked about a macro to renumber grids in the order they are picked. Here’s how:


public void renumberByPicks()
{
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;

    // list that will contain references to the selected elements
    IList<Reference> refList = new List<Reference>();
    try
    {
        // create a loop to repeatedly prompt the user to select an element
        while (true)
            refList.Add(uidoc.Selection.PickObject(ObjectType.Element, "Select elements in order to be renumbered. ESC when finished."));
    }
    // When the user hits ESC Revit will throw an OperationCanceledException which will get them out of the while loop
    catch
    {}

    using (Transaction t = new Transaction(doc,"Renumber"))
    {
        t.Start();
        // need to avoid encountering the error "The name entered is already in use. Enter a unique name."
        // for example, if there is already a grid 2 we can't renumber some other grid to 2
        // therefore, first renumber everny element to a temporary name then to the real one
        int ctr = 1;
        int startValue = 0;
        foreach (Reference r in refList)
        {
            Parameter p = getParameterForReference(doc, r);

            // get the value of the first element to use as the start value for the renumbering in the next loop
            if (ctr == 1)
                startValue = Convert.ToInt16(p.AsString()); 

            setParameterToValue(p, ctr + 12345); // hope this # is unused (could use Failure API to make this more robust
            ctr++;
        }

        ctr = startValue;
        foreach (Reference r in refList)
        {
            Parameter p = getParameterForReference(doc, r);
            setParameterToValue(p, ctr);
            ctr++;
        }
        t.Commit();
    }

}
private Parameter getParameterForReference(Document doc, Reference r)
{
    Element e = doc.GetElement(r);
    Parameter p = null;
    if (e is Grid)
        p = e.get_Parameter("Name");
    else if (e is Room)
        p = e.get_Parameter("Number");
    else if (e is FamilyInstance)
        p = e.get_Parameter("Mark");
    else
    {
        TaskDialog.Show("Error","Unsupported element");
        return null;
    }
    return p;
}        
private void setParameterToValue(Parameter p, int i)
{
    if (p.StorageType == StorageType.Integer)
        p.Set(i);
    else if (p.StorageType == StorageType.String)
        p.Set(i.ToString());    
}

22 thoughts on “Quick way to renumber doors, grids, and family instances

  1. Hi Harry, can you suggest how to improve this code to include the Viewport > Detail Number? I can’t seem to find the string in 2012 API Guide.

    Is it:
    else if (e is ViewSheetSetting)
    p = e.get_Parameter(“Detail Number”);

    ???

    Thanks

    Jeff

  2. Hi Harry,
    Is it possible to add an if else statement before the FamilyInstance that would allow me to select a different shared parameter in the Mechanical Equipment category only before it goes over to all FamilyInstance? I was not able to get it to go beyond BuiltInCategory to select this.

  3. Is it possible to increment numbers that contain other characters? For instance our equipment might be 01-100 or A1111 depending on the client’s standard.

  4. Harry,

    I am trying to build this solution in 2016. it is giving me 9 build errors under the Private Parameter getParameterForReference. the errors occur in the e.get & “Name” as well as (e is Room)

    Thanks,

    • Autodesk has removed get_Parameter from the API. To replace it you can do something like this:
      element.GetOrderedParameters().FirstOrDefault(q => q.Definition != null && q.Definition.Name == “Parameter Name”);

      • Harry,

        thanks for the update. I am new to the API and have only done a few simple macros before.

        I am still getting 3 errors. they are being highlighted at element.

        private Parameter getParameterForReference(Document doc, Reference r)
        {
        Element e = doc.GetElement(r);
        Parameter p = null;
        if (e is Grid)
        p = element.GetOrderedParameters().FirstOrDefault(q => q.Definition != null && q.Definition.Name == “Name”);
        else if (e is FamilyInstance)
        p = element.GetOrderedParameters().FirstOrDefault(q => q.Definition != null && q.Definition.Name == “Mark”);
        else if (e is Viewport)
        p = element.GetOrderedParameters().FirstOrDefault(q => q.Definition != null && q.Definition.Name == “Detail Number”);
        else
        {
        TaskDialog.Show(“Error”,”Unsupported element”);
        return null;
        }
        return p;
        }

          • Harry,

            I am trying to convert this into now an Addin, also i have it only set to renumber viewports.

            i keep getting an error in “ObjectType.” inaccessible due to its protection level

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Threading.Tasks;
            using Autodesk.Revit.DB;
            using Autodesk.Revit.UI;
            using Autodesk.Revit.Attributes;

            namespace Renumber_Viewports
            {
            [Transaction(TransactionMode.Manual)]

            public class renumberByPicks : IExternalCommand
            {
            static AddInId appId = new AddInId(new Guid(“47BDCF1C-9647-40C8-9B16-98E217F76444”));
            public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elementSet)
            {
            UIDocument uidoc = commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;

            // list that will contain references to the selected elements
            IList refList = new List();
            try
            {
            // create a loop to repeatedly prompt the user to select an element
            while (true)

            refList.Add(uidoc.Selection.PickObject(ObjectType.Element, “Select elements in order to be renumbered. ESC when finished.”));
            }
            // When the user hits ESC Revit will throw an OperationCanceledException which will get them out of the while loop
            catch
            { }

            using (Transaction t = new Transaction(doc, “Renumber”))
            {
            t.Start();
            // need to avoid encountering the error “The name entered is already in use. Enter a unique name.”
            // for example, if there is already a grid 2 we can’t renumber some other grid to 2
            // therefore, first renumber everny element to a temporary name then to the real one
            int ctr = 1;
            int startValue = 0;
            foreach (Reference r in refList)
            {
            Parameter p = getParameterForReference(doc, r);

            // get the value of the first element to use as the start value for the renumbering in the next loop
            if (ctr == 1)
            startValue = Convert.ToInt16(p.AsString());

            setParameterToValue(p, ctr + 12345); // hope this # is unused (could use Failure API to make this more robust
            ctr++;
            }

            ctr = startValue;
            foreach (Reference r in refList)
            {
            Parameter p = getParameterForReference(doc, r);
            setParameterToValue(p, ctr);
            ctr++;
            }
            t.Commit();
            }

            }
            private Parameter getParameterForReference(Document doc, Reference r)
            {
            Element e = doc.GetElement(r);
            Parameter p = null;
            if (e is Viewport)
            p = e.GetOrderedParameters().FirstOrDefault(q => q.Definition != null && q.Definition.Name == “Detail Number”);
            else
            {
            TaskDialog.Show(“Error”, “Unsupported element”);
            return null;
            }
            return p;
            }
            private void setParameterToValue(Parameter p, int i)
            {
            if (p.StorageType == StorageType.Integer)
            p.Set(i);
            else if (p.StorageType == StorageType.String)
            p.Set(i.ToString());

            return Result.Succeeded;

            }

            }
            }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s