Rerun addin problem

Rerun addin problem

nia98bim
Enthusiast Enthusiast
324 Views
1 Reply
Message 1 of 2

Rerun addin problem

nia98bim
Enthusiast
Enthusiast

Hey, I'm trying to create add-in to the crate level with a specific name, in the first run in Revit it works well but the second time, it gives an error that Revit couldn't complete the external command.

 

I thought it was because of the unique level name, but I didn't know how can I handle it. 

using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
using System.Diagnostics;
using System;
using Clel.Properties;
using System.Collections.Generic;
using System.Linq;

namespace Clel
{
    [Transaction(TransactionMode.Manual)]
    public class Class1 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            var uiapp = commandData.Application;
            var uidoc = uiapp.ActiveUIDocument;
            var app = uiapp.Application;
            var doc = uidoc.Document;


            //add form
            Form1 fr1 = new Form1(commandData);
            fr1.ShowDialog();


            //add form items
            string stringlevelheighvalue = fr1.levelheigh.ToString();
            double intvaluelevel = double.Parse(stringlevelheighvalue);
            ///////////////////////////////////////////////////////////////////
            string stringlevelquantityvalue = fr1.levelquantity.ToString();
            int levaluequantity = int.Parse(stringlevelquantityvalue);
            string Stringdecipline = fr1.Dropitem;

            string std = "";



            if (Stringdecipline == "Architecture")
            {
                std = "ARC";
            }
            else if (Stringdecipline == "Structure")
            {
                std = "STR";

            }
            else if (Stringdecipline == "Mechanical")
            {
                std = "MEP";
            }


            //picklevel

            FilteredElementCollector coll = new FilteredElementCollector(doc)
                .OfCategory(BuiltInCategory.OST_Levels)
                .WhereElementIsNotElementType().
                OfClass(typeof(Level));
            //
            List<Level> levels = coll.Cast<Level>().ToList();
            Level highestLevel = levels.OrderByDescending(l => l.Elevation).FirstOrDefault();


            string highestLevelName = highestLevel.Name;
            string levelBaseName = highestLevelName.Replace("Level", "").Trim();
            int existlvlname = int.Parse(levelBaseName);

            //



            List<double> levelElevations = new List<double>();
            foreach (Level lvl in coll)
            {
                levelElevations.Add(lvl.Elevation);
            }


            double highestElevationInFeet = levelElevations.Max();




            //double elevationInMeters = 12.0;
            //double elevationInFeet = elevationInMeters * 3.28084;
            double elevationinmeter = highestElevationInFeet;
            double levelvaluemeter = intvaluelevel * 3.28084;


            using (Transaction tx = new Transaction(doc))
            {


                tx.Start("Bouttn name");
                //
                for (int i = 0; i < levaluequantity; i++)
                {

                    elevationinmeter += levelvaluemeter;

                    Level newlevel = Level.Create(doc, elevationinmeter);

                    string levelName = $"{std}_Level {i + 1 + existlvlname}";

                    newlevel.Name = levelName;

                }




                tx.Commit();


                return Result.Succeeded;


            }
        }

    }
}

 

I really appreciated if you help me to create my  addin.

 

 

 

 

 

0 Likes
Accepted solutions (1)
325 Views
1 Reply
Reply (1)
Message 2 of 2

TripleM-Dev.net
Advisor
Advisor
Accepted solution

Hi @nia98bim,

 

It's hard to follow what the addin supposed to do, seems it adds a level above the highest one with a certain name from a dialog with some input and a from a levelname along with a piece of the name of the highest level.

 

From the first pass it creates a level with a name like "ARC_level <nr>...."

The second pass would have this name above as the highest level, so the line below would fail:

 

 

 int existlvlname = int.Parse(levelBaseName);

 

 

As now levelBaseName  only removes "Level" and not the "ARC_" before it.

 

I suggest writing down what the steps in the addin support to be (not the actual needed code!)

And in this case, create a list of level names desired before and after.

 

Maybe split the string name after the text part "Level"?, and only keep the number at the then end...

 

Also, the code below can be optimized with linq, but is actually not needed.

You already have the highest level, why iterate them again and take the highest value.

 

 

List<double> levelElevations = new List<double>();
foreach (Level lvl in coll)
{
    levelElevations.Add(lvl.Elevation);
}
double highestElevationInFeet = levelElevations.Max();

 

 

the line below is already the highest level (which subnumber has to used?) so why not take also it's elevation directly?

 

Level highestLevel = levels.OrderByDescending(l => l.Elevation).FirstOrDefault();

 

 

Also don't convert units manually, use the Utils in the Revit API: ConvertToInternalUnits Method 

 

- Michel