Communauté
BIM Revit, BIM et Autodesk Construction Cloud (ACC) - Français
Bienvenue sur le forum AEC francophone dédié aux solutions BIM de la société Autodesk. Cet espace est dédié aux professionnels et passionnés du secteur de l'Architecture, de l'Ingénierie et de la Construction (AEC) qui utilisent le logiciel Revit ainsi que les plateformes collaboratives d'Autodesk (ACC et Autodesk Forma). Partagez vos connaissances, posez des questions, collaborez sur des idées, et explorez les sujets, que vous soyez architecte, ingénieur, gestionnaire de projet ou tout autre acteur de l'AEC.
annuler
Affichage des résultats de 
Afficher  uniquement  | Rechercher plutôt 
Vouliez-vous dire : 

Maintenir a jour une base de données - Revit API - C#

13 RÉPONSES 13
RÉSOLU
Répondre
Message 1 sur 14
samuel.cailletMDQ7N
770 Visites, 13 Réponses

Maintenir a jour une base de données - Revit API - C#

Bonjour,

Je développe un plugin qui vérifie des informations dans le modèle et je rencontre une difficulté.
En effet, je ne parviens pas à maintenir à jour ma base de données dans le cas d'une suppression d'un element...
Cela peut paraitre simple mais je bloque sur ce point et viens ici demander de l'aide après de nombreuses tentatives infructueuses.
Pour toutes autres modifications, ma base de données reste à jour grâce à l'utilisation de "GetModifiedElementIds Method".

En revanche, pour la partie suppression, l'utilisation de "GetDeletedElementIds Method" ne m'aide pas vraiment. Comme soulevé ici il serait intéressant d'avoir plus d'informations retourné de l'évènement de suppression.

Enfin, voici ma question, comment maintenir à jour ma base de donné dans le cas d'un element supprimer ?
J'ai bien tenté ceci mais cela ne donne rien comme si une exception était présente pour autant rien ne s'affiche en débogage.

 

 

ICollection<ElementId> DeletedIds = e.GetDeletedElementIds();
foreach (ElementId id in DeletedIds)
{
   foreach ( Element element in ListElementInMyDataBase)
   {
      if(element.id == id)
      {
         //Do Something
      }
   }
}

 

 

Quelqu'un aurait une idée ? 
Toutes aide seraient grandement appréciées !
Merci d'avance aux éventuelles réponses.
Samuel Caillet

Étiquettes (2)
13 RÉPONSES 13
Message 2 sur 14

Salut,

 

effectivement la difficulté de travailler avec les élément supprimés c'est que tu ne peu plus récupérer d'infos et donc mettre à jour ta bdd.

Première solution faire les liaisons au sein de ta bdd :  une info est relié  à un id.

l'autre solution c'est qu'à chaque sélection d'objet, tu le sauvegarde dans une variable, ainsi lorsque tu passe dans l'évent de suppression, tu te réfère à tes variables pour avoir accès aux infos.

 

😉



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 3 sur 14

Merci beaucoup pour ta réponse 🙂

J'avoue ne pas bien comprendre ta première suggestion, qu'appel tu une liaison au sein de ma bdd ?

 

une info est relié  à un id.


Ok, mais je ne vois pas comment m'en servir. Dans mon exemple, je souhaite comparer l'id supprimé avec l'id de l'element de la base de donné mais cela ne fonctionne pas.
Dans ta deuxième proposition tu suggères de récupérer les infos des éléments sélectionnés a chaque SelectionChange, sauf erreur je n'ai pas trouvé l'existence d'un tel event.
The Building Coder: Element Selection Changed Event (typepad.com)
Le sujet est abordé ici , mais cette solution ne satisfait pas les attentes car d'après ce que j'ai compris, si un element est ajouté à la sélection existante l'element n'est pas pris en compte...

Message 4 sur 14

Salut,

 

suite a votre message je ne comprend pas bien votre problématique.

Au sein d'un IUpdater, vous récupérer bien l'ID des éléments supprimé :

 public class DetectModifications : IUpdater
    {
        UpdaterId m_updaterId = null;

        public void Execute(UpdaterData data)
        {
            Document doc = data.GetDocument();

            if (data.GetDeletedElementIds().Count() > 0)
            {
                ICollection<ElementId> lstIds = data.GetDeletedElementIds();
               //your code with all deleted ids
            }

        }

        public string GetAdditionalInformation()
        {
            return "This updater checks for changes in Project Param value";
        }

        public ChangePriority GetChangePriority()
        {
            return ChangePriority.Masses;
        }

        public UpdaterId GetUpdaterId()
        {
            return m_updaterId;
        }

        public string GetUpdaterName()
        {
            return "Test Updater";
        }

        public DetectModifications(AddInId id)
        {
            m_updaterId = new UpdaterId(id, new Guid("88928A42-4660-414B-BA51-04F9CDF6CD22"));
        }
    }

 

😉



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 5 sur 14

Pour compléter ma réponse précédente, le fonctionnement est le même avec Event DocumentChanged :

private void App_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
        {
            ICollection<ElementId> collIdDeleted = e.GetDeletedElementIds();
            if (collIdDeleted .Count() > 0)
            {
                //Your code with deleted ids
            }
        }

 

😉



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 6 sur 14

Oui c'est bien ca, j'obtiens comme il faut la liste des id supprimer, mon problème c'est que je ne sais pas quoi en faire.
Quand je souhaite vérifier les id de ma liste avec les id supprimé la commande n'aboutit pas.

ICollection<ElementId> DeletedIds = e.GetDeletedElementIds();
foreach (ElementId id in DeletedIds)
{
   foreach ( Element element in ListElementInMyDataBase)
   {
      if(element.id == id)//ICI Jamais true...
      {
         //Do Something
      }
   }
}

 Dans l'idéal, avec cette condition if, je serai en mesure de directement retirer l'element de la bdd. 

Message 7 sur 14

Salut,

 

donc le problème provient de la base de données !!

Comment est-elle constituée ?

 

😉



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 8 sur 14

Et bien, ce n'est rein de plus qu'une liste d'element.

List<Element> ListElementInMyDataBase = new List<Element> ();

Pour lire la liste je fais donc ceci :

foreach ( Element element in ListElementInMyDataBase)

Je parviens à lire l'id de chaque element c'est lors de la confrontation avec l'id supprimer que cela bloque...
Je suis désolé si je ne m'explique pas bien. 😅

Message 9 sur 14

Ok,

 

donc c'est pour cela que votre code ne fonctionne pas !! En fonctionnant ainsi votre liste est lié à la base Revit donc lors de la suppression de l'objet dans la base Revit, votre liste se met à jour et les objets ne sont plus à jour !

Il faut créer une classe spécifique contenant les informations des objets que vous souhaitez conserver.

A chaque élément à ajouter a votre base de donnée vous ajouter un objet de votre classe.

Ainsi lors de la suppression vous pourrez comparer sans problème.

 

😉

 

 



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 10 sur 14

Ok, je crois comprendre, je vais faire quelques essais et je reviendrais poster un message pour clôturer le sujet dans le cas d'une réussite. 
Merci pour ton aide, à mon tour de joué 😀

Message 11 sur 14

Bonjour,

Bon, il y a du mieux, je parviens à mettre à jour la bdd suite à une suppression, j'ai en effet changé la méthode de stockage.
Dans le cas d'un retour en arrière, je souhaite que la bdd retrouve l'element supprimé. Comment faire ceci ?
J'utilise DocumentChangedEvent, qui prend en compte le retour en arrière mais ici cela ne récupère pas les infos.

Message 12 sur 14

Salut,

 

effectivement lors d'un retour en arrière, on a pas accès aux élément remis en place dans le projet.

Je te propose une solution :

Lors de la suppression d'un élément, stockage de celui-ci dans une liste d'objets supprimés. Lors d'un retour en arrière (utiliser le type d'opération pour le détecter : TransactionUndone, TransactionRedone) analyser la liste des objets supprimer via leur ID afin de vérifier la présence de l'objet dans le projet.

S'il est présent, alors il faut le remettre dans la bdd du projet.

 

😉



PIRO Charles
Developer

PIRO CIE
Linkedin


Message 13 sur 14

Bonjour,

Si j'ai bien compris ta proposition cela donnerai quelque choses dans ce style là.

 

static void OnDocumentChanged(object sender,DocumentChangedEventArgs e)
        {
            Document doc = e.GetDocument();

            if(e.Operation.ToString() == "TransactionUndone")
            {
                foreach (Object item in DataSaveDeletedObject)
                {
                        if (doc.GetElement(item.Id) != null)
                        {
                            //Remise en place de l'objet dans la liste de sauvegarde
                            DataSaveObject.Add(item);
                            
                            //suppression de l'objet dans la liste des objets supprimé
                            DataSaveDeletedObject.Remove(item);
                        }
                }
            }
        }

 

Pour détecter une Transaction Undone j'ai trouvé que cela.
Ce n'est pas idéal car a chaque annulation quelle que soit sa nature, je scan les Objects supprimé pour voir si l'un d'entre eux est revenue dans le projet.
Le truc c'est que dans mon test, l'objet n'est pas détecté dans le projet comme si il ne revenait qu'après l'opération ci-dessus... Tu confirmes où j'ai fait une erreur quelque part ? J'ai correctement interprété ta proposition ?

Message 14 sur 14

Bonjour,

Je reviens vers toi après quelques essaies, je ne suis pas parvenu à suivre ta proposition.

Saurais-tu m'en dire plus ? 🤔

Vous n'avez pas trouvé ce que vous recherchiez ? Posez une question à la communauté ou partagez vos connaissances.

Publier dans les forums  

Autodesk Design & Make Report