I have two code samples and I don't know why one of them works and the other doesn't

I have two code samples and I don't know why one of them works and the other doesn't

danail.momchilov
Contributor Contributor
370 Views
3 Replies
Message 1 of 4

I have two code samples and I don't know why one of them works and the other doesn't

danail.momchilov
Contributor
Contributor

Hi! I have rewritten the code snippet to solve my issue already, but I still can't find the reason why the previous one didn't work and it's driving me crazy 😄 so if anyone can find the issue, it would be amazing! 

 

So I'm working a plug in that automatically sets area parameters and makes all the calculations for common areas, common area percentages, gross areas, etc. 

 

I have created a simple method, that is searching for 'secondary' areas, whose area should be summed up with the main one. A good example would be this case:

 

danailmomchilov_0-1704964941491.png

 

which is a terrace, whose area should be added to the one of the ground floor apartment. In this case, the area of the terrace should summed up with the one of the apartment and written into this parameter:

danailmomchilov_1-1704965031435.png

 

So I first used this method:

 

        public string calculatePrimaryArea()
        {
            string errorMessage = "";
            List<string> missingNumbers = new List<string>();

            transaction.Start();
            
            foreach (Area mainArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
            {
                mainArea.LookupParameter("A Instance Gross Area").Set(mainArea.LookupParameter("Area").AsDouble());
            }

            foreach (Area secondaryArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
            {
                bool wasfound = false;
                
                if (secondaryArea.LookupParameter("A Instance Area Primary").HasValue && secondaryArea.LookupParameter("A Instance Area Primary").AsString() != "" && secondaryArea.Area != 0)
                {
                    foreach (Area mainArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
                    {
                        if (secondaryArea.LookupParameter("A Instance Area Primary").AsString() == mainArea.LookupParameter("Number").AsString())
                        {
                            double sum = mainArea.LookupParameter("A Instance Gross Area").AsDouble() + secondaryArea.LookupParameter("Area").AsDouble();

                            bool wasSet = mainArea.LookupParameter("A Instance Gross Area").Set(sum);

                            wasfound = true;

                            // test

                            errorMessage += $"An area of: {secondaryArea.LookupParameter("Area").AsDouble()/areaConvert} is added to the one of Area Number: {mainArea.Number}, " +
                                $"whioch is at the moment: {mainArea.Area/areaConvert}! The total sum is {secondaryArea.LookupParameter("Area").AsDouble() / areaConvert + mainArea.Area / areaConvert}\n" +
                                $"calculated sum = {sum/areaConvert}\ncalculated sum in imperial = {sum}\nwasSet = {wasSet}\n" +
                                $"value for A Instance Gross Area after being set: = {mainArea.LookupParameter("A Instance Gross Area").AsDouble()}\n" +
                                $"the secondary Area object, added to the main one, has a number {secondaryArea.Number} and an Id: {secondaryArea.Id}\n\n";

                            // test
                        }
                    }

                    if (!wasfound && !missingNumbers.Contains(secondaryArea.LookupParameter("Number").AsString()))
                    {
                        missingNumbers.Add(secondaryArea.LookupParameter("Number").AsString());
                        errorMessage += $"Грешка: Area {secondaryArea.LookupParameter("Number").AsString()} / id: {secondaryArea.Id} / Посочената Area е зададена като подчинена на такава с несъществуващ номер. Моля, проверете го и стартирайте апликацията отново\n";
                    }
                }
            }
            
            transaction.Commit();

            return errorMessage;
        }

 

As you can see, I have created a very informative report message in order to check if everything is alright. I would then set the parameter value to 0 and run the plugin:

danailmomchilov_2-1704965452647.png

 

Based on that, it seems that everything should be alright and even the parameter value, when read directly from the area instance, should be properly set:

danailmomchilov_3-1704965579775.png


However, when you select the area in Revit, the value of the parameter seems to somehow have reverted back to its previous value 😄 

danailmomchilov_4-1704965627626.png


If I then write the method in this way:

        public string calculatePrimaryArea()
        {
            string errorMessage = "";
            List<string> missingNumbers = new List<string>();

            transaction.Start();
            
            foreach (Area mainArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
            {
                mainArea.LookupParameter("A Instance Gross Area").Set(mainArea.LookupParameter("Area").AsDouble());

                foreach (Area secArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
                {
                    if (secArea.LookupParameter("A Instance Area Primary").AsString() == mainArea.LookupParameter("Number").AsString() && secArea.LookupParameter("A Instance Area Primary").HasValue && secArea.Area != 0)
                    {
                        double sum = mainArea.LookupParameter("A Instance Gross Area").AsDouble() + secArea.LookupParameter("Area").AsDouble();
                        mainArea.LookupParameter("A Instance Gross Area").Set(sum);
                    }
                }
            }

            foreach (Area secArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
            {
                if (secArea.LookupParameter("A Instance Area Primary").HasValue && secArea.LookupParameter("A Instance Area Primary").AsString() != "" && secArea.Area != 0)
                {
                    bool wasFound = false;

                    foreach (Area mainArea in new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Areas).WhereElementIsNotElementType().ToList())
                        if (secArea.LookupParameter("A Instance Area Primary").AsString() == mainArea.LookupParameter("Number").AsString())
                            wasFound = true;

                    if (!wasFound && !missingNumbers.Contains(secArea.LookupParameter("Number").AsString()))
                    {
                        missingNumbers.Add(secArea.LookupParameter("Number").AsString());
                        errorMessage += $"Грешка: Area {secArea.LookupParameter("Number").AsString()} / id: {secArea.Id} / Посочената Area е зададена като подчинена на такава с несъществуващ номер. Моля, проверете го и стартирайте апликацията отново\n";
                    }
                }
            }

            transaction.Commit();

            return errorMessage;
        }


And now it actually works:

danailmomchilov_5-1704966046908.png

 

I just don't see any essential difference between the two and I would not get a proper nights sleep until I find out why the first one didn't work 😄 

 

0 Likes
371 Views
3 Replies
Replies (3)
Message 2 of 4

studio-a-int
Advocate
Advocate

Probably the parameter value is not set, because the boolean you have on this line:

bool wasSet = mainArea.LookupParameter("A Instance Gross Area").Set(sum);

since execution is guaranteed, set the bool manually, change your code like:

mainArea.LookupParameter("A Instance Gross Area").Set(sum);
bool wasSet = true;

Message 3 of 4

danail.momchilov
Contributor
Contributor

Hi, thank you for your suggestion!

 

I am afraid this is not the reason, as it was just like you mentioned in the beginning. It is a standard way to check if the parameter was set in the API. Here's some info on the method:

danailmomchilov_0-1705046447305.pngdanailmomchilov_1-1705046462254.png

 

0 Likes
Message 4 of 4

jeremy_tammik
Alumni
Alumni

I would try to clean up and simplify the code before looking further at it. I avoid the use of LookupParameter, and especially making use of it several times over to retrieve the same parameter object, cf., optimising setting shared parameters:

  

  

I find code easier to read and understand the shorter and more legible it is.

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes