Communauté
AutoCAD – tous produits - Français
Bienvenue sur les forums AutoCAD d’Autodesk. Partagez vos connaissances, posez des questions, et explorez les sujets AutoCAD populaires.
annuler
Affichage des résultats de 
Afficher  uniquement  | Rechercher plutôt 
Vouliez-vous dire : 

Ajout d'un attribut dans un bloc

13 RÉPONSES 13
RÉSOLU
Répondre
Message 1 sur 14
BE78
6629 Visites, 13 Réponses

Ajout d'un attribut dans un bloc

Bonjour 

 

Je voudrait rajouter un attribut dans un bloc qui en contient déjà 2. (ça je sais faire)

 

Mon problème c'est que pour l'attribut soit pris en compte il faut exécuter la commande ATTSYNC ce qui me replace tous les attributs de mon dessin à leur place originale... ce que je ne veux pas

 

Je ne veux pas car sur un plan j'ai 300 blocs identique dont j'ai déjà déplacé un à un les attributs pour qu'il soit lisible et bien placé.

 

Hors si j'effectue la commande ATTSYNC tous mes attributs vont se déplacer et je devrai tout recommencer.

 

Quelqu'un connais une possibilité ???

 

Merci de votre aide

 

 

13 RÉPONSES 13
Message 2 sur 14
100james
en réponse à: BE78

bonjour

 

le fait d'avoir déplacer les attributs de ton bloc rend ton bloc "différent" tu as bien une seule occurence de ton bloc mais de 300 présentation différentes  .... 

 

tu aurais du faire l'inverse d'abord modifier ton bloc, lancer attsync pour synchroniser, puis déplacer tes attributs

ATTSYNC synchronise les blocs avec attributs par rapport à l'original, position tailles etc...cette commande ne garde pas le déplacement manuel des attributs 

 

peut etre qu'avec un lisp

Message 3 sur 14
BE78
en réponse à: 100james

Smiley gêné

Oh que oui j'aurais du faire les choses à l'endroit.

 

Voilà pourquoi maintenant je demande de l'aide parce que j'ai pas réfléchi avant d'agir.

 

Un lisp pour me sauver ça serait l'idéal Smiley heureux

Message 4 sur 14
kwizats_haderack
en réponse à: BE78

Bonjour,
est ce que tu as essayé avec ATTREDEF.
Bien cordialement / Best regards

----------------------------------------------------

Erwan ( FRENCH AUTOCAD M.E.P CAD/BIM MANAGER )
Message 5 sur 14
BE78
en réponse à: BE78

Bonjour 

 

ATTREDEF ne marche pas non plus il me replace les attribut à leur place initiale.

 

Quelqu'un à pas un petit lisp qui me permettrait de faire cette action sans changer la place des attribut ???

 

Merci de votre aide

Message 6 sur 14
_gile
en réponse à: BE78

Salut,

 

Je ne suis pas sûr que ce soit possible en LISP, mais je te propose un petit truc vite fait en .NET

Télécharge le fichier SynchronizeNewlyAddedAttribute.zip joint.

Il contient 2 Dlls, il est possible que tu aies besoin de les "débloquer".

 

Charge la DLL correspondant à la version d'autoCAD que tu utilises (SynchronizeNewlyAddedAttribute_18.dll pour AutoCAD 2010-2012 et SynchronizeNewlyAddedAttribute_19 pour AutoCAD 2013+).

Lance la commande SYNCNEWATT et sélectionne le bloc à synchroniser.

 

En l'état, la commande ne fonctionne pas avec les blocs dynamiques, si c'était nécessaire je modifierais le code.

 

Pour ceux que ça intéresse, le code (C#) :

 

// (C) Copyright 2012 by Gilles Chanteau 
//
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(SynchronizeNewlyAddedAttribute.CommandMethods))]

namespace SynchronizeNewlyAddedAttribute
{
    public class CommandMethods
    {
        [CommandMethod("SyncNewAtt", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSélectionnez le bloc à synchroniser: ");
            peo.SetRejectMessage("Object non valide.");
            peo.AddAllowedClass(typeof(BlockReference), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var bRef = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                var btr = (BlockTableRecord)tr.GetObject(bRef.BlockTableRecord, OpenMode.ForRead);
                var attDefs = btr.Cast<ObjectId>()
                    .Where(id => id.ObjectClass == RXClass.GetClass(typeof(AttributeDefinition)))
                    .Select(id => (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead))
                    .ToArray();
                foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
                {
                    var br = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
                    var attRefs = new HashSet<string>(
                        br.AttributeCollection.Cast<ObjectId>()
                        .Select(attId => ((AttributeReference)tr.GetObject(attId, OpenMode.ForRead)).Tag));
                    foreach (var attDef in attDefs)
                    {
                        if (!attRefs.Contains(attDef.Tag))
                        {
                            var attRef = new AttributeReference();
                            attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                            br.AttributeCollection.AppendAttribute(attRef);
                            tr.AddNewlyCreatedDBObject(attRef, true);
                        }
                    }
                }
                tr.Commit();
            }
        }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 sur 14
BE78
en réponse à: _gile

Merci gile de ta réponse

 

Comment je fais pour charger le DLL 

Faut il que je le place à un endroit en particulier?? que dois-je faire??

 

Apparemment il est pas bloqué et je suis en version Autocad 2012 donc j'ai pris le fichier SynchronizeNewlyAddedAttribute_18.dll 

 

Merci de ta réponse

 

Message 8 sur 14
braudpat
en réponse à: BE78

 

Hello

 

WHAOU !  Gilles t'a developpe un programme "aux petits oignons" !

 

Pour charger une DLL sous AutoCAD, Commande : NETLOAD

 

Puis Commande:  SYNCNEWATT

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 9 sur 14
_gile
en réponse à: BE78

Tu n'as pas besoin de placer la DLL dans un répertoire particuler (excepté à partir de A2014 où il vaut mieux la placer dans un "répertoire approuvé" (TRUSTEDPATHS).

 

Comme l'a dit Patrice, pour charger une DLL .NET, il faut lancer la commande NETLOAD.

 

Ci-joint une version qui fonctionne aussi avec les blocs dynamiques.

 

Le code :

 

// (C) Copyright 2012 by Gilles Chanteau 
//
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(SynchronizeNewlyAddedAttribute.CommandMethods))]

namespace SynchronizeNewlyAddedAttribute
{
    public class CommandMethods
    {
        [CommandMethod("SyncNewAtt", CommandFlags.Modal)]
        public void Test()
        {
            Document doc = AcAp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nSélectionnez le bloc à synchroniser: ");
            peo.SetRejectMessage("Object non valide.");
            peo.AddAllowedClass(typeof(BlockReference), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                var bRef = (BlockReference)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                bool isDyn = bRef.IsDynamicBlock;
                var btr = isDyn ?
                    (BlockTableRecord)tr.GetObject(bRef.DynamicBlockTableRecord, OpenMode.ForRead) :
                    (BlockTableRecord)tr.GetObject(bRef.BlockTableRecord, OpenMode.ForRead);
                var attDefs = GetAttributeDefinitions(btr);
                foreach (ObjectId id in btr.GetBlockReferenceIds(true, false))
                {
                    SyncAtt(id, attDefs);
                }
                if (isDyn)
                {
                    btr.UpdateAnonymousBlocks();
                    foreach (ObjectId dynId in btr.GetAnonymousBlockIds())
                    {
                        var dynBtr = (BlockTableRecord)tr.GetObject(dynId, OpenMode.ForRead);
                        var dynAttDefs = GetAttributeDefinitions(dynBtr);
                        foreach (ObjectId brId in dynBtr.GetBlockReferenceIds(true, false))
                        {
                            SyncAtt(brId, dynAttDefs);
                        }
                    }
                }
                tr.Commit();
            }
        }

        private static AttributeDefinition[] GetAttributeDefinitions(BlockTableRecord btr)
        {
            return btr.Cast<ObjectId>()
                .Where(id => id.ObjectClass == RXClass.GetClass(typeof(AttributeDefinition)))
                .Select(id => (AttributeDefinition)id.GetObject(OpenMode.ForRead))
                .ToArray();
        }

        private static void SyncAtt(ObjectId id, AttributeDefinition[] attDefs)
        {
            var br = (BlockReference)id.GetObject(OpenMode.ForWrite);
            var attRefs = new HashSet<string>(
                br.AttributeCollection
                .Cast<ObjectId>()
                .Select(attId => ((AttributeReference)attId.GetObject(OpenMode.ForRead)).Tag));
            foreach (var attDef in attDefs)
            {
                if (!attRefs.Contains(attDef.Tag))
                {
                    var attRef = new AttributeReference();
                    attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
                    br.AttributeCollection.AppendAttribute(attRef);
                    attDef.Database.TransactionManager.AddNewlyCreatedDBObject(attRef, true);
                }
            }
        }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 10 sur 14
BE78
en réponse à: BE78

Smiley heureux

Smiley heureux

Smiley heureux

Smiley heureux

Smiley heureux

 

ça fonctionne 

Merci Merci beaucoup Merci gile c'est royal

 

Smiley heureux

Smiley heureux

Smiley heureux

Smiley heureux

Smiley heureux

 

J'utilise pas les bloc dynamique donc je laisse le soin à ceux que ça interesse et qui en ont besoin de vérifier le fonctionnement.

 

Merci encore des heures de travail que je n'aurais pas à faire.

 

Smiley clignant de l'œil

Message 11 sur 14
ahbevi
en réponse à: BE78

Salut a tous,
il existe aussi le lisp "SYN.LSP V1.23
Synchroniser en conservant ou pas la valeur, la position
et l'angle des attributs.de Patrick_35"
si cela peut aider aussi.
ahg
Message 12 sur 14
magdi_95
en réponse à: ahbevi

Bonjour ahbevi,

Aurais tu ce lisp encore sous la main SYN.lsp je ne l'ai trouver ni sur ce forum, ni sur le site de Patrick!

Merci d'avance

Magdi

Message 13 sur 14
braudpat
en réponse à: magdi_95

 

Hello

 

Voici SYN.lsp vs 1.23 ...

 

SVP tu nous diras sur quelle version d'AutoCAD tu vas l'utiliser avec succes !?

 

 

Patrice ( Supporting Troops ) - Autodesk Expert Elite
If you are happy with my answer please mark "Accept as Solution" and if very happy please give me a Kudos (Felicitations) - Thanks

Patrice BRAUD

EESignature


Message 14 sur 14
magdi_95
en réponse à: braudpat

Bonjour Braudpat

Merci pour l'envoi du lisp, il fonctionne tres bien sur version pleine Autocad 2013

Bonne journée

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