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
Résolu ! Accéder à la solution.
Résolu par _gile. Accéder à la solution.
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
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
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
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(); } } } }
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
Hello
WHAOU ! Gilles t'a developpe un programme "aux petits oignons" !
Pour charger une DLL sous AutoCAD, Commande : NETLOAD
Puis Commande: SYNCNEWATT
Patrice BRAUD
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); } } } } }
ça fonctionne
Merci Merci beaucoup Merci gile c'est royal
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.
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
Hello
Voici SYN.lsp vs 1.23 ...
SVP tu nous diras sur quelle version d'AutoCAD tu vas l'utiliser avec succes !?
Patrice BRAUD
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.