CAD
Ihr Add-in setzt auf Knopfdruck das Schriftfeld in jedes Layout. Der Block sieht gut aus – aber Zeichnungsnummer, Datum und Bearbeiter fehlen. Oder die Stückliste zählt weniger Türen, als im Plan stehen. Beides hat eine einfache Ursache.
Stempel und Abdruck
Eine Blockdefinition ist wie ein Firmenstempel: Sie beschreibt einmal, woraus der Block besteht. Jede Blockreferenz ist ein Abdruck, der nur sagt, wo der Block steht, wie er gedreht und wie groß er ist. Anders als im Büro ändern sich in AutoCAD alle Abdrücke mit, wenn man den Stempel umschnitzt – denn die Referenz verweist nur auf die Definition. Dasselbe Prinzip gilt für Attribute:
| Was | Definition (einmal) | Referenz (beliebig oft) |
|---|---|---|
| Block | BlockTableRecord in der BlockTable |
BlockReference |
| Attribut | AttributeDefinition in der Blockdefinition |
AttributeReference an der Blockreferenz |
Vorsicht: BlockReference.BlockTableRecord ist eine ObjectId, kein Objekt.
Eine Blockdefinition anlegen
Eine Definition ist ein BlockTableRecord wie der Modellbereich, nur wird sie selbst nicht gezeichnet. Drei Regeln ersparen Ärger:
- Reihenfolge: Erst kommt die Definition mit
Addin dieBlockTableund mitAddNewlyCreatedDBObjectin die Transaktion, dann folgen die Elemente. Umgekehrt gibt esErrorStatus.NotInDatabase. - Layer 0: Elemente ohne Layerangabe landen auch im Block auf dem aktuellen Layer. Setzen Sie
LayerId = db.LayerZero, damit sich der Block nach dem Layer der Referenz richtet. Mit der Farbe VonBlock (ColorIndex = 0) folgt ein Element der Farbe der Referenz. - Basispunkt: Zeichnen Sie die Elemente um den Ursprung herum.
Originbleibt dann (0,0,0), so wie es auch der Befehl_BLOCKmacht.
Attribute beim Einfügen selbst anlegen
Hier liegt der häufigste Fehler. Fügt der Anwender einen Block mit _INSERT ein, legt AutoCAD für jede Attributdefinition ein Attribut an der Referenz an. Wer per Code eine BlockReference einfügt, bekommt nur die Referenz. Die Attribute muss er selbst erzeugen:
// Blockreferenz einfügen und – wie _INSERT – die Attribute selbst anlegen
public static ObjectId FügeEinMitAttributen(Transaction tr, BlockTableRecord besitzer,
ObjectId blockId, Point3d position, IDictionary<string, string> werte)
{
var referenz = new BlockReference(position, blockId);
var ergebnis = besitzer.AppendEntity(referenz);
tr.AddNewlyCreatedDBObject(referenz, true);
var definition = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
foreach (ObjectId elementId in definition)
{
// Konstante Attribute bleiben in der Definition, die Referenz bekommt keins
if (tr.GetObject(elementId, OpenMode.ForRead) is AttributeDefinition attDef
&& !attDef.Constant)
{
var attribut = new AttributeReference();
// Übernimmt Tag, Vorgabe, Stil und Lage – umgerechnet in die Zeichnung
attribut.SetAttributeFromBlock(attDef, referenz.BlockTransform);
if (werte.TryGetValue(attDef.Tag, out var wert))
{
attribut.TextString = wert;
}
referenz.AttributeCollection.AppendAttribute(attribut);
tr.AddNewlyCreatedDBObject(attribut, true);
}
}
return ergebnis;
}
SetAttributeFromBlock übernimmt Tag, Vorgabewert, Texthöhe, Stil und Layer aus der Definition. Die BlockTransform der Referenz braucht die Methode für die Lage: Die Definition hat Blockkoordinaten, das Attribut an der Referenz Weltkoordinaten. Mit einer falschen Matrix stünden die Attribute rund um den Ursprung der Zeichnung. Legen Sie das Wörterbuch mit StringComparer.OrdinalIgnoreCase an, denn Tags werden gern unterschiedlich geschrieben.
Werte lesen und ändern
Die AttributeCollection einer Referenz enthält keine Attribute, sondern deren ObjectIds. Jedes Attribut öffnen Sie über die Transaktion, finden es über den Tag – ohne Rücksicht auf Groß- und Kleinschreibung – und öffnen es mit UpgradeOpen zum Schreiben. Bei zentrierten oder rechtsbündigen Attributen rufen Sie nach dem Setzen von TextString die Methode AdjustAlignment auf, damit die Position neu berechnet wird. Zwei Besonderheiten:
- Konstante Attribute haben keine
AttributeReference. Ihr Wert steht nur in der Definition. Wer alle Attribute einer Referenz auflisten will, muss auch dort nachsehen. - Neue Attributdefinitionen erreichen vorhandene Referenzen nicht von selbst. Erst das Synchronisieren gleicht sie ab, mit
_ATTSYNCoder eigenem Code. Wer dabei über den Tag abgleicht, verliert bei einem umbenannten Tag den Wert.
Dynamische Blöcke: Der Name täuscht
Ändert der Anwender bei einem dynamischen Block eine Eigenschaft, etwa die Türbreite, legt AutoCAD einen anonymen Block an – eine Kopie mit der geänderten Geometrie – und lässt die Referenz darauf zeigen. Ihr Name lautet dann zum Beispiel *U12. Den Namen, den der Anwender sieht, liefert DynamicBlockTableRecord. Und GetBlockReferenceIds findet nur die Referenzen mit Vorgabewerten – so entsteht die zu kurze Türliste. Alle Referenzen finden Sie über die anonymen Blöcke:
// Alle Referenzen eines dynamischen Blocks – auch die geänderten (*U…)
var definition = (BlockTableRecord)tr.GetObject(definitionId, OpenMode.ForRead);
var alle = definition.GetBlockReferenceIds(true, false).Cast<ObjectId>().ToList();
foreach (ObjectId anonymId in definition.GetAnonymousBlockIds())
{
var anonym = (BlockTableRecord)tr.GetObject(anonymId, OpenMode.ForRead);
alle.AddRange(anonym.GetBlockReferenceIds(true, false).Cast<ObjectId>());
}
Die dynamischen Eigenschaften stehen nicht in der AttributeCollection, sondern in der DynamicBlockReferencePropertyCollection. Gesetzt wird ein Wert mit genau dem Typ, den er hat: Double, Int16 oder String, Winkel im Bogenmaß. Anlegen lässt sich ein dynamischer Block per .NET nicht; das Add-in holt ihn mit WblockCloneObjects aus einer Bibliothekszeichnung.
Typische Fehler
- Eine Referenz per Code einfügen und die Attribute vergessen.
SetAttributeFromBlockmitMatrix3d.Identitystatt mit derBlockTransformaufrufen.- Elemente der Definition ohne Layer anlegen – sie landen auf dem aktuellen Layer.
- Blöcke über ihren Namen zählen und die anonymen Blöcke dynamischer Blöcke übersehen.
- Ein Element der Blockdefinition ändern und glauben, nur eine Referenz sei betroffen.
So helfen wir
- Schulung: In der Schulung „AutoCAD .NET API mit C#“ programmieren Sie Blöcke, Attribute und dynamische Blöcke mit AutoCAD 2027.
- Add-in-Check: Wir prüfen Ihr Add-in auf diese Fallen und auf AutoCAD 2027 – als Einstiegspaket zum Festpreis.
- Entwicklung: Stücklisten, Schriftfelder, Blockbibliotheken – sprechen Sie uns an.
- Das Buch: Ausführlich steht alles in Ebi F. Eilbers Fachbuch „AutoCAD .NET API“, das voraussichtlich 2027 erscheint.
Quelle: Ebi F. Eilber, AutoCAD .NET API (Fachbuch, erscheint voraussichtlich 2027), Kapitel „Blöcke“, „Attribute“ und „Dynamische Blöcke“
