Makro w Revicie opisujące rzędną osi otworu

0

Cześć,
mam napisane makro dla programu Revit prawdopodobnie w C# przez poprzedniego pracownika (niestety ja nie programuje).
Jego zadaniem było opisanie rzędnej osi otworów w całym modelu. W wersji polskiej działa fajnie, jednak w wersji angielskiej coś sie wysypało i zaczął uzupełniać wartość 0,00 zamiast rzeczywistej wartości.

screenshot-20230222131706.png

screenshot-20230222131726.png

Poniżej przesyłam kod:

/*
 * Created by SharpDevelop.
 * User: xxx
 * Date: 2020-01-15
 * Time: 14:29
 * 
 * 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;

namespace ElevationParameterENU
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("35453963-A3B1-4F75-9656-3149B8DA9BD0")]
	public partial class ThisDocument
	{
		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);
		}
		#endregion
		public void OpeningTag()
		{
            
            //UIDocument uidoc = ActiveUIDocument;
            Document doc = this.Application.ActiveUIDocument.Document;
            
            
            // 1. All Generic Instances
            ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_GenericModel);
            IList<Element> instanceList = new FilteredElementCollector(doc).WherePasses(filter).WhereElementIsNotElementType().ToElements();

            // To select and count instances at completion
            IList<ElementId> toSelect = new List<ElementId>();
            long count = 0;

            // 2. Conditioned Instances            
            foreach (Element ins in instanceList)
            {                
                
                double elevation = 0;
                IList<bool> flag = new List<bool>();
                bool heightIsAvailable = false;
                bool BasedLevelIsAvailable = false;
                ParameterSet paramSet = ins.Parameters; 

                foreach (Parameter param in paramSet)
                {
                    
                    if (param.Definition.Name.Equals("Elevation"))
                    {
                        elevation = param.AsDouble();
                    }
                }
                // The separation of the two loops is necessary to avoid confusion in taking parameter value
                foreach (Parameter param in paramSet)
                {
                    if (heightIsAvailable = BasedLevelIsAvailable = true && param.Definition.Name.Equals("Oś otworu")) // "Oś otworu" - custom instance parameter"
                    {
                        using (Transaction t = new Transaction(doc, "Set parameters value"))
                        {
                            t.Start();
                            param.Set(elevation);
                            t.Commit();
                            count += 1;
                            flag.Add(true);
                        }
                    }
                }                
                if (flag.Contains(true))
                {
                    toSelect.Add(ins.Id);
                }
            }
            // 4. Report 
            if (toSelect.Count > 0)
            {
                TaskDialog.Show("Wykonano na " + count + " otworach", "Zakończono: Rzędna - oś otworu - otwór okrągły oraz otwór prostokątny");
            }
            else
            {
                TaskDialog.Show("Revit", "Nie znaleziono obiektów");
            }
            UIDocument uidoc = new UIDocument(doc);
            uidoc.Selection.SetElementIds(toSelect);
            }
	}
}

Czy miałby ktoś z Was pomysł dlaczego mogło przestać działać? :)
Wielka prośba o pomoc - kierownictwo wymaga abym to naprawił (pomimo że nie programuje - na forum Revita nikt mi nie pomógł).

3

W tej linijce jest szukany parametr o polskiej nazwie - stąd problem z angielską wersją

if (heightIsAvailable = BasedLevelIsAvailable = true && param.Definition.Name.Equals("Oś otworu"))
0
mar-ek1 napisał(a):

W tej linijce jest szukany parametr o polskiej nazwie - stąd problem z angielską wersją

if (heightIsAvailable = BasedLevelIsAvailable = true && param.Definition.Name.Equals("Oś otworu"))

Tak to prawda, też na początku na to zwróciłem uwagę. Dzieje się tak ze względnu na to ze otwór który opisuje makro jest rodziną w revicie i posiada parametry w języku polskim:
screenshot-20230223084402.png

Wiec to niestety nie to :/

1

@Krzysiek Nowak:

W wersji polskiej działa fajnie, jednak w wersji angielskiej coś sie wysypało i zaczął uzupełniać wartość 0,00 zamiast rzeczywistej wartości.

Parsowanie liczb po polsku z przecinkiem / amerykańsku / międzynarodowemu ?

Szerszy kontekst niezupełnie mi się widzi ....
Jeśli to dialekt C#, to BARDZO zdzwiony jestem
if (heightIsAvailable = BasedLevelIsAvailable = true && param.Definition.Name.Equals("Oś otworu")) // "Oś otworu" - custom instance parameter"

To powinno rzucać błędem

Po drugie Equals("String") pachnie doświadczeniami javowskimi a nie C#.
Porónianie czegkolwiek do true mi źle pachnie w każdym jezyku.

Osobiście prosze:
inżynierowie innych branż: postawcie nam po znajomości czasem jakas kawę, tak raz na kwartał, za zerkniecie lewym okiem do kodu, czy nie narastają problemy. Sam tak pomagałem elektronikowi mikroprocesorowcowi. Wydał dobrowolnie najlepiej w życiu wydane 50zł (mielismy dzieci we wspólnej szkole)

0
ZrobieDobrze napisał(a):

@Krzysiek Nowak:

W wersji polskiej działa fajnie, jednak w wersji angielskiej coś sie wysypało i zaczął uzupełniać wartość 0,00 zamiast rzeczywistej wartości.

Parsowanie liczb po polsku z przecinkiem / amerykańsku / międzynarodowemu ?

Nie rozumiem niestety, coś w kodzie trzeba by zmienić?
Jedyna moja styczność z programowaniem to podstawy programowania wizualnego w Dynamo (i 2 kody w pythonie PRZEROBIŁEM tak aby mi działało) tak to jestem totalnym laikiem :(

1

@Krzysiek Nowak:

Nie widzę w tym kodzie gotowego takiego miejsca - ale zeznania pięknie pasują do takiej interpretacji (liczby zmiennoprzecinkowe się psują po zmianie ust. miedzynarodowych)

Jedyne co ma zapach przetwarzania double to
param.AsDouble();

Ale nie mam pojęcia co to u was param i jakie wzorce zrobienia tego poprawnie w waszym ekosystemie sa proponowane

edit: swoją drogą, program ma jakieś okno błędów, log, coś podobnego ?

0
ZrobieDobrze napisał(a):

@Krzysiek Nowak:

Nie widzę w tym kodzie gotowego takiego miejsca - ale zeznania pięknie pasują do takiej interpretacji (liczby zmiennoprzecinkowe się psują po zmianie ust. miedzynarodowych)

Jedyne co ma zapach przetwarzania double to
param.AsDouble();

Ale nie mam pojęcia co to u was param i jakie wzorce zrobienia tego poprawnie w waszym ekosystemie sa proponowane

edit: swoją drogą, program ma jakieś okno błędów, log, coś podobnego ?

Tylko:
screenshot-20230223093305.png

0

Dodam że próbowałem to konsultować z chatgpt i podsunął coś takiego co niewiele mi mówi:
screenshot-20230223094828.png

1

@Krzysiek Nowak:

Dokładnie to samo stawiam w hipotezie. Nie jest read correctly - po zmianie narodowości - przez format liczby rozumianej jako sekwencja znaków.

I tak samo widzę potrzebę "try debugging" tyle że nie ma pojęcia o środowisku

0

O proszę, po tylu latach jakiś problem Revitowy się pojawił tutaj na forum, może wreszcie Revit zaczyna się mocniej przebijać w Polsze :D.

Do każdego problemu z Revitem, dobrze dołączyć minimalny model na którym można powtórzyć dany błąd, czyli w tym przypadku zawierający problematyczną rodzinę i tag, czy jak to tam się po polsku nazywa.

to powinno działać pod revitem 2023:

public void OpeningTag()
{			
    Document doc = this.ActiveUIDocument.Document;
    IList<Element> genericModels = new FilteredElementCollector(doc).WhereElementIsNotElementType().OfCategory(BuiltInCategory.OST_GenericModel).ToElements();
    IList<ElementId> toSelect = new List<ElementId>();           
    
    using (Transaction t = new Transaction(doc, "Set parameters value"))
    {
        t.Start();
     
        foreach (Element element in genericModels)
        {  
            double elevation = 0;
        
           var elevationParam = element.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
           if  ((elevationParam != null) && (elevationParam.HasValue == true))
           {
         	   elevation = elevationParam.AsDouble();
           }
        
            var kinkyParam = element.GetParameters("Oś otworu").FirstOrDefault();
            if ((kinkyParam != null) && (kinkyParam.IsReadOnly == false))
            {
        	    kinkyParam.Set(elevation);
        	    toSelect.Add(element.Id);
            }
        }
    
        t.Commit(); 
    }
    // 4. Report 
    if (toSelect.Count > 0)
    {
        TaskDialog.Show("Wykonano na " + toSelect.Count + " otworach", "Zakończono: Rzędna - oś otworu - otwór okrągły oraz otwór prostokątny");
    }
    else
    {
        TaskDialog.Show("Revit", "Nie znaleziono obiektów");
    }
    this.ActiveUIDocument.Selection.SetElementIds(toSelect);
}

ogólnie problem był w tym, że paramet w wersji angielskiej się nie nazywa Elevation tylko Elevation from Level, ale przy okazji poprawiłem resztę głupot w kodzie. Zamiast nazw parametrów lepiej używać ich idków, to samo tyczy się parametru Oś otworu, mam nadzieje że to parmetr współdzielony/shared i lepiej jego nazwę zastąpić GUIDem.

Ogólnie przy programowaniu pod Revita polecam używać Revit database explorer (RDBE), koniec reklamy :D.

1 użytkowników online, w tym zalogowanych: 0, gości: 1