Goud Posté(e) le 1 mai 2019 Posté(e) le 1 mai 2019 Bonjour à tous, J'aimerai modifier l'attribut d'un bloc précédemment importé d'un dwg extérieur. J'importe mon bloc : public void ajouterblocs() { // Get the current document and database Document acDoc = Application.DocumentManager.MdiActiveDocument; Database acCurDb = acDoc.Database; Editor ed = acDoc.Editor; using (acDoc.LockDocument()) // Create a transaction for the current drawing using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction()) { BlockTable blkTbl = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead); if (!blkTbl.Has("COT-altimétrie")) { string blockQualifiedFileName = "C:/Users/antoi/Documents/GitHub/GenDet/GenDet/GenDet/blocs/cotealtimetrie.dwg"; Database tmpDb = new Database(false, true); tmpDb.ReadDwgFile(blockQualifiedFileName, System.IO.FileShare.ReadWrite, true, ""); IdMapping iMap = new IdMapping(); ObjectIdCollection ids = new ObjectIdCollection(); using (Transaction tr = tmpDb.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(tmpDb.BlockTableId, OpenMode.ForRead); ids.Add(bt["COT-altimétrie"]); ids.Add(bt["COT-altimétrie-inf"]); tr.Commit(); } acCurDb.WblockCloneObjects(ids, acCurDb.BlockTableId, iMap, DuplicateRecordCloning.Ignore, false); } acTrans.Commit(); } } Ensuite, j'insère mon bloc dans le Model Space (cela marche) et j'essaie de modifier son attribut mais le "AttributeCollection" est vide : private void cotealti(Document acDoc, Database acCurDb, BlockTable blkTbl, BlockTableRecord btr, Transaction acTrans, double x, double y, double altimetrie, int inf) { BlockReference bloccotealti; if (inf == 1) bloccotealti = new BlockReference(new Point3d(x, y, 0), blkTbl["COT-altimétrie-inf"]); else bloccotealti = new BlockReference(new Point3d(x, y, 0), blkTbl["COT-altimétrie"]); using (bloccotealti) { bloccotealti.TransformBy(Matrix3d.Scaling(500, new Point3d(x, y, 0))); btr.AppendEntity(bloccotealti); acTrans.AddNewlyCreatedDBObject(bloccotealti, true); if (inf == 1) acDoc.SendStringToExecute("_.attsync Nom COT-altimétrie-inf" + "\n", true, false, true); else acDoc.SendStringToExecute("_.attsync Nom COT-altimétrie" + "\n", true, false, true); ObjectId arId = bloccotealti.AttributeCollection[0]; DBObject objetatt = acTrans.GetObject(arId, OpenMode.ForRead); AttributeReference ar = objetatt as AttributeReference; ar.UpgradeOpen(); ar.TextString = altimetrie.ToString(); ar.DowngradeOpen(); } } Je n'ai pas copié tout le code car il est très long et sans rapport avec le problème je pense. N'hésitez pas à me demander ce que j'ai oublié de préciser pour que vous puissiez, je l'espère, m'aider. Merci Edit : Lorsque je mets en commentaires la partie de modification de l'attribut, le bloc est bien inséré et je peux modifier son attribut manuellement.
(gile) Posté(e) le 1 mai 2019 Posté(e) le 1 mai 2019 Salut, En .NET (comme en AutoLISP avec entmake), il revient au programme de créer explicitement les références d'attribut liée à la référence de bloc insérée.Tu peux voir ce sujet de la documentation du développeur. Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Goud Posté(e) le 1 mai 2019 Auteur Posté(e) le 1 mai 2019 Salut Gille, Oui je me suis justement inspiré de ce sujet pour la partie de modification de l'attribut. Mon programme est appelé depuis un bouton créé sur une palette (WPF) insérée. Si j'essaie d'insérer le bloc + modifier son attribut à partir du même bouton de la palette, cela donne le problème évoqué dans mon premier message. En revanche, si j'insère le bloc depuis un bouton puis j'essaie de modifier son attribut à partir d'un 2ème bouton, cela fonctionne correctement. Je me suis dis qu'il était possible de faire les deux sans passer par un second bouton.
(gile) Posté(e) le 1 mai 2019 Posté(e) le 1 mai 2019 Le problème avec ton code, c'est que tu ajoutes les références d'attribut avec la commande ATTSYNC que tu lances avec SendStringToExecute qui est asynchrone (la commande n'est exécutée qu'a la fin de la méthode). Tu peux ajouter explicitement les attributs comme dans le code de la documentation. private void CoteAlti(Database db, BlockTable bt, BlockTableRecord owner, Transaction tr, double x, double y, double alt, int inf) { BlockReference blocCoteAlti; if (inf == 1) blocCoteAlti = new BlockReference(new Point3d(x, y, 0), bt["COT-altimétrie-inf"]); else blocCoteAlti = new BlockReference(new Point3d(x, y, 0), bt["COT-altimétrie"]); using (blocCoteAlti) { blocCoteAlti.TransformBy(Matrix3d.Scaling(500, new Point3d(x, y, 0))); owner.AppendEntity(blocCoteAlti); tr.AddNewlyCreatedDBObject(blocCoteAlti, true); // ajout des références d'attribut var btr = (BlockTableRecord)tr.GetObject(blocCoteAlti.BlockTableRecord, OpenMode.ForRead); bool first = true; foreach (ObjectId id in btr) { if (id.ObjectClass.DxfName == "ATTDEF") { var attDef = (AttributeDefinition)tr.GetObject(id, OpenMode.ForRead); if (!attDef.Constant) { var attRef = new AttributeReference(); attRef.SetAttributeFromBlock(attDef, blocCoteAlti.BlockTransform); if (first) attRef.TextString = alt.ToString(); first = false; owner.AppendEntity(attRef); tr.AddNewlyCreatedDBObject(attRef, true); } } } } } Gilles Chanteau - gileCAD - GitHub Développements sur mesure pour AutoCAD
Goud Posté(e) le 12 mai 2019 Auteur Posté(e) le 12 mai 2019 Bonjour gile, Merci pour ta réponse ! J'avais en revanche une erreur du type ":eIllegalEntityType".J'ai juste du remplacer "owner.AppendEntity(attRef);" par "bloccotealti.AttributeCollection.AppendAttribute(attRef);" pour que cela fonctionne.
Messages recommandés
Créer un compte ou se connecter pour commenter
Vous devez être membre afin de pouvoir déposer un commentaire
Créer un compte
Créez un compte sur notre communauté. C’est facile !
Créer un nouveau compteSe connecter
Vous avez déjà un compte ? Connectez-vous ici.
Connectez-vous maintenant